diff --git a/dashboard/README.md b/dashboard/README.md index aa62a9a5..5df9bfb7 100644 --- a/dashboard/README.md +++ b/dashboard/README.md @@ -2,7 +2,4 @@ ![](assets/screenshot.png) -Web application providing specialised interaction UI for the APIs -presented by the `node-microservices` apps, such as -[attic](https://github.com/c-d-lewis/attic) or -[visuals](https://github.com/c-d-lewis/visuals). +Webapp to monitor device fleet and issue commands. diff --git a/dashboard/assets/app.png b/dashboard/assets/images/app.png similarity index 100% rename from dashboard/assets/app.png rename to dashboard/assets/images/app.png diff --git a/dashboard/assets/commit.png b/dashboard/assets/images/commit.png similarity index 100% rename from dashboard/assets/commit.png rename to dashboard/assets/images/commit.png diff --git a/dashboard/assets/disk.png b/dashboard/assets/images/disk.png similarity index 100% rename from dashboard/assets/disk.png rename to dashboard/assets/images/disk.png diff --git a/dashboard/assets/eye.png b/dashboard/assets/images/eye.png similarity index 100% rename from dashboard/assets/eye.png rename to dashboard/assets/images/eye.png diff --git a/dashboard/assets/other.png b/dashboard/assets/images/other.png similarity index 100% rename from dashboard/assets/other.png rename to dashboard/assets/images/other.png diff --git a/dashboard/assets/pc.png b/dashboard/assets/images/pc.png similarity index 100% rename from dashboard/assets/pc.png rename to dashboard/assets/images/pc.png diff --git a/dashboard/assets/raspberrypi.png b/dashboard/assets/images/raspberrypi.png similarity index 100% rename from dashboard/assets/raspberrypi.png rename to dashboard/assets/images/raspberrypi.png diff --git a/dashboard/assets/restart.png b/dashboard/assets/images/restart.png similarity index 100% rename from dashboard/assets/restart.png rename to dashboard/assets/images/restart.png diff --git a/dashboard/assets/server-white.png b/dashboard/assets/images/server-white.png similarity index 100% rename from dashboard/assets/server-white.png rename to dashboard/assets/images/server-white.png diff --git a/dashboard/assets/shutdown.png b/dashboard/assets/images/shutdown.png similarity index 100% rename from dashboard/assets/shutdown.png rename to dashboard/assets/images/shutdown.png diff --git a/dashboard2/assets/images/uptime.png b/dashboard/assets/images/uptime.png similarity index 100% rename from dashboard2/assets/images/uptime.png rename to dashboard/assets/images/uptime.png diff --git a/dashboard/css/global.css b/dashboard/css/global.css index a2b029df..8c838b3a 100644 --- a/dashboard/css/global.css +++ b/dashboard/css/global.css @@ -6,9 +6,5 @@ html, body, #app { margin: 0; width: 100%; height: 100%; - background-color: #222; -} - -tr { - margin-top: 10px; + background-color: #111; } diff --git a/dashboard/index.html b/dashboard/index.html index ab96df54..12799ce1 100644 --- a/dashboard/index.html +++ b/dashboard/index.html @@ -1,20 +1,20 @@ - Service Dashboard + Node Microservices Dashboard - + - + - + - \ No newline at end of file + diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index 2470a88d..1580e163 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -18,8 +18,7 @@ "http-server": "^14.1.1", "ts-loader": "^9.4.4", "typescript": "^5.1.6", - "webpack": "^5.88.1", - "webpack-cli": "^5.1.4" + "vite": "^5.4.10" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -43,15 +42,6 @@ "eslint-plugin-jsdoc": "^39.6.2" } }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/@es-joy/jsdoccomment": { "version": "0.36.1", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", @@ -67,6 +57,374 @@ "node": "^14 || ^16 || ^17 || ^18 || ^19" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -166,6 +524,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, + "peer": true, "engines": { "node": ">=6.0.0" } @@ -175,19 +534,22 @@ "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.4.tgz", "integrity": "sha512-KE/SxsDqNs3rrWwFHcRh15ZLVFrI0YoZtgAdIyIq9k5hUNmiWRXXThPomIxHuL20sLdgzbDFyvkUMna14bvtrw==", "deprecated": "the version has a bug with typescript type resolution", - "dev": true + "dev": true, + "peer": true }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.18", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "dev": true, + "peer": true, "dependencies": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" @@ -228,11 +590,246 @@ "node": ">= 8" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@types/eslint": { "version": "8.40.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz", "integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==", "dev": true, + "peer": true, "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -243,15 +840,16 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "dev": true, + "peer": true, "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "node_modules/@types/json-schema": { @@ -271,7 +869,8 @@ "version": "20.3.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@types/semver": { "version": "7.5.2", @@ -473,6 +1072,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -482,25 +1082,29 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -511,13 +1115,15 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -530,6 +1136,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, + "peer": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } @@ -539,6 +1146,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, + "peer": true, "dependencies": { "@xtuc/long": "4.2.2" } @@ -547,13 +1155,15 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -570,6 +1180,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -583,6 +1194,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -595,6 +1207,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -609,72 +1222,32 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, + "peer": true, "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/acorn": { "version": "8.9.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", "dev": true, + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -687,6 +1260,7 @@ "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, + "peer": true, "peerDependencies": { "acorn": "^8" } @@ -706,6 +1280,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -722,6 +1297,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "peer": true, "peerDependencies": { "ajv": "^6.9.1" } @@ -964,6 +1540,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001503", "electron-to-chromium": "^1.4.431", @@ -981,7 +1558,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/call-bind": { "version": "1.0.2", @@ -1024,7 +1602,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "peer": true }, "node_modules/chalk": { "version": "4.1.2", @@ -1047,24 +1626,11 @@ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true, + "peer": true, "engines": { "node": ">=6.0" } }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1083,17 +1649,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/comment-parser": { "version": "1.3.1", @@ -1133,6 +1694,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "peer": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1228,7 +1790,8 @@ "version": "1.4.447", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.447.tgz", "integrity": "sha512-sxX0LXh+uL41hSJsujAN86PjhrV/6c79XmpY0TvjZStV6VxIgarf8SRkUoUTuYmFcZQTemsoqo8qXOGw5npWfw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/enhanced-resolve": { "version": "5.15.0", @@ -1243,18 +1806,6 @@ "node": ">=10.13.0" } }, - "node_modules/envinfo": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", - "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/es-abstract": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", @@ -1313,7 +1864,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", - "dev": true + "dev": true, + "peer": true }, "node_modules/es-set-tostringtag": { "version": "2.0.1", @@ -1358,11 +1910,50 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, + "peer": true, "engines": { "node": ">=6" } @@ -1630,6 +2221,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -1723,6 +2315,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "peer": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -1735,6 +2328,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -1744,6 +2338,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, + "peer": true, "engines": { "node": ">=4.0" } @@ -1769,6 +2364,7 @@ "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, + "peer": true, "engines": { "node": ">=0.8.x" } @@ -1782,7 +2378,8 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "peer": true }, "node_modules/fast-glob": { "version": "3.3.1", @@ -1816,7 +2413,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -1825,15 +2423,6 @@ "dev": true, "peer": true }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "engines": { - "node": ">= 4.9.1" - } - }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -1944,6 +2533,20 @@ "dev": true, "peer": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2061,7 +2664,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/globals": { "version": "13.21.0", @@ -2324,25 +2928,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -2386,15 +2971,6 @@ "node": ">= 0.4" } }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -2550,18 +3126,6 @@ "node": ">=8" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -2664,22 +3228,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "peer": true }, "node_modules/jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "peer": true, "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -2694,6 +3251,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -2738,13 +3296,15 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "peer": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "peer": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -2776,15 +3336,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2804,6 +3355,7 @@ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", "dev": true, + "peer": true, "engines": { "node": ">=6.11.5" } @@ -2853,7 +3405,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "peer": true }, "node_modules/merge2": { "version": "1.4.1", @@ -2894,6 +3447,7 @@ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true, + "peer": true, "engines": { "node": ">= 0.6" } @@ -2903,6 +3457,7 @@ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, + "peer": true, "dependencies": { "mime-db": "1.52.0" }, @@ -2947,6 +3502,24 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "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/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -2957,13 +3530,15 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "peer": true }, "node_modules/node-releases": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", - "dev": true + "dev": true, + "peer": true }, "node_modules/object-inspect": { "version": "1.12.3", @@ -3136,15 +3711,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -3163,6 +3729,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -3182,6 +3749,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -3190,7 +3758,8 @@ "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 + "dev": true, + "peer": true }, "node_modules/path-type": { "version": "4.0.0", @@ -3202,85 +3771,21 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, "engines": { - "node": ">=8" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/portfinder": { @@ -3312,6 +3817,34 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "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.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -3327,6 +3860,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, + "peer": true, "engines": { "node": ">=6" } @@ -3371,22 +3905,11 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "peer": true, "dependencies": { "safe-buffer": "^5.1.0" } }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -3416,6 +3939,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dev": true, + "peer": true, "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -3428,27 +3952,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3494,6 +3997,43 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -3568,6 +4108,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "peer": true, "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -3607,6 +4148,7 @@ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, + "peer": true, "dependencies": { "randombytes": "^2.1.0" } @@ -3626,23 +4168,12 @@ "node": ">= 0.4" } }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "peer": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -3655,6 +4186,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "peer": true, "engines": { "node": ">=8" } @@ -3687,6 +4219,16 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -3696,6 +4238,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "peer": true, "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -3827,6 +4370,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "peer": true, "engines": { "node": ">= 0.4" }, @@ -3848,6 +4392,7 @@ "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.2.tgz", "integrity": "sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w==", "dev": true, + "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -3866,6 +4411,7 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, + "peer": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", @@ -4113,6 +4659,7 @@ "url": "https://github.com/sponsors/ai" } ], + "peer": true, "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -4129,6 +4676,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "peer": true, "dependencies": { "punycode": "^2.1.0" } @@ -4139,11 +4687,71 @@ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, + "node_modules/vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "dev": true, + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, + "peer": true, "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -4157,6 +4765,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", "integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==", "dev": true, + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -4199,78 +4808,12 @@ } } }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-merge": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", - "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", "dev": true, + "peer": true, "engines": { "node": ">=10.13.0" } @@ -4292,6 +4835,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "peer": true, "dependencies": { "isexe": "^2.0.0" }, @@ -4339,12 +4883,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4387,12 +4925,6 @@ "dev": true, "requires": {} }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true - }, "@es-joy/jsdoccomment": { "version": "0.36.1", "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", @@ -4405,6 +4937,167 @@ "jsdoc-type-pratt-parser": "~3.1.0" } }, + "@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "dev": true, + "optional": true + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -4475,25 +5168,29 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true + "dev": true, + "peer": true }, "@jridgewell/source-map": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.4.tgz", "integrity": "sha512-KE/SxsDqNs3rrWwFHcRh15ZLVFrI0YoZtgAdIyIq9k5hUNmiWRXXThPomIxHuL20sLdgzbDFyvkUMna14bvtrw==", - "dev": true + "dev": true, + "peer": true }, "@jridgewell/sourcemap-codec": { "version": "1.4.14", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "dev": true, + "peer": true }, "@jridgewell/trace-mapping": { "version": "0.3.18", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", "dev": true, + "peer": true, "requires": { "@jridgewell/resolve-uri": "3.1.0", "@jridgewell/sourcemap-codec": "1.4.14" @@ -4525,11 +5222,138 @@ "fastq": "^1.6.0" } }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz", + "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz", + "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz", + "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz", + "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz", + "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz", + "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz", + "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz", + "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz", + "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz", + "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz", + "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz", + "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz", + "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz", + "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz", + "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz", + "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz", + "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz", + "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==", + "dev": true, + "optional": true + }, "@types/eslint": { "version": "8.40.2", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.2.tgz", "integrity": "sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ==", "dev": true, + "peer": true, "requires": { "@types/estree": "*", "@types/json-schema": "*" @@ -4540,15 +5364,16 @@ "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", "dev": true, + "peer": true, "requires": { "@types/eslint": "*", "@types/estree": "*" } }, "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "dev": true }, "@types/json-schema": { @@ -4568,7 +5393,8 @@ "version": "20.3.3", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.3.3.tgz", "integrity": "sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==", - "dev": true + "dev": true, + "peer": true }, "@types/semver": { "version": "7.5.2", @@ -4681,6 +5507,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -4690,25 +5517,29 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true + "dev": true, + "peer": true }, "@webassemblyjs/helper-api-error": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true + "dev": true, + "peer": true }, "@webassemblyjs/helper-buffer": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true + "dev": true, + "peer": true }, "@webassemblyjs/helper-numbers": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4719,13 +5550,15 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true + "dev": true, + "peer": true }, "@webassemblyjs/helper-wasm-section": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -4738,6 +5571,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, + "peer": true, "requires": { "@xtuc/ieee754": "^1.2.0" } @@ -4747,6 +5581,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, + "peer": true, "requires": { "@xtuc/long": "4.2.2" } @@ -4755,13 +5590,15 @@ "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true + "dev": true, + "peer": true }, "@webassemblyjs/wasm-edit": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -4778,6 +5615,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -4791,6 +5629,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -4803,6 +5642,7 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4817,55 +5657,39 @@ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, + "peer": true, "requires": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, - "@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "requires": {} - }, - "@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "requires": {} - }, - "@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "requires": {} - }, "@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true + "dev": true, + "peer": true }, "@xtuc/long": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true + "dev": true, + "peer": true }, "acorn": { "version": "8.9.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", - "dev": true + "dev": true, + "peer": true }, "acorn-import-assertions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, + "peer": true, "requires": {} }, "acorn-jsx": { @@ -4881,6 +5705,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -4893,6 +5718,7 @@ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true, + "peer": true, "requires": {} }, "ansi-regex": { @@ -5062,6 +5888,7 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz", "integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==", "dev": true, + "peer": true, "requires": { "caniuse-lite": "^1.0.30001503", "electron-to-chromium": "^1.4.431", @@ -5073,7 +5900,8 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true + "dev": true, + "peer": true }, "call-bind": { "version": "1.0.2", @@ -5096,7 +5924,8 @@ "version": "1.0.30001509", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001509.tgz", "integrity": "sha512-2uDDk+TRiTX5hMcUYT/7CSyzMZxjfGu0vAUjS2g0LSD8UoXOv0LtpH4LxGMemsiPq6LCVIUjNwVM0erkOkGCDA==", - "dev": true + "dev": true, + "peer": true }, "chalk": { "version": "4.1.2", @@ -5112,18 +5941,8 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } + "peer": true }, "color-convert": { "version": "2.0.1", @@ -5140,17 +5959,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true - }, "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "dev": true, + "peer": true }, "comment-parser": { "version": "1.3.1", @@ -5184,6 +5998,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "peer": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5253,7 +6068,8 @@ "version": "1.4.447", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.447.tgz", "integrity": "sha512-sxX0LXh+uL41hSJsujAN86PjhrV/6c79XmpY0TvjZStV6VxIgarf8SRkUoUTuYmFcZQTemsoqo8qXOGw5npWfw==", - "dev": true + "dev": true, + "peer": true }, "enhanced-resolve": { "version": "5.15.0", @@ -5265,12 +6081,6 @@ "tapable": "^2.2.0" } }, - "envinfo": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", - "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", - "dev": true - }, "es-abstract": { "version": "1.22.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.2.tgz", @@ -5323,7 +6133,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==", - "dev": true + "dev": true, + "peer": true }, "es-set-tostringtag": { "version": "2.0.1", @@ -5359,11 +6170,43 @@ "is-symbol": "^1.0.2" } }, + "esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "dev": true, + "peer": true }, "escape-string-regexp": { "version": "4.0.0", @@ -5595,6 +6438,7 @@ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, + "peer": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -5642,6 +6486,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "peer": true, "requires": { "estraverse": "^5.2.0" }, @@ -5650,7 +6495,8 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true + "dev": true, + "peer": true } } }, @@ -5658,7 +6504,8 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "dev": true, + "peer": true }, "esutils": { "version": "2.0.3", @@ -5677,7 +6524,8 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true + "dev": true, + "peer": true }, "fabricate.js": { "version": "3.5.0", @@ -5688,7 +6536,8 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "peer": true }, "fast-glob": { "version": "3.3.1", @@ -5718,7 +6567,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "peer": true }, "fast-levenshtein": { "version": "2.0.6", @@ -5727,12 +6577,6 @@ "dev": true, "peer": true }, - "fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true - }, "fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -5814,6 +6658,13 @@ "dev": true, "peer": true }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -5901,7 +6752,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true + "dev": true, + "peer": true }, "globals": { "version": "13.21.0", @@ -6086,16 +6938,6 @@ "resolve-from": "^4.0.0" } }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -6133,12 +6975,6 @@ "side-channel": "^1.0.4" } }, - "interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true - }, "is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -6243,15 +7079,6 @@ "dev": true, "peer": true }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -6324,19 +7151,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true + "dev": true, + "peer": true }, "jest-worker": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "dev": true, + "peer": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -6348,6 +7171,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "peer": true, "requires": { "has-flag": "^4.0.0" } @@ -6382,13 +7206,15 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "peer": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "peer": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -6417,12 +7243,6 @@ "json-buffer": "3.0.1" } }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -6438,7 +7258,8 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", - "dev": true + "dev": true, + "peer": true }, "locate-path": { "version": "6.0.0", @@ -6476,7 +7297,8 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "peer": true }, "merge2": { "version": "1.4.1", @@ -6504,13 +7326,15 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true + "dev": true, + "peer": true }, "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==", "dev": true, + "peer": true, "requires": { "mime-db": "1.52.0" } @@ -6546,6 +7370,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6556,13 +7386,15 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true + "dev": true, + "peer": true }, "node-releases": { "version": "2.0.12", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==", - "dev": true + "dev": true, + "peer": true }, "object-inspect": { "version": "1.12.3", @@ -6690,12 +7522,6 @@ "p-limit": "^3.0.2" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6710,7 +7536,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "dev": true, + "peer": true }, "path-is-absolute": { "version": "1.0.1", @@ -6723,13 +7550,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true + "dev": true, + "peer": true }, "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 + "dev": true, + "peer": true }, "path-type": { "version": "4.0.0", @@ -6738,9 +7567,9 @@ "dev": true }, "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "picomatch": { @@ -6749,54 +7578,6 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, "portfinder": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", @@ -6825,6 +7606,17 @@ } } }, + "postcss": { + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -6836,7 +7628,8 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "dev": true, + "peer": true }, "qs": { "version": "6.11.0", @@ -6858,19 +7651,11 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "peer": true, "requires": { "safe-buffer": "^5.1.0" } }, - "rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "requires": { - "resolve": "^1.20.0" - } - }, "regexp.prototype.flags": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", @@ -6894,29 +7679,13 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.5.tgz", "integrity": "sha512-qWhv7PF1V95QPvRoUGHxOtnAlEvlXBylMZcjUR9pAumMmveFtcHJRXGIr+TkjfNJVQypqv2qcDiiars2y1PsSg==", "dev": true, + "peer": true, "requires": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -6946,6 +7715,34 @@ "glob": "^7.1.3" } }, + "rollup": { + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz", + "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.24.3", + "@rollup/rollup-android-arm64": "4.24.3", + "@rollup/rollup-darwin-arm64": "4.24.3", + "@rollup/rollup-darwin-x64": "4.24.3", + "@rollup/rollup-freebsd-arm64": "4.24.3", + "@rollup/rollup-freebsd-x64": "4.24.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.3", + "@rollup/rollup-linux-arm-musleabihf": "4.24.3", + "@rollup/rollup-linux-arm64-gnu": "4.24.3", + "@rollup/rollup-linux-arm64-musl": "4.24.3", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3", + "@rollup/rollup-linux-riscv64-gnu": "4.24.3", + "@rollup/rollup-linux-s390x-gnu": "4.24.3", + "@rollup/rollup-linux-x64-gnu": "4.24.3", + "@rollup/rollup-linux-x64-musl": "4.24.3", + "@rollup/rollup-win32-arm64-msvc": "4.24.3", + "@rollup/rollup-win32-ia32-msvc": "4.24.3", + "@rollup/rollup-win32-x64-msvc": "4.24.3", + "@types/estree": "1.0.6", + "fsevents": "~2.3.2" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6997,6 +7794,7 @@ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, + "peer": true, "requires": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -7023,6 +7821,7 @@ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", "dev": true, + "peer": true, "requires": { "randombytes": "^2.1.0" } @@ -7039,20 +7838,12 @@ "has-property-descriptors": "^1.0.0" } }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "peer": true, "requires": { "shebang-regex": "^3.0.0" } @@ -7061,7 +7852,8 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "dev": true, + "peer": true }, "side-channel": { "version": "1.0.4", @@ -7084,6 +7876,13 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "peer": true + }, + "source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true }, "source-map-support": { @@ -7091,6 +7890,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "dev": true, + "peer": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -7194,7 +7994,8 @@ "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 + "dev": true, + "peer": true }, "tapable": { "version": "2.2.1", @@ -7207,6 +8008,7 @@ "resolved": "https://registry.npmjs.org/terser/-/terser-5.18.2.tgz", "integrity": "sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w==", "dev": true, + "peer": true, "requires": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -7219,6 +8021,7 @@ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", "dev": true, + "peer": true, "requires": { "@jridgewell/trace-mapping": "^0.3.17", "jest-worker": "^27.4.5", @@ -7376,6 +8179,7 @@ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", "dev": true, + "peer": true, "requires": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -7386,6 +8190,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "peer": true, "requires": { "punycode": "^2.1.0" } @@ -7396,11 +8201,24 @@ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", "dev": true }, + "vite": { + "version": "5.4.10", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz", + "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "dev": true, + "requires": { + "esbuild": "^0.21.3", + "fsevents": "~2.3.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + } + }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", "dev": true, + "peer": true, "requires": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -7411,6 +8229,7 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.88.1.tgz", "integrity": "sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ==", "dev": true, + "peer": true, "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -7438,50 +8257,12 @@ "webpack-sources": "^3.2.3" } }, - "webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true - } - } - }, - "webpack-merge": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.9.0.tgz", - "integrity": "sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, "webpack-sources": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true + "dev": true, + "peer": true }, "whatwg-encoding": { "version": "2.0.0", @@ -7497,6 +8278,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "peer": true, "requires": { "isexe": "^2.0.0" } @@ -7529,12 +8311,6 @@ "has-tostringtag": "^1.0.0" } }, - "wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/dashboard/package.json b/dashboard/package.json index 815ec8a8..65789f38 100644 --- a/dashboard/package.json +++ b/dashboard/package.json @@ -1,12 +1,12 @@ { - "name": "service-dashboard", - "version": "1.0.0", - "description": "Web application providing specialised interaction UI for the APIs presented by the node-microservices apps", + "name": "node-microservices-dashboard", + "version": "2.0.0", + "description": "Webapp to monitor device fleet and issue commands.", "scripts": { "clean": "rm -rf ./dist", - "build:dev": "npm run clean && webpack --mode development", - "build": "npm run clean && webpack --mode production", - "start": "npm run build:dev && http-server" + "build:dev": "npm run clean && vite", + "build": "npm run clean && vite build", + "start": "vite --port 54449" }, "devDependencies": { "@chris-lewis/eslint-config": "^1.0.3", @@ -16,8 +16,7 @@ "http-server": "^14.1.1", "ts-loader": "^9.4.4", "typescript": "^5.1.6", - "webpack": "^5.88.1", - "webpack-cli": "^5.1.4" + "vite": "^5.4.10" }, "dependencies": { "fabricate.js": "^3.5.0" diff --git a/dashboard2/src/components/AppArea.ts b/dashboard/src/components/AppArea.ts similarity index 100% rename from dashboard2/src/components/AppArea.ts rename to dashboard/src/components/AppArea.ts diff --git a/dashboard/src/components/AppCard.ts b/dashboard/src/components/AppCard.ts index 38086ae8..32becc9a 100644 --- a/dashboard/src/components/AppCard.ts +++ b/dashboard/src/components/AppCard.ts @@ -1,158 +1,107 @@ -import { Fabricate, FabricateComponent } from 'fabricate.js'; -import { APP_CARD_WIDTH } from '../constants'; -import { AppState } from '../types'; -import AppControls from './AppControls'; -import { appRequestStateKey, getAppStatusColor, getReqStateColor } from '../utils'; +import { Fabricate } from 'fabricate.js'; +import { AppState, DeviceApp } from '../types'; declare const fabricate: Fabricate; -/** - * CardContainer component. - * - * @returns {HTMLElement} Fabricate component. - */ -const CardContainer = () => fabricate('Card') - .asFlex('column') - .setStyles(({ palette }) => ({ - width: `${APP_CARD_WIDTH}px`, - margin: '10px 0px 10px 20px', - backgroundColor: palette.grey5, - boxShadow: '2px 2px 3px 1px #0004', - })); +const dummy = fabricate('div'); + +const controlsMap: Record = { + monitor: dummy, + visuals: dummy, +}; /** - * DeviceIcon component. + * AppControls component. * + * @param {object} props - Component props. + * @param {object} props.app - Device. * @returns {HTMLElement} Fabricate component. */ -const AppIcon = () => fabricate('Image', { src: 'assets/app.png' }) +const AppControls = ({ app }: { app: DeviceApp }) => fabricate('Column') .setStyles({ - margin: '4px 4px 4px', - width: '24px', - height: '24px', - }); -/** - * AppName component. - * - * @returns {HTMLElement} Fabricate component. - */ -const AppName = () => fabricate('Text') - .setStyles(({ fonts }) => ({ - fontSize: '1.1rem', - flex: '1', - color: 'white', - margin: '6px 5px 5px 5px', - fontFamily: fonts.code, - fontWeight: 'bold', - cursor: 'default', - })); + }) + .setChildren([ + // fabricate('Text').setText('Controls here'), + ]); /** * StatusText component. * - * @returns {HTMLElement} Fabricate component. - */ -const StatusText = () => fabricate('Text') - .setStyles(({ palette }) => ({ - color: palette.lightGrey, - fontSize: '0.9rem', - paddingTop: '1', - marginBottom: '2px', - cursor: 'default', - })); - -/** - * StatusLED component. - * * @param {object} props - Component props. - * @param {string} props.app - App. + * @param {DeviceApp} props.app - App name. * @returns {HTMLElement} Fabricate component. */ -const StatusLED = ({ app }: { app: string }) => { - const reqStateKey = appRequestStateKey(app); - - /** - * Update the LED color. - * - * @param {FabricateComponent} el - This element. - * @param {AppState} state - App state. - */ - const updateColor = (el: FabricateComponent, state: AppState) => { - const { selectedDevice } = state; - if (selectedDevice === null) return; +const StatusText = ({ app }: { app: DeviceApp }) => { + const { status, port } = app; - const pending = state[reqStateKey] === 'pending'; - const reqStateColor = getReqStateColor(state[reqStateKey]); - const statusColor = getAppStatusColor(state, app); - el.setStyles({ backgroundColor: pending ? reqStateColor : statusColor }); - }; - - return fabricate('div') - .setStyles({ - width: '15px', - height: '15px', - borderRadius: '9px', - marginRight: '5px', - }) - .onCreate(updateColor) - .onUpdate(updateColor, [reqStateKey]); + return fabricate('Text') + .setStyles(({ palette }) => ({ + color: palette.greyC, + fontSize: '0.9rem', + cursor: 'default', + textAlign: 'end', + width: '100%', + })) + .setText(`${status} (${port})`); }; /** - * CardStatus component. + * AppStatusRow component. * * @param {object} props - Component props. - * @param {string} props.app - App. + * @param {object} props.app - Device. * @returns {HTMLElement} Fabricate component. */ -const CardStatus = ({ app }: { app: string }) => fabricate('Row') - .setStyles({ +const AppStatusRow = ({ app }: { app: DeviceApp }) => fabricate('Row') + .setStyles(({ palette }) => ({ + backgroundColor: palette.grey4, + padding: '5px', alignItems: 'center', - justifyContent: 'flex-end', - flex: '2', - }) + })) .setChildren([ - StatusLED({ app }), - StatusText() - .onCreate((el, { selectedDevice, deviceApps }) => { - if (selectedDevice === null) return; - - const apps = deviceApps[selectedDevice.deviceName]; - const { status, port } = apps.find((p) => p.app === app)!; - el.setText(`${status} (${port})`); + fabricate('Image', { src: 'assets/images/app.png' }) + .setStyles({ + width: '24px', + height: '24px', + margin: '0px 5px', }), + fabricate('Text') + .setStyles(({ fonts }) => ({ + color: 'white', + fontSize: '1.1rem', + fontWeight: 'bold', + fontFamily: fonts.code, + cursor: 'default', + })) + .setText(app.app!), + StatusText({ app }), + // Port ]); -/** - * CardTitleRow component. - * - * @returns {HTMLElement} Fabricate component. - */ -const CardTitleRow = () => fabricate('Row') - .setStyles(({ palette }) => ({ - alignItems: 'center', - backgroundColor: palette.grey5, - padding: '3px 5px', - height: '35px', - })); - /** * AppCard component. * * @param {object} props - Component props. - * @param {string} props.app - App name. + * @param {object} props.app - Device. * @returns {HTMLElement} Fabricate component. */ -const AppCard = ({ app }: { app: string }) => CardContainer() - .setChildren([ - CardTitleRow() - .setChildren([ - AppIcon(), - AppName().setText(app), - CardStatus({ app }), - ]), - AppControls({ app }), - ]); +const AppCard = ({ app }: { app: DeviceApp }) => { + const hasControls = !!controlsMap[app.app!]; + + return fabricate('Column') + .setStyles(({ palette }) => ({ + margin: '15px', + backgroundColor: palette.grey3, + width: '300px', + border: `solid 2px ${palette.grey6}`, + height: '100%', + })) + .setNarrowStyles({ width: '100%' }) + .setChildren([ + AppStatusRow({ app }), + fabricate.conditional(() => hasControls, () => AppControls({ app })), + ]); +}; export default AppCard; diff --git a/dashboard2/src/components/AppLoader.ts b/dashboard/src/components/AppLoader.ts similarity index 100% rename from dashboard2/src/components/AppLoader.ts rename to dashboard/src/components/AppLoader.ts diff --git a/dashboard2/src/components/DeviceMetrics.ts b/dashboard/src/components/DeviceMetrics.ts similarity index 100% rename from dashboard2/src/components/DeviceMetrics.ts rename to dashboard/src/components/DeviceMetrics.ts diff --git a/dashboard2/src/components/SideBar.ts b/dashboard/src/components/SideBar.ts similarity index 100% rename from dashboard2/src/components/SideBar.ts rename to dashboard/src/components/SideBar.ts diff --git a/dashboard2/src/components/StatRow.ts b/dashboard/src/components/StatRow.ts similarity index 100% rename from dashboard2/src/components/StatRow.ts rename to dashboard/src/components/StatRow.ts diff --git a/dashboard/src/constants.ts b/dashboard/src/constants.ts index b34352ad..0bed9031 100644 --- a/dashboard/src/constants.ts +++ b/dashboard/src/constants.ts @@ -6,60 +6,19 @@ export const FLEET_HOST = 'polaris.chrislewis.me.uk'; /** Port to look for conduit apps */ export const CONDUIT_PORT = 5959; -/** App card width */ -export const APP_CARD_WIDTH = 375; - /** Initial total app state */ export const INITIAL_STATE: AppState = { // App data token: '', - deviceApps: {}, - fleet: [], - metricHistory: [], + publicIp: '', + + // Loaded data + selectedDeviceApps: [], + devices: [], + metricNames: [], // Selections - page: 'FleetPage', selectedDevice: null, - - // App data - atticData: { - app: '', - key: '', - value: '', - }, - conduitData: { - app: '', - topic: 'status', - message: '{}', - }, - visualsData: { - index: 0, - red: 128, - green: 128, - blue: 128, - text: '', - }, - guestlistData: { - adminPassword: '', - name: '', - apps: '', - topics: '', - }, - clacksData: { - topic: '', - message: '{}', - connected: false, - }, - monitorData: { - metricNames: [], - metric: '', - plugins: [], - minValue: 0, - maxValue: 99999, - minTime: 0, - maxTime: 99999, - type: 'number', - }, }; /** Icon type names */ @@ -69,3 +28,9 @@ export const ICON_NAMES: Record = { pi: 'raspberrypi', server: 'server-white', }; + +/** Navbar height from fabricate.js */ +export const NAVBAR_HEIGHT = 40; + +/** Metric bucket size */ +export const BUCKET_SIZE = 5; diff --git a/dashboard/src/index.ts b/dashboard/src/index.ts index 6741a3b9..91c2702b 100644 --- a/dashboard/src/index.ts +++ b/dashboard/src/index.ts @@ -1,63 +1,21 @@ import { Fabricate } from 'fabricate.js'; import { AppState } from './types'; import Theme from './theme'; -import { CONDUIT_PORT, FLEET_HOST, INITIAL_STATE } from './constants'; -import SubNavBar from './components/SubNavBar'; -import FleetPage from './pages/FleetPage'; -import AppsPage from './pages/AppsPage'; +import { INITIAL_STATE } from './constants'; +import { parseParams } from './util'; +import SideBar from './components/SideBar'; +import AppArea from './components/AppArea'; +import { fetchFleetList } from './services/conduitService'; declare const fabricate: Fabricate; -/** - * Re-load the fleet list data. - * - * @param {object} state - App state. - */ -const fetchFleetList = async (state: AppState) => { - const { token } = state; - fabricate.update({ fleet: [] }); - - try { - // Can't use sendConduitPacket, not a device by name - const res = await fetch(`http://${FLEET_HOST}:${CONDUIT_PORT}/conduit`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - to: 'attic', - topic: 'get', - message: { app: 'conduit', key: 'fleetList' }, - auth: token || '', - }), - }); - const { message } = await res.json(); - fabricate.update({ fleet: message.value }); - } catch (err) { - console.error(err); - alert(err); - } -}; - -/** - * Parse query params. - */ -const parseParams = () => { - const params = new URLSearchParams(window.location.search); - const token = params.get('token'); - if (!token) { - alert('Please provide token param'); - return; - } - - fabricate.update({ token }); -}; - /** * AppNavBar component. * * @returns {HTMLElement} Fabricate component. */ const AppNavBar = () => fabricate('NavBar', { - title: 'Service Dashboard', + title: 'Node Microservices Dashboard', backgroundColor: Theme.palette.primary, }); @@ -67,11 +25,16 @@ const AppNavBar = () => fabricate('NavBar', { * @returns {HTMLElement} Fabricate component. */ const App = () => fabricate('Column') + .setStyles({ height: '100vh' }) .setChildren([ AppNavBar(), - SubNavBar(), - fabricate.conditional(({ page }) => page === 'FleetPage', FleetPage), - fabricate.conditional(({ page }) => page === 'AppsPage', AppsPage), + fabricate('Row') + .setStyles({ height: '100vh' }) + .setNarrowStyles({ flexWrap: 'wrap' }) + .setChildren([ + SideBar(), + AppArea(), + ]), ]) .onUpdate(async (el, state, keys) => { if (keys.includes(fabricate.StateKeys.Created)) { diff --git a/dashboard/src/services/conduitService.ts b/dashboard/src/services/conduitService.ts index 4f2386b2..db259c6d 100644 --- a/dashboard/src/services/conduitService.ts +++ b/dashboard/src/services/conduitService.ts @@ -1,10 +1,16 @@ import { Fabricate } from 'fabricate.js'; -import { CONDUIT_PORT, FLEET_HOST } from '../constants'; -import { AppState, Packet } from '../types'; -import { appRequestStateKey, isReachableKey } from '../utils'; +import { + AppState, DataPoint, Device, DeviceApp, + Packet, +} from '../types'; +import { BUCKET_SIZE, CONDUIT_PORT, FLEET_HOST } from '../constants'; +import { shortDateTime, sortAppByName } from '../util'; declare const fabricate: Fabricate; +/** Extra Y for visibility */ +const Y_EXTRA = 1.1; + /** * Send a conduit packet. * @@ -22,45 +28,209 @@ export const sendConduitPacket = async ( deviceNameOverride?: string, tokenOverride?: string, ) => { - const { token, selectedDevice, fleet } = state; - const reqStateKey = appRequestStateKey(packet.to); - fabricate.update(reqStateKey, 'pending'); + const { token, selectedDevice, devices, publicIp: currentPublicIp } = state; + // const reqStateKey = appRequestStateKey(packet.to); + // fabricate.update(reqStateKey, 'pending'); try { - // Begin with host unless some device is selected to drill down - let destination = FLEET_HOST; - const finalDevice = deviceNameOverride - ? fleet.find(({ deviceName }) => deviceName === deviceNameOverride)! + ? devices.find(({ deviceName }) => deviceName === deviceNameOverride)! : selectedDevice; if (!finalDevice) throw new Error('Unable to identify device to send message to.'); - const { localIp, publicIp, deviceName } = finalDevice; - const isLocalReachable = state[isReachableKey(deviceName, 'local')]; + // If we're on the same local detwork, use local IP, else try conduit forwarding + const { localIp, publicIp } = finalDevice; + const isLocalDevice = publicIp === currentPublicIp; + const finalIp = isLocalDevice ? localIp : publicIp; + const finalHost = isLocalDevice ? undefined : localIp; // Destination is local if reachable, else forward local via public - destination = isLocalReachable ? localIp : publicIp; - const forwardHost = destination === publicIp ? localIp : undefined; console.log(`${finalDevice?.deviceName} >>> ${JSON.stringify(packet)}`); - const res = await fetch(`http://${destination}:${CONDUIT_PORT}/conduit`, { + const res = await fetch(`http://${finalIp}:${CONDUIT_PORT}/conduit`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ ...packet, auth: tokenOverride || token || '', - host: forwardHost, + host: finalHost, device: finalDevice && finalDevice.deviceName, }), }); const json = await res.json(); console.log(`<<< ${finalDevice?.deviceName} ${JSON.stringify(json)}`); - fabricate.update(reqStateKey, 'success'); + // fabricate.update(reqStateKey, 'success'); return json; } catch (error) { console.log(error); - fabricate.update(reqStateKey, 'error'); + // fabricate.update(reqStateKey, 'error'); throw error; } }; + +/** + * Re-load the devices list data. + * + * @param {object} state - App state. + */ +export const fetchFleetList = async (state: AppState) => { + const { token } = state; + fabricate.update({ devices: [] }); + + // First get this machine's public IP to know if we can use local IPs + const { ip: publicIp } = await fetch('https://api.ipify.org?format=json') + .then((r) => r.json()); + + try { + // Can't use sendConduitPacket, not a device by name + const res = await fetch(`http://${FLEET_HOST}:${CONDUIT_PORT}/conduit`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + to: 'attic', + topic: 'get', + message: { app: 'conduit', key: 'fleetList' }, + auth: token || '', + }), + }); + const { message } = await res.json(); + fabricate.update({ devices: message.value, publicIp }); + } catch (err) { + console.error(err); + alert(err); + } +}; + +/** + * Load apps for all fleet devices. + * + * @param {AppState} state - App state. + * @param {Device} device - Device to use. + */ +export const fetchDeviceApps = async (state: AppState, device: Device) => { + const { deviceName } = device!; + + fabricate.update({ selectedDeviceApps: [] }); + + try { + const { message } = await sendConduitPacket( + state, + { to: 'conduit', topic: 'getApps' }, + deviceName, + ); + + let selectedDeviceApps: DeviceApp[] = []; + if (message && message.error) { + console.error(message.error); + selectedDeviceApps = []; + } else if (!message) { + console.error('No response in fetchApps'); + selectedDeviceApps = []; + } else { + selectedDeviceApps = (message as DeviceApp[]).sort(sortAppByName); + } + + fabricate.update({ selectedDeviceApps }); + } catch (err: unknown) { + console.error(err); + fabricate.update({ selectedDeviceApps: [] }); + } +}; + +/** + * Fetch data for a metric. + * + * @param {AppState} state - App state. + * @param {string} name - Metric name. + */ +export const fetchMetric = async (state: AppState, name: string) => { + const dataKey = fabricate.buildKey('metricData', name); + // fabricate.update( + // dataKey, + // { + // buckets: [], + // minTime: 0, + // maxTime: 0, + // minValue: 0, + // maxValue: 0, + // }, + // ); + + const res = await sendConduitPacket( + state, + { + to: 'monitor', + topic: 'getMetricToday', + message: { name }, + }, + ); + const { message: newHistory } = res; + if (res.error) console.log(res); + if (!newHistory.length) return; + + const type = Array.isArray(newHistory[0][1]) ? 'array' : 'number'; + + const minTime = shortDateTime(newHistory[0][0]); + const maxTime = shortDateTime(newHistory[newHistory.length - 1][0]); + let minValue = 0; + let maxValue = 0; + + if (type === 'number') { + // Aggregate values + minValue = name.includes('Perc') + ? 0 + : newHistory.reduce( + // @ts-expect-error handled with 'type' + (acc: number, [, value]: MetricPoint) => (value < acc ? value : acc), + 9999999, + ); + maxValue = name.includes('Perc') + ? Math.round(100 * Y_EXTRA) + : Math.round( + newHistory.reduce( + // @ts-expect-error handled with 'type' + (acc: number, [, value]: MetricPoint) => (value > acc ? value : acc), + 0, + ) * Y_EXTRA, + ); + } else { + throw new Error('Unexpected metric data type'); + } + + // Average into buckets + const copy = [...newHistory]; + const buckets: DataPoint[] = []; + while (copy.length) { + const points = copy.splice(0, BUCKET_SIZE); + const avgIndex = Math.floor(points.length / 2); + buckets.push({ + value: points.reduce((acc, [, value]) => acc + value, 0) / points.length, + timestamp: points[avgIndex][0], + dateTime: new Date(points[avgIndex][0]).toISOString(), + }); + } + + fabricate.update( + dataKey, + { + buckets, + minTime, + maxTime, + minValue, + maxValue, + }, + ); +}; + +/** + * Fetch metric names, triggering update of graphs if they are shown. + * + * @param {AppState} state - App state. + */ +export const fetchMetricNames = async (state: AppState) => { + const { + message: metricNames = [], + } = await sendConduitPacket(state, { to: 'monitor', topic: 'getMetricNames' }); + fabricate.update({ metricNames }); +}; diff --git a/dashboard/src/theme.ts b/dashboard/src/theme.ts index 0bf459eb..c6ed1ecf 100644 --- a/dashboard/src/theme.ts +++ b/dashboard/src/theme.ts @@ -1,16 +1,18 @@ /** App colors */ const Theme = { palette: { - primary: '#303F9F', - datapoint: 'orange', - instanceHealthy: '#007800', + primary: '#c7053d', + secondary: 'orange', text: 'white', grey1: '#111', grey2: '#222', grey3: '#333', grey4: '#444', grey5: '#555', - lightGrey: '#eee', + grey6: '#666', + greyA: '#aaa', + greyC: '#ccc', + greyE: '#eee', statusOk: '#43D047', statusDown: '#DD6E40', statusPending: 'orange', @@ -18,11 +20,6 @@ const Theme = { }, styles: { boxShadow: '2px 2px 3px 1px #0004', - controlButton: { - borderRadius: '0', - margin: '0', - minWidth: '50px', - }, }, fonts: { body: 'sans-serif', diff --git a/dashboard/src/types.ts b/dashboard/src/types.ts index 8367a42b..dd9b9a03 100644 --- a/dashboard/src/types.ts +++ b/dashboard/src/types.ts @@ -28,28 +28,28 @@ export type Device = { deviceType: 'other' | 'pc' | 'pi' | 'other'; diskSize: string; diskUsage: number; + uptimeDays?: number; }; /** Graph data point. */ export type DataPoint = { value: number; + timestamp: number; dateTime: string; }; /** Raw metric point */ -export type MetricPoint = [number, number | string[]]; +export type MetricPoint = [number, number]; -/** monitor plugin configuration */ -export type MonitorPlugin = { - FILE_NAME: string; - EVERY?: number; - AT?: string; - ENABLED?: boolean; +/** Metric data */ +export type MetricData = { + buckets: DataPoint[]; + minTime: string; + maxTime: string; + minValue: number; + maxValue: number; }; -/** App pages */ -type Pages = 'FleetPage' | 'AppsPage'; - /** App state type */ export type AppState = { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -57,60 +57,15 @@ export type AppState = { // App data token: string; - deviceApps: Record; - fleet: Device[]; - metricHistory: MetricPoint[]; + publicIp: string; + + // Loaded data + selectedDeviceApps: DeviceApp[]; + devices: Device[]; + metricNames: string[]; // Selections - page: Pages, selectedDevice: Device | null, - - // App data - atticData: { - app: string; - key: string; - value: string; - }; - conduitData: { - app: string; - topic: string; - message: string; - }; - visualsData: { - index: number; - red: number; - green: number; - blue: number; - text: string; - }; - guestlistData: { - adminPassword: string; - name: string; - apps: string; - topics: string; - }; - clacksData: { - topic: string; - message: string; - connected: boolean; - }; - monitorData: { - metricNames: string[]; - metric: string; - plugins: MonitorPlugin[]; - minValue: number; - maxValue: number; - minTime: number; - maxTime: number; - type: 'array' | 'number'; - }; -}; - -/** Fake type for WebSocket message event */ -export type WSMessageEvent = { - data: { - text: () => Promise, - }, }; /** Request states */ diff --git a/dashboard2/src/util.ts b/dashboard/src/util.ts similarity index 100% rename from dashboard2/src/util.ts rename to dashboard/src/util.ts diff --git a/dashboard2/README.md b/dashboard2/README.md deleted file mode 100644 index 5df9bfb7..00000000 --- a/dashboard2/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# service-dashboard - -![](assets/screenshot.png) - -Webapp to monitor device fleet and issue commands. diff --git a/dashboard2/src/components/AppCard.ts b/dashboard2/src/components/AppCard.ts deleted file mode 100644 index 32becc9a..00000000 --- a/dashboard2/src/components/AppCard.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Fabricate } from 'fabricate.js'; -import { AppState, DeviceApp } from '../types'; - -declare const fabricate: Fabricate; - -const dummy = fabricate('div'); - -const controlsMap: Record = { - monitor: dummy, - visuals: dummy, -}; - -/** - * AppControls component. - * - * @param {object} props - Component props. - * @param {object} props.app - Device. - * @returns {HTMLElement} Fabricate component. - */ -const AppControls = ({ app }: { app: DeviceApp }) => fabricate('Column') - .setStyles({ - - }) - .setChildren([ - // fabricate('Text').setText('Controls here'), - ]); - -/** - * StatusText component. - * - * @param {object} props - Component props. - * @param {DeviceApp} props.app - App name. - * @returns {HTMLElement} Fabricate component. - */ -const StatusText = ({ app }: { app: DeviceApp }) => { - const { status, port } = app; - - return fabricate('Text') - .setStyles(({ palette }) => ({ - color: palette.greyC, - fontSize: '0.9rem', - cursor: 'default', - textAlign: 'end', - width: '100%', - })) - .setText(`${status} (${port})`); -}; - -/** - * AppStatusRow component. - * - * @param {object} props - Component props. - * @param {object} props.app - Device. - * @returns {HTMLElement} Fabricate component. - */ -const AppStatusRow = ({ app }: { app: DeviceApp }) => fabricate('Row') - .setStyles(({ palette }) => ({ - backgroundColor: palette.grey4, - padding: '5px', - alignItems: 'center', - })) - .setChildren([ - fabricate('Image', { src: 'assets/images/app.png' }) - .setStyles({ - width: '24px', - height: '24px', - margin: '0px 5px', - }), - fabricate('Text') - .setStyles(({ fonts }) => ({ - color: 'white', - fontSize: '1.1rem', - fontWeight: 'bold', - fontFamily: fonts.code, - cursor: 'default', - })) - .setText(app.app!), - StatusText({ app }), - // Port - ]); - -/** - * AppCard component. - * - * @param {object} props - Component props. - * @param {object} props.app - Device. - * @returns {HTMLElement} Fabricate component. - */ -const AppCard = ({ app }: { app: DeviceApp }) => { - const hasControls = !!controlsMap[app.app!]; - - return fabricate('Column') - .setStyles(({ palette }) => ({ - margin: '15px', - backgroundColor: palette.grey3, - width: '300px', - border: `solid 2px ${palette.grey6}`, - height: '100%', - })) - .setNarrowStyles({ width: '100%' }) - .setChildren([ - AppStatusRow({ app }), - fabricate.conditional(() => hasControls, () => AppControls({ app })), - ]); -}; - -export default AppCard; diff --git a/dashboard2/src/constants.ts b/dashboard2/src/constants.ts deleted file mode 100644 index 0bed9031..00000000 --- a/dashboard2/src/constants.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { AppState } from './types'; - -/** Fleet host URL */ -export const FLEET_HOST = 'polaris.chrislewis.me.uk'; - -/** Port to look for conduit apps */ -export const CONDUIT_PORT = 5959; - -/** Initial total app state */ -export const INITIAL_STATE: AppState = { - // App data - token: '', - publicIp: '', - - // Loaded data - selectedDeviceApps: [], - devices: [], - metricNames: [], - - // Selections - selectedDevice: null, -}; - -/** Icon type names */ -export const ICON_NAMES: Record = { - other: 'other', - pc: 'pc', - pi: 'raspberrypi', - server: 'server-white', -}; - -/** Navbar height from fabricate.js */ -export const NAVBAR_HEIGHT = 40; - -/** Metric bucket size */ -export const BUCKET_SIZE = 5; diff --git a/dashboard2/src/index.ts b/dashboard2/src/index.ts deleted file mode 100644 index 91c2702b..00000000 --- a/dashboard2/src/index.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Fabricate } from 'fabricate.js'; -import { AppState } from './types'; -import Theme from './theme'; -import { INITIAL_STATE } from './constants'; -import { parseParams } from './util'; -import SideBar from './components/SideBar'; -import AppArea from './components/AppArea'; -import { fetchFleetList } from './services/conduitService'; - -declare const fabricate: Fabricate; - -/** - * AppNavBar component. - * - * @returns {HTMLElement} Fabricate component. - */ -const AppNavBar = () => fabricate('NavBar', { - title: 'Node Microservices Dashboard', - backgroundColor: Theme.palette.primary, -}); - -/** - * App component. - * - * @returns {HTMLElement} Fabricate component. - */ -const App = () => fabricate('Column') - .setStyles({ height: '100vh' }) - .setChildren([ - AppNavBar(), - fabricate('Row') - .setStyles({ height: '100vh' }) - .setNarrowStyles({ flexWrap: 'wrap' }) - .setChildren([ - SideBar(), - AppArea(), - ]), - ]) - .onUpdate(async (el, state, keys) => { - if (keys.includes(fabricate.StateKeys.Created)) { - parseParams(); - return; - } - - if (keys.includes('token')) { - await fetchFleetList(state); - } - }, [fabricate.StateKeys.Created, 'token']); - -fabricate.app( - App, - INITIAL_STATE, - { theme: Theme }, -); diff --git a/dashboard2/src/services/conduitService.ts b/dashboard2/src/services/conduitService.ts deleted file mode 100644 index db259c6d..00000000 --- a/dashboard2/src/services/conduitService.ts +++ /dev/null @@ -1,236 +0,0 @@ -import { Fabricate } from 'fabricate.js'; -import { - AppState, DataPoint, Device, DeviceApp, - Packet, -} from '../types'; -import { BUCKET_SIZE, CONDUIT_PORT, FLEET_HOST } from '../constants'; -import { shortDateTime, sortAppByName } from '../util'; - -declare const fabricate: Fabricate; - -/** Extra Y for visibility */ -const Y_EXTRA = 1.1; - -/** - * Send a conduit packet. - * - * @param {AppState} state - App state. - * @param {Packet} packet - Packet to send. - * @param {string} deviceNameOverride - Override device name. - * @param {string} [tokenOverride] - Override auth token sent. - * @returns {Promise} Response. - * @throws {Error} Any error encountered. - */ -// eslint-disable-next-line import/prefer-default-export -export const sendConduitPacket = async ( - state: AppState, - packet: Packet, - deviceNameOverride?: string, - tokenOverride?: string, -) => { - const { token, selectedDevice, devices, publicIp: currentPublicIp } = state; - // const reqStateKey = appRequestStateKey(packet.to); - // fabricate.update(reqStateKey, 'pending'); - - try { - const finalDevice = deviceNameOverride - ? devices.find(({ deviceName }) => deviceName === deviceNameOverride)! - : selectedDevice; - if (!finalDevice) throw new Error('Unable to identify device to send message to.'); - - // If we're on the same local detwork, use local IP, else try conduit forwarding - const { localIp, publicIp } = finalDevice; - const isLocalDevice = publicIp === currentPublicIp; - const finalIp = isLocalDevice ? localIp : publicIp; - const finalHost = isLocalDevice ? undefined : localIp; - - // Destination is local if reachable, else forward local via public - console.log(`${finalDevice?.deviceName} >>> ${JSON.stringify(packet)}`); - - const res = await fetch(`http://${finalIp}:${CONDUIT_PORT}/conduit`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - ...packet, - auth: tokenOverride || token || '', - host: finalHost, - device: finalDevice && finalDevice.deviceName, - }), - }); - const json = await res.json(); - console.log(`<<< ${finalDevice?.deviceName} ${JSON.stringify(json)}`); - - // fabricate.update(reqStateKey, 'success'); - return json; - } catch (error) { - console.log(error); - // fabricate.update(reqStateKey, 'error'); - throw error; - } -}; - -/** - * Re-load the devices list data. - * - * @param {object} state - App state. - */ -export const fetchFleetList = async (state: AppState) => { - const { token } = state; - fabricate.update({ devices: [] }); - - // First get this machine's public IP to know if we can use local IPs - const { ip: publicIp } = await fetch('https://api.ipify.org?format=json') - .then((r) => r.json()); - - try { - // Can't use sendConduitPacket, not a device by name - const res = await fetch(`http://${FLEET_HOST}:${CONDUIT_PORT}/conduit`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - to: 'attic', - topic: 'get', - message: { app: 'conduit', key: 'fleetList' }, - auth: token || '', - }), - }); - const { message } = await res.json(); - fabricate.update({ devices: message.value, publicIp }); - } catch (err) { - console.error(err); - alert(err); - } -}; - -/** - * Load apps for all fleet devices. - * - * @param {AppState} state - App state. - * @param {Device} device - Device to use. - */ -export const fetchDeviceApps = async (state: AppState, device: Device) => { - const { deviceName } = device!; - - fabricate.update({ selectedDeviceApps: [] }); - - try { - const { message } = await sendConduitPacket( - state, - { to: 'conduit', topic: 'getApps' }, - deviceName, - ); - - let selectedDeviceApps: DeviceApp[] = []; - if (message && message.error) { - console.error(message.error); - selectedDeviceApps = []; - } else if (!message) { - console.error('No response in fetchApps'); - selectedDeviceApps = []; - } else { - selectedDeviceApps = (message as DeviceApp[]).sort(sortAppByName); - } - - fabricate.update({ selectedDeviceApps }); - } catch (err: unknown) { - console.error(err); - fabricate.update({ selectedDeviceApps: [] }); - } -}; - -/** - * Fetch data for a metric. - * - * @param {AppState} state - App state. - * @param {string} name - Metric name. - */ -export const fetchMetric = async (state: AppState, name: string) => { - const dataKey = fabricate.buildKey('metricData', name); - // fabricate.update( - // dataKey, - // { - // buckets: [], - // minTime: 0, - // maxTime: 0, - // minValue: 0, - // maxValue: 0, - // }, - // ); - - const res = await sendConduitPacket( - state, - { - to: 'monitor', - topic: 'getMetricToday', - message: { name }, - }, - ); - const { message: newHistory } = res; - if (res.error) console.log(res); - if (!newHistory.length) return; - - const type = Array.isArray(newHistory[0][1]) ? 'array' : 'number'; - - const minTime = shortDateTime(newHistory[0][0]); - const maxTime = shortDateTime(newHistory[newHistory.length - 1][0]); - let minValue = 0; - let maxValue = 0; - - if (type === 'number') { - // Aggregate values - minValue = name.includes('Perc') - ? 0 - : newHistory.reduce( - // @ts-expect-error handled with 'type' - (acc: number, [, value]: MetricPoint) => (value < acc ? value : acc), - 9999999, - ); - maxValue = name.includes('Perc') - ? Math.round(100 * Y_EXTRA) - : Math.round( - newHistory.reduce( - // @ts-expect-error handled with 'type' - (acc: number, [, value]: MetricPoint) => (value > acc ? value : acc), - 0, - ) * Y_EXTRA, - ); - } else { - throw new Error('Unexpected metric data type'); - } - - // Average into buckets - const copy = [...newHistory]; - const buckets: DataPoint[] = []; - while (copy.length) { - const points = copy.splice(0, BUCKET_SIZE); - const avgIndex = Math.floor(points.length / 2); - buckets.push({ - value: points.reduce((acc, [, value]) => acc + value, 0) / points.length, - timestamp: points[avgIndex][0], - dateTime: new Date(points[avgIndex][0]).toISOString(), - }); - } - - fabricate.update( - dataKey, - { - buckets, - minTime, - maxTime, - minValue, - maxValue, - }, - ); -}; - -/** - * Fetch metric names, triggering update of graphs if they are shown. - * - * @param {AppState} state - App state. - */ -export const fetchMetricNames = async (state: AppState) => { - const { - message: metricNames = [], - } = await sendConduitPacket(state, { to: 'monitor', topic: 'getMetricNames' }); - fabricate.update({ metricNames }); -}; diff --git a/dashboard2/src/types.ts b/dashboard2/src/types.ts deleted file mode 100644 index dd9b9a03..00000000 --- a/dashboard2/src/types.ts +++ /dev/null @@ -1,72 +0,0 @@ -/** Type of IP */ -export type IPType = 'public' | 'local'; - -/** Device apps data */ -export type DeviceApp = { - app?: string; - status?: string; - port?: number; - error?: string; -}; - -/** Conduit packet type */ -export type Packet = { - to: string; - from?: string; - topic: string; - message?: object; -}; - -/** Device type */ -export type Device = { - deviceName: string; - localIp: string; - publicIp: string; - commit: string; - commitDate: string; - lastCheckIn: number; - deviceType: 'other' | 'pc' | 'pi' | 'other'; - diskSize: string; - diskUsage: number; - uptimeDays?: number; -}; - -/** Graph data point. */ -export type DataPoint = { - value: number; - timestamp: number; - dateTime: string; -}; - -/** Raw metric point */ -export type MetricPoint = [number, number]; - -/** Metric data */ -export type MetricData = { - buckets: DataPoint[]; - minTime: string; - maxTime: string; - minValue: number; - maxValue: number; -}; - -/** App state type */ -export type AppState = { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any; - - // App data - token: string; - publicIp: string; - - // Loaded data - selectedDeviceApps: DeviceApp[]; - devices: Device[]; - metricNames: string[]; - - // Selections - selectedDevice: Device | null, -}; - -/** Request states */ -export type RequestState = 'pending' | 'success' | 'error'; diff --git a/dashboard2/webpack.config.js b/dashboard2/webpack.config.js deleted file mode 100644 index ca792d13..00000000 --- a/dashboard2/webpack.config.js +++ /dev/null @@ -1,26 +0,0 @@ -const path = require('path'); - -module.exports = { - entry: './src/index.ts', - module: { - rules: [ - { - test: /\.ts?$/, - use: 'ts-loader', - exclude: /node_modules/, - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - }, - output: { - filename: 'bundle.js', - path: path.resolve(__dirname, 'dist'), - }, - devServer: { - static: path.join(__dirname, 'dist'), - compress: true, - port: 8080, - }, -}; diff --git a/launch-config/launchConfig.json b/launch-config/launchConfig.json index 428b05db..5e997623 100755 --- a/launch-config/launchConfig.json +++ b/launch-config/launchConfig.json @@ -8,7 +8,7 @@ { "location": "code/node-microservices/apps/concierge", "start": "npm start &" }, { "location": "code/node-microservices/apps/visuals", "start": "npm start &" }, { "location": "code/node-microservices/apps/monitor", "start": "npm start &" }, - { "location": "code/node-microservices/dashboard2", "start": "npm run build && http-server -p 54449 &" }, + { "location": "code/node-microservices/dashboard", "start": "npm start &" }, { "location": "code/microdiary", "start": "http-server -p 34279 &" }, { "location": "code/discord-bot-norren", diff --git a/unused/dashboard-v1/README.md b/unused/dashboard-v1/README.md new file mode 100644 index 00000000..aa62a9a5 --- /dev/null +++ b/unused/dashboard-v1/README.md @@ -0,0 +1,8 @@ +# service-dashboard + +![](assets/screenshot.png) + +Web application providing specialised interaction UI for the APIs +presented by the `node-microservices` apps, such as +[attic](https://github.com/c-d-lewis/attic) or +[visuals](https://github.com/c-d-lewis/visuals). diff --git a/dashboard2/assets/images/app.png b/unused/dashboard-v1/assets/app.png similarity index 100% rename from dashboard2/assets/images/app.png rename to unused/dashboard-v1/assets/app.png diff --git a/dashboard/assets/check.png b/unused/dashboard-v1/assets/check.png similarity index 100% rename from dashboard/assets/check.png rename to unused/dashboard-v1/assets/check.png diff --git a/dashboard2/assets/images/commit.png b/unused/dashboard-v1/assets/commit.png similarity index 100% rename from dashboard2/assets/images/commit.png rename to unused/dashboard-v1/assets/commit.png diff --git a/dashboard2/assets/images/disk.png b/unused/dashboard-v1/assets/disk.png similarity index 100% rename from dashboard2/assets/images/disk.png rename to unused/dashboard-v1/assets/disk.png diff --git a/dashboard/assets/download.png b/unused/dashboard-v1/assets/download.png similarity index 100% rename from dashboard/assets/download.png rename to unused/dashboard-v1/assets/download.png diff --git a/dashboard2/assets/images/eye.png b/unused/dashboard-v1/assets/eye.png similarity index 100% rename from dashboard2/assets/images/eye.png rename to unused/dashboard-v1/assets/eye.png diff --git a/dashboard/assets/local.png b/unused/dashboard-v1/assets/local.png similarity index 100% rename from dashboard/assets/local.png rename to unused/dashboard-v1/assets/local.png diff --git a/dashboard/assets/log.png b/unused/dashboard-v1/assets/log.png similarity index 100% rename from dashboard/assets/log.png rename to unused/dashboard-v1/assets/log.png diff --git a/dashboard/assets/network.png b/unused/dashboard-v1/assets/network.png similarity index 100% rename from dashboard/assets/network.png rename to unused/dashboard-v1/assets/network.png diff --git a/dashboard/assets/off.png b/unused/dashboard-v1/assets/off.png similarity index 100% rename from dashboard/assets/off.png rename to unused/dashboard-v1/assets/off.png diff --git a/dashboard2/assets/images/other.png b/unused/dashboard-v1/assets/other.png similarity index 100% rename from dashboard2/assets/images/other.png rename to unused/dashboard-v1/assets/other.png diff --git a/dashboard2/assets/images/pc.png b/unused/dashboard-v1/assets/pc.png similarity index 100% rename from dashboard2/assets/images/pc.png rename to unused/dashboard-v1/assets/pc.png diff --git a/dashboard/assets/plug-off.png b/unused/dashboard-v1/assets/plug-off.png similarity index 100% rename from dashboard/assets/plug-off.png rename to unused/dashboard-v1/assets/plug-off.png diff --git a/dashboard/assets/plug.png b/unused/dashboard-v1/assets/plug.png similarity index 100% rename from dashboard/assets/plug.png rename to unused/dashboard-v1/assets/plug.png diff --git a/dashboard/assets/plugin.png b/unused/dashboard-v1/assets/plugin.png similarity index 100% rename from dashboard/assets/plugin.png rename to unused/dashboard-v1/assets/plugin.png diff --git a/dashboard/assets/public.png b/unused/dashboard-v1/assets/public.png similarity index 100% rename from dashboard/assets/public.png rename to unused/dashboard-v1/assets/public.png diff --git a/dashboard2/assets/images/raspberrypi.png b/unused/dashboard-v1/assets/raspberrypi.png similarity index 100% rename from dashboard2/assets/images/raspberrypi.png rename to unused/dashboard-v1/assets/raspberrypi.png diff --git a/dashboard/assets/reload.png b/unused/dashboard-v1/assets/reload.png similarity index 100% rename from dashboard/assets/reload.png rename to unused/dashboard-v1/assets/reload.png diff --git a/dashboard2/assets/images/restart.png b/unused/dashboard-v1/assets/restart.png similarity index 100% rename from dashboard2/assets/images/restart.png rename to unused/dashboard-v1/assets/restart.png diff --git a/dashboard/assets/screenshot-old.png b/unused/dashboard-v1/assets/screenshot-old.png similarity index 100% rename from dashboard/assets/screenshot-old.png rename to unused/dashboard-v1/assets/screenshot-old.png diff --git a/dashboard/assets/screenshot.png b/unused/dashboard-v1/assets/screenshot.png similarity index 100% rename from dashboard/assets/screenshot.png rename to unused/dashboard-v1/assets/screenshot.png diff --git a/dashboard/assets/server-black.png b/unused/dashboard-v1/assets/server-black.png similarity index 100% rename from dashboard/assets/server-black.png rename to unused/dashboard-v1/assets/server-black.png diff --git a/dashboard2/assets/images/server-white.png b/unused/dashboard-v1/assets/server-white.png similarity index 100% rename from dashboard2/assets/images/server-white.png rename to unused/dashboard-v1/assets/server-white.png diff --git a/dashboard2/assets/images/shutdown.png b/unused/dashboard-v1/assets/shutdown.png similarity index 100% rename from dashboard2/assets/images/shutdown.png rename to unused/dashboard-v1/assets/shutdown.png diff --git a/dashboard/assets/spotify.png b/unused/dashboard-v1/assets/spotify.png similarity index 100% rename from dashboard/assets/spotify.png rename to unused/dashboard-v1/assets/spotify.png diff --git a/dashboard/assets/upload.png b/unused/dashboard-v1/assets/upload.png similarity index 100% rename from dashboard/assets/upload.png rename to unused/dashboard-v1/assets/upload.png diff --git a/dashboard2/css/global.css b/unused/dashboard-v1/css/global.css similarity index 64% rename from dashboard2/css/global.css rename to unused/dashboard-v1/css/global.css index 8c838b3a..a2b029df 100644 --- a/dashboard2/css/global.css +++ b/unused/dashboard-v1/css/global.css @@ -6,5 +6,9 @@ html, body, #app { margin: 0; width: 100%; height: 100%; - background-color: #111; + background-color: #222; +} + +tr { + margin-top: 10px; } diff --git a/dashboard2/favicon.ico b/unused/dashboard-v1/favicon.ico similarity index 100% rename from dashboard2/favicon.ico rename to unused/dashboard-v1/favicon.ico diff --git a/dashboard2/index.html b/unused/dashboard-v1/index.html similarity index 73% rename from dashboard2/index.html rename to unused/dashboard-v1/index.html index e661fe00..ab96df54 100644 --- a/dashboard2/index.html +++ b/unused/dashboard-v1/index.html @@ -1,14 +1,14 @@ - Node Microservices Dashboard + Service Dashboard - + - + diff --git a/dashboard2/package-lock.json b/unused/dashboard-v1/package-lock.json similarity index 100% rename from dashboard2/package-lock.json rename to unused/dashboard-v1/package-lock.json diff --git a/dashboard2/package.json b/unused/dashboard-v1/package.json similarity index 90% rename from dashboard2/package.json rename to unused/dashboard-v1/package.json index 0e387922..815ec8a8 100644 --- a/dashboard2/package.json +++ b/unused/dashboard-v1/package.json @@ -1,7 +1,7 @@ { "name": "service-dashboard", "version": "1.0.0", - "description": "Webapp to monitor device fleet and issue commands.", + "description": "Web application providing specialised interaction UI for the APIs presented by the node-microservices apps", "scripts": { "clean": "rm -rf ./dist", "build:dev": "npm run clean && webpack --mode development", diff --git a/unused/dashboard-v1/src/components/AppCard.ts b/unused/dashboard-v1/src/components/AppCard.ts new file mode 100644 index 00000000..38086ae8 --- /dev/null +++ b/unused/dashboard-v1/src/components/AppCard.ts @@ -0,0 +1,158 @@ +import { Fabricate, FabricateComponent } from 'fabricate.js'; +import { APP_CARD_WIDTH } from '../constants'; +import { AppState } from '../types'; +import AppControls from './AppControls'; +import { appRequestStateKey, getAppStatusColor, getReqStateColor } from '../utils'; + +declare const fabricate: Fabricate; + +/** + * CardContainer component. + * + * @returns {HTMLElement} Fabricate component. + */ +const CardContainer = () => fabricate('Card') + .asFlex('column') + .setStyles(({ palette }) => ({ + width: `${APP_CARD_WIDTH}px`, + margin: '10px 0px 10px 20px', + backgroundColor: palette.grey5, + boxShadow: '2px 2px 3px 1px #0004', + })); + +/** + * DeviceIcon component. + * + * @returns {HTMLElement} Fabricate component. + */ +const AppIcon = () => fabricate('Image', { src: 'assets/app.png' }) + .setStyles({ + margin: '4px 4px 4px', + width: '24px', + height: '24px', + }); + +/** + * AppName component. + * + * @returns {HTMLElement} Fabricate component. + */ +const AppName = () => fabricate('Text') + .setStyles(({ fonts }) => ({ + fontSize: '1.1rem', + flex: '1', + color: 'white', + margin: '6px 5px 5px 5px', + fontFamily: fonts.code, + fontWeight: 'bold', + cursor: 'default', + })); + +/** + * StatusText component. + * + * @returns {HTMLElement} Fabricate component. + */ +const StatusText = () => fabricate('Text') + .setStyles(({ palette }) => ({ + color: palette.lightGrey, + fontSize: '0.9rem', + paddingTop: '1', + marginBottom: '2px', + cursor: 'default', + })); + +/** + * StatusLED component. + * + * @param {object} props - Component props. + * @param {string} props.app - App. + * @returns {HTMLElement} Fabricate component. + */ +const StatusLED = ({ app }: { app: string }) => { + const reqStateKey = appRequestStateKey(app); + + /** + * Update the LED color. + * + * @param {FabricateComponent} el - This element. + * @param {AppState} state - App state. + */ + const updateColor = (el: FabricateComponent, state: AppState) => { + const { selectedDevice } = state; + if (selectedDevice === null) return; + + const pending = state[reqStateKey] === 'pending'; + const reqStateColor = getReqStateColor(state[reqStateKey]); + const statusColor = getAppStatusColor(state, app); + el.setStyles({ backgroundColor: pending ? reqStateColor : statusColor }); + }; + + return fabricate('div') + .setStyles({ + width: '15px', + height: '15px', + borderRadius: '9px', + marginRight: '5px', + }) + .onCreate(updateColor) + .onUpdate(updateColor, [reqStateKey]); +}; + +/** + * CardStatus component. + * + * @param {object} props - Component props. + * @param {string} props.app - App. + * @returns {HTMLElement} Fabricate component. + */ +const CardStatus = ({ app }: { app: string }) => fabricate('Row') + .setStyles({ + alignItems: 'center', + justifyContent: 'flex-end', + flex: '2', + }) + .setChildren([ + StatusLED({ app }), + StatusText() + .onCreate((el, { selectedDevice, deviceApps }) => { + if (selectedDevice === null) return; + + const apps = deviceApps[selectedDevice.deviceName]; + const { status, port } = apps.find((p) => p.app === app)!; + el.setText(`${status} (${port})`); + }), + ]); + +/** + * CardTitleRow component. + * + * @returns {HTMLElement} Fabricate component. + */ +const CardTitleRow = () => fabricate('Row') + .setStyles(({ palette }) => ({ + alignItems: 'center', + backgroundColor: palette.grey5, + padding: '3px 5px', + height: '35px', + })); + +/** + * AppCard component. + * + * @param {object} props - Component props. + * @param {string} props.app - App name. + * @returns {HTMLElement} Fabricate component. + */ +const AppCard = ({ app }: { app: string }) => CardContainer() + .setChildren([ + CardTitleRow() + .setChildren([ + AppIcon(), + AppName().setText(app), + CardStatus({ app }), + ]), + AppControls({ app }), + ]); + +export default AppCard; diff --git a/dashboard/src/components/AppControls.ts b/unused/dashboard-v1/src/components/AppControls.ts similarity index 100% rename from dashboard/src/components/AppControls.ts rename to unused/dashboard-v1/src/components/AppControls.ts diff --git a/dashboard/src/components/DeviceCard.ts b/unused/dashboard-v1/src/components/DeviceCard.ts similarity index 100% rename from dashboard/src/components/DeviceCard.ts rename to unused/dashboard-v1/src/components/DeviceCard.ts diff --git a/dashboard2/src/components/IconButton.ts b/unused/dashboard-v1/src/components/IconButton.ts similarity index 100% rename from dashboard2/src/components/IconButton.ts rename to unused/dashboard-v1/src/components/IconButton.ts diff --git a/dashboard/src/components/ItemPill.ts b/unused/dashboard-v1/src/components/ItemPill.ts similarity index 100% rename from dashboard/src/components/ItemPill.ts rename to unused/dashboard-v1/src/components/ItemPill.ts diff --git a/dashboard/src/components/MetricGraph.ts b/unused/dashboard-v1/src/components/MetricGraph.ts similarity index 100% rename from dashboard/src/components/MetricGraph.ts rename to unused/dashboard-v1/src/components/MetricGraph.ts diff --git a/dashboard/src/components/SubNavBar.ts b/unused/dashboard-v1/src/components/SubNavBar.ts similarity index 100% rename from dashboard/src/components/SubNavBar.ts rename to unused/dashboard-v1/src/components/SubNavBar.ts diff --git a/dashboard/src/components/SwatchButton.ts b/unused/dashboard-v1/src/components/SwatchButton.ts similarity index 100% rename from dashboard/src/components/SwatchButton.ts rename to unused/dashboard-v1/src/components/SwatchButton.ts diff --git a/dashboard/src/components/TextBox.ts b/unused/dashboard-v1/src/components/TextBox.ts similarity index 100% rename from dashboard/src/components/TextBox.ts rename to unused/dashboard-v1/src/components/TextBox.ts diff --git a/dashboard/src/components/TextButton.ts b/unused/dashboard-v1/src/components/TextButton.ts similarity index 100% rename from dashboard/src/components/TextButton.ts rename to unused/dashboard-v1/src/components/TextButton.ts diff --git a/dashboard/src/components/controls/AtticControls.ts b/unused/dashboard-v1/src/components/controls/AtticControls.ts similarity index 100% rename from dashboard/src/components/controls/AtticControls.ts rename to unused/dashboard-v1/src/components/controls/AtticControls.ts diff --git a/dashboard/src/components/controls/ClacksControls.ts b/unused/dashboard-v1/src/components/controls/ClacksControls.ts similarity index 100% rename from dashboard/src/components/controls/ClacksControls.ts rename to unused/dashboard-v1/src/components/controls/ClacksControls.ts diff --git a/dashboard/src/components/controls/ConduitControls.ts b/unused/dashboard-v1/src/components/controls/ConduitControls.ts similarity index 100% rename from dashboard/src/components/controls/ConduitControls.ts rename to unused/dashboard-v1/src/components/controls/ConduitControls.ts diff --git a/dashboard/src/components/controls/GuestlistControls.ts b/unused/dashboard-v1/src/components/controls/GuestlistControls.ts similarity index 100% rename from dashboard/src/components/controls/GuestlistControls.ts rename to unused/dashboard-v1/src/components/controls/GuestlistControls.ts diff --git a/dashboard/src/components/controls/MonitorControls.ts b/unused/dashboard-v1/src/components/controls/MonitorControls.ts similarity index 100% rename from dashboard/src/components/controls/MonitorControls.ts rename to unused/dashboard-v1/src/components/controls/MonitorControls.ts diff --git a/dashboard/src/components/controls/VisualsControls.ts b/unused/dashboard-v1/src/components/controls/VisualsControls.ts similarity index 100% rename from dashboard/src/components/controls/VisualsControls.ts rename to unused/dashboard-v1/src/components/controls/VisualsControls.ts diff --git a/unused/dashboard-v1/src/constants.ts b/unused/dashboard-v1/src/constants.ts new file mode 100644 index 00000000..b34352ad --- /dev/null +++ b/unused/dashboard-v1/src/constants.ts @@ -0,0 +1,71 @@ +import { AppState } from './types'; + +/** Fleet host URL */ +export const FLEET_HOST = 'polaris.chrislewis.me.uk'; + +/** Port to look for conduit apps */ +export const CONDUIT_PORT = 5959; + +/** App card width */ +export const APP_CARD_WIDTH = 375; + +/** Initial total app state */ +export const INITIAL_STATE: AppState = { + // App data + token: '', + deviceApps: {}, + fleet: [], + metricHistory: [], + + // Selections + page: 'FleetPage', + selectedDevice: null, + + // App data + atticData: { + app: '', + key: '', + value: '', + }, + conduitData: { + app: '', + topic: 'status', + message: '{}', + }, + visualsData: { + index: 0, + red: 128, + green: 128, + blue: 128, + text: '', + }, + guestlistData: { + adminPassword: '', + name: '', + apps: '', + topics: '', + }, + clacksData: { + topic: '', + message: '{}', + connected: false, + }, + monitorData: { + metricNames: [], + metric: '', + plugins: [], + minValue: 0, + maxValue: 99999, + minTime: 0, + maxTime: 99999, + type: 'number', + }, +}; + +/** Icon type names */ +export const ICON_NAMES: Record = { + other: 'other', + pc: 'pc', + pi: 'raspberrypi', + server: 'server-white', +}; diff --git a/unused/dashboard-v1/src/index.ts b/unused/dashboard-v1/src/index.ts new file mode 100644 index 00000000..6741a3b9 --- /dev/null +++ b/unused/dashboard-v1/src/index.ts @@ -0,0 +1,91 @@ +import { Fabricate } from 'fabricate.js'; +import { AppState } from './types'; +import Theme from './theme'; +import { CONDUIT_PORT, FLEET_HOST, INITIAL_STATE } from './constants'; +import SubNavBar from './components/SubNavBar'; +import FleetPage from './pages/FleetPage'; +import AppsPage from './pages/AppsPage'; + +declare const fabricate: Fabricate; + +/** + * Re-load the fleet list data. + * + * @param {object} state - App state. + */ +const fetchFleetList = async (state: AppState) => { + const { token } = state; + fabricate.update({ fleet: [] }); + + try { + // Can't use sendConduitPacket, not a device by name + const res = await fetch(`http://${FLEET_HOST}:${CONDUIT_PORT}/conduit`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + to: 'attic', + topic: 'get', + message: { app: 'conduit', key: 'fleetList' }, + auth: token || '', + }), + }); + const { message } = await res.json(); + fabricate.update({ fleet: message.value }); + } catch (err) { + console.error(err); + alert(err); + } +}; + +/** + * Parse query params. + */ +const parseParams = () => { + const params = new URLSearchParams(window.location.search); + const token = params.get('token'); + if (!token) { + alert('Please provide token param'); + return; + } + + fabricate.update({ token }); +}; + +/** + * AppNavBar component. + * + * @returns {HTMLElement} Fabricate component. + */ +const AppNavBar = () => fabricate('NavBar', { + title: 'Service Dashboard', + backgroundColor: Theme.palette.primary, +}); + +/** + * App component. + * + * @returns {HTMLElement} Fabricate component. + */ +const App = () => fabricate('Column') + .setChildren([ + AppNavBar(), + SubNavBar(), + fabricate.conditional(({ page }) => page === 'FleetPage', FleetPage), + fabricate.conditional(({ page }) => page === 'AppsPage', AppsPage), + ]) + .onUpdate(async (el, state, keys) => { + if (keys.includes(fabricate.StateKeys.Created)) { + parseParams(); + return; + } + + if (keys.includes('token')) { + await fetchFleetList(state); + } + }, [fabricate.StateKeys.Created, 'token']); + +fabricate.app( + App, + INITIAL_STATE, + { theme: Theme }, +); diff --git a/dashboard/src/pages/AppsPage.ts b/unused/dashboard-v1/src/pages/AppsPage.ts similarity index 100% rename from dashboard/src/pages/AppsPage.ts rename to unused/dashboard-v1/src/pages/AppsPage.ts diff --git a/dashboard/src/pages/FleetPage.ts b/unused/dashboard-v1/src/pages/FleetPage.ts similarity index 100% rename from dashboard/src/pages/FleetPage.ts rename to unused/dashboard-v1/src/pages/FleetPage.ts diff --git a/dashboard/src/services/clacksService.ts b/unused/dashboard-v1/src/services/clacksService.ts similarity index 100% rename from dashboard/src/services/clacksService.ts rename to unused/dashboard-v1/src/services/clacksService.ts diff --git a/unused/dashboard-v1/src/services/conduitService.ts b/unused/dashboard-v1/src/services/conduitService.ts new file mode 100644 index 00000000..4f2386b2 --- /dev/null +++ b/unused/dashboard-v1/src/services/conduitService.ts @@ -0,0 +1,66 @@ +import { Fabricate } from 'fabricate.js'; +import { CONDUIT_PORT, FLEET_HOST } from '../constants'; +import { AppState, Packet } from '../types'; +import { appRequestStateKey, isReachableKey } from '../utils'; + +declare const fabricate: Fabricate; + +/** + * Send a conduit packet. + * + * @param {AppState} state - App state. + * @param {Packet} packet - Packet to send. + * @param {string} deviceNameOverride - Override device name. + * @param {string} [tokenOverride] - Override auth token sent. + * @returns {Promise} Response. + * @throws {Error} Any error encountered. + */ +// eslint-disable-next-line import/prefer-default-export +export const sendConduitPacket = async ( + state: AppState, + packet: Packet, + deviceNameOverride?: string, + tokenOverride?: string, +) => { + const { token, selectedDevice, fleet } = state; + const reqStateKey = appRequestStateKey(packet.to); + fabricate.update(reqStateKey, 'pending'); + + try { + // Begin with host unless some device is selected to drill down + let destination = FLEET_HOST; + + const finalDevice = deviceNameOverride + ? fleet.find(({ deviceName }) => deviceName === deviceNameOverride)! + : selectedDevice; + if (!finalDevice) throw new Error('Unable to identify device to send message to.'); + + const { localIp, publicIp, deviceName } = finalDevice; + const isLocalReachable = state[isReachableKey(deviceName, 'local')]; + + // Destination is local if reachable, else forward local via public + destination = isLocalReachable ? localIp : publicIp; + const forwardHost = destination === publicIp ? localIp : undefined; + console.log(`${finalDevice?.deviceName} >>> ${JSON.stringify(packet)}`); + + const res = await fetch(`http://${destination}:${CONDUIT_PORT}/conduit`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + ...packet, + auth: tokenOverride || token || '', + host: forwardHost, + device: finalDevice && finalDevice.deviceName, + }), + }); + const json = await res.json(); + console.log(`<<< ${finalDevice?.deviceName} ${JSON.stringify(json)}`); + + fabricate.update(reqStateKey, 'success'); + return json; + } catch (error) { + console.log(error); + fabricate.update(reqStateKey, 'error'); + throw error; + } +}; diff --git a/dashboard2/src/theme.ts b/unused/dashboard-v1/src/theme.ts similarity index 67% rename from dashboard2/src/theme.ts rename to unused/dashboard-v1/src/theme.ts index c6ed1ecf..0bf459eb 100644 --- a/dashboard2/src/theme.ts +++ b/unused/dashboard-v1/src/theme.ts @@ -1,18 +1,16 @@ /** App colors */ const Theme = { palette: { - primary: '#c7053d', - secondary: 'orange', + primary: '#303F9F', + datapoint: 'orange', + instanceHealthy: '#007800', text: 'white', grey1: '#111', grey2: '#222', grey3: '#333', grey4: '#444', grey5: '#555', - grey6: '#666', - greyA: '#aaa', - greyC: '#ccc', - greyE: '#eee', + lightGrey: '#eee', statusOk: '#43D047', statusDown: '#DD6E40', statusPending: 'orange', @@ -20,6 +18,11 @@ const Theme = { }, styles: { boxShadow: '2px 2px 3px 1px #0004', + controlButton: { + borderRadius: '0', + margin: '0', + minWidth: '50px', + }, }, fonts: { body: 'sans-serif', diff --git a/unused/dashboard-v1/src/types.ts b/unused/dashboard-v1/src/types.ts new file mode 100644 index 00000000..8367a42b --- /dev/null +++ b/unused/dashboard-v1/src/types.ts @@ -0,0 +1,117 @@ +/** Type of IP */ +export type IPType = 'public' | 'local'; + +/** Device apps data */ +export type DeviceApp = { + app?: string; + status?: string; + port?: number; + error?: string; +}; + +/** Conduit packet type */ +export type Packet = { + to: string; + from?: string; + topic: string; + message?: object; +}; + +/** Device type */ +export type Device = { + deviceName: string; + localIp: string; + publicIp: string; + commit: string; + commitDate: string; + lastCheckIn: number; + deviceType: 'other' | 'pc' | 'pi' | 'other'; + diskSize: string; + diskUsage: number; +}; + +/** Graph data point. */ +export type DataPoint = { + value: number; + dateTime: string; +}; + +/** Raw metric point */ +export type MetricPoint = [number, number | string[]]; + +/** monitor plugin configuration */ +export type MonitorPlugin = { + FILE_NAME: string; + EVERY?: number; + AT?: string; + ENABLED?: boolean; +}; + +/** App pages */ +type Pages = 'FleetPage' | 'AppsPage'; + +/** App state type */ +export type AppState = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [key: string]: any; + + // App data + token: string; + deviceApps: Record; + fleet: Device[]; + metricHistory: MetricPoint[]; + + // Selections + page: Pages, + selectedDevice: Device | null, + + // App data + atticData: { + app: string; + key: string; + value: string; + }; + conduitData: { + app: string; + topic: string; + message: string; + }; + visualsData: { + index: number; + red: number; + green: number; + blue: number; + text: string; + }; + guestlistData: { + adminPassword: string; + name: string; + apps: string; + topics: string; + }; + clacksData: { + topic: string; + message: string; + connected: boolean; + }; + monitorData: { + metricNames: string[]; + metric: string; + plugins: MonitorPlugin[]; + minValue: number; + maxValue: number; + minTime: number; + maxTime: number; + type: 'array' | 'number'; + }; +}; + +/** Fake type for WebSocket message event */ +export type WSMessageEvent = { + data: { + text: () => Promise, + }, +}; + +/** Request states */ +export type RequestState = 'pending' | 'success' | 'error'; diff --git a/dashboard/src/utils.ts b/unused/dashboard-v1/src/utils.ts similarity index 100% rename from dashboard/src/utils.ts rename to unused/dashboard-v1/src/utils.ts diff --git a/dashboard2/tsconfig.json b/unused/dashboard-v1/tsconfig.json similarity index 100% rename from dashboard2/tsconfig.json rename to unused/dashboard-v1/tsconfig.json diff --git a/dashboard/webpack.config.js b/unused/dashboard-v1/webpack.config.js similarity index 100% rename from dashboard/webpack.config.js rename to unused/dashboard-v1/webpack.config.js