From a85a54651070765d6254287369835d747be1c276 Mon Sep 17 00:00:00 2001 From: "Alex Pooley (@zuedev)" Date: Sat, 25 Jul 2026 17:27:38 +0100 Subject: manager is now using react --- 174bg/manager/.gitignore | 3 +- 174bg/manager/index.html | 18 + 174bg/manager/package-lock.json | 2324 ++++++++++++++++++++-- 174bg/manager/package.json | 18 +- 174bg/manager/public/index.html | 1163 ----------- 174bg/manager/public/theme.css | 423 ---- 174bg/manager/src/App.jsx | 182 ++ 174bg/manager/src/components/Ledger.jsx | 73 + 174bg/manager/src/components/OnCallSchedule.jsx | 186 ++ 174bg/manager/src/components/RequiredInfo.jsx | 66 + 174bg/manager/src/components/RolePreferences.jsx | 171 ++ 174bg/manager/src/components/Welcome.jsx | 14 + 174bg/manager/src/lib/oncallTime.js | 242 +++ 174bg/manager/src/lib/otherJsonData.js | 13 + 174bg/manager/src/lib/pocketbase.js | 3 + 174bg/manager/src/lib/roles.js | 142 ++ 174bg/manager/src/main.jsx | 10 + 174bg/manager/src/theme.css | 423 ++++ 174bg/manager/vite.config.js | 9 + 174bg/manager/wrangler.jsonc | 2 +- 20 files changed, 3682 insertions(+), 1803 deletions(-) create mode 100644 174bg/manager/index.html delete mode 100644 174bg/manager/public/index.html delete mode 100644 174bg/manager/public/theme.css create mode 100644 174bg/manager/src/App.jsx create mode 100644 174bg/manager/src/components/Ledger.jsx create mode 100644 174bg/manager/src/components/OnCallSchedule.jsx create mode 100644 174bg/manager/src/components/RequiredInfo.jsx create mode 100644 174bg/manager/src/components/RolePreferences.jsx create mode 100644 174bg/manager/src/components/Welcome.jsx create mode 100644 174bg/manager/src/lib/oncallTime.js create mode 100644 174bg/manager/src/lib/otherJsonData.js create mode 100644 174bg/manager/src/lib/pocketbase.js create mode 100644 174bg/manager/src/lib/roles.js create mode 100644 174bg/manager/src/main.jsx create mode 100644 174bg/manager/src/theme.css create mode 100644 174bg/manager/vite.config.js (limited to '174bg/manager') diff --git a/174bg/manager/.gitignore b/174bg/manager/.gitignore index 9397005..da996ac 100644 --- a/174bg/manager/.gitignore +++ b/174bg/manager/.gitignore @@ -1,2 +1,3 @@ /node_modules/ -/.wrangler \ No newline at end of file +/.wrangler +/dist \ No newline at end of file diff --git a/174bg/manager/index.html b/174bg/manager/index.html new file mode 100644 index 0000000..2527574 --- /dev/null +++ b/174bg/manager/index.html @@ -0,0 +1,18 @@ + + + + + + 174th Battle Group: Manager + + + + + +
+ + + diff --git a/174bg/manager/package-lock.json b/174bg/manager/package-lock.json index 72956e6..505b3ad 100644 --- a/174bg/manager/package-lock.json +++ b/174bg/manager/package-lock.json @@ -5,13 +5,334 @@ "packages": { "": { "dependencies": { + "pocketbase": "^0.27.0", + "react": "^19.1.0", + "react-dom": "^19.1.0" + }, + "devDependencies": { + "@vitejs/plugin-react": "^4.3.4", + "vite": "^6.2.0", "wrangler": "^4.95.0" } }, + "node_modules/@babel/code-frame": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", + "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.7" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.29.7.tgz", + "integrity": "sha512-TL0hMc9xzy86VD31nUiwzd5otRAcyEPcsegCxolO0PvcXuH1v0kECe/UIznYFihpkvU5wg/jk4v0TTEFfm53fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.29.7.tgz", + "integrity": "sha512-06IyK09H3wi4cGbhDBwp5gUGo0IKtnYa8tyTiephirPCK6fbobVGiXMMI5zLQ4aKEYP3wZ3ArU44o+8KMrSG/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", + "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@cloudflare/kv-asset-handler": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz", "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==", + "dev": true, "license": "MIT OR Apache-2.0", "engines": { "node": ">=22.0.0" @@ -21,6 +342,7 @@ "version": "2.16.1", "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz", "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==", + "dev": true, "license": "MIT OR Apache-2.0", "peerDependencies": { "unenv": "2.0.0-rc.24", @@ -39,6 +361,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -55,6 +378,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -71,6 +395,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -87,6 +412,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -103,6 +429,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -116,6 +443,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -128,6 +456,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -141,6 +470,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -157,6 +487,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -173,6 +504,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -189,6 +521,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -205,6 +538,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -221,6 +555,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -237,6 +572,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -253,6 +589,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -269,6 +606,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -285,6 +623,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -301,6 +640,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -317,6 +657,7 @@ "cpu": [ "loong64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -333,6 +674,7 @@ "cpu": [ "mips64el" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -349,6 +691,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -365,6 +708,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -381,6 +725,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -397,6 +742,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -413,6 +759,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -429,6 +776,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -445,6 +793,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -461,6 +810,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -477,6 +827,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -493,6 +844,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -509,6 +861,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -525,6 +878,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -541,6 +895,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -554,6 +909,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -566,6 +922,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -588,6 +945,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -610,6 +968,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -626,6 +985,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -642,6 +1002,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -658,6 +1019,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -674,6 +1036,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -690,6 +1053,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -706,6 +1070,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -722,6 +1087,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -738,6 +1104,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -754,6 +1121,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -770,6 +1138,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -792,6 +1161,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -814,6 +1184,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -836,6 +1207,7 @@ "cpu": [ "riscv64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -858,6 +1230,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -880,6 +1253,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -902,6 +1276,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -924,6 +1299,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0", "optional": true, "os": [ @@ -946,6 +1322,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -965,6 +1342,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -984,6 +1362,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -1003,6 +1382,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "Apache-2.0 AND LGPL-3.0-or-later", "optional": true, "os": [ @@ -1015,10 +1395,55 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1028,12 +1453,14 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -1044,6 +1471,7 @@ "version": "4.1.6", "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", + "dev": true, "license": "MIT", "dependencies": { "kleur": "^4.1.5" @@ -1053,6 +1481,7 @@ "version": "0.6.5", "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", + "dev": true, "license": "MIT", "dependencies": { "@poppinss/colors": "^4.1.5", @@ -1064,78 +1493,655 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", + "dev": true, "license": "MIT" }, - "node_modules/@sindresorhus/is": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", - "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz", + "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==", + "cpu": [ + "arm" + ], + "dev": true, "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } + "optional": true, + "os": [ + "android" + ] }, - "node_modules/@speed-highlight/core": { - "version": "1.2.15", - "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz", - "integrity": "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==", - "license": "CC0-1.0" + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz", + "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/blake3-wasm": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", - "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", - "license": "MIT" + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz", + "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz", + "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz", + "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/error-stack-parser-es": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", - "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz", + "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/antfu" - } + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/esbuild": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", - "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", - "hasInstallScript": true, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz", + "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.27.3", - "@esbuild/android-arm": "0.27.3", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz", + "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz", + "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz", + "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz", + "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz", + "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz", + "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz", + "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz", + "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz", + "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz", + "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz", + "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz", + "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz", + "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz", + "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz", + "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz", + "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz", + "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz", + "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sindresorhus/is": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", + "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@speed-highlight/core": { + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.15.tgz", + "integrity": "sha512-BMq1K3DsElxDWawkX6eLg9+CKJrTVGCBAWVuHXVUV2u0s2711qiChLSId6ikYPfxhdYocLNt3wWwSvDiTvFabw==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.3", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.3.tgz", + "integrity": "sha512-sbT0Ui/CZwyAyy7icT1Gw5P1LKRlFaHwaF6tDCW5YHq2X5SeeZFphBuIagopSfwSSZq3sQcbmEL072yphxm7ew==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/blake3-wasm": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", + "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", + "dev": true, + "license": "MIT" + }, + "node_modules/browserslist": { + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.396", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.396.tgz", + "integrity": "sha512-yHiw2Y3C3H9U6TMbOfoWK/BPreiOPXRfTWPBwQBoZG6/8TB6eOPnsy5oaRYuatR7Fw2SJ4kKforgufeo7fq0EQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/error-stack-parser-es": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", + "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", @@ -1162,218 +2168,1103 @@ "@esbuild/win32-x64": "0.27.3" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": 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, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/miniflare": { + "version": "4.20260526.0", + "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260526.0.tgz", + "integrity": "sha512-JYQ7jPZZWoaaj9jWHb8Ucp6Cu2SbDVqIsAJhumqdzzLkkfq0pYkDeino/sZfW1ixJWPjv/C44zjm9gVJC2izCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "0.8.1", + "sharp": "^0.34.5", + "undici": "7.24.8", + "workerd": "1.20260526.1", + "ws": "8.20.1", + "youch": "4.1.0-beta.10" + }, + "bin": { + "miniflare": "bootstrap.js" + }, + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pocketbase": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.27.0.tgz", + "integrity": "sha512-K5N6d93UP/BNMbMnlZ6BUfy9VPCIvLyqhJFOsNI8OsZwzvKWEAfyD36boi5K4ECIOl5HMlo0TzuaeGdKpMwizQ==", + "license": "MIT" + }, + "node_modules/postcss": { + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "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" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.8" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.62.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz", + "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.2", + "@rollup/rollup-android-arm64": "4.62.2", + "@rollup/rollup-darwin-arm64": "4.62.2", + "@rollup/rollup-darwin-x64": "4.62.2", + "@rollup/rollup-freebsd-arm64": "4.62.2", + "@rollup/rollup-freebsd-x64": "4.62.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.2", + "@rollup/rollup-linux-arm-musleabihf": "4.62.2", + "@rollup/rollup-linux-arm64-gnu": "4.62.2", + "@rollup/rollup-linux-arm64-musl": "4.62.2", + "@rollup/rollup-linux-loong64-gnu": "4.62.2", + "@rollup/rollup-linux-loong64-musl": "4.62.2", + "@rollup/rollup-linux-ppc64-gnu": "4.62.2", + "@rollup/rollup-linux-ppc64-musl": "4.62.2", + "@rollup/rollup-linux-riscv64-gnu": "4.62.2", + "@rollup/rollup-linux-riscv64-musl": "4.62.2", + "@rollup/rollup-linux-s390x-gnu": "4.62.2", + "@rollup/rollup-linux-x64-gnu": "4.62.2", + "@rollup/rollup-linux-x64-musl": "4.62.2", + "@rollup/rollup-openbsd-x64": "4.62.2", + "@rollup/rollup-openharmony-arm64": "4.62.2", + "@rollup/rollup-win32-arm64-msvc": "4.62.2", + "@rollup/rollup-win32-ia32-msvc": "4.62.2", + "@rollup/rollup-win32-x64-gnu": "4.62.2", + "@rollup/rollup-win32-x64-msvc": "4.62.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/rosie-skills": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/rosie-skills/-/rosie-skills-0.6.4.tgz", + "integrity": "sha512-ojfhSiQRdZ2QyWbmKAHOSAUbaLYrTc5zIH7mS1jKoP8KCFSQddwVhMyFqldckTeybTfW3zNcsZzyOTzGTN1SBA==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "rosie-skills": "dist/bin.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "rosie-skills-darwin-arm64": "0.6.4", + "rosie-skills-freebsd-x64": "0.6.4", + "rosie-skills-linux-x64": "0.6.4" + } + }, + "node_modules/rosie-skills-darwin-arm64": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/rosie-skills-darwin-arm64/-/rosie-skills-darwin-arm64-0.6.4.tgz", + "integrity": "sha512-rn1s5hqFKcxeiDEWWoFa1hdGPshR8TkwHLzy/cBavb9XJNAaUxbe3oQ78W9sQkRHAgRyzJYyk9tw68Qrdnizgg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/rosie-skills-freebsd-x64": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/rosie-skills-freebsd-x64/-/rosie-skills-freebsd-x64-0.6.4.tgz", + "integrity": "sha512-SxCRduPBMtfjkQ+q56Yw9OLA3PyaqoALzt7kER7IDKuUVfM2O/1w8sa5xhTDiCvWkZJixnH5d5Ya6KT+/Mwcng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/rosie-skills-linux-x64": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/rosie-skills-linux-x64/-/rosie-skills-linux-x64-0.6.4.tgz", + "integrity": "sha512-D9Y9mfu7goB0s0X59uU3hcFeUTef3VbpCIDwFMzyvJrAq3XhRACWBDMHQsHlyWdHxTXPX/ILyW65RXyrJlgqng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", + "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "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, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/undici": { + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz", + "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unenv": { + "version": "2.0.0-rc.24", + "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", + "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pathe": "^2.0.3" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz", + "integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.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 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" + "linux" ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=18" } }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=18" } }, - "node_modules/miniflare": { - "version": "4.20260526.0", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-4.20260526.0.tgz", - "integrity": "sha512-JYQ7jPZZWoaaj9jWHb8Ucp6Cu2SbDVqIsAJhumqdzzLkkfq0pYkDeino/sZfW1ixJWPjv/C44zjm9gVJC2izCA==", + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "sharp": "^0.34.5", - "undici": "7.24.8", - "workerd": "1.20260526.1", - "ws": "8.20.1", - "youch": "4.1.0-beta.10" - }, - "bin": { - "miniflare": "bootstrap.js" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=22.0.0" + "node": ">=18" } }, - "node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "license": "MIT" - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "license": "MIT" + "node_modules/vite/node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/rosie-skills": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills/-/rosie-skills-0.6.4.tgz", - "integrity": "sha512-ojfhSiQRdZ2QyWbmKAHOSAUbaLYrTc5zIH7mS1jKoP8KCFSQddwVhMyFqldckTeybTfW3zNcsZzyOTzGTN1SBA==", - "license": "BSD-3-Clause", - "bin": { - "rosie-skills": "dist/bin.js" - }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { "node": ">=18" - }, - "optionalDependencies": { - "rosie-skills-darwin-arm64": "0.6.4", - "rosie-skills-freebsd-x64": "0.6.4", - "rosie-skills-linux-x64": "0.6.4" } }, - "node_modules/rosie-skills-darwin-arm64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills-darwin-arm64/-/rosie-skills-darwin-arm64-0.6.4.tgz", - "integrity": "sha512-rn1s5hqFKcxeiDEWWoFa1hdGPshR8TkwHLzy/cBavb9XJNAaUxbe3oQ78W9sQkRHAgRyzJYyk9tw68Qrdnizgg==", + "node_modules/vite/node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], - "license": "BSD-3-Clause", + "dev": true, + "license": "MIT", "optional": true, "os": [ - "darwin" - ] + "openbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/rosie-skills-freebsd-x64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills-freebsd-x64/-/rosie-skills-freebsd-x64-0.6.4.tgz", - "integrity": "sha512-SxCRduPBMtfjkQ+q56Yw9OLA3PyaqoALzt7kER7IDKuUVfM2O/1w8sa5xhTDiCvWkZJixnH5d5Ya6KT+/Mwcng==", + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], - "license": "BSD-3-Clause", + "dev": true, + "license": "MIT", "optional": true, "os": [ - "freebsd" - ] + "openbsd" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/rosie-skills-linux-x64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/rosie-skills-linux-x64/-/rosie-skills-linux-x64-0.6.4.tgz", - "integrity": "sha512-D9Y9mfu7goB0s0X59uU3hcFeUTef3VbpCIDwFMzyvJrAq3XhRACWBDMHQsHlyWdHxTXPX/ILyW65RXyrJlgqng==", + "node_modules/vite/node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "cpu": [ - "x64" + "arm64" ], - "license": "BSD-3-Clause", + "dev": true, + "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, + "openharmony" + ], "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@img/colour": "^1.0.0", - "detect-libc": "^2.1.2", - "semver": "^7.7.3" - }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" + "node": ">=18" } }, - "node_modules/supports-color": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", - "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "optional": true + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } }, - "node_modules/undici": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.8.tgz", - "integrity": "sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==", + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=20.18.1" + "node": ">=18" } }, - "node_modules/unenv": { - "version": "2.0.0-rc.24", - "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", - "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", + "node_modules/vite/node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, "license": "MIT", - "peer": true, - "dependencies": { - "pathe": "^2.0.3" + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, "node_modules/workerd": { "version": "1.20260526.1", "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260526.1.tgz", "integrity": "sha512-IHzymht98p10JH1zzwdCpbViAqw97HrwKl7+KfZeASFMsYSrIsAULWdPn0LRC5FTUzBpamLNyKCCKxbgXHgRHQ==", + "dev": true, "hasInstallScript": true, "license": "Apache-2.0", - "peer": true, "bin": { "workerd": "bin/workerd" }, @@ -1392,6 +3283,7 @@ "version": "4.95.0", "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.95.0.tgz", "integrity": "sha512-vgXzFVSCdUbeCadgVXvu8fK5tzNm8T9W+7lriyGWZMx0B1+CAdr4d8JTlZszHfgjypRAHmAxb49etZGIRD9pgg==", + "dev": true, "license": "MIT OR Apache-2.0", "dependencies": { "@cloudflare/kv-asset-handler": "0.5.0", @@ -1427,6 +3319,7 @@ "version": "8.20.1", "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", "integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", + "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -1444,10 +3337,18 @@ } } }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, "node_modules/youch": { "version": "4.1.0-beta.10", "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", + "dev": true, "license": "MIT", "dependencies": { "@poppinss/colors": "^4.1.5", @@ -1461,6 +3362,7 @@ "version": "0.3.3", "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", + "dev": true, "license": "MIT", "dependencies": { "@poppinss/exception": "^1.2.2", diff --git a/174bg/manager/package.json b/174bg/manager/package.json index 076395b..0e4769e 100644 --- a/174bg/manager/package.json +++ b/174bg/manager/package.json @@ -1,9 +1,19 @@ { + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "deploy": "npm run build && npx wrangler deploy --minify" + }, "dependencies": { - "wrangler": "^4.95.0" + "pocketbase": "^0.27.0", + "react": "^19.1.0", + "react-dom": "^19.1.0" }, - "scripts": { - "deploy": "npx wrangler deploy --minify", - "dev": "npx wrangler dev" + "devDependencies": { + "@vitejs/plugin-react": "^4.3.4", + "vite": "^6.2.0", + "wrangler": "^4.95.0" } } diff --git a/174bg/manager/public/index.html b/174bg/manager/public/index.html deleted file mode 100644 index 002417a..0000000 --- a/174bg/manager/public/index.html +++ /dev/null @@ -1,1163 +0,0 @@ - - - - - - - - - - - -

174th Battle Group: Manager

- -
-

You are not logged in. Please log in to access this site:

- -
- -

- - - - - diff --git a/174bg/manager/public/theme.css b/174bg/manager/public/theme.css deleted file mode 100644 index 907a77e..0000000 --- a/174bg/manager/public/theme.css +++ /dev/null @@ -1,423 +0,0 @@ -:root { - --bg: #070b14; - --bg-grid: rgba(56, 189, 248, 0.06); - --panel: rgba(15, 23, 42, 0.72); - --panel-border: rgba(56, 189, 248, 0.22); - --panel-border-strong: rgba(56, 189, 248, 0.5); - --text: #dbe7f3; - --text-dim: #7e93ab; - --accent: #38bdf8; - --accent-2: #22d3ee; - --accent-glow: rgba(56, 189, 248, 0.45); - --danger: #f87171; - --danger-bg: rgba(248, 113, 113, 0.12); - --success: #34d399; - --row-alt: rgba(56, 189, 248, 0.04); -} - -* { - box-sizing: border-box; -} - -html { - font-family: "Rajdhani", system-ui, sans-serif; - font-size: 16px; - color-scheme: dark; -} - -body { - margin: 0; - min-height: 100vh; - padding: 2.5rem 1.25rem 4rem; - color: var(--text); - background-color: var(--bg); - background-image: - radial-gradient( - ellipse 80% 60% at 50% -10%, - rgba(56, 189, 248, 0.18), - transparent 60% - ), - linear-gradient(var(--bg-grid) 1px, transparent 1px), - linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px); - background-size: - 100% 100%, - 44px 44px, - 44px 44px; - background-attachment: fixed; - display: flex; - flex-direction: column; - align-items: center; -} - -h1 { - font-family: "Orbitron", sans-serif; - font-weight: 900; - font-size: clamp(1.5rem, 4vw, 2.4rem); - letter-spacing: 0.04em; - text-align: center; - margin: 0 0 1.75rem; - background: linear-gradient(120deg, var(--accent), var(--accent-2)); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - text-shadow: 0 0 28px var(--accent-glow); -} - -h2 { - font-family: "Orbitron", sans-serif; - font-size: 1.05rem; - letter-spacing: 0.06em; - text-transform: uppercase; - color: var(--accent); - margin: 0 0 0.75rem; -} - -a { - color: var(--accent-2); - text-decoration: none; - border-bottom: 1px solid transparent; - transition: border-color 0.15s ease; -} - -a:hover { - border-bottom-color: var(--accent-2); -} - -body > h1, -#anonymous, -#oauth-status, -#authed { - width: 100%; - max-width: 760px; -} - -/* Panels ----------------------------------------------------------- */ -#anonymous, -#required-info, -#preferences, -#oncall, -#ledger, -#welcome { - background: var(--panel); - border: 1px solid var(--panel-border); - border-radius: 14px; - padding: 1.25rem 1.4rem; - backdrop-filter: blur(10px); - box-shadow: - 0 0 0 1px rgba(0, 0, 0, 0.3), - 0 18px 48px rgba(0, 0, 0, 0.45); -} - -#anonymous p { - margin-top: 0; -} - -/* Buttons ---------------------------------------------------------- */ -button { - font-family: "Rajdhani", sans-serif; - font-weight: 600; - font-size: 0.95rem; - letter-spacing: 0.03em; - color: #04121f; - background: linear-gradient(120deg, var(--accent), var(--accent-2)); - border: none; - border-radius: 8px; - padding: 0.55rem 1.1rem; - cursor: pointer; - transition: - transform 0.12s ease, - box-shadow 0.2s ease, - filter 0.2s ease; - box-shadow: 0 6px 18px var(--accent-glow); -} - -button:hover:not(:disabled) { - transform: translateY(-1px); - box-shadow: 0 8px 26px var(--accent-glow); - filter: brightness(1.08); -} - -button:active:not(:disabled) { - transform: translateY(0); -} - -button:disabled { - opacity: 0.5; - cursor: not-allowed; - box-shadow: none; -} - -/* Required info ---------------------------------------------------- */ -#required-info > div:not(:first-child):not(#profile-warning) { - display: flex; - justify-content: space-between; - gap: 1rem; - padding: 0.4rem 0; - border-bottom: 1px solid rgba(56, 189, 248, 0.08); -} - -#required-info > div b { - color: var(--text-dim); - font-weight: 600; -} - -/* Tables ----------------------------------------------------------- */ -#preferences table, -#oncall table, -#ledger table { - border-collapse: collapse; - width: 100%; - min-width: 16rem; -} - -#preferences thead th, -#oncall thead th, -#ledger thead th { - text-align: left; - padding: 0.5rem 0.75rem; - border-bottom: 2px solid var(--panel-border-strong); - font-family: "Orbitron", sans-serif; - font-size: 0.68rem; - text-transform: uppercase; - letter-spacing: 0.08em; - color: var(--accent); -} - -#preferences tbody tr:nth-child(even), -#oncall tbody tr:nth-child(even), -#ledger tbody tr:nth-child(even) { - background: var(--row-alt); -} - -#preferences tbody td, -#oncall tbody td, -#ledger tbody td { - padding: 0.45rem 0.75rem; - border-bottom: 1px solid rgba(56, 189, 248, 0.1); -} - -#preferences tbody tr:hover:not([data-separator]), -#oncall tbody tr:hover, -#ledger tbody tr:hover { - background: rgba(56, 189, 248, 0.1); -} - -#preferences thead th:not(:first-child) { - text-align: center; - width: 2.5rem; -} - -#preferences tbody td:not(:first-child) { - text-align: center; - width: 2.5rem; -} - -#ledger td.uec { - text-align: right; - font-variant-numeric: tabular-nums; - color: var(--accent-2); - font-weight: 600; -} - -#ledger .empty { - margin: 0.25rem 0 0; - font-size: 0.9rem; - color: var(--text-dim); -} - -input[type="checkbox"] { - width: 1.05rem; - height: 1.05rem; - accent-color: var(--accent); - cursor: pointer; -} - -#oncall input[type="time"] { - font-family: "Rajdhani", sans-serif; - font-size: 0.9rem; - color: var(--text); - background: rgba(15, 23, 42, 0.6); - border: 1px solid var(--panel-border); - border-radius: 6px; - padding: 0.3rem 0.5rem; - color-scheme: dark; -} - -#oncall input[type="time"]:disabled { - opacity: 0.35; -} - -#oncall select { - font-family: "Rajdhani", sans-serif; - font-size: 0.9rem; - color: var(--text); - background: rgba(15, 23, 42, 0.6); - border: 1px solid var(--panel-border); - border-radius: 6px; - padding: 0.3rem 0.5rem; - color-scheme: dark; - max-width: 16rem; -} - -/* Status & warnings ------------------------------------------------ */ -#oauth-status { - font-size: 0.9rem; -} - -#profile-warning { - margin-top: 0.75rem; - padding: 0.7rem 1rem; - background: var(--danger-bg); - border: 1px solid var(--danger); - border-radius: 8px; - color: var(--danger); - font-weight: 700; -} - -/* Welcome ---------------------------------------------------------- */ -#welcome { - display: flex; - align-items: center; - gap: 1rem; -} - -#welcome-avatar { - width: 3.25rem; - height: 3.25rem; - border-radius: 50%; - object-fit: cover; - border: 2px solid var(--accent); - box-shadow: 0 0 18px var(--accent-glow); -} - -#welcome-text { - font-family: "Orbitron", sans-serif; - font-size: 1.2rem; - font-weight: 700; - letter-spacing: 0.02em; -} - -/* Tables can scroll horizontally if they ever overflow ------------- */ -#preferences, -#oncall, -#ledger { - overflow-x: auto; -} - -/* ================================================================= */ -/* Responsive — tablet */ -/* ================================================================= */ -@media (max-width: 640px) { - body { - padding: 1.5rem 0.85rem 3rem; - } - - #anonymous, - #required-info, - #preferences, - #oncall, - #ledger, - #welcome { - padding: 1rem 1.1rem; - border-radius: 12px; - } - - #welcome { - gap: 0.75rem; - } - - #welcome-avatar { - width: 2.75rem; - height: 2.75rem; - } - - #welcome-text { - font-size: 1.05rem; - } - - /* Stack required-info rows so long values don't get squeezed */ - #required-info > div:not(:first-child):not(#profile-warning) { - flex-direction: column; - gap: 0.1rem; - word-break: break-word; - } - - button { - width: 100%; - } - - #preferences thead th:first-child, - #preferences tbody td:first-child { - white-space: normal; - } -} - -/* ================================================================= */ -/* Responsive — phone: turn the ledger into stacked cards */ -/* ================================================================= */ -@media (max-width: 520px) { - #ledger { - overflow-x: visible; - } - - #ledger table, - #ledger thead, - #ledger tbody, - #ledger tr, - #ledger td { - display: block; - width: 100%; - } - - /* Hide the table header row; labels come from data-label instead */ - #ledger thead { - position: absolute; - width: 1px; - height: 1px; - overflow: hidden; - clip: rect(0 0 0 0); - white-space: nowrap; - } - - #ledger tbody tr { - margin-bottom: 0.85rem; - border: 1px solid var(--panel-border); - border-radius: 10px; - padding: 0.35rem 0.6rem; - background: var(--row-alt); - } - - #ledger tbody tr:nth-child(even) { - background: rgba(56, 189, 248, 0.08); - } - - #ledger tbody td { - display: flex; - justify-content: space-between; - align-items: baseline; - gap: 1rem; - padding: 0.4rem 0.25rem; - border-bottom: 1px solid rgba(56, 189, 248, 0.1); - text-align: right; - word-break: break-word; - } - - #ledger tbody tr td:last-child { - border-bottom: none; - } - - #ledger tbody td::before { - content: attr(data-label); - font-family: "Orbitron", sans-serif; - font-size: 0.62rem; - text-transform: uppercase; - letter-spacing: 0.06em; - color: var(--accent); - text-align: left; - flex-shrink: 0; - } - - #ledger td.uec { - text-align: right; - } -} diff --git a/174bg/manager/src/App.jsx b/174bg/manager/src/App.jsx new file mode 100644 index 0000000..5f455bb --- /dev/null +++ b/174bg/manager/src/App.jsx @@ -0,0 +1,182 @@ +import { useCallback, useEffect, useState } from "react"; +import { pb } from "./lib/pocketbase"; +import Welcome from "./components/Welcome.jsx"; +import RequiredInfo from "./components/RequiredInfo.jsx"; +import RolePreferences from "./components/RolePreferences.jsx"; +import OnCallSchedule from "./components/OnCallSchedule.jsx"; +import Ledger from "./components/Ledger.jsx"; + +export default function App() { + const [record, setRecord] = useState(pb.authStore.record); + const [loggedIn, setLoggedIn] = useState(pb.authStore.isValid); + const [loginDisabled, setLoginDisabled] = useState(false); + const [oauthStatus, setOauthStatus] = useState({ text: "" }); + + const refreshFromStore = useCallback(() => { + setRecord(pb.authStore.record); + setLoggedIn(pb.authStore.isValid); + }, []); + + useEffect(() => pb.authStore.onChange(refreshFromStore), [refreshFromStore]); + + useEffect(() => { + let cancelled = false; + + async function init() { + if (pb.authStore.isValid) { + try { + await pb.collection("members").authRefresh(); + } catch { + pb.authStore.clear(); + } + } + + const oauthParams = new URLSearchParams(window.location.search); + const storedProvider = localStorage.getItem("pb_oauth_provider"); + + if (oauthParams.has("code") && oauthParams.has("state")) { + if (!storedProvider) { + setOauthStatus({ + text: "Login error: OAuth state lost (localStorage empty). Please try again.", + variant: "error-plain", + }); + window.history.replaceState({}, "", window.location.pathname); + } else { + setOauthStatus({ text: "Completing login..." }); + const provider = JSON.parse(storedProvider); + localStorage.removeItem("pb_oauth_provider"); + const redirectUrl = window.location.origin + window.location.pathname; + try { + await pb + .collection("members") + .authWithOAuth2Code( + provider.name, + oauthParams.get("code"), + provider.codeVerifier, + redirectUrl, + ); + setOauthStatus({ text: "✅ Login successful!", variant: "success" }); + window.history.replaceState({}, "", window.location.pathname); + if (!cancelled) refreshFromStore(); + } catch (err) { + console.error("OAuth callback failed:", err); + const detail = [ + err?.message, + err?.response ? JSON.stringify(err.response) : null, + `code=${oauthParams.get("code")?.slice(0, 8)}…`, + `state=${oauthParams.get("state")?.slice(0, 8)}…`, + `redirect=${redirectUrl}`, + `provider=${provider.name}`, + ] + .filter(Boolean) + .join(" | "); + setOauthStatus({ + text: `Login error — send this to your admin:\n${detail}`, + variant: "error", + }); + window.history.replaceState({}, "", window.location.pathname); + } + } + } else if (!cancelled) { + refreshFromStore(); + } + } + + init(); + return () => { + cancelled = true; + }; + }, [refreshFromStore]); + + const handleLogin = useCallback(async () => { + setLoginDisabled(true); + try { + const methods = await pb.collection("members").listAuthMethods(); + const provider = methods.oauth2.providers.find((p) => p.name === "discord"); + if (!provider) throw new Error("Discord provider not found"); + const redirectUrl = window.location.origin + window.location.pathname; + localStorage.setItem("pb_oauth_provider", JSON.stringify(provider)); + window.location.href = provider.authUrl + encodeURIComponent(redirectUrl); + } catch (err) { + console.error("Login failed:", err); + setLoginDisabled(false); + } + }, []); + + const handleLogout = useCallback(() => { + pb.authStore.clear(); + refreshFromStore(); + }, [refreshFromStore]); + + const handleRecordUpdate = useCallback( + (updated) => { + pb.authStore.save(pb.authStore.token, updated); + refreshFromStore(); + }, + [refreshFromStore], + ); + + let oauthStatusStyle = { fontSize: "0.9rem" }; + if (oauthStatus.variant === "success") { + oauthStatusStyle = { + color: "green", + background: "#dfd", + border: "1px solid #080", + borderRadius: "4px", + padding: "0.5rem", + }; + } else if (oauthStatus.variant === "error") { + oauthStatusStyle = { + color: "red", + background: "#fdd", + border: "1px solid #c00", + borderRadius: "4px", + padding: "0.5rem", + fontFamily: "monospace", + fontSize: "0.8rem", + whiteSpace: "pre-wrap", + wordBreak: "break-all", + }; + } else if (oauthStatus.variant === "error-plain") { + oauthStatusStyle = { fontSize: "0.9rem", color: "red" }; + } + + return ( + <> +

174th Battle Group: Manager

+ + {!loggedIn && ( +
+

You are not logged in. Please log in to access this site:

+ +
+ )} + + {oauthStatus.text && ( +

+ {oauthStatus.text} +

+ )} + + {loggedIn && ( +
+ + + + + +
+ +
+
+ )} + + ); +} diff --git a/174bg/manager/src/components/Ledger.jsx b/174bg/manager/src/components/Ledger.jsx new file mode 100644 index 0000000..247b343 --- /dev/null +++ b/174bg/manager/src/components/Ledger.jsx @@ -0,0 +1,73 @@ +import { useEffect, useState } from "react"; +import { pb } from "../lib/pocketbase"; + +function memberLabel(record, id) { + const m = record?.expand?.[id]; + return m ? m.RSI_Handle || m.name || m.id : (record?.[id] ?? "—"); +} + +export default function Ledger() { + const [records, setRecords] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + let cancelled = false; + pb + .collection("ledger") + .getFullList({ expand: "sender,recipient", sort: "-created", requestKey: null }) + .then((recs) => { + if (!cancelled) setRecords(recs); + }) + .catch((err) => { + console.error("Failed to load ledger:", err); + if (!cancelled) setError(err); + }); + return () => { + cancelled = true; + }; + }, []); + + return ( +
+
+ Ledger +
+ {error && ( +

+ Failed to load ledger: {error?.message ?? String(error)} +

+ )} + {!error && records && records.length === 0 && ( +

No ledger entries.

+ )} + {!error && records && records.length > 0 && ( + + + + + + + + + + + + {records.map((rec) => ( + + + + + + + + ))} + +
DateSenderRecipientUECNote
+ {rec.created ? new Date(rec.created).toLocaleString() : "—"} + {memberLabel(rec, "sender")}{memberLabel(rec, "recipient")} + {Number(rec.uec ?? 0).toLocaleString()} + {rec.note ?? ""}
+ )} +
+ ); +} diff --git a/174bg/manager/src/components/OnCallSchedule.jsx b/174bg/manager/src/components/OnCallSchedule.jsx new file mode 100644 index 0000000..725e5c8 --- /dev/null +++ b/174bg/manager/src/components/OnCallSchedule.jsx @@ -0,0 +1,186 @@ +import { useMemo, useState } from "react"; +import { pb } from "../lib/pocketbase"; +import { + DAYS_OF_WEEK, + formatUtcOffset, + getLocalOnCallSchedule, + listTimeZones, + localScheduleToUtc, +} from "../lib/oncallTime"; + +export default function OnCallSchedule({ record, onUpdate }) { + const [editing, setEditing] = useState(false); + const [timeZone, setTimeZone] = useState(null); + const [schedule, setSchedule] = useState({}); + const [saving, setSaving] = useState(false); + const [status, setStatus] = useState({ text: "", error: false }); + + const display = useMemo(() => getLocalOnCallSchedule(record), [record]); + const zones = useMemo(() => listTimeZones(), []); + + function startEdit() { + const { timeZone: tz, schedule: sched } = getLocalOnCallSchedule(record); + setTimeZone(tz); + setSchedule(sched); + setEditing(true); + setStatus({ text: "", error: false }); + } + + function cancelEdit() { + setEditing(false); + } + + function toggleDay(day, available) { + setSchedule((prev) => { + const next = { ...prev }; + if (available) { + next[day] = { + available: true, + start: prev[day]?.start ?? "", + end: prev[day]?.end ?? "", + }; + } else { + delete next[day]; + } + return next; + }); + } + + function setDayTime(day, key, value) { + setSchedule((prev) => ({ + ...prev, + [day]: { ...prev[day], [key]: value }, + })); + } + + async function save() { + setSaving(true); + try { + const utcSchedule = localScheduleToUtc(schedule, timeZone); + const payload = { timezone: timeZone, ...utcSchedule }; + const updated = await pb.collection("members").update(record.id, { + onCallSchedule: payload, + }); + onUpdate(updated); + setEditing(false); + setStatus({ text: "", error: false }); + } catch (err) { + const msg = err?.response + ? JSON.stringify(err.response) + : (err?.message ?? String(err)); + setStatus({ text: `Save failed: ${msg}`, error: true }); + } finally { + setSaving(false); + } + } + + const shownTz = editing ? timeZone : display.timeZone; + const shownSchedule = editing ? schedule : display.schedule; + const tzOptions = zones.includes(shownTz) ? zones : [shownTz, ...zones]; + + return ( +
+
+ On-Call Schedule{" "} + {!editing && ( + + )} + {editing && ( + <> + {" "} + + + )} +
+

+ Let the group know which days and hours you're usually free to join operations. +

+
+ Timezone: + {editing ? ( + + ) : ( + + {shownTz} ({formatUtcOffset(shownTz)}) + + )} +
+ + + + + + + + + + + {DAYS_OF_WEEK.map((day) => { + const entry = shownSchedule[day] ?? {}; + return ( + + + + + + + ); + })} + +
DayFreeFromTo
{day} + {editing ? ( + toggleDay(day, e.target.checked)} + /> + ) : entry.available ? ( + "✅" + ) : ( + "❌" + )} + + {editing ? ( + setDayTime(day, "start", e.target.value)} + /> + ) : entry.available && entry.start ? ( + entry.start + ) : ( + "—" + )} + + {editing ? ( + setDayTime(day, "end", e.target.value)} + /> + ) : entry.available && entry.end ? ( + entry.end + ) : ( + "—" + )} +
+

+ {status.text} +

+
+ ); +} diff --git a/174bg/manager/src/components/RequiredInfo.jsx b/174bg/manager/src/components/RequiredInfo.jsx new file mode 100644 index 0000000..67c6799 --- /dev/null +++ b/174bg/manager/src/components/RequiredInfo.jsx @@ -0,0 +1,66 @@ +import { RANK_NAMES } from "../lib/roles"; + +const REQUIRED_INFO_FIELDS = [ + { field: "id", label: "174BG ID" }, + { field: "UEE_Citizen_Record_ID", label: "UEE Citizen Record ID" }, + { field: "RSI_Display_Name", label: "RSI Display Name" }, + { field: "RSI_Handle", label: "RSI Handle" }, + { field: "joined_rsi_org", label: "Joined RSI Organisation" }, + { field: "email", label: "Email" }, + { field: "Branch", label: "Branch" }, + { field: "Rank_Number", label: "Rank Number" }, +]; + +export default function RequiredInfo({ record }) { + let anyMissing = false; + + const rows = REQUIRED_INFO_FIELDS.map(({ field, label }) => { + const value = record?.[field]; + // Treat only null/undefined/empty-string as missing so legitimately + // falsy values (e.g. Rank_Number 0, joined_rsi_org false) still show. + const missing = value == null || value === ""; + if (missing) anyMissing = true; + return { field, label, value, missing }; + }); + + const branch = record?.Branch; + const rankNumber = record?.Rank_Number; + const rankName = RANK_NAMES[branch]?.[rankNumber]; + if (!rankName) anyMissing = true; + + const staffRolesRaw = record?.StaffRoles; + const staffList = Array.isArray(staffRolesRaw) + ? staffRolesRaw + : staffRolesRaw + ? [staffRolesRaw] + : []; + + return ( +
+

Required Information

+ {rows.map(({ field, label, value, missing }) => ( +
+ {label}:{" "} + + {missing ? "MISSING" : value} + +
+ ))} +
+ Rank Name:{" "} + + {rankName ?? "MISSING"} + +
+
+ Staff Roles:{" "} + {staffList.length > 0 ? staffList.join(", ") : "none"} +
+ {anyMissing && ( +
+ ⚠️ Your profile is incomplete. Message an officer ASAP! +
+ )} +
+ ); +} diff --git a/174bg/manager/src/components/RolePreferences.jsx b/174bg/manager/src/components/RolePreferences.jsx new file mode 100644 index 0000000..ab3f282 --- /dev/null +++ b/174bg/manager/src/components/RolePreferences.jsx @@ -0,0 +1,171 @@ +import { Fragment, useState } from "react"; +import { pb } from "../lib/pocketbase"; +import { ROLES } from "../lib/roles"; +import { getOtherJsonData } from "../lib/otherJsonData"; + +export default function RolePreferences({ record, onUpdate }) { + const [editing, setEditing] = useState(false); + const [selected, setSelected] = useState([]); + const [favourite, setFavourite] = useState(null); + const [saving, setSaving] = useState(false); + const [status, setStatus] = useState({ text: "", error: false }); + + const savedPrefs = record?.RolePreferencesSelect ?? []; + const savedFavourite = getOtherJsonData(record).FavouriteRole ?? null; + + function startEdit() { + setSelected(savedPrefs); + setFavourite(savedFavourite); + setEditing(true); + setStatus({ text: "", error: false }); + } + + function cancelEdit() { + setEditing(false); + } + + function toggleRole(value) { + setSelected((prev) => + prev.includes(value) + ? prev.filter((v) => v !== value) + : [...prev, value], + ); + } + + function toggleFavourite(value) { + setFavourite((prev) => (prev === value ? null : value)); + } + + async function save() { + setSaving(true); + try { + const fav = favourite && selected.includes(favourite) ? favourite : null; + const other = getOtherJsonData(record); + if (fav) other.FavouriteRole = fav; + else delete other.FavouriteRole; + + const updated = await pb.collection("members").update(record.id, { + RolePreferencesSelect: selected, + OtherJsonData: other, + }); + onUpdate(updated); + setEditing(false); + setStatus({ text: "", error: false }); + } catch (err) { + const msg = err?.response + ? JSON.stringify(err.response) + : (err?.message ?? String(err)); + setStatus({ text: `Save failed: ${msg}`, error: true }); + } finally { + setSaving(false); + } + } + + const displayPrefs = editing ? selected : savedPrefs; + const displayFavourite = editing ? favourite : savedFavourite; + + let lastBranch = null; + + return ( +
+
+ Role Preferences{" "} + {!editing && ( + + )} + {editing && ( + <> + {" "} + + + )} +
+ + + + + + + + + + {ROLES.map((role) => { + const branchHeader = role.branch !== lastBranch; + lastBranch = role.branch; + return ( + + {branchHeader && ( + + + + )} + + + + + + + ); + })} + +
Role
+ {role.branch ?? ""} +
+ {role.link ? ( + + {role.text} + + ) : ( + role.text + )} + + {editing ? ( + toggleRole(role.value)} + /> + ) : displayPrefs.includes(role.value) ? ( + "✅" + ) : ( + "❌" + )} + + {editing ? ( + {}} + onClick={() => toggleFavourite(role.value)} + /> + ) : displayFavourite === role.value ? ( + "⭐" + ) : ( + "" + )} +
+

+ {status.text} +

+
+ ); +} diff --git a/174bg/manager/src/components/Welcome.jsx b/174bg/manager/src/components/Welcome.jsx new file mode 100644 index 0000000..da771cf --- /dev/null +++ b/174bg/manager/src/components/Welcome.jsx @@ -0,0 +1,14 @@ +export default function Welcome({ record }) { + const name = record?.RSI_Handle || record?.name || "Pilot"; + const avatarFile = record?.avatar; + const avatarUrl = avatarFile + ? `https://db.174bg.net/api/files/${record.collectionId}/${record.id}/${avatarFile}` + : null; + + return ( +
+ {avatarUrl && {name}} + Welcome back, {name}! +
+ ); +} diff --git a/174bg/manager/src/lib/oncallTime.js b/174bg/manager/src/lib/oncallTime.js new file mode 100644 index 0000000..e8afaf3 --- /dev/null +++ b/174bg/manager/src/lib/oncallTime.js @@ -0,0 +1,242 @@ +export const DAYS_OF_WEEK = [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday", +]; + +// Sunday-first, matching Date#getDay()/getUTCDay() and Intl's "weekday" +export const WEEKDAY_NAMES = [ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", +]; +export const WEEKDAY_INDEX = Object.fromEntries( + WEEKDAY_NAMES.map((d, i) => [d, i]), +); + +export function pad2(n) { + return String(n).padStart(2, "0"); +} + +export function getBrowserTimeZone() { + try { + return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC"; + } catch { + return "UTC"; + } +} + +export function listTimeZones() { + if (typeof Intl.supportedValuesOf === "function") { + try { + return Intl.supportedValuesOf("timeZone"); + } catch { + // fall through to the fallback list below + } + } + return [ + "UTC", + "America/Los_Angeles", + "America/Denver", + "America/Chicago", + "America/New_York", + "America/Sao_Paulo", + "Europe/London", + "Europe/Paris", + "Europe/Berlin", + "Europe/Moscow", + "Africa/Johannesburg", + "Asia/Dubai", + "Asia/Kolkata", + "Asia/Shanghai", + "Asia/Tokyo", + "Australia/Sydney", + "Pacific/Auckland", + ]; +} + +// Offset (ms) of `timeZone` from UTC at the instant `date` represents. +export function tzOffsetMs(date, timeZone) { + const dtf = new Intl.DateTimeFormat("en-US", { + timeZone, + hourCycle: "h23", + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + }); + const parts = {}; + for (const { type, value } of dtf.formatToParts(date)) { + parts[type] = value; + } + const asUTC = Date.UTC( + Number(parts.year), + Number(parts.month) - 1, + Number(parts.day), + parts.hour === "24" ? 0 : Number(parts.hour), + Number(parts.minute), + Number(parts.second), + ); + return asUTC - date.getTime(); +} + +// Formats `timeZone`'s UTC offset at `date` as "UTC+HH:MM"/"UTC-HH:MM". +export function formatUtcOffset(timeZone, date = new Date()) { + const totalMinutes = Math.round(tzOffsetMs(date, timeZone) / 60000); + const sign = totalMinutes < 0 ? "-" : "+"; + const abs = Math.abs(totalMinutes); + return `UTC${sign}${pad2(Math.floor(abs / 60))}:${pad2(abs % 60)}`; +} + +// Nearest same-or-later calendar date whose local weekday in `timeZone` +// is `day` - used as a DST-correct anchor for the conversion below. +function nextLocalDateFor(day, timeZone) { + const dtf = new Intl.DateTimeFormat("en-US", { + timeZone, + year: "numeric", + month: "2-digit", + day: "2-digit", + weekday: "long", + }); + const parts = {}; + for (const { type, value } of dtf.formatToParts(new Date())) { + parts[type] = value; + } + const diff = (WEEKDAY_INDEX[day] - WEEKDAY_INDEX[parts.weekday] + 7) % 7; + const base = new Date( + Date.UTC(Number(parts.year), Number(parts.month) - 1, Number(parts.day)), + ); + base.setUTCDate(base.getUTCDate() + diff); + return base; +} + +// Nearest same-or-later UTC calendar date whose UTC weekday is `day`. +function nextUtcDateFor(day) { + const now = new Date(); + const diff = (WEEKDAY_INDEX[day] - now.getUTCDay() + 7) % 7; + const base = new Date( + Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()), + ); + base.setUTCDate(base.getUTCDate() + diff); + return base; +} + +// Converts a weekday + "HH:MM" wall-clock time in `timeZone` to the +// equivalent UTC weekday + "HH:MM" (the day may shift due to the offset). +export function localDayTimeToUtc(day, time, timeZone) { + const [hour, minute] = time.split(":").map(Number); + const base = nextLocalDateFor(day, timeZone); + const guess = Date.UTC( + base.getUTCFullYear(), + base.getUTCMonth(), + base.getUTCDate(), + hour, + minute, + ); + const offset = tzOffsetMs(new Date(guess), timeZone); + const actual = new Date(guess - offset); + return { + day: WEEKDAY_NAMES[actual.getUTCDay()], + time: `${pad2(actual.getUTCHours())}:${pad2(actual.getUTCMinutes())}`, + }; +} + +// Converts a UTC weekday + "HH:MM" back to weekday + "HH:MM" wall-clock +// time in `timeZone`. +export function utcDayTimeToLocal(day, time, timeZone) { + const [hour, minute] = time.split(":").map(Number); + const base = nextUtcDateFor(day); + const instant = new Date( + Date.UTC( + base.getUTCFullYear(), + base.getUTCMonth(), + base.getUTCDate(), + hour, + minute, + ), + ); + const dtf = new Intl.DateTimeFormat("en-US", { + timeZone, + hourCycle: "h23", + weekday: "long", + hour: "2-digit", + minute: "2-digit", + }); + const parts = {}; + for (const { type, value } of dtf.formatToParts(instant)) { + parts[type] = value; + } + return { + day: parts.weekday, + time: `${parts.hour === "24" ? "00" : parts.hour}:${parts.minute}`, + }; +} + +export function getEffectiveTimezone(raw) { + return raw.timezone || getBrowserTimeZone(); +} + +// Converts the stored UTC schedule to local wall-clock times, keyed by +// local weekday, for display/editing. +export function utcScheduleToLocal(raw, timeZone) { + const local = {}; + for (const day of DAYS_OF_WEEK) { + const entry = raw[day]; + if (!entry?.available) continue; + const start = utcDayTimeToLocal(day, entry.start, timeZone); + const end = utcDayTimeToLocal(day, entry.end, timeZone); + local[start.day] = { + available: true, + start: start.time, + end: end.time, + }; + } + return local; +} + +// Converts a local-keyed schedule (from the edit form) to UTC for storage. +export function localScheduleToUtc(local, timeZone) { + const utc = {}; + for (const day of DAYS_OF_WEEK) { + const entry = local[day]; + if (!entry?.available) continue; + const start = localDayTimeToUtc(day, entry.start || "00:00", timeZone); + const end = localDayTimeToUtc(day, entry.end || "00:00", timeZone); + utc[start.day] = { available: true, start: start.time, end: end.time }; + } + return utc; +} + +// onCallSchedule is stored as JSON, UTC-normalized: +// { timezone: "IANA/Zone", [utcDay]: { available, start, end } } +export function getOnCallRaw(record) { + const raw = record?.onCallSchedule; + if (!raw) return {}; + if (typeof raw === "string") { + try { + return JSON.parse(raw) || {}; + } catch { + return {}; + } + } + return { ...raw }; +} + +// Legacy records saved before timezone support has no `timezone` key - those +// values are already local wall-clock times, so skip conversion. +export function getLocalOnCallSchedule(record) { + const raw = getOnCallRaw(record); + const timeZone = getEffectiveTimezone(raw); + const schedule = raw.timezone ? utcScheduleToLocal(raw, timeZone) : raw; + return { timeZone, schedule }; +} diff --git a/174bg/manager/src/lib/otherJsonData.js b/174bg/manager/src/lib/otherJsonData.js new file mode 100644 index 0000000..866e6fc --- /dev/null +++ b/174bg/manager/src/lib/otherJsonData.js @@ -0,0 +1,13 @@ +// OtherJsonData may be stored as an object or a JSON string +export function getOtherJsonData(record) { + const raw = record?.OtherJsonData; + if (!raw) return {}; + if (typeof raw === "string") { + try { + return JSON.parse(raw) || {}; + } catch { + return {}; + } + } + return { ...raw }; +} diff --git a/174bg/manager/src/lib/pocketbase.js b/174bg/manager/src/lib/pocketbase.js new file mode 100644 index 0000000..ed0b2eb --- /dev/null +++ b/174bg/manager/src/lib/pocketbase.js @@ -0,0 +1,3 @@ +import PocketBase from "pocketbase"; + +export const pb = new PocketBase("https://db.174bg.net"); diff --git a/174bg/manager/src/lib/roles.js b/174bg/manager/src/lib/roles.js new file mode 100644 index 0000000..1d02e37 --- /dev/null +++ b/174bg/manager/src/lib/roles.js @@ -0,0 +1,142 @@ +export const ROLES = [ + { + branch: "Naval", + value: "Ship Captain", + text: "Ship Captain", + link: "https://handbook.174bg.net/#ship-captain", + }, + { + branch: "Naval", + value: "Pilot", + text: "Pilot", + link: "https://handbook.174bg.net/#pilot", + }, + { + branch: "Naval", + value: "Helmsman", + text: "Helmsman", + link: "https://handbook.174bg.net/#helmsman", + }, + { + branch: "Naval", + value: "Gunner", + text: "Gunner", + link: "https://handbook.174bg.net/#gunner", + }, + { + branch: "Marine", + value: "Tactical Marine", + text: "Tactical Marine", + link: "https://handbook.174bg.net/#tactical-marine", + }, + { + branch: "Marine", + value: "Heavy Marine", + text: "Heavy Marine", + link: "https://handbook.174bg.net/#heavy-marine", + }, + { + branch: "Marine", + value: "Scout Marine", + text: "Scout Marine", + link: "https://handbook.174bg.net/#scout-marine", + }, + { + branch: "Marine", + value: "Combat Medic", + text: "Combat Medic", + link: "https://handbook.174bg.net/#combat-medic", + }, + { + branch: "Marine", + value: "Combat Engineer", + text: "Combat Engineer", + link: "https://handbook.174bg.net/#combat-engineer", + }, + { + branch: "Marine", + value: "Warden", + text: "Warden", + link: "https://handbook.174bg.net/#warden", + }, + { + branch: "Auxiliary", + value: "Engineer", + text: "Engineer", + link: "https://handbook.174bg.net/#engineer", + }, + { + branch: "Auxiliary", + value: "Hazardous Materials Specialist", + text: "Hazardous Materials Specialist", + link: "https://handbook.174bg.net/#hazardous-materials-specialist", + }, + { + branch: "Auxiliary", + value: "Medical Doctor", + text: "Medical Doctor", + link: "https://handbook.174bg.net/#medical-doctor", + }, + { + branch: "Auxiliary", + value: "Quartermaster", + text: "Quartermaster", + link: "https://handbook.174bg.net/#quartermaster", + }, + { + branch: "Auxiliary", + value: "Cargo Technician", + text: "Cargo Technician", + link: "https://handbook.174bg.net/#cargo-technician", + }, + { + branch: "Auxiliary", + value: "Craftsman", + text: "Craftsman", + link: "https://handbook.174bg.net/#craftsman", + }, + { + branch: "Auxiliary", + value: "Mining Technician", + text: "Mining Technician", + link: "https://handbook.174bg.net/#mining-technician", + }, + { + branch: "Auxiliary", + value: "Salvage Operator", + text: "Salvage Operator", + link: "https://handbook.174bg.net/#salvage-operator", + }, + { + branch: "Auxiliary", + value: "Expeditionary Analyst", + text: "Expeditionary Analyst", + link: "https://handbook.174bg.net/#expeditionary-analyst", + }, + { + branch: "Auxiliary", + value: "Intelligence Agent", + text: "Intelligence Agent", + link: "https://handbook.174bg.net/#intelligence-agent", + }, +]; + +export const RANK_NAMES = { + Naval: ["Cadet", "Ensign", "Lieutenant", "Captain", "Commodore", "Admiral"], + Marine: [ + "Private", + "Corporal", + "Sergeant", + "Major", + "Commander", + "General", + ], + Auxiliary: [ + "Trainee", + "Technician", + "Specialist", + "Supervisor", + "Chief", + "Marshal", + ], +}; diff --git a/174bg/manager/src/main.jsx b/174bg/manager/src/main.jsx new file mode 100644 index 0000000..ed1507f --- /dev/null +++ b/174bg/manager/src/main.jsx @@ -0,0 +1,10 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import App from "./App.jsx"; +import "./theme.css"; + +createRoot(document.getElementById("root")).render( + + + , +); diff --git a/174bg/manager/src/theme.css b/174bg/manager/src/theme.css new file mode 100644 index 0000000..907a77e --- /dev/null +++ b/174bg/manager/src/theme.css @@ -0,0 +1,423 @@ +:root { + --bg: #070b14; + --bg-grid: rgba(56, 189, 248, 0.06); + --panel: rgba(15, 23, 42, 0.72); + --panel-border: rgba(56, 189, 248, 0.22); + --panel-border-strong: rgba(56, 189, 248, 0.5); + --text: #dbe7f3; + --text-dim: #7e93ab; + --accent: #38bdf8; + --accent-2: #22d3ee; + --accent-glow: rgba(56, 189, 248, 0.45); + --danger: #f87171; + --danger-bg: rgba(248, 113, 113, 0.12); + --success: #34d399; + --row-alt: rgba(56, 189, 248, 0.04); +} + +* { + box-sizing: border-box; +} + +html { + font-family: "Rajdhani", system-ui, sans-serif; + font-size: 16px; + color-scheme: dark; +} + +body { + margin: 0; + min-height: 100vh; + padding: 2.5rem 1.25rem 4rem; + color: var(--text); + background-color: var(--bg); + background-image: + radial-gradient( + ellipse 80% 60% at 50% -10%, + rgba(56, 189, 248, 0.18), + transparent 60% + ), + linear-gradient(var(--bg-grid) 1px, transparent 1px), + linear-gradient(90deg, var(--bg-grid) 1px, transparent 1px); + background-size: + 100% 100%, + 44px 44px, + 44px 44px; + background-attachment: fixed; + display: flex; + flex-direction: column; + align-items: center; +} + +h1 { + font-family: "Orbitron", sans-serif; + font-weight: 900; + font-size: clamp(1.5rem, 4vw, 2.4rem); + letter-spacing: 0.04em; + text-align: center; + margin: 0 0 1.75rem; + background: linear-gradient(120deg, var(--accent), var(--accent-2)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; + text-shadow: 0 0 28px var(--accent-glow); +} + +h2 { + font-family: "Orbitron", sans-serif; + font-size: 1.05rem; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--accent); + margin: 0 0 0.75rem; +} + +a { + color: var(--accent-2); + text-decoration: none; + border-bottom: 1px solid transparent; + transition: border-color 0.15s ease; +} + +a:hover { + border-bottom-color: var(--accent-2); +} + +body > h1, +#anonymous, +#oauth-status, +#authed { + width: 100%; + max-width: 760px; +} + +/* Panels ----------------------------------------------------------- */ +#anonymous, +#required-info, +#preferences, +#oncall, +#ledger, +#welcome { + background: var(--panel); + border: 1px solid var(--panel-border); + border-radius: 14px; + padding: 1.25rem 1.4rem; + backdrop-filter: blur(10px); + box-shadow: + 0 0 0 1px rgba(0, 0, 0, 0.3), + 0 18px 48px rgba(0, 0, 0, 0.45); +} + +#anonymous p { + margin-top: 0; +} + +/* Buttons ---------------------------------------------------------- */ +button { + font-family: "Rajdhani", sans-serif; + font-weight: 600; + font-size: 0.95rem; + letter-spacing: 0.03em; + color: #04121f; + background: linear-gradient(120deg, var(--accent), var(--accent-2)); + border: none; + border-radius: 8px; + padding: 0.55rem 1.1rem; + cursor: pointer; + transition: + transform 0.12s ease, + box-shadow 0.2s ease, + filter 0.2s ease; + box-shadow: 0 6px 18px var(--accent-glow); +} + +button:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 8px 26px var(--accent-glow); + filter: brightness(1.08); +} + +button:active:not(:disabled) { + transform: translateY(0); +} + +button:disabled { + opacity: 0.5; + cursor: not-allowed; + box-shadow: none; +} + +/* Required info ---------------------------------------------------- */ +#required-info > div:not(:first-child):not(#profile-warning) { + display: flex; + justify-content: space-between; + gap: 1rem; + padding: 0.4rem 0; + border-bottom: 1px solid rgba(56, 189, 248, 0.08); +} + +#required-info > div b { + color: var(--text-dim); + font-weight: 600; +} + +/* Tables ----------------------------------------------------------- */ +#preferences table, +#oncall table, +#ledger table { + border-collapse: collapse; + width: 100%; + min-width: 16rem; +} + +#preferences thead th, +#oncall thead th, +#ledger thead th { + text-align: left; + padding: 0.5rem 0.75rem; + border-bottom: 2px solid var(--panel-border-strong); + font-family: "Orbitron", sans-serif; + font-size: 0.68rem; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--accent); +} + +#preferences tbody tr:nth-child(even), +#oncall tbody tr:nth-child(even), +#ledger tbody tr:nth-child(even) { + background: var(--row-alt); +} + +#preferences tbody td, +#oncall tbody td, +#ledger tbody td { + padding: 0.45rem 0.75rem; + border-bottom: 1px solid rgba(56, 189, 248, 0.1); +} + +#preferences tbody tr:hover:not([data-separator]), +#oncall tbody tr:hover, +#ledger tbody tr:hover { + background: rgba(56, 189, 248, 0.1); +} + +#preferences thead th:not(:first-child) { + text-align: center; + width: 2.5rem; +} + +#preferences tbody td:not(:first-child) { + text-align: center; + width: 2.5rem; +} + +#ledger td.uec { + text-align: right; + font-variant-numeric: tabular-nums; + color: var(--accent-2); + font-weight: 600; +} + +#ledger .empty { + margin: 0.25rem 0 0; + font-size: 0.9rem; + color: var(--text-dim); +} + +input[type="checkbox"] { + width: 1.05rem; + height: 1.05rem; + accent-color: var(--accent); + cursor: pointer; +} + +#oncall input[type="time"] { + font-family: "Rajdhani", sans-serif; + font-size: 0.9rem; + color: var(--text); + background: rgba(15, 23, 42, 0.6); + border: 1px solid var(--panel-border); + border-radius: 6px; + padding: 0.3rem 0.5rem; + color-scheme: dark; +} + +#oncall input[type="time"]:disabled { + opacity: 0.35; +} + +#oncall select { + font-family: "Rajdhani", sans-serif; + font-size: 0.9rem; + color: var(--text); + background: rgba(15, 23, 42, 0.6); + border: 1px solid var(--panel-border); + border-radius: 6px; + padding: 0.3rem 0.5rem; + color-scheme: dark; + max-width: 16rem; +} + +/* Status & warnings ------------------------------------------------ */ +#oauth-status { + font-size: 0.9rem; +} + +#profile-warning { + margin-top: 0.75rem; + padding: 0.7rem 1rem; + background: var(--danger-bg); + border: 1px solid var(--danger); + border-radius: 8px; + color: var(--danger); + font-weight: 700; +} + +/* Welcome ---------------------------------------------------------- */ +#welcome { + display: flex; + align-items: center; + gap: 1rem; +} + +#welcome-avatar { + width: 3.25rem; + height: 3.25rem; + border-radius: 50%; + object-fit: cover; + border: 2px solid var(--accent); + box-shadow: 0 0 18px var(--accent-glow); +} + +#welcome-text { + font-family: "Orbitron", sans-serif; + font-size: 1.2rem; + font-weight: 700; + letter-spacing: 0.02em; +} + +/* Tables can scroll horizontally if they ever overflow ------------- */ +#preferences, +#oncall, +#ledger { + overflow-x: auto; +} + +/* ================================================================= */ +/* Responsive — tablet */ +/* ================================================================= */ +@media (max-width: 640px) { + body { + padding: 1.5rem 0.85rem 3rem; + } + + #anonymous, + #required-info, + #preferences, + #oncall, + #ledger, + #welcome { + padding: 1rem 1.1rem; + border-radius: 12px; + } + + #welcome { + gap: 0.75rem; + } + + #welcome-avatar { + width: 2.75rem; + height: 2.75rem; + } + + #welcome-text { + font-size: 1.05rem; + } + + /* Stack required-info rows so long values don't get squeezed */ + #required-info > div:not(:first-child):not(#profile-warning) { + flex-direction: column; + gap: 0.1rem; + word-break: break-word; + } + + button { + width: 100%; + } + + #preferences thead th:first-child, + #preferences tbody td:first-child { + white-space: normal; + } +} + +/* ================================================================= */ +/* Responsive — phone: turn the ledger into stacked cards */ +/* ================================================================= */ +@media (max-width: 520px) { + #ledger { + overflow-x: visible; + } + + #ledger table, + #ledger thead, + #ledger tbody, + #ledger tr, + #ledger td { + display: block; + width: 100%; + } + + /* Hide the table header row; labels come from data-label instead */ + #ledger thead { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; + } + + #ledger tbody tr { + margin-bottom: 0.85rem; + border: 1px solid var(--panel-border); + border-radius: 10px; + padding: 0.35rem 0.6rem; + background: var(--row-alt); + } + + #ledger tbody tr:nth-child(even) { + background: rgba(56, 189, 248, 0.08); + } + + #ledger tbody td { + display: flex; + justify-content: space-between; + align-items: baseline; + gap: 1rem; + padding: 0.4rem 0.25rem; + border-bottom: 1px solid rgba(56, 189, 248, 0.1); + text-align: right; + word-break: break-word; + } + + #ledger tbody tr td:last-child { + border-bottom: none; + } + + #ledger tbody td::before { + content: attr(data-label); + font-family: "Orbitron", sans-serif; + font-size: 0.62rem; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--accent); + text-align: left; + flex-shrink: 0; + } + + #ledger td.uec { + text-align: right; + } +} diff --git a/174bg/manager/vite.config.js b/174bg/manager/vite.config.js new file mode 100644 index 0000000..ccadc66 --- /dev/null +++ b/174bg/manager/vite.config.js @@ -0,0 +1,9 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + build: { + outDir: "dist", + }, +}); diff --git a/174bg/manager/wrangler.jsonc b/174bg/manager/wrangler.jsonc index 3285789..a6e5afe 100644 --- a/174bg/manager/wrangler.jsonc +++ b/174bg/manager/wrangler.jsonc @@ -4,7 +4,7 @@ "account_id": "424d9dabd39849818d9e22366a20e4d6", "name": "174bg-manager", "assets": { - "directory": "./public/", + "directory": "./dist/", "not_found_handling": "single-page-application", }, "minify": true, -- cgit v1.2.3