diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..0a0c0bd
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,6 @@
+*.ico filter=lfs diff=lfs merge=lfs -text
+*.png filter=lfs diff=lfs merge=lfs -text
+*.jpg filter=lfs diff=lfs merge=lfs -text
+*.gif filter=lfs diff=lfs merge=lfs -text
+*.webp filter=lfs diff=lfs merge=lfs -text
+*.svg filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/screenshots/7s0842oAC9.png b/.github/screenshots/7s0842oAC9.png
new file mode 100644
index 0000000..4c55f38
--- /dev/null
+++ b/.github/screenshots/7s0842oAC9.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:df932e6c24b3d70cb7ad7d7ec3ea240341e4be80cee328eee41d35c36e1937c6
+size 1556410
diff --git a/.github/screenshots/8jipsHiLST.png b/.github/screenshots/8jipsHiLST.png
new file mode 100644
index 0000000..7abc387
--- /dev/null
+++ b/.github/screenshots/8jipsHiLST.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1e2db97ea3b385ac01fb6ec4ac89197dfd4fc6c727639c9493336ddd23be60c7
+size 1003321
diff --git a/.github/screenshots/EWPHmIBEE5.png b/.github/screenshots/EWPHmIBEE5.png
new file mode 100644
index 0000000..6fd9f40
--- /dev/null
+++ b/.github/screenshots/EWPHmIBEE5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a03b0cd56b78f51f8bc4c304b8b14fa611748b9efa192ef26283e732beff90c1
+size 643600
diff --git a/.github/screenshots/FHMzJjGOs6.png b/.github/screenshots/FHMzJjGOs6.png
new file mode 100644
index 0000000..d9dbbf8
--- /dev/null
+++ b/.github/screenshots/FHMzJjGOs6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:96eef8c330ed6739ed2a595fa2170c8f5b5cb7a9cec9b4ad58af51a63eb22b4f
+size 1325789
diff --git a/.github/screenshots/J5BHVZBh7k.png b/.github/screenshots/J5BHVZBh7k.png
new file mode 100644
index 0000000..dc1bf97
--- /dev/null
+++ b/.github/screenshots/J5BHVZBh7k.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c92749fe4122c719f09a9397345f1a06df4aedee8f50855601be3ec25e85ad3c
+size 50175
diff --git a/.forgejo/workflows/build.yml b/.github/workflows/build.yml
similarity index 86%
rename from .forgejo/workflows/build.yml
rename to .github/workflows/build.yml
index 5e3da10..0a064c8 100644
--- a/.forgejo/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -22,14 +22,14 @@ jobs:
run: |
# Download and install via official script
curl -fsSL https://bun.sh/install | bash
-
+
# Manually add Bun to the PATH for subsequent steps
echo "BUN_INSTALL=$HOME/.bun" >> $GITHUB_ENV
echo "$HOME/.bun/bin" >> $GITHUB_PATH
-
+
# Force execution permissions just in case
chmod +x $HOME/.bun/bin/bun
-
+
# Verify it works immediately
$HOME/.bun/bin/bun --version
@@ -37,12 +37,11 @@ jobs:
run: bun install --frozen-lockfile
- name: Build Canary
- run: bun run build:canary
+ run: bun run package:auto-prod
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: canary-build
- # Replace 'dist' with your actual output folder (e.g., 'out' or 'build')
- path: artifacts/
- retention-days: 7
\ No newline at end of file
+ path: build/
+ retention-days: 7
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..fea718a
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,38 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+
+ {
+ "type": "bun",
+ "internalConsoleOptions": "neverOpen",
+ "request": "launch",
+ "name": "Debug File",
+ "program": "./src/bun/index.ts",
+ "cwd": "${workspaceFolder}",
+ "stopOnEntry": false,
+ "watchMode": true
+ },
+ {
+ "type": "bun",
+ "internalConsoleOptions": "neverOpen",
+ "request": "launch",
+ "name": "Run File",
+ "program": "./src/bun/index.ts",
+ "cwd": "${workspaceFolder}",
+ "noDebug": true,
+ "watchMode": false
+ },
+ {
+ "type": "bun",
+ "internalConsoleOptions": "neverOpen",
+ "request": "attach",
+ "name": "Attach Bun",
+ "url": "ws://127.0.0.1:9229/nvnfnsqez8s",
+ "localRoot": "${workspaceFolder}",
+ "stopOnEntry": false
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 8e45f31..411cba2 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,9 +1,27 @@
+{
"files.readonlyInclude": {
- "**/routeTree.gen.ts": true
+ "**/*.gen.ts": true,
+ "src/mainview/gen/*": true,
},
"files.watcherExclude": {
- "**/routeTree.gen.ts": true
+ "**/*.gen.ts": true,
+ "src/mainview/gen/*": true,
},
"search.exclude": {
- "**/routeTree.gen.ts": true
- }
\ No newline at end of file
+ "**/*.gen.ts": true,
+ "src/mainview/gen/*": true,
+
+ },
+ "editor.formatOnSave": true,
+ "[typescriptreact]": {
+ "editor.defaultFormatter": "vscode.typescript-language-features",
+ "editor.formatOnSave": true
+ },
+ "[typescript]": {
+ "editor.defaultFormatter": "vscode.typescript-language-features",
+ "editor.formatOnSave": true
+ },
+ "cSpell.words": [
+ "elysia"
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 0000000..c6d29c6
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,18 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Run Act",
+ "type": "shell",
+ "command": "act",
+ "args": ["--artifact-server-path", "artifacts", "-W", ".github/workflows/build.yml"],
+ "options": {
+ "env": {
+ "PATH": "${env:PATH}",
+ "ACTIONS_RUNTIME_TOKEN": "foo"
+ },
+ },
+ "problemMatcher": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 2ddd3b3..101f462 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,58 @@
# Gameflow Deck
-## Getting Started
+A Cross-Platform Retro gaming frontend designed for handheld and controllers.
+Focused on building a simple user experience and intuitive UI.
+
+> [!WARNING]
+> This app is actively in development, it doesn't have most of its critical features implemented yet.
+
+## Features
+
+- **Cross Platform**: Can run on multiple platforms. Built with web technologies and bun backend.
+- **[Romm](https://github.com/rommapp/romm) Support**: Has integration with romm.
+- **Lightweight**: It uses the existing system browser to launch the front end, so no need to include a whole web browser.
+ - On Windows it first uses webview2 then your browser
+ - On linux it uses WebKitGTK or a browser even from flatpak
+ - Not tested on Mac yet
+- **Steam Deck Support**: Extensively tested with the steam deck. It can use flatpak installed browsers.
+- **Great for Controllers**: The UI is inspired by the switch and works great with joysticks and dpads.
+
+## Screenshots
+
+
+
+
+
+
+
+## Development
1. Install dependencies:
+
```bash
bun install
```
2. Run in development mode:
+
```bash
+ # Use 'bun run dev:hmr' for hot reload
bun run dev
```
3. Build for production:
```bash
- bun run build
- ```
\ No newline at end of file
+ bun run package:auto-prod
+ ```
+ Builds will go in `/builds/`.
+
+### Tech Stack
+
+- [Bun](https://bun.com/) for the backend
+- [React](https://react.dev/) for the frontend
+- [tailwindcss](https://tailwindcss.com/) for styling
+- [daisyUI](https://daisyui.com/) for base theme
+- [Vite](https://vite.dev/) for building the frontend
+- [Tanstack](https://tanstack.com/) router and query for navigation and data
+- [elysia](https://elysiajs.com/) for the APIs
+- [webview](https://github.com/webview/webview) for launching existing system webviews instead of full browser if possible.
diff --git a/bun.lock b/bun.lock
index dc9cb5f..1f8eac5 100644
--- a/bun.lock
+++ b/bun.lock
@@ -5,30 +5,56 @@
"": {
"name": "electrobun-hello-world",
"dependencies": {
- "@tanstack/react-router": "^1.154.10",
- "@tanstack/router-plugin": "^1.154.10",
- "classnames": "^2.5.1",
- "electrobun": "latest",
- "gamepad.css": "^0.0.4",
- "lucide-react": "^0.562.0",
- "react": "^19.2.3",
- "react-dom": "^19.2.3",
+ "@auth/core": "^0.34.3",
+ "@elysiajs/cors": "^1.4.1",
+ "@elysiajs/eden": "^1.4.6",
+ "@elysiajs/static": "^1.4.7",
+ "@rcompat/webview": "^0.18.0",
+ "conf": "^15.0.2",
+ "elysia": "^1.4.22",
+ "pathe": "^2.0.3",
+ "zod": "^4.3.6",
},
"devDependencies": {
+ "@hey-api/openapi-ts": "^0.91.0",
+ "@noriginmedia/norigin-spatial-navigation": "^2.3.0",
"@tailwindcss/vite": "^4.1.18",
- "@tanstack/react-router-devtools": "^1.154.10",
+ "@tanstack/react-query": "^5.90.20",
+ "@tanstack/react-query-devtools": "^5.91.3",
+ "@tanstack/react-router": "^1.157.16",
+ "@tanstack/react-router-devtools": "^1.154.12",
+ "@tanstack/react-router-ssr-query": "^1.157.17",
+ "@tanstack/router-plugin": "^1.157.16",
"@types/bun": "latest",
"@types/react": "^19.2.9",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.2",
+ "animate.css": "^4.1.1",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "classnames": "^2.5.1",
"concurrently": "^9.2.1",
+ "cross-env": "^10.1.0",
+ "daisyui": "^5.5.14",
+ "lucide-react": "^0.563.0",
+ "pretty-bytes": "^7.1.0",
+ "react": "^19.2.4",
+ "react-dom": "^19.2.4",
+ "react-error-boundary": "^6.1.0",
+ "react-hot-toast": "^2.6.0",
+ "tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.18",
+ "tailwindcss-animate": "^1.0.7",
"typescript": "^5.9.3",
+ "usehooks-ts": "^3.1.1",
"vite": "^7.3.1",
+ "vite-plugin-svg-icons-ng": "^1.5.2",
+ "vite-static-assets-plugin": "^1.2.2",
},
},
},
"packages": {
+ "@auth/core": ["@auth/core@0.34.3", "", { "dependencies": { "@panva/hkdf": "^1.1.1", "@types/cookie": "0.6.0", "cookie": "0.6.0", "jose": "^5.1.3", "oauth4webapi": "^2.10.4", "preact": "10.11.3", "preact-render-to-string": "5.2.3" }, "peerDependencies": { "@simplewebauthn/browser": "^9.0.1", "@simplewebauthn/server": "^9.0.2", "nodemailer": "^7" }, "optionalPeers": ["@simplewebauthn/browser", "@simplewebauthn/server", "nodemailer"] }, "sha512-jMjY/S0doZnWYNV90x0jmU3B+UcrsfGYnukxYrRbj0CVvGI/MX3JbHsxSrx2d4mbnXaUsqJmAcDfoQWA6r0lOw=="],
+
"@babel/code-frame": ["@babel/code-frame@7.28.6", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q=="],
"@babel/compat-data": ["@babel/compat-data@7.28.6", "", {}, "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg=="],
@@ -71,6 +97,16 @@
"@babel/types": ["@babel/types@7.28.6", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg=="],
+ "@borewit/text-codec": ["@borewit/text-codec@0.2.1", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="],
+
+ "@elysiajs/cors": ["@elysiajs/cors@1.4.1", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-lQfad+F3r4mNwsxRKbXyJB8Jg43oAOXjRwn7sKUL6bcOW3KjUqUimTS+woNpO97efpzjtDE0tEjGk9DTw8lqTQ=="],
+
+ "@elysiajs/eden": ["@elysiajs/eden@1.4.6", "", { "peerDependencies": { "elysia": ">=1.4.19" } }, "sha512-Tsa4NwXEWg/u73vWiYZQ3L5/ecgZSxqiEjYwpS+4qBKXeTZqZKl2hcgHJSVBL+InEDMi35Xugct7qyAXE5oM4Q=="],
+
+ "@elysiajs/static": ["@elysiajs/static@1.4.7", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-Go4kIXZ0G3iWfkAld07HmLglqIDMVXdyRKBQK/sVEjtpDdjHNb+rUIje73aDTWpZYg4PEVHUpi9v4AlNEwrQug=="],
+
+ "@epic-web/invariant": ["@epic-web/invariant@1.0.0", "", {}, "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA=="],
+
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="],
@@ -123,7 +159,19 @@
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="],
- "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
+ "@hey-api/codegen-core": ["@hey-api/codegen-core@0.6.0", "", { "dependencies": { "@hey-api/types": "0.1.3", "ansi-colors": "4.1.3", "c12": "3.3.3", "color-support": "1.1.3" }, "peerDependencies": { "typescript": ">=5.5.3" } }, "sha512-O6TRP3g1188gdpZC9yio64KkvWD97QpLjaCFnwTgykTZtzQXZbkyw+lYPVfZ7Ee+m7eLau1/jEJmQcUY9G0sLw=="],
+
+ "@hey-api/json-schema-ref-parser": ["@hey-api/json-schema-ref-parser@1.2.3", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.1", "lodash": "^4.17.21" } }, "sha512-gRbyyTjzpFVNmbD+Upn3w4dWV+bCXGJbff3A7leDO/tfNxSz1xIb6Ad/5UKtvEW9kDt/2Uyc3XkFZ6rpafvbfQ=="],
+
+ "@hey-api/openapi-ts": ["@hey-api/openapi-ts@0.91.0", "", { "dependencies": { "@hey-api/codegen-core": "0.6.0", "@hey-api/json-schema-ref-parser": "1.2.3", "@hey-api/shared": "0.1.0", "@hey-api/types": "0.1.3", "ansi-colors": "4.1.3", "color-support": "1.1.3", "commander": "14.0.2" }, "peerDependencies": { "typescript": ">=5.5.3" }, "bin": { "openapi-ts": "bin/run.js" } }, "sha512-AHkd982HsPz1XpqRm59URwJyJqTzyzzC30EAp07b/0M9KojjneCPxm8FnvFnXLRTMyKgcOymMsYXuLzJ9mpMHA=="],
+
+ "@hey-api/shared": ["@hey-api/shared@0.1.0", "", { "dependencies": { "@hey-api/codegen-core": "0.6.0", "@hey-api/json-schema-ref-parser": "1.2.3", "@hey-api/types": "0.1.3", "ansi-colors": "4.1.3", "cross-spawn": "7.0.6", "open": "11.0.0", "semver": "7.7.3" }, "peerDependencies": { "typescript": ">=5.5.3" } }, "sha512-qEDMSBWEEWxcBU5XHacjCCnFOVq1YWPPR3owURVep60I7ejfSG5OINxM4eF+p3KJGMcZduzzfq9pd1grStHZBg=="],
+
+ "@hey-api/types": ["@hey-api/types@0.1.3", "", { "peerDependencies": { "typescript": ">=5.5.3" } }, "sha512-mZaiPOWH761yD4GjDQvtjS2ZYLu5o5pI1TVSvV/u7cmbybv51/FVtinFBeaE1kFQCKZ8OQpn2ezjLBJrKsGATw=="],
+
+ "@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
+
+ "@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
@@ -135,9 +183,27 @@
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
- "@oneidentity/zstd-js": ["@oneidentity/zstd-js@1.0.3", "", { "dependencies": { "@types/emscripten": "^1.39.4" } }, "sha512-Jm6sawqxLzBrjC4sg2BeXToa33yPzUmq20CKsehKY2++D/gHb/oSwVjNgT+RH4vys+r8FynrgcNzGwhZWMLzfQ=="],
+ "@jsdevtools/ono": ["@jsdevtools/ono@7.1.3", "", {}, "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg=="],
- "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
+ "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
+
+ "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
+
+ "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
+
+ "@noriginmedia/norigin-spatial-navigation": ["@noriginmedia/norigin-spatial-navigation@2.3.0", "", { "dependencies": { "lodash": "^4.17.21" }, "peerDependencies": { "react": ">=16.8.0" } }, "sha512-gR//N45NnKz1h0/AVknkfg7QnNATETdgXUUD3EKPxuQPyhk7NhsphODzRamyvjYaxsU6VbY/szcUlzBWWBkNMw=="],
+
+ "@panva/hkdf": ["@panva/hkdf@1.2.1", "", {}, "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw=="],
+
+ "@rcompat/assert": ["@rcompat/assert@0.6.0", "", { "dependencies": { "@rcompat/is": "^0.4.0", "@rcompat/type": "^0.9.0" } }, "sha512-V8YrttJqBNsLo9DQkXGpPt09LqfUGvwA30q8Tf+uukEhE6Nraw4jM4Nq0c5yKQF0IWv1eSoPUJyCO4W4neS5IA=="],
+
+ "@rcompat/dict": ["@rcompat/dict@0.3.1", "", { "dependencies": { "@rcompat/assert": "^0.6.0", "@rcompat/is": "^0.4.2" } }, "sha512-eWZ4ACk0DpT8PS+umVlp/TmFfWAD0yqkGxfvvtfL/9fqPEh1bcCFtGMySCwmTGx/FU8sPnxwnSiZGZmN36gTBQ=="],
+
+ "@rcompat/is": ["@rcompat/is@0.4.3", "", {}, "sha512-IRTVOUhgmRjnlEyZ76wmxPNS46TnUTp7m54mbNgMFDdTTNpjnmpuWw0DcBSUuh4p66fqP/7t9M5tmMUiYAFVzQ=="],
+
+ "@rcompat/type": ["@rcompat/type@0.9.0", "", {}, "sha512-oMGchVrm9K98rXigdfHY98P223iHKfmCxH2GfD+vcwHdWqC3YyuJxlfhd6AeLFNkuBz+0G27GD5qm9g03IPIrA=="],
+
+ "@rcompat/webview": ["@rcompat/webview@0.18.0", "", { "dependencies": { "@rcompat/dict": "^0.3.0" } }, "sha512-bJaDPFPSgXg4dhKVbohDgUZZcP+wsO49RRDaWj01L4klxyiMa6EUCv7RIoOgYnwNt+WRDZ0dJbH8AuSmhHdcPA=="],
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0-beta.53", "", {}, "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ=="],
@@ -191,6 +257,8 @@
"@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.56.0", "", { "os": "win32", "cpu": "x64" }, "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g=="],
+ "@sinclair/typebox": ["@sinclair/typebox@0.34.48", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="],
+
"@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.18", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.18", "@tailwindcss/oxide-darwin-arm64": "4.1.18", "@tailwindcss/oxide-darwin-x64": "4.1.18", "@tailwindcss/oxide-freebsd-x64": "4.1.18", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", "@tailwindcss/oxide-linux-x64-musl": "4.1.18", "@tailwindcss/oxide-wasm32-wasi": "4.1.18", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A=="],
@@ -221,21 +289,33 @@
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.18", "", { "dependencies": { "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "tailwindcss": "4.1.18" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA=="],
- "@tanstack/history": ["@tanstack/history@1.154.7", "", {}, "sha512-YBgwS9qG4rs1ZY/ZrhQtjOH8BG9Qa2wf2AsxT/SnZ4HZJ1DcCEqkoiHH0yH6CYvdDit31X5HokOqQrRSsZEwGA=="],
+ "@tanstack/history": ["@tanstack/history@1.154.14", "", {}, "sha512-xyIfof8eHBuub1CkBnbKNKQXeRZC4dClhmzePHVOEel4G7lk/dW+TQ16da7CFdeNLv6u6Owf5VoBQxoo6DFTSA=="],
- "@tanstack/react-router": ["@tanstack/react-router@1.154.12", "", { "dependencies": { "@tanstack/history": "1.154.7", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.154.12", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-WiYfC6IYC2HwjkATouJCQlAM5RJ8MViefslfUcZpsbCb+WGQpdpvUY7GPJLEeessSpqgiC2EabRYC2kYVNyMPg=="],
+ "@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="],
+
+ "@tanstack/query-devtools": ["@tanstack/query-devtools@5.93.0", "", {}, "sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg=="],
+
+ "@tanstack/react-query": ["@tanstack/react-query@5.90.20", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-vXBxa+qeyveVO7OA0jX1z+DeyCA4JKnThKv411jd5SORpBKgkcVnYKCiBgECvADvniBX7tobwBmg01qq9JmMJw=="],
+
+ "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.3", "", { "dependencies": { "@tanstack/query-devtools": "5.93.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.20", "react": "^18 || ^19" } }, "sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA=="],
+
+ "@tanstack/react-router": ["@tanstack/react-router@1.157.16", "", { "dependencies": { "@tanstack/history": "1.154.14", "@tanstack/react-store": "^0.8.0", "@tanstack/router-core": "1.157.16", "isbot": "^5.1.22", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" }, "peerDependencies": { "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-xwFQa7S7dhBhm3aJYwU79cITEYgAKSrcL6wokaROIvl2JyIeazn8jueWqUPJzFjv+QF6Q8euKRlKUEyb5q2ymg=="],
"@tanstack/react-router-devtools": ["@tanstack/react-router-devtools@1.154.12", "", { "dependencies": { "@tanstack/router-devtools-core": "1.154.12" }, "peerDependencies": { "@tanstack/react-router": "^1.154.12", "@tanstack/router-core": "^1.154.12", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" }, "optionalPeers": ["@tanstack/router-core"] }, "sha512-TcGe7pmeVjk1zD58eMR87GG9OXMx6LDGz5QopmJS4LafvK2hvuaht+eKBnZlCvKLPlXu5juwHT4u+2bYdn6sqQ=="],
+ "@tanstack/react-router-ssr-query": ["@tanstack/react-router-ssr-query@1.157.17", "", { "dependencies": { "@tanstack/router-ssr-query-core": "1.157.16" }, "peerDependencies": { "@tanstack/query-core": ">=5.90.0", "@tanstack/react-query": ">=5.90.0", "@tanstack/react-router": ">=1.127.0", "react": ">=18.0.0 || >=19.0.0", "react-dom": ">=18.0.0 || >=19.0.0" } }, "sha512-IrLi+cNLOAiTShuwGUi9WCNWXMG4993fnyXnWMC53M64rhUngPRFCAQiA05BavE/d7bifC6WKDTt1ZhC1Pewaw=="],
+
"@tanstack/react-store": ["@tanstack/react-store@0.8.0", "", { "dependencies": { "@tanstack/store": "0.8.0", "use-sync-external-store": "^1.6.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-1vG9beLIuB7q69skxK9r5xiLN3ztzIPfSQSs0GfeqWGO2tGIyInZx0x1COhpx97RKaONSoAb8C3dxacWksm1ow=="],
- "@tanstack/router-core": ["@tanstack/router-core@1.154.12", "", { "dependencies": { "@tanstack/history": "1.154.7", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.4.2", "seroval-plugins": "^1.4.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-p+TKxkXcLGtCwwW237D8pV4f6ea2K1pzc/e65ljugoTawsA/YR2/gmTSBDTUsSYy6Tmu4mMJmZ0Q4zNkcfCS3g=="],
+ "@tanstack/router-core": ["@tanstack/router-core@1.157.16", "", { "dependencies": { "@tanstack/history": "1.154.14", "@tanstack/store": "^0.8.0", "cookie-es": "^2.0.0", "seroval": "^1.4.2", "seroval-plugins": "^1.4.2", "tiny-invariant": "^1.3.3", "tiny-warning": "^1.0.3" } }, "sha512-eJuVgM7KZYTTr4uPorbUzUflmljMVcaX2g6VvhITLnHmg9SBx9RAgtQ1HmT+72mzyIbRSlQ1q0fY/m+of/fosA=="],
"@tanstack/router-devtools-core": ["@tanstack/router-devtools-core@1.154.12", "", { "dependencies": { "clsx": "^2.1.1", "goober": "^2.1.16", "tiny-invariant": "^1.3.3" }, "peerDependencies": { "@tanstack/router-core": "^1.154.12", "csstype": "^3.0.10" }, "optionalPeers": ["csstype"] }, "sha512-lvnP9cqknvSSkUjqQRVn61TcBhq72hCFFOzMwdFdFPTO8nMEXvYE6ZZJiXtivwcvsKmO6XVFLMXuJr/928gNkw=="],
- "@tanstack/router-generator": ["@tanstack/router-generator@1.154.12", "", { "dependencies": { "@tanstack/router-core": "1.154.12", "@tanstack/router-utils": "1.154.7", "@tanstack/virtual-file-routes": "1.154.7", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-cjr3KS3Esnyh05CWl78KgK2Z9kTjeFasZXcSUrh//TzzU72eXQ+dzKppD3kMsjuyRfUxAfdufsR9GDNMMuLk9w=="],
+ "@tanstack/router-generator": ["@tanstack/router-generator@1.157.16", "", { "dependencies": { "@tanstack/router-core": "1.157.16", "@tanstack/router-utils": "1.154.7", "@tanstack/virtual-file-routes": "1.154.7", "prettier": "^3.5.0", "recast": "^0.23.11", "source-map": "^0.7.4", "tsx": "^4.19.2", "zod": "^3.24.2" } }, "sha512-Ae2M00VTFjjED7glSCi/mMLENRzhEym6NgjoOx7UVNbCC/rLU/5ASDe5VIlDa8QLEqP5Pj088Gi51gjmRuICvQ=="],
- "@tanstack/router-plugin": ["@tanstack/router-plugin@1.154.12", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.154.12", "@tanstack/router-generator": "1.154.12", "@tanstack/router-utils": "1.154.7", "@tanstack/virtual-file-routes": "1.154.7", "babel-dead-code-elimination": "^1.0.11", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.154.12", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-YlFjrL5j7RbYT/B3RZZedbXOHXfqRV7b/qIGyojBaHsrIgKFGo4AHg/FyS50HJaHGQ27vvgWNSy/4Orrozbm0Q=="],
+ "@tanstack/router-plugin": ["@tanstack/router-plugin@1.157.16", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-syntax-jsx": "^7.27.1", "@babel/plugin-syntax-typescript": "^7.27.1", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@tanstack/router-core": "1.157.16", "@tanstack/router-generator": "1.157.16", "@tanstack/router-utils": "1.154.7", "@tanstack/virtual-file-routes": "1.154.7", "babel-dead-code-elimination": "^1.0.11", "chokidar": "^3.6.0", "unplugin": "^2.1.2", "zod": "^3.24.2" }, "peerDependencies": { "@rsbuild/core": ">=1.0.2", "@tanstack/react-router": "^1.157.16", "vite": ">=5.0.0 || >=6.0.0 || >=7.0.0", "vite-plugin-solid": "^2.11.10", "webpack": ">=5.92.0" }, "optionalPeers": ["@rsbuild/core", "@tanstack/react-router", "vite", "vite-plugin-solid", "webpack"] }, "sha512-YQg7L06xyCJAYyrEJNZGAnDL8oChILU+G/eSDIwEfcWn5iLk+47x1Gcdxr82++47PWmOPhzuTo8edDQXWs7kAA=="],
+
+ "@tanstack/router-ssr-query-core": ["@tanstack/router-ssr-query-core@1.157.16", "", { "peerDependencies": { "@tanstack/query-core": ">=5.90.0", "@tanstack/router-core": ">=1.127.0" } }, "sha512-YuwNG4jdtn+r90yyti8yP27IKaVoflWmRezqnj0gyJxpRauBkK7MVLvWSNbJadnk88b9H+rdtNOF2k3owGaong=="],
"@tanstack/router-utils": ["@tanstack/router-utils@1.154.7", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/generator": "^7.28.5", "@babel/parser": "^7.28.5", "ansis": "^4.1.0", "diff": "^8.0.2", "pathe": "^2.0.3", "tinyglobby": "^0.2.15" } }, "sha512-61bGx32tMKuEpVRseu2sh1KQe8CfB7793Mch/kyQt0EP3tD7X0sXmimCl3truRiDGUtI0CaSoQV1NPjAII1RBA=="],
@@ -243,6 +323,12 @@
"@tanstack/virtual-file-routes": ["@tanstack/virtual-file-routes@1.154.7", "", {}, "sha512-cHHDnewHozgjpI+MIVp9tcib6lYEQK5MyUr0ChHpHFGBl8Xei55rohFK0I0ve/GKoHeioaK42Smd8OixPp6CTg=="],
+ "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
+
+ "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
+
+ "@trysound/sax": ["@trysound/sax@0.2.0", "", {}, "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="],
+
"@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="],
"@types/babel__generator": ["@types/babel__generator@7.27.0", "", { "dependencies": { "@babel/types": "^7.0.0" } }, "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg=="],
@@ -253,15 +339,11 @@
"@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
- "@types/emscripten": ["@types/emscripten@1.40.1", "", {}, "sha512-sr53lnYkQNhjHNN0oJDdUm5564biioI5DuOpycufDVK7D3y+GR3oUswe2rlwY1nPNyusHbrJ9WoTyIHl4/Bpwg=="],
+ "@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
- "@types/filesystem": ["@types/filesystem@0.0.36", "", { "dependencies": { "@types/filewriter": "*" } }, "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA=="],
-
- "@types/filewriter": ["@types/filewriter@0.0.33", "", {}, "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g=="],
-
- "@types/har-format": ["@types/har-format@1.2.16", "", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="],
+ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/node": ["@types/node@24.1.0", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
@@ -269,14 +351,18 @@
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
- "@types/webextension-polyfill": ["@types/webextension-polyfill@0.12.3", "", {}, "sha512-F58aDVSeN/MjUGazXo/cPsmR76EvqQhQ1v4x23hFjUX0cfAJYE+JBWwiOGW36/VJGGxoH74sVlRIF3z7SJCKyg=="],
-
"@vitejs/plugin-react": ["@vitejs/plugin-react@5.1.2", "", { "dependencies": { "@babel/core": "^7.28.5", "@babel/plugin-transform-react-jsx-self": "^7.27.1", "@babel/plugin-transform-react-jsx-source": "^7.27.1", "@rolldown/pluginutils": "1.0.0-beta.53", "@types/babel__core": "^7.20.5", "react-refresh": "^0.18.0" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" } }, "sha512-EcA07pHJouywpzsoTUqNh5NwGayl2PPVEJKUSinGGSxFGYn+shYbqMGBg6FXDqgXum9Ou/ecb+411ssw8HImJQ=="],
- "abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
-
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
+ "ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
+
+ "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="],
+
+ "animate.css": ["animate.css@4.1.1", "", {}, "sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ=="],
+
+ "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
+
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
@@ -285,49 +371,39 @@
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
- "archiver": ["archiver@7.0.1", "", { "dependencies": { "archiver-utils": "^5.0.2", "async": "^3.2.4", "buffer-crc32": "^1.0.0", "readable-stream": "^4.0.0", "readdir-glob": "^1.1.2", "tar-stream": "^3.0.0", "zip-stream": "^6.0.1" } }, "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ=="],
-
- "archiver-utils": ["archiver-utils@5.0.2", "", { "dependencies": { "glob": "^10.0.0", "graceful-fs": "^4.2.0", "is-stream": "^2.0.1", "lazystream": "^1.0.0", "lodash": "^4.17.15", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA=="],
+ "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="],
- "async": ["async@3.2.6", "", {}, "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="],
-
- "b4a": ["b4a@1.6.7", "", {}, "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg=="],
+ "atomically": ["atomically@2.1.0", "", { "dependencies": { "stubborn-fs": "^2.0.0", "when-exit": "^2.1.4" } }, "sha512-+gDffFXRW6sl/HCwbta7zK4uNqbPjv4YJEAdz7Vu+FLQHe77eZ4bvbJGi4hE0QPeJlMYMA3piXEr1UL3dAwx7Q=="],
"babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.12", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-GERT7L2TiYcYDtYk1IpD+ASAYXjKbLTDPhBtYj7X1NuRMDTMtAx9kyBenub1Ev41lo91OHCKdmP+egTDmfQ7Ig=="],
- "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
-
- "bare-events": ["bare-events@2.6.1", "", {}, "sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g=="],
-
- "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
+ "babel-plugin-react-compiler": ["babel-plugin-react-compiler@1.0.0", "", { "dependencies": { "@babel/types": "^7.26.0" } }, "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.9.17", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ=="],
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
- "brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
+ "boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
- "browser-namespace": ["browser-namespace@1.4.0", "", { "dependencies": { "@types/filesystem": "*", "@types/har-format": "*", "@types/webextension-polyfill": "*" } }, "sha512-9b4yNTNs+8HVPssSq8RSZMRunf+G4cVQ2PMtOTn+uEVFOW5C0Uo+eGXuJ5LfxS1UDph5oAdWj92thPyxVhpqXg=="],
-
"browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="],
- "buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
-
- "buffer-crc32": ["buffer-crc32@1.0.0", "", {}, "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w=="],
-
"bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
+ "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
+
+ "c12": ["c12@3.3.3", "", { "dependencies": { "chokidar": "^5.0.0", "confbox": "^0.2.2", "defu": "^6.1.4", "dotenv": "^17.2.3", "exsolve": "^1.0.8", "giget": "^2.0.0", "jiti": "^2.6.1", "ohash": "^2.0.11", "pathe": "^2.0.3", "perfect-debounce": "^2.0.0", "pkg-types": "^2.3.0", "rc9": "^2.1.2" }, "peerDependencies": { "magicast": "*" }, "optionalPeers": ["magicast"] }, "sha512-750hTRvgBy5kcMNPdh95Qo+XUBeGo8C7nsKSmedDmaQI+E0r82DwHeM6vBewDe4rGFbnxoa4V9pw+sPh5+Iz8Q=="],
+
"caniuse-lite": ["caniuse-lite@1.0.30001765", "", {}, "sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ=="],
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
- "chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
+ "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="],
"classnames": ["classnames@2.5.1", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="],
@@ -339,71 +415,119 @@
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
- "compress-commons": ["compress-commons@6.0.2", "", { "dependencies": { "crc-32": "^1.2.0", "crc32-stream": "^6.0.0", "is-stream": "^2.0.1", "normalize-path": "^3.0.0", "readable-stream": "^4.0.0" } }, "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg=="],
+ "color-support": ["color-support@1.1.3", "", { "bin": { "color-support": "bin.js" } }, "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="],
+
+ "commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="],
"concurrently": ["concurrently@9.2.1", "", { "dependencies": { "chalk": "4.1.2", "rxjs": "7.8.2", "shell-quote": "1.8.3", "supports-color": "8.1.1", "tree-kill": "1.2.2", "yargs": "17.7.2" }, "bin": { "conc": "dist/bin/concurrently.js", "concurrently": "dist/bin/concurrently.js" } }, "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng=="],
+ "conf": ["conf@15.0.2", "", { "dependencies": { "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "atomically": "^2.0.3", "debounce-fn": "^6.0.0", "dot-prop": "^10.0.0", "env-paths": "^3.0.0", "json-schema-typed": "^8.0.1", "semver": "^7.7.2", "uint8array-extras": "^1.5.0" } }, "sha512-JBSrutapCafTrddF9dH3lc7+T2tBycGF4uPkI4Js+g4vLLEhG6RZcFi3aJd5zntdf5tQxAejJt8dihkoQ/eSJw=="],
+
+ "confbox": ["confbox@0.2.2", "", {}, "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ=="],
+
+ "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
+
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
+ "cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
+
"cookie-es": ["cookie-es@2.0.0", "", {}, "sha512-RAj4E421UYRgqokKUmotqAwuplYw15qtdXfY+hGzgCJ/MBjCVZcSoHK/kH9kocfjRjcDME7IiDWR/1WX1TM2Pg=="],
- "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
-
- "crc-32": ["crc-32@1.2.2", "", { "bin": { "crc32": "bin/crc32.njs" } }, "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ=="],
-
- "crc32-stream": ["crc32-stream@6.0.0", "", { "dependencies": { "crc-32": "^1.2.0", "readable-stream": "^4.0.0" } }, "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g=="],
+ "cross-env": ["cross-env@10.1.0", "", { "dependencies": { "@epic-web/invariant": "^1.0.0", "cross-spawn": "^7.0.6" }, "bin": { "cross-env": "dist/bin/cross-env.js", "cross-env-shell": "dist/bin/cross-env-shell.js" } }, "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
+ "css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
+
+ "css-tree": ["css-tree@2.3.1", "", { "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" } }, "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw=="],
+
+ "css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
+
+ "csso": ["csso@5.0.5", "", { "dependencies": { "css-tree": "~2.2.0" } }, "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ=="],
+
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
+ "daisyui": ["daisyui@5.5.14", "", {}, "sha512-L47rvw7I7hK68TA97VB8Ee0woHew+/ohR6Lx6Ah/krfISOqcG4My7poNpX5Mo5/ytMxiR40fEaz6njzDi7cuSg=="],
+
+ "debounce-fn": ["debounce-fn@6.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ=="],
+
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+ "default-browser": ["default-browser@5.4.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg=="],
+
+ "default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="],
+
+ "define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="],
+
+ "defu": ["defu@6.1.4", "", {}, "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="],
+
+ "destr": ["destr@2.0.5", "", {}, "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA=="],
+
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="],
- "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
+ "dom-serializer": ["dom-serializer@2.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", "entities": "^4.2.0" } }, "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg=="],
- "electrobun": ["electrobun@0.8.0", "", { "dependencies": { "@oneidentity/zstd-js": "^1.0.3", "archiver": "^7.0.1", "rpc-anywhere": "1.5.0", "tar": "^6.2.1" }, "bin": { "electrobun": "bin/electrobun.cjs" } }, "sha512-tjYmWyp9NIR80ejVUrqeMHu/H0QR2nb7zC79MJxSOfQYk6uKE5XCgr9UBURiIdnX71LfTd4Mb+R9A/Oo7vxxUg=="],
+ "domelementtype": ["domelementtype@2.3.0", "", {}, "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="],
+
+ "domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
+
+ "domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
+
+ "dot-prop": ["dot-prop@10.1.0", "", { "dependencies": { "type-fest": "^5.0.0" } }, "sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q=="],
+
+ "dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
"electron-to-chromium": ["electron-to-chromium@1.5.277", "", {}, "sha512-wKXFZw4erWmmOz5N/grBoJ2XrNJGDFMu2+W5ACHza5rHtvsqrK4gb6rnLC7XxKB9WlJ+RmyQatuEXmtm86xbnw=="],
+ "elysia": ["elysia@1.4.22", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.6", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-Q90VCb1RVFxnFaRV0FDoSylESQQLWgLHFmWciQJdX9h3b2cSasji9KWEUvaJuy/L9ciAGg4RAhUVfsXHg5K2RQ=="],
+
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"enhanced-resolve": ["enhanced-resolve@5.18.4", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q=="],
+ "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
+
+ "env-paths": ["env-paths@3.0.0", "", {}, "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A=="],
+
"esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
- "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
+ "exact-mirror": ["exact-mirror@0.2.6", "", { "peerDependencies": { "@sinclair/typebox": "^0.34.15" }, "optionalPeers": ["@sinclair/typebox"] }, "sha512-7s059UIx9/tnOKSySzUk5cPGkoILhTE4p6ncf6uIPaQ+9aRBQzQjc9+q85l51+oZ+P6aBxh084pD0CzBQPcFUA=="],
- "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
+ "exsolve": ["exsolve@1.0.8", "", {}, "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA=="],
- "fast-fifo": ["fast-fifo@1.3.2", "", {}, "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="],
+ "fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
+
+ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
+
+ "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
+
+ "fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
+
+ "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
+ "file-type": ["file-type@21.3.0", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA=="],
+
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
- "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
-
- "fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
+ "fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
- "gamepad.css": ["gamepad.css@0.0.4", "", {}, "sha512-cgE1dbJT+HXbivqSIuendOrO920BlSBVzSWI695tturtPqd41bBmhljIuRu/wOSkq40n/yA2oTs45pj6vR06Jw=="],
-
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
"get-tsconfig": ["get-tsconfig@4.13.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ=="],
- "glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
+ "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="],
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
@@ -413,39 +537,49 @@
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
+ "he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
+
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
- "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
-
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
+ "is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
+
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
+ "is-in-ssh": ["is-in-ssh@1.0.0", "", {}, "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw=="],
+
+ "is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="],
+
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
- "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
-
- "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
+ "is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="],
"isbot": ["isbot@5.1.33", "", {}, "sha512-P4Hgb5NqswjkI0J1CM6XKXon/sxKY1SuowE7Qx2hrBhIwICFyXy54mfgB5eMHXsbe/eStzzpbIGNOvGmz+dlKg=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
- "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
-
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
+ "jose": ["jose@5.10.0", "", {}, "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg=="],
+
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
+ "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
+
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
+ "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
+
+ "json-schema-typed": ["json-schema-typed@8.0.2", "", {}, "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA=="],
+
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
- "lazystream": ["lazystream@1.0.1", "", { "dependencies": { "readable-stream": "^2.0.5" } }, "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw=="],
+ "jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
@@ -471,79 +605,115 @@
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
- "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
+ "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="],
+
+ "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
- "lucide-react": ["lucide-react@0.562.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw=="],
+ "lucide-react": ["lucide-react@0.563.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-8dXPB2GI4dI8jV4MgUDGBeLdGk8ekfqVZ0BdLcrRzocGgG75ltNEmWS+gE7uokKF/0oSUuczNDT+g9hFJ23FkA=="],
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
- "minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
+ "mdn-data": ["mdn-data@2.0.30", "", {}, "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA=="],
- "minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
+ "memoirist": ["memoirist@0.4.0", "", {}, "sha512-zxTgA0mSYELa66DimuNQDvyLq36AwDlTuVRbnQtB+VuTcKWm5Qc4z3WkSpgsFWHNhexqkIooqpv4hdcqrX5Nmg=="],
- "minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
+ "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
- "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
+ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
+
+ "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
+
+ "minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
+ "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="],
+
+ "node-html-parser": ["node-html-parser@7.0.2", "", { "dependencies": { "css-select": "^5.1.0", "he": "1.2.0" } }, "sha512-DxodLVh7a6JMkYzWyc8nBX9MaF4M0lLFYkJHlWOiu7+9/I6mwNK9u5TbAMC7qfqDJEPX9OIoWA2A9t4C2l1mUQ=="],
+
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
- "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
+ "nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
+
+ "nypm": ["nypm@0.6.4", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-1TvCKjZyyklN+JJj2TS3P4uSQEInrM/HkkuSXsEzm1ApPgBffOn8gFguNnZf07r/1X6vlryfIqMUkJKQMzlZiw=="],
+
+ "oauth4webapi": ["oauth4webapi@2.17.0", "", {}, "sha512-lbC0Z7uzAFNFyzEYRIC+pkSVvDHJTbEW+dYlSBAlCYDe6RxUkJ26bClhk8ocBZip1wfI9uKTe0fm4Ib4RHn6uQ=="],
+
+ "ohash": ["ohash@2.0.11", "", {}, "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ=="],
+
+ "open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="],
+
+ "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
- "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
-
"pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="],
+ "perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="],
+
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
+ "pkg-types": ["pkg-types@2.3.0", "", { "dependencies": { "confbox": "^0.2.2", "exsolve": "^1.0.7", "pathe": "^2.0.3" } }, "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig=="],
+
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
+ "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
+
+ "preact": ["preact@10.11.3", "", {}, "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg=="],
+
+ "preact-render-to-string": ["preact-render-to-string@5.2.3", "", { "dependencies": { "pretty-format": "^3.8.0" }, "peerDependencies": { "preact": ">=10" } }, "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA=="],
+
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
- "process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
+ "pretty-bytes": ["pretty-bytes@7.1.0", "", {}, "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw=="],
- "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
+ "pretty-format": ["pretty-format@3.8.0", "", {}, "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="],
- "react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
+ "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
- "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="],
+ "rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
+
+ "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
+
+ "react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
+
+ "react-error-boundary": ["react-error-boundary@6.1.0", "", { "peerDependencies": { "react": "^18.0.0 || ^19.0.0" } }, "sha512-02k9WQ/mUhdbXir0tC1NiMesGzRPaCsJEWU/4bcFrbY1YMZOtHShtZP6zw0SJrBWA/31H0KT9/FgdL8+sPKgHA=="],
+
+ "react-hot-toast": ["react-hot-toast@2.6.0", "", { "dependencies": { "csstype": "^3.1.3", "goober": "^2.1.16" }, "peerDependencies": { "react": ">=16", "react-dom": ">=16" } }, "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg=="],
"react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
- "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="],
-
- "readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="],
-
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"recast": ["recast@0.23.11", "", { "dependencies": { "ast-types": "^0.16.1", "esprima": "~4.0.0", "source-map": "~0.6.1", "tiny-invariant": "^1.3.3", "tslib": "^2.0.1" } }, "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA=="],
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
+ "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
+
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
+ "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
+
"rollup": ["rollup@4.56.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.56.0", "@rollup/rollup-android-arm64": "4.56.0", "@rollup/rollup-darwin-arm64": "4.56.0", "@rollup/rollup-darwin-x64": "4.56.0", "@rollup/rollup-freebsd-arm64": "4.56.0", "@rollup/rollup-freebsd-x64": "4.56.0", "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", "@rollup/rollup-linux-arm-musleabihf": "4.56.0", "@rollup/rollup-linux-arm64-gnu": "4.56.0", "@rollup/rollup-linux-arm64-musl": "4.56.0", "@rollup/rollup-linux-loong64-gnu": "4.56.0", "@rollup/rollup-linux-loong64-musl": "4.56.0", "@rollup/rollup-linux-ppc64-gnu": "4.56.0", "@rollup/rollup-linux-ppc64-musl": "4.56.0", "@rollup/rollup-linux-riscv64-gnu": "4.56.0", "@rollup/rollup-linux-riscv64-musl": "4.56.0", "@rollup/rollup-linux-s390x-gnu": "4.56.0", "@rollup/rollup-linux-x64-gnu": "4.56.0", "@rollup/rollup-linux-x64-musl": "4.56.0", "@rollup/rollup-openbsd-x64": "4.56.0", "@rollup/rollup-openharmony-arm64": "4.56.0", "@rollup/rollup-win32-arm64-msvc": "4.56.0", "@rollup/rollup-win32-ia32-msvc": "4.56.0", "@rollup/rollup-win32-x64-gnu": "4.56.0", "@rollup/rollup-win32-x64-msvc": "4.56.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg=="],
- "rpc-anywhere": ["rpc-anywhere@1.5.0", "", { "dependencies": { "browser-namespace": "^1.4.0" } }, "sha512-ZYrB0foAM4oE7oBnUH3BL7LwtW9d6+RkzL/rFnjj8GCaFt5c81Rbw6oVl6u9AMsGONsKeJX0mL62TpbPXSO6og=="],
+ "run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="],
+
+ "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
"rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="],
- "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
-
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
- "semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
+ "semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"seroval": ["seroval@1.4.2", "", {}, "sha512-N3HEHRCZYn3cQbsC4B5ldj9j+tHdf4JZoYPlcI4rRYu0Xy4qN8MQf1Z08EibzB0WpgRG5BGK08FTrmM66eSzKQ=="],
@@ -555,89 +725,99 @@
"shell-quote": ["shell-quote@1.8.3", "", {}, "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw=="],
- "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
-
"source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
- "streamx": ["streamx@2.22.1", "", { "dependencies": { "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" }, "optionalDependencies": { "bare-events": "^2.2.0" } }, "sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA=="],
-
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
- "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
-
- "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
-
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
- "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
+ "strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
+
+ "stubborn-fs": ["stubborn-fs@2.0.0", "", { "dependencies": { "stubborn-utils": "^1.0.1" } }, "sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA=="],
+
+ "stubborn-utils": ["stubborn-utils@1.0.2", "", {}, "sha512-zOh9jPYI+xrNOyisSelgym4tolKTJCQd5GBhK0+0xJvcYDcwlOoxF/rnFKQ2KRZknXSG9jWAp66fwP6AxN9STg=="],
"supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
+ "svgo": ["svgo@3.3.2", "", { "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", "css-tree": "^2.3.1", "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, "bin": "./bin/svgo" }, "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw=="],
+
+ "tagged-tag": ["tagged-tag@1.0.0", "", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="],
+
+ "tailwind-merge": ["tailwind-merge@3.4.0", "", {}, "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g=="],
+
"tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="],
+ "tailwindcss-animate": ["tailwindcss-animate@1.0.7", "", { "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } }, "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA=="],
+
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
- "tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
-
- "tar-stream": ["tar-stream@3.1.7", "", { "dependencies": { "b4a": "^1.6.4", "fast-fifo": "^1.2.0", "streamx": "^2.15.0" } }, "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ=="],
-
- "text-decoder": ["text-decoder@1.2.3", "", { "dependencies": { "b4a": "^1.6.4" } }, "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA=="],
-
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
"tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="],
+ "tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
+
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
+ "token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
+
"tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="],
+ "type-fest": ["type-fest@5.4.1", "", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-xygQcmneDyzsEuKZrFbRMne5HDqMs++aFzefrJTgEIKjQ3rekM+RPfFCVq2Gp1VIDqddoYeppCj4Pcb+RZW0GQ=="],
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
+ "uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
+
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
+ "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
+
"unplugin": ["unplugin@2.3.11", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", "picomatch": "^4.0.3", "webpack-virtual-modules": "^0.6.2" } }, "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww=="],
"update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="],
"use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="],
- "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+ "usehooks-ts": ["usehooks-ts@3.1.1", "", { "dependencies": { "lodash.debounce": "^4.0.8" }, "peerDependencies": { "react": "^16.8.0 || ^17 || ^18 || ^19 || ^19.0.0-rc" } }, "sha512-I4diPp9Cq6ieSUH2wu+fDAVQO43xwtulo+fKEidHUwZPnYImbtkTjzIJYcDcJqxgmX31GVqNFURodvcgHcW0pA=="],
"vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
+ "vite-plugin-svg-icons-ng": ["vite-plugin-svg-icons-ng@1.5.2", "", { "dependencies": { "fast-glob": "^3.3.3", "fs-extra": "^11.3.2", "node-html-parser": "^7.0.1", "svgo": "^3.3.2" }, "peerDependencies": { "vite": ">=5.0.0" } }, "sha512-A68obs8XDT+q8q8dKyjrT/v0qw8h5pEBKXJ27aUXjARYeJ6MNvhIhRLLiUwnSrbn/B4TBF4UVaWRXKftAqP7+A=="],
+
+ "vite-static-assets-plugin": ["vite-static-assets-plugin@1.2.2", "", { "dependencies": { "chalk": "^5.4.1", "chokidar": "^3.5.3", "minimatch": "^10.0.1" }, "peerDependencies": { "typescript": "^5.0.0", "vite": "^6.2.0" } }, "sha512-0mzHsxFa46Np5AixQcdWYLVH6eJxeok7qL7tXmxYavg/Uo0e5z+J6gavJ0TJ6dmJSe2Z+gwmDb64bCCZfg+gqA=="],
+
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
+ "when-exit": ["when-exit@2.1.5", "", {}, "sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg=="],
+
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
- "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
+ "wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="],
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
- "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
+ "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
- "zip-stream": ["zip-stream@6.0.1", "", { "dependencies": { "archiver-utils": "^5.0.0", "compress-commons": "^6.0.2", "readable-stream": "^4.0.0" } }, "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA=="],
+ "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
- "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
+ "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
- "@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
-
- "@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
-
- "@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
+ "@babel/helper-compilation-targets/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
@@ -651,38 +831,34 @@
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+ "@tanstack/router-generator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
+
+ "@tanstack/router-plugin/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
+
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+ "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="],
+
"chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
- "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+ "csso/css-tree": ["css-tree@2.2.1", "", { "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" } }, "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA=="],
- "glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
+ "elysia/cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
- "glob/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
- "lazystream/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
-
- "lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
-
- "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
-
- "path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
-
- "path-scurry/minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="],
+ "nypm/citty": ["citty@0.2.0", "", {}, "sha512-8csy5IBFI2ex2hTVpaHN2j+LNE199AgiI7y4dMintrr8i0lQiFn+0AWMZrWdHKIgMOer65f8IThysYhoReqjWA=="],
"readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"recast/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
- "@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
+ "svgo/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="],
- "@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
+ "vite-static-assets-plugin/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
- "@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
+ "c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="],
- "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
-
- "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
+ "csso/css-tree/mdn-data": ["mdn-data@2.0.28", "", {}, "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="],
}
}
diff --git a/package.json b/package.json
index 2e20b23..9d29ca5 100644
--- a/package.json
+++ b/package.json
@@ -1,36 +1,66 @@
{
- "name": "gameflow-deck",
+ "name": "com.simeonradivoev.gameflow-deck",
+ "displayName": "Gameflow",
"version": "1.0.0",
"description": "Game Launcher",
+ "type": "module",
"scripts": {
- "dev": "bun run build && electrobun dev",
- "dev:hmr": "concurrently \"bun run hmr\" \"bun run dev\"",
- "build": "vite build && electrobun build",
- "build:canary": "vite build && electrobun build --env=canary",
- "build:stable": "vite build && electrobun build --env=stable",
- "hmr": "vite --port 5173",
- "start": "bun run dev"
+ "dev": "bun run build:dev && NODE_ENV=development bun run --inspect=127.0.0.1:9229 --watch ./src/bun/index.ts",
+ "dev:hmr": "PUBLIC_ACCESS=true conc -k 'bun run hmr' 'bun run dev'",
+ "build": "vite build",
+ "build:pro": "NODE_ENV=production bun run build",
+ "build:dev": "NODE_ENV=development bun run build",
+ "package": "bun run build && bun run ./scripts/package-bun.ts",
+ "package:auto-prod": "bun run build:pro && NODE_ENV=production bun run ./scripts/package-bun.ts",
+ "package:linux": "bun run build && TARGET=bun-linux-x64 bun run ./scripts/package-bun.ts",
+ "openapi-ts": "bun run ./scripts/romm/openapi-ts.ts",
+ "run:build-action": "act --artifact-server-path artifacts --env ACTIONS_RUNTIME_TOKEN=foo -W .github/workflows/build.yml",
+ "hmr": "vite --port 5173"
},
"dependencies": {
- "@tanstack/react-router": "^1.154.12",
- "@tanstack/router-plugin": "^1.154.12",
- "classnames": "^2.5.1",
- "electrobun": "latest",
- "gamepad.css": "^0.0.4",
- "lucide-react": "^0.562.0",
- "react": "^19.2.3",
- "react-dom": "^19.2.3"
+ "@auth/core": "^0.34.3",
+ "@elysiajs/cors": "^1.4.1",
+ "@elysiajs/eden": "^1.4.6",
+ "@elysiajs/static": "^1.4.7",
+ "@rcompat/webview": "^0.18.0",
+ "conf": "^15.0.2",
+ "elysia": "^1.4.22",
+ "pathe": "^2.0.3",
+ "zod": "^4.3.6"
},
"devDependencies": {
+ "@hey-api/openapi-ts": "^0.91.0",
+ "@noriginmedia/norigin-spatial-navigation": "^2.3.0",
"@tailwindcss/vite": "^4.1.18",
+ "@tanstack/react-query": "^5.90.20",
+ "@tanstack/react-query-devtools": "^5.91.3",
+ "@tanstack/react-router": "^1.157.16",
"@tanstack/react-router-devtools": "^1.154.12",
+ "@tanstack/react-router-ssr-query": "^1.157.17",
+ "@tanstack/router-plugin": "^1.157.16",
"@types/bun": "latest",
"@types/react": "^19.2.9",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.2",
+ "animate.css": "^4.1.1",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "classnames": "^2.5.1",
"concurrently": "^9.2.1",
+ "cross-env": "^10.1.0",
+ "daisyui": "^5.5.14",
+ "lucide-react": "^0.563.0",
+ "pretty-bytes": "^7.1.0",
+ "react": "^19.2.4",
+ "react-dom": "^19.2.4",
+ "react-error-boundary": "^6.1.0",
+ "react-hot-toast": "^2.6.0",
+ "tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.18",
+ "tailwindcss-animate": "^1.0.7",
"typescript": "^5.9.3",
- "vite": "^7.3.1"
+ "usehooks-ts": "^3.1.1",
+ "vite": "^7.3.1",
+ "vite-plugin-svg-icons-ng": "^1.5.2",
+ "vite-static-assets-plugin": "^1.2.2"
}
}
\ No newline at end of file
diff --git a/scripts/package-bun.ts b/scripts/package-bun.ts
new file mode 100644
index 0000000..fba4a8f
--- /dev/null
+++ b/scripts/package-bun.ts
@@ -0,0 +1,85 @@
+import { PluginBuilder } from "bun";
+import fs from "node:fs/promises";
+import path, { resolve, sep } from "node:path";
+import os from "node:os";
+import appPackage from '../package.json';
+
+const plugin = {
+ name: "dist-absolute-filter",
+ setup (build: PluginBuilder)
+ {
+ build.onStart(async () =>
+ {
+ if (await fs.exists('./build'))
+ {
+ await fs.rm('./build', { recursive: true });
+ }
+ });
+ // 1. Intercept all resolutions to check their REAL path
+ build.onResolve({ filter: /.*/, namespace: 'file' }, (args) =>
+ {
+ if (args.path.startsWith(`.${sep}dist`))
+ {
+ return { path: resolve(args.resolveDir, args.path), namespace: "dist_assets" };
+ }
+ });
+ build.onLoad({ filter: /.*/, namespace: 'dist_assets' }, async (args) =>
+ {
+ console.log(args.path);
+ return { contents: await Bun.file(args.path).bytes(), loader: 'file' };
+ });
+ },
+};
+
+const compileOption: Bun.CompileBuildOptions = {
+ outfile: "gameflow",
+ execArgv: ['--windows-hide-console'],
+ autoloadTsconfig: true,
+ autoloadPackageJson: true,
+ autoloadDotenv: true,
+ autoloadBunfig: true
+};
+
+if (process.env.TARGET)
+{
+ compileOption.target = process.env.TARGET as any;
+}
+
+await Bun.build({
+ entrypoints: ["./src/bun/index.ts", "./src/bun/webview-worker.ts"],
+ metafile: true,
+ compile: compileOption,
+ outdir: `./build/${os.platform()}`,
+ root: './src/bun',
+ define: {
+ "process.env.IS_BINARY": "true"
+ },
+ minify: true,
+ sourcemap: "linked",
+ target: 'bun',
+ format: 'esm',
+ loader: {
+ ".ico": "file"
+ },
+ plugins: [{
+ name: "clean build folder",
+ setup (build)
+ {
+ build.onStart(async () =>
+ {
+ if (await fs.exists(`./build/${os.platform()}`))
+ {
+ const files = await fs.readdir(`./build/${os.platform()}`, { withFileTypes: true });
+ for (const file of files)
+ {
+ await fs.rm(path.join(file.parentPath, file.name), { recursive: true });
+ }
+ }
+ });
+ build.onEnd(async () =>
+ {
+ await fs.cp('./dist', `./build/${os.platform()}/dist`, { recursive: true });
+ });
+ },
+ }]
+});
\ No newline at end of file
diff --git a/scripts/romm/openapi-ts.ts b/scripts/romm/openapi-ts.ts
new file mode 100644
index 0000000..54df5ba
--- /dev/null
+++ b/scripts/romm/openapi-ts.ts
@@ -0,0 +1,8 @@
+
+import { createClient } from '@hey-api/openapi-ts';
+
+createClient({
+ input: './scripts/romm/openapi.json', // sign up at app.heyapi.dev
+ output: './src/clients/romm',
+ plugins: ['@tanstack/react-query', '@hey-api/client-fetch', '@hey-api/typescript'],
+});
\ No newline at end of file
diff --git a/scripts/romm/openapi.json b/scripts/romm/openapi.json
new file mode 100644
index 0000000..86d3921
--- /dev/null
+++ b/scripts/romm/openapi.json
@@ -0,0 +1 @@
+{"openapi":"3.1.0","info":{"title":"RomM API","version":"4.6.1"},"paths":{"/api/heartbeat":{"get":{"tags":["system"],"summary":"Heartbeat","description":"Endpoint to set the CSRF token in cache and return all the basic RomM config\n\nReturns:\n HeartbeatReturn: TypedDict structure with all the defined values in the HeartbeatReturn class.","operationId":"heartbeat_api_heartbeat_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatResponse"}}}}}}},"/api/heartbeat/metadata/{source}":{"get":{"tags":["system"],"summary":"Metadata Heartbeat","description":"Endpoint to return the heartbeat of the metadata sources","operationId":"metadata_heartbeat_api_heartbeat_metadata__source__get","parameters":[{"name":"source","in":"path","required":true,"schema":{"type":"string","title":"Source"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"boolean","title":"Response Metadata Heartbeat Api Heartbeat Metadata Source Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/setup/library":{"get":{"tags":["system"],"summary":"Get Setup Library Info","description":"Get library structure information for setup wizard.\n\nOnly accessible during initial setup (no admin users) or with authentication.\n\nReturns:\n - detected_structure: \"struct_a\" (roms/{platform}), \"struct_b\" ({platform}/roms), or None\n - existing_platforms: list of objects with fs_slug and rom_count\n - supported_platforms: list of all supported platforms with metadata","operationId":"get_setup_library_info_api_setup_library_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBasic":[]}]}},"/api/setup/platforms":{"post":{"tags":["system"],"summary":"Create Setup Platforms","description":"Create platform folders during setup wizard.\n\nOnly accessible during initial setup (no admin users) or with authentication.\n\nArgs:\n platform_slugs: List of platform fs_slugs to create\n\nReturns:\n - success: bool\n - created_count: number of platforms created\n - message: success or error message","operationId":"create_setup_platforms_api_setup_platforms_post","requestBody":{"content":{"application/json":{"schema":{"items":{"type":"string"},"type":"array","title":"Platform Slugs"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBasic":[]}]}},"/api/login":{"post":{"tags":["auth"],"summary":"Login","description":"Session login endpoint\n\nArgs:\n request (Request): Fastapi Request object\n credentials: Defaults to Depends(HTTPBasic()).\n\nRaises:\n CredentialsException: Invalid credentials\n UserDisabledException: Auth is disabled","operationId":"login_api_login_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBasic":[]}]}},"/api/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"Session logout endpoint\n\nArgs:\n request (Request): Fastapi Request object","operationId":"logout_api_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/token":{"post":{"tags":["auth"],"summary":"Token","description":"OAuth2 token endpoint\n\nArgs:\n form_data (Annotated[OAuth2RequestForm, Depends): Form Data with OAuth2 info\n\nRaises:\n HTTPException: Missing refresh token\n HTTPException: Invalid refresh token\n HTTPException: Missing username or password\n HTTPException: Invalid username or password\n HTTPException: Client credentials are not yet supported\n HTTPException: Invalid or unsupported grant type\n HTTPException: Insufficient scope\n\nReturns:\n TokenResponse: TypedDict with the new generated token info","operationId":"token_api_token_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_token_api_token_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/login/openid":{"get":{"tags":["auth"],"summary":"Login Via Openid","description":"OIDC login endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nRaises:\n OIDCDisabledException: OAuth is disabled\n OIDCNotConfiguredException: OAuth not configured\n\nReturns:\n RedirectResponse: Redirect to OIDC provider","operationId":"login_via_openid_api_login_openid_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/oauth/openid":{"get":{"tags":["auth"],"summary":"Auth Openid","description":"OIDC callback endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nRaises:\n OIDCDisabledException: OAuth is disabled\n OIDCNotConfiguredException: OAuth not configured\n AuthCredentialsException: Invalid credentials\n UserDisabledException: Auth is disabled\n\nReturns:\n RedirectResponse: Redirect to home page","operationId":"auth_openid_api_oauth_openid_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/forgot-password":{"post":{"tags":["auth"],"summary":"Request Password Reset","description":"Request a password reset link for the user.\n\nArgs:\n username (str): Username of the user requesting the reset\nReturns:\n None: Returns 200 OK status","operationId":"request_password_reset_api_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_request_password_reset_api_forgot_password_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reset-password":{"post":{"tags":["auth"],"summary":"Reset Password","description":"Reset password using the token.\n\nArgs:\n token (str): Reset token from the URL\n new_password (str): New user password\n\nReturns:\n None: Returns 200 OK status","operationId":"reset_password_api_reset_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_reset_password_api_reset_password_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users":{"get":{"tags":["users"],"summary":"Get Users","description":"Get all users endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n list[UserSchema]: All users stored in the RomM's database","operationId":"get_users_api_users_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/UserSchema"},"type":"array","title":"Response Get Users Api Users Get"}}}}},"security":[{"OAuth2PasswordBearer":["users.read"]},{"HTTPBasic":[]}]},"post":{"tags":["users"],"summary":"Add User","description":"Create user endpoint\n\nArgs:\n request (Request): Fastapi Requests object\n username (str): User username\n password (str): User password\n email (str): User email\n role (str): RomM Role object represented as string\n\nReturns:\n UserSchema: Newly created user","operationId":"add_user_api_users_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_add_user_api_users_post"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":[]},{"HTTPBasic":[]}]}},"/api/users/invite-link":{"post":{"tags":["users"],"summary":"Create Invite Link","description":"Create an invite link for a user.\n\nArgs:\n request (Request): FastAPI Request object\n role (str): The role of the user\n\nReturns:\n InviteLinkSchema: Invite link","operationId":"create_invite_link_api_users_invite_link_post","security":[{"OAuth2PasswordBearer":[]},{"HTTPBasic":[]}],"parameters":[{"name":"role","in":"query","required":true,"schema":{"type":"string","title":"Role"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteLinkSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/register":{"post":{"tags":["users"],"summary":"Create User From Invite","description":"Create user endpoint with invite link\n\nArgs:\n username (str): User username\n email (str): User email\n password (str): User password\n token (str): Invite link token\n\nReturns:\n UserSchema: Newly created user","operationId":"create_user_from_invite_api_users_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_create_user_from_invite_api_users_register_post"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/me":{"get":{"tags":["users"],"summary":"Get Current User","description":"Get current user endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n UserSchema | None: Current user","operationId":"get_current_user_api_users_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/UserSchema"},{"type":"null"}],"title":"Response Get Current User Api Users Me Get"}}}}},"security":[{"OAuth2PasswordBearer":["me.read"]},{"HTTPBasic":[]}]}},"/api/users/{id}":{"get":{"tags":["users"],"summary":"Get User","description":"Get user endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n UserSchem: User stored in the RomM's database","operationId":"get_user_api_users__id__get","security":[{"OAuth2PasswordBearer":["users.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["users"],"summary":"Update User","description":"Update user endpoint\n\nArgs:\n request (Request): Fastapi Requests object\n user_id (int): User internal id\n form_data (Annotated[UserUpdateForm, Depends): Form Data with user updated info\n\nRaises:\n HTTPException: User is not found in database\n HTTPException: Username already in use by another user\n\nReturns:\n UserSchema: Updated user info","operationId":"update_user_api_users__id__put","security":[{"OAuth2PasswordBearer":["me.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/UserForm"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["users"],"summary":"Delete User","description":"Delete a user by ID.\n\nRaises:\n HTTPException: User is not found in database\n HTTPException: User deleting itself\n HTTPException: User is the last admin user","operationId":"delete_user_api_users__id__delete","security":[{"OAuth2PasswordBearer":["users.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"User internal id.","title":"Id"},"description":"User internal id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"400":{"description":"Bad Request"},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/users/{id}/ra/refresh":{"post":{"tags":["users"],"summary":"Refresh RetroAchievements","description":"Refresh RetroAchievements progression data for a user.","operationId":"refresh_retro_achievements_api_users__id__ra_refresh_post","security":[{"OAuth2PasswordBearer":["me.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"User internal id.","title":"Id"},"description":"User internal id."}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_refresh_retro_achievements_api_users__id__ra_refresh_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/platforms":{"post":{"tags":["platforms"],"summary":"Add Platform","description":"Create a platform.","operationId":"add_platform_api_platforms_post","security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_add_platform_api_platforms_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["platforms"],"summary":"Get Platforms","description":"Retrieve platforms.","operationId":"get_platforms_api_platforms_get","security":[{"OAuth2PasswordBearer":["platforms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"updated_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter platforms updated after this datetime (ISO 8601 format with timezone information).","title":"Updated After"},"description":"Filter platforms updated after this datetime (ISO 8601 format with timezone information)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlatformSchema"},"title":"Response Get Platforms Api Platforms Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/platforms/supported":{"get":{"tags":["platforms"],"summary":"Get Supported Platforms Endpoint","description":"Retrieve the list of supported platforms.","operationId":"get_supported_platforms_endpoint_api_platforms_supported_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PlatformSchema"},"type":"array","title":"Response Get Supported Platforms Endpoint Api Platforms Supported Get"}}}}},"security":[{"OAuth2PasswordBearer":["platforms.read"]},{"HTTPBasic":[]}]}},"/api/platforms/{id}":{"get":{"tags":["platforms"],"summary":"Get Platform","description":"Retrieve a platform by ID.","operationId":"get_platform_api_platforms__id__get","security":[{"OAuth2PasswordBearer":["platforms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Platform id.","title":"Id"},"description":"Platform id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["platforms"],"summary":"Update Platform","description":"Update a platform.","operationId":"update_platform_api_platforms__id__put","security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Platform id.","title":"Id"},"description":"Platform id."}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_update_platform_api_platforms__id__put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["platforms"],"summary":"Delete Platform","description":"Delete a platform by ID.","operationId":"delete_platform_api_platforms__id__delete","security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Platform id.","title":"Id"},"description":"Platform id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms":{"post":{"tags":["roms"],"summary":"Add Rom","description":"Upload a single rom.","operationId":"add_rom_api_roms_post","security":[{"OAuth2PasswordBearer":["roms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"x-upload-platform","in":"header","required":true,"schema":{"type":"integer","minimum":1,"description":"Platform internal id.","title":"X-Upload-Platform"},"description":"Platform internal id."},{"name":"x-upload-filename","in":"header","required":true,"schema":{"type":"string","description":"The name of the file being uploaded.","title":"X-Upload-Filename"},"description":"The name of the file being uploaded."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"400":{"description":"Bad Request"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["roms"],"summary":"Get Roms","description":"Retrieve roms.","operationId":"get_roms_api_roms_get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"with_char_index","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to get the char index.","default":true,"title":"With Char Index"},"description":"Whether to get the char index."},{"name":"with_filter_values","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to return filter values.","default":true,"title":"With Filter Values"},"description":"Whether to return filter values."},{"name":"search_term","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search term to filter roms.","title":"Search Term"},"description":"Search term to filter roms."},{"name":"platform_ids","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"integer"}},{"type":"null"}],"description":"Platform internal ids. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Platform Ids"},"description":"Platform internal ids. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"collection_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Collection internal id.","title":"Collection Id"},"description":"Collection internal id."},{"name":"virtual_collection_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Virtual collection internal id.","title":"Virtual Collection Id"},"description":"Virtual collection internal id."},{"name":"smart_collection_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Smart collection internal id.","title":"Smart Collection Id"},"description":"Smart collection internal id."},{"name":"matched","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom matched at least one metadata source.","title":"Matched"},"description":"Whether the rom matched at least one metadata source."},{"name":"favorite","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom is marked as favorite.","title":"Favorite"},"description":"Whether the rom is marked as favorite."},{"name":"duplicate","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom is marked as duplicate.","title":"Duplicate"},"description":"Whether the rom is marked as duplicate."},{"name":"last_played","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom has a last played value for the current user.","title":"Last Played"},"description":"Whether the rom has a last played value for the current user."},{"name":"playable","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom is playable from the browser.","title":"Playable"},"description":"Whether the rom is playable from the browser."},{"name":"missing","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom is missing from the filesystem.","title":"Missing"},"description":"Whether the rom is missing from the filesystem."},{"name":"has_ra","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom has RetroAchievements data.","title":"Has Ra"},"description":"Whether the rom has RetroAchievements data."},{"name":"verified","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Whether the rom is verified by Hasheous.","title":"Verified"},"description":"Whether the rom is verified by Hasheous."},{"name":"group_by_meta_id","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to group roms by metadata ID (IGDB / Moby / ScreenScraper / RetroAchievements / LaunchBox).","default":false,"title":"Group By Meta Id"},"description":"Whether to group roms by metadata ID (IGDB / Moby / ScreenScraper / RetroAchievements / LaunchBox)."},{"name":"genres","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated genre. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Genres"},"description":"Associated genre. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"franchises","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated franchise. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Franchises"},"description":"Associated franchise. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"collections","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated collection. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Collections"},"description":"Associated collection. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"companies","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated company. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Companies"},"description":"Associated company. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"age_ratings","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated age rating. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Age Ratings"},"description":"Associated age rating. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"statuses","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Game status, set by the current user. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Statuses"},"description":"Game status, set by the current user. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"regions","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated region tag. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Regions"},"description":"Associated region tag. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"languages","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated language tag. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Languages"},"description":"Associated language tag. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"player_counts","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Associated player count. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned.","title":"Player Counts"},"description":"Associated player count. Multiple values are allowed by repeating the parameter, and results that match any of the values will be returned."},{"name":"genres_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for genres filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Genres Logic"},"description":"Logic operator for genres filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"franchises_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for franchises filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Franchises Logic"},"description":"Logic operator for franchises filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"collections_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for collections filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Collections Logic"},"description":"Logic operator for collections filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"companies_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for companies filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Companies Logic"},"description":"Logic operator for companies filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"age_ratings_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for age ratings filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Age Ratings Logic"},"description":"Logic operator for age ratings filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"regions_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for regions filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Regions Logic"},"description":"Logic operator for regions filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"languages_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for languages filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Languages Logic"},"description":"Logic operator for languages filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"statuses_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for statuses filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Statuses Logic"},"description":"Logic operator for statuses filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"player_counts_logic","in":"query","required":false,"schema":{"type":"string","description":"Logic operator for player counts filter: 'any' (OR), 'all' (AND) or 'none' (NOT).","default":"any","title":"Player Counts Logic"},"description":"Logic operator for player counts filter: 'any' (OR), 'all' (AND) or 'none' (NOT)."},{"name":"order_by","in":"query","required":false,"schema":{"type":"string","description":"Field to order results by.","default":"name","title":"Order By"},"description":"Field to order results by."},{"name":"order_dir","in":"query","required":false,"schema":{"type":"string","description":"Order direction, either 'asc' or 'desc'.","default":"asc","title":"Order Dir"},"description":"Order direction, either 'asc' or 'desc'."},{"name":"updated_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter roms updated after this datetime (ISO 8601 format with timezone information).","title":"Updated After"},"description":"Filter roms updated after this datetime (ISO 8601 format with timezone information)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":10000,"minimum":1,"description":"Page size limit","default":50,"title":"Limit"},"description":"Page size limit"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Page offset","default":0,"title":"Offset"},"description":"Page offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomLimitOffsetPage_SimpleRomSchema_"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/download":{"get":{"tags":["roms"],"summary":"Download Roms","description":"Download a list of roms as a zip file.","operationId":"download_roms_api_roms_download_get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"rom_ids","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated list of ROM IDs to download as a zip file.","title":"Rom Ids"},"description":"Comma-separated list of ROM IDs to download as a zip file."},{"name":"filename","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Name for the zip file (optional).","title":"Filename"},"description":"Name for the zip file (optional)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/by-metadata-provider":{"get":{"tags":["roms"],"summary":"Get Rom By Metadata Provider","description":"Retrieve a rom by metadata ID.","operationId":"get_rom_by_metadata_provider_api_roms_by_metadata_provider_get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"igdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"IGDB ID to search by","title":"Igdb Id"},"description":"IGDB ID to search by"},{"name":"moby_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"MobyGames ID to search by","title":"Moby Id"},"description":"MobyGames ID to search by"},{"name":"ss_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"ScreenScraper ID to search by","title":"Ss Id"},"description":"ScreenScraper ID to search by"},{"name":"ra_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"RetroAchievements ID to search by","title":"Ra Id"},"description":"RetroAchievements ID to search by"},{"name":"launchbox_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"LaunchBox ID to search by","title":"Launchbox Id"},"description":"LaunchBox ID to search by"},{"name":"hasheous_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Hasheous ID to search by","title":"Hasheous Id"},"description":"Hasheous ID to search by"},{"name":"tgdb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"TGDB ID to search by","title":"Tgdb Id"},"description":"TGDB ID to search by"},{"name":"flashpoint_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Flashpoint ID to search by","title":"Flashpoint Id"},"description":"Flashpoint ID to search by"},{"name":"hltb_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"HLTB ID to search by","title":"Hltb Id"},"description":"HLTB ID to search by"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedRomSchema"}}}},"404":{"description":"Not Found"},"400":{"description":"Bad Request"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/by-hash":{"get":{"tags":["roms"],"summary":"Get Rom By Hash","operationId":"get_rom_by_hash_api_roms_by_hash_get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"crc_hash","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"CRC hash value","title":"Crc Hash"},"description":"CRC hash value"},{"name":"md5_hash","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"MD5 hash value","title":"Md5 Hash"},"description":"MD5 hash value"},{"name":"sha1_hash","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"SHA1 hash value","title":"Sha1 Hash"},"description":"SHA1 hash value"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedRomSchema"}}}},"404":{"description":"Not Found"},"400":{"description":"Bad Request"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/filters":{"get":{"tags":["roms"],"summary":"Get Rom Filters","operationId":"get_rom_filters_api_roms_filters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RomFiltersDict"}}}}},"security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}]}},"/api/roms/{id}":{"get":{"tags":["roms"],"summary":"Get Rom","description":"Retrieve a rom by ID.","operationId":"get_rom_api_roms__id__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedRomSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["roms"],"summary":"Update Rom","description":"Update a rom.","operationId":"update_rom_api_roms__id__put","security":[{"OAuth2PasswordBearer":["roms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."},{"name":"remove_cover","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to remove the cover image for this rom.","default":false,"title":"Remove Cover"},"description":"Whether to remove the cover image for this rom."},{"name":"unmatch_metadata","in":"query","required":false,"schema":{"type":"boolean","description":"Whether to remove the metadata matches for this game.","default":false,"title":"Unmatch Metadata"},"description":"Whether to remove the metadata matches for this game."}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_update_rom_api_roms__id__put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailedRomSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/{id}/content/{file_name}":{"head":{"tags":["roms"],"summary":"Head Rom Content","description":"Retrieve head information for a rom file download.","operationId":"head_rom_content_api_roms__id__content__file_name__head","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."},{"name":"file_name","in":"path","required":true,"schema":{"type":"string","description":"File name to download","title":"File Name"},"description":"File name to download"},{"name":"file_ids","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated list of file ids to download for multi-part roms.","title":"File Ids"},"description":"Comma-separated list of file ids to download for multi-part roms."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["roms"],"summary":"Get Rom Content","description":"Download a rom.\n\nThis endpoint serves the content of the requested rom, as:\n- A single file for single file roms.\n- A zipped file for multi-part roms, including a .m3u file if applicable.","operationId":"get_rom_content_api_roms__id__content__file_name__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."},{"name":"file_name","in":"path","required":true,"schema":{"type":"string","description":"Zip file output name","title":"File Name"},"description":"Zip file output name"},{"name":"file_ids","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated list of file ids to download for multi-part roms.","title":"File Ids"},"description":"Comma-separated list of file ids to download for multi-part roms."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/{id}/manuals":{"post":{"tags":["roms"],"summary":"Add Rom Manuals","description":"Upload manuals for a rom.","operationId":"add_rom_manuals_api_roms__id__manuals_post","security":[{"OAuth2PasswordBearer":["roms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."},{"name":"x-upload-filename","in":"header","required":true,"schema":{"type":"string","description":"The name of the file being uploaded.","title":"X-Upload-Filename"},"description":"The name of the file being uploaded."}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["roms"],"summary":"Delete Rom Manuals","description":"Delete manuals for a rom.","operationId":"delete_rom_manuals_api_roms__id__manuals_delete","security":[{"OAuth2PasswordBearer":["roms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/delete":{"post":{"tags":["roms"],"summary":"Delete Roms","description":"Delete roms.","operationId":"delete_roms_api_roms_delete_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_delete_roms_api_roms_delete_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkOperationResponse"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":["roms.write"]},{"HTTPBasic":[]}]}},"/api/roms/{id}/props":{"put":{"tags":["roms"],"summary":"Update Rom User","description":"Update rom data associated to the current user.","operationId":"update_rom_user_api_roms__id__props_put","security":[{"OAuth2PasswordBearer":["roms.user.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_update_rom_user_api_roms__id__props_put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RomUserSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/files/{id}":{"get":{"tags":["roms"],"summary":"Get Romfile","description":"Retrieve a rom file by ID.","operationId":"get_romfile_api_roms_files__id__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom file internal id.","title":"Id"},"description":"Rom file internal id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RomFileSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/romsfiles/{id}/content/{file_name}":{"get":{"tags":["roms"],"summary":"Get Romfile Content","description":"Download a rom file.","operationId":"get_romfile_content_api_romsfiles__id__content__file_name__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom file internal id.","title":"Id"},"description":"Rom file internal id."},{"name":"file_name","in":"path","required":true,"schema":{"type":"string","description":"File name to download","title":"File Name"},"description":"File name to download"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/{id}/notes":{"get":{"tags":["roms"],"summary":"Get Rom Notes","description":"Get all notes for a ROM.","operationId":"get_rom_notes_api_roms__id__notes_get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."},{"name":"public_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only return public notes","default":false,"title":"Public Only"},"description":"Only return public notes"},{"name":"search","in":"query","required":false,"schema":{"type":"string","description":"Search notes by title or content","title":"Search"},"description":"Search notes by title or content"},{"name":"tags","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"Filter by tags","title":"Tags"},"description":"Filter by tags"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserNoteSchema"},"title":"Response Get Rom Notes Api Roms Id Notes Get"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["roms"],"summary":"Create Rom Note","description":"Create a new note for a ROM.","operationId":"create_rom_note_api_roms__id__notes_post","security":[{"OAuth2PasswordBearer":["roms.user.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Note Data"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserNoteSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/roms/{id}/notes/{note_id}":{"put":{"tags":["roms"],"summary":"Update Rom Note","description":"Update a ROM note.","operationId":"update_rom_note_api_roms__id__notes__note_id__put","security":[{"OAuth2PasswordBearer":["roms.user.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."},{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Note id.","title":"Note Id"},"description":"Note id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Note Data"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserNoteSchema"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["roms"],"summary":"Delete Rom Note","description":"Delete a ROM note.","operationId":"delete_rom_note_api_roms__id__notes__note_id__delete","security":[{"OAuth2PasswordBearer":["roms.user.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Rom internal id.","title":"Id"},"description":"Rom internal id."},{"name":"note_id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Note id.","title":"Note Id"},"description":"Note id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Rom Note Api Roms Id Notes Note Id Delete"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search/roms":{"get":{"tags":["search"],"summary":"Search Rom","description":"Search for rom in metadata providers\n\nArgs:\n request (Request): FastAPI request\n rom_id (int): Rom ID\n source (str): Source of the rom\n search_term (str, optional): Search term. Defaults to None.\n search_by (str, optional): Search by name or ID. Defaults to \"name\".\n search_extended (bool, optional): Search extended info. Defaults to False.\n\nReturns:\n list[SearchRomSchema]: List of matched roms","operationId":"search_rom_api_search_roms_get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"rom_id","in":"query","required":true,"schema":{"type":"integer","title":"Rom Id"}},{"name":"search_term","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search Term"}},{"name":"search_by","in":"query","required":false,"schema":{"type":"string","default":"name","title":"Search By"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SearchRomSchema"},"title":"Response Search Rom Api Search Roms Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search/cover":{"get":{"tags":["search"],"summary":"Search Cover","operationId":"search_cover_api_search_cover_get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"search_term","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search Term"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SearchCoverSchema"},"title":"Response Search Cover Api Search Cover Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/saves":{"post":{"tags":["saves"],"summary":"Add Save","operationId":"add_save_api_saves_post","security":[{"OAuth2PasswordBearer":["assets.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"rom_id","in":"query","required":true,"schema":{"type":"integer","title":"Rom Id"}},{"name":"emulator","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emulator"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["saves"],"summary":"Get Saves","operationId":"get_saves_api_saves_get","security":[{"OAuth2PasswordBearer":["assets.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"rom_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rom Id"}},{"name":"platform_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Platform Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SaveSchema"},"title":"Response Get Saves Api Saves Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/saves/{id}":{"get":{"tags":["saves"],"summary":"Get Save","operationId":"get_save_api_saves__id__get","security":[{"OAuth2PasswordBearer":["assets.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["saves"],"summary":"Update Save","operationId":"update_save_api_saves__id__put","security":[{"OAuth2PasswordBearer":["assets.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/saves/delete":{"post":{"tags":["saves"],"summary":"Delete Saves","description":"Delete saves.","operationId":"delete_saves_api_saves_delete_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_delete_saves_api_saves_delete_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"integer"},"type":"array","title":"Response Delete Saves Api Saves Delete Post"}}}},"400":{"description":"Bad Request"},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":["assets.write"]},{"HTTPBasic":[]}]}},"/api/states":{"post":{"tags":["states"],"summary":"Add State","operationId":"add_state_api_states_post","security":[{"OAuth2PasswordBearer":["assets.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"rom_id","in":"query","required":true,"schema":{"type":"integer","title":"Rom Id"}},{"name":"emulator","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emulator"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StateSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["states"],"summary":"Get States","operationId":"get_states_api_states_get","security":[{"OAuth2PasswordBearer":["assets.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"rom_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rom Id"}},{"name":"platform_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Platform Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StateSchema"},"title":"Response Get States Api States Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/states/{id}":{"get":{"tags":["states"],"summary":"Get State","operationId":"get_state_api_states__id__get","security":[{"OAuth2PasswordBearer":["assets.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StateSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["states"],"summary":"Update State","operationId":"update_state_api_states__id__put","security":[{"OAuth2PasswordBearer":["assets.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StateSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/states/delete":{"post":{"tags":["states"],"summary":"Delete States","description":"Delete states.","operationId":"delete_states_api_states_delete_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_delete_states_api_states_delete_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"integer"},"type":"array","title":"Response Delete States Api States Delete Post"}}}},"400":{"description":"Bad Request"},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":["assets.write"]},{"HTTPBasic":[]}]}},"/api/tasks":{"get":{"tags":["tasks"],"summary":"List Tasks","description":"List all available tasks grouped by task type.\n\nArgs:\n request (Request): FastAPI Request object\nReturns:\n GroupedTasksDict: Dictionary with tasks grouped by their type (scheduled, manual, watcher)","operationId":"list_tasks_api_tasks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":{"items":{"$ref":"#/components/schemas/TaskInfo"},"type":"array"},"type":"object","title":"Response List Tasks Api Tasks Get"}}}}},"security":[{"OAuth2PasswordBearer":["tasks.run"]},{"HTTPBasic":[]}]}},"/api/tasks/status":{"get":{"tags":["tasks"],"summary":"Get Tasks Status","description":"Get all active, queued, completed, and failed tasks.\n\nArgs:\n request (Request): FastAPI Request object\nReturns:\n list[TaskStatusResponse]: List of all tasks with their current status","operationId":"get_tasks_status_api_tasks_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"anyOf":[{"$ref":"#/components/schemas/ScanTaskStatusResponse"},{"$ref":"#/components/schemas/ConversionTaskStatusResponse"},{"$ref":"#/components/schemas/UpdateTaskStatusResponse"},{"$ref":"#/components/schemas/CleanupTaskStatusResponse"},{"$ref":"#/components/schemas/WatcherTaskStatusResponse"},{"$ref":"#/components/schemas/GenericTaskStatusResponse"}]},"type":"array","title":"Response Get Tasks Status Api Tasks Status Get"}}}}},"security":[{"OAuth2PasswordBearer":["tasks.run"]},{"HTTPBasic":[]}]}},"/api/tasks/{task_id}":{"get":{"tags":["tasks"],"summary":"Get Task By Id","description":"Get the status of a task by its job ID.\n\nArgs:\n request (Request): FastAPI Request object\n task_id (str): Job ID of the task to retrieve status for\nReturns:\n TaskStatusResponse: Task status information","operationId":"get_task_by_id_api_tasks__task_id__get","security":[{"OAuth2PasswordBearer":["tasks.run"]},{"HTTPBasic":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ScanTaskStatusResponse"},{"$ref":"#/components/schemas/ConversionTaskStatusResponse"},{"$ref":"#/components/schemas/UpdateTaskStatusResponse"},{"$ref":"#/components/schemas/CleanupTaskStatusResponse"},{"$ref":"#/components/schemas/WatcherTaskStatusResponse"},{"$ref":"#/components/schemas/GenericTaskStatusResponse"}],"title":"Response Get Task By Id Api Tasks Task Id Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tasks/run":{"post":{"tags":["tasks"],"summary":"Run All Tasks","description":"Run all runnable tasks endpoint\n\nArgs:\n request (Request): FastAPI Request object\nReturns:\n TaskExecutionResponse: Task execution response with details","operationId":"run_all_tasks_api_tasks_run_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/TaskExecutionResponse"},"type":"array","title":"Response Run All Tasks Api Tasks Run Post"}}}}},"security":[{"OAuth2PasswordBearer":["tasks.run"]},{"HTTPBasic":[]}]}},"/api/tasks/run/{task_name}":{"post":{"tags":["tasks"],"summary":"Run Single Task","description":"Run a single task endpoint.\n\nArgs:\n request (Request): FastAPI Request object\n task_name (str): Name of the task to run\nReturns:\n TaskExecutionResponse: Task execution response with details","operationId":"run_single_task_api_tasks_run__task_name__post","security":[{"OAuth2PasswordBearer":["tasks.run"]},{"HTTPBasic":[]}],"parameters":[{"name":"task_name","in":"path","required":true,"schema":{"type":"string","title":"Task Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskExecutionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/feeds/webrcade":{"get":{"tags":["feeds"],"summary":"Platforms Webrcade Feed","description":"Get webrcade feed endpoint\nhttps://docs.webrcade.com/feeds/format/\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n WebrcadeFeedSchema: Webrcade feed object schema","operationId":"platforms_webrcade_feed_api_feeds_webrcade_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebrcadeFeedSchema"}}}}},"security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}]}},"/api/feeds/tinfoil":{"get":{"tags":["feeds"],"summary":"Tinfoil Index Feed","description":"Get tinfoil custom index feed endpoint\nhttps://blawar.github.io/tinfoil/custom_index/\n\nArgs:\n request (Request): Fastapi Request object\n slug (str, optional): Platform slug. Defaults to \"switch\".\n\nReturns:\n TinfoilFeedSchema: Tinfoil feed object schema","operationId":"tinfoil_index_feed_api_feeds_tinfoil_get","security":[{"OAuth2PasswordBearer":[]},{"HTTPBasic":[]}],"parameters":[{"name":"slug","in":"query","required":false,"schema":{"type":"string","default":"switch","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TinfoilFeedSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/feeds/pkgi/ps3/{content_type}":{"get":{"tags":["feeds"],"summary":"Pkgi Ps3 Feed","description":"Get PKGi PS3 feed endpoint\nhttps://github.com/bucanero/pkgi-ps3\n\nArgs:\n request (Request): Fastapi Request object\n content_type (str): Content type (game, dlc, demo, update, patch, mod, translation, prototype)\n\nReturns:\n Response: txt file with PKGi PS3 database format","operationId":"pkgi_ps3_feed_api_feeds_pkgi_ps3__content_type__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"content_type","in":"path","required":true,"schema":{"type":"string","description":"Content type","title":"Content Type"},"description":"Content type"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/feeds/pkgi/psvita/{content_type}":{"get":{"tags":["feeds"],"summary":"Pkgi Psvita Feed","description":"Get PKGi PS Vita feed endpoint\nhttps://github.com/mmozeiko/pkgi\n\nArgs:\n request (Request): Fastapi Request object\n content_type (str): Content type (game, dlc, demo, update, patch, mod, translation, prototype)\n\nReturns:\n Response: txt file with PKGi PS Vita database format","operationId":"pkgi_psvita_feed_api_feeds_pkgi_psvita__content_type__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"content_type","in":"path","required":true,"schema":{"type":"string","description":"Content type","title":"Content Type"},"description":"Content type"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/feeds/pkgi/psp/{content_type}":{"get":{"tags":["feeds"],"summary":"Pkgi Psp Feed","description":"Get PKGi PSP feed endpoint\nhttps://github.com/bucanero/pkgi-psp\n\nArgs:\n request (Request): Fastapi Request object\n content_type (str): Content type (game, dlc, demo, update, patch, mod, translation, prototype)\n\nReturns:\n Response: txt file with PKGi PSP database format","operationId":"pkgi_psp_feed_api_feeds_pkgi_psp__content_type__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"content_type","in":"path","required":true,"schema":{"type":"string","description":"Content type","title":"Content Type"},"description":"Content type"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/feeds/fpkgi/{platform_slug}":{"get":{"tags":["feeds"],"summary":"Fpkgi Feed","description":"https://github.com/ItsJokerZz/FPKGi\n\nArgs:\n request (Request): Fastapi Request object\n platform_slug (str): Platform slug (ps4, ps5)\n\nReturns:\n Response: JSON file in FPKGi format","operationId":"fpkgi_feed_api_feeds_fpkgi__platform_slug__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"platform_slug","in":"path","required":true,"schema":{"type":"string","title":"Platform Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/feeds/kekatsu/{platform_slug}":{"get":{"tags":["feeds"],"summary":"Kekatsu Ds Feed","description":"Get Kekatsu DS feed endpoint\nhttps://github.com/cavv-dev/Kekatsu-DS\n\nArgs:\n request (Request): Fastapi Request object\n platform_slug (str): Platform slug (nds, nintendo-ds, ds, gba, etc.)\n\nReturns:\n Response: Text file with Kekatsu DS database format","operationId":"kekatsu_ds_feed_api_feeds_kekatsu__platform_slug__get","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"platform_slug","in":"path","required":true,"schema":{"type":"string","title":"Platform Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/config":{"get":{"tags":["config"],"summary":"Get Config","description":"Get config endpoint\n\nReturns:\n ConfigResponse: RomM's configuration","operationId":"get_config_api_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigResponse"}}}}}}},"/api/config/system/platforms":{"post":{"tags":["config"],"summary":"Add Platform Binding","description":"Add platform binding to the configuration","operationId":"add_platform_binding_api_config_system_platforms_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}]}},"/api/config/system/platforms/{fs_slug}":{"delete":{"tags":["config"],"summary":"Delete Platform Binding","description":"Delete platform binding from the configuration","operationId":"delete_platform_binding_api_config_system_platforms__fs_slug__delete","security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"fs_slug","in":"path","required":true,"schema":{"type":"string","title":"Fs Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/config/system/versions":{"post":{"tags":["config"],"summary":"Add Platform Version","description":"Add platform version to the configuration","operationId":"add_platform_version_api_config_system_versions_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}]}},"/api/config/system/versions/{fs_slug}":{"delete":{"tags":["config"],"summary":"Delete Platform Version","description":"Delete platform version from the configuration","operationId":"delete_platform_version_api_config_system_versions__fs_slug__delete","security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"fs_slug","in":"path","required":true,"schema":{"type":"string","title":"Fs Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/config/exclude":{"post":{"tags":["config"],"summary":"Add Exclusion","description":"Add platform exclusion to the configuration","operationId":"add_exclusion_api_config_exclude_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}]}},"/api/config/exclude/{exclusion_type}/{exclusion_value}":{"delete":{"tags":["config"],"summary":"Delete Exclusion","description":"Delete platform binding from the configuration","operationId":"delete_exclusion_api_config_exclude__exclusion_type___exclusion_value__delete","security":[{"OAuth2PasswordBearer":["platforms.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"exclusion_type","in":"path","required":true,"schema":{"type":"string","title":"Exclusion Type"}},{"name":"exclusion_value","in":"path","required":true,"schema":{"type":"string","title":"Exclusion Value"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stats":{"get":{"tags":["stats"],"summary":"Stats","description":"Endpoint to return the current RomM stats\n\nReturns:\n dict: Dictionary with all the stats","operationId":"stats_api_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsReturn"}}}}}}},"/api/raw/assets/{path}":{"head":{"tags":["raw"],"summary":"Head Raw Asset","operationId":"head_raw_asset_api_raw_assets__path__head","security":[{"OAuth2PasswordBearer":["assets.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["raw"],"summary":"Get Raw Asset","description":"Download a single asset file\n\nArgs:\n request (Request): Fastapi Request object\n path (str): Relative path to the asset file\n\nReturns:\n FileResponse: Returns a single asset file\n\nRaises:\n HTTPException: 404 if asset not found or access denied","operationId":"get_raw_asset_api_raw_assets__path__get","security":[{"OAuth2PasswordBearer":["assets.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/screenshots":{"post":{"tags":["screenshots"],"summary":"Add Screenshot","operationId":"add_screenshot_api_screenshots_post","security":[{"OAuth2PasswordBearer":["assets.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"rom_id","in":"query","required":true,"schema":{"type":"integer","title":"Rom Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScreenshotSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/firmware":{"post":{"tags":["firmware"],"summary":"Add Firmware","description":"Upload firmware files endpoint\n\nArgs:\n request (Request): Fastapi Request object\n platform_slug (str): Slug of the platform where to upload the files\n files (list[UploadFile], optional): List of files to upload\n\nRaises:\n HTTPException\n\nReturns:\n AddFirmwareResponse: Standard message response","operationId":"add_firmware_api_firmware_post","security":[{"OAuth2PasswordBearer":["firmware.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"platform_id","in":"query","required":true,"schema":{"type":"integer","title":"Platform Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_add_firmware_api_firmware_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddFirmwareResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["firmware"],"summary":"Get Platform Firmware","description":"Get firmware endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n list[FirmwareSchema]: Firmware stored in the database","operationId":"get_platform_firmware_api_firmware_get","security":[{"OAuth2PasswordBearer":["firmware.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"platform_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Platform Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FirmwareSchema"},"title":"Response Get Platform Firmware Api Firmware Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/firmware/{id}":{"get":{"tags":["firmware"],"summary":"Get Firmware","description":"Get firmware endpoint\n\nArgs:\n request (Request): Fastapi Request object\n id (int): Firmware internal id\n\nReturns:\n FirmwareSchema: Firmware stored in the database","operationId":"get_firmware_api_firmware__id__get","security":[{"OAuth2PasswordBearer":["firmware.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirmwareSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/firmware/{id}/content/{file_name}":{"head":{"tags":["firmware"],"summary":"Head Firmware Content","description":"Head firmware content endpoint\n\nArgs:\n request (Request): Fastapi Request object\n id (int): Rom internal id\n file_name (str): Required due to a bug in emulatorjs\n\nReturns:\n FileResponse: Returns the response with headers","operationId":"head_firmware_content_api_firmware__id__content__file_name__head","security":[{"OAuth2PasswordBearer":["firmware.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"file_name","in":"path","required":true,"schema":{"type":"string","title":"File Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["firmware"],"summary":"Get Firmware Content","description":"Download firmware endpoint\n\nArgs:\n request (Request): Fastapi Request object\n id (int): Rom internal id\n file_name (str): Required due to a bug in emulatorjs\n\nReturns:\n FileResponse: Returns the firmware file","operationId":"get_firmware_content_api_firmware__id__content__file_name__get","security":[{"OAuth2PasswordBearer":["firmware.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"file_name","in":"path","required":true,"schema":{"type":"string","title":"File Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/firmware/delete":{"post":{"tags":["firmware"],"summary":"Delete Firmware","description":"Delete firmware.","operationId":"delete_firmware_api_firmware_delete_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_delete_firmware_api_firmware_delete_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkOperationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"OAuth2PasswordBearer":["firmware.write"]},{"HTTPBasic":[]}]}},"/api/collections":{"post":{"tags":["collections"],"summary":"Add Collection","description":"Create collection endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n CollectionSchema: Just created collection","operationId":"add_collection_api_collections_post","security":[{"OAuth2PasswordBearer":["collections.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"is_public","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"}},{"name":"is_favorite","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Favorite"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_add_collection_api_collections_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["collections"],"summary":"Get Collections","description":"Get collections endpoint\n\nArgs:\n request (Request): Fastapi Request object\n updated_after: Filter collections updated after this datetime\n\nReturns:\n list[CollectionSchema]: List of collections","operationId":"get_collections_api_collections_get","security":[{"OAuth2PasswordBearer":["collections.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"updated_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter collections updated after this datetime (ISO 8601 format with timezone information).","title":"Updated After"},"description":"Filter collections updated after this datetime (ISO 8601 format with timezone information)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CollectionSchema"},"title":"Response Get Collections Api Collections Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/collections/smart":{"post":{"tags":["collections"],"summary":"Add Smart Collection","description":"Create smart collection endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n SmartCollectionSchema: Just created smart collection","operationId":"add_smart_collection_api_collections_smart_post","security":[{"OAuth2PasswordBearer":["collections.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"is_public","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartCollectionSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["collections"],"summary":"Get Smart Collections","description":"Get smart collections endpoint\n\nArgs:\n request (Request): Fastapi Request object\n updated_after: Filter smart collections updated after this datetime\n\nReturns:\n list[SmartCollectionSchema]: List of smart collections","operationId":"get_smart_collections_api_collections_smart_get","security":[{"OAuth2PasswordBearer":["collections.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"updated_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Filter smart collections updated after this datetime (ISO 8601 format with timezone information).","title":"Updated After"},"description":"Filter smart collections updated after this datetime (ISO 8601 format with timezone information)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SmartCollectionSchema"},"title":"Response Get Smart Collections Api Collections Smart Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/collections/virtual":{"get":{"tags":["collections"],"summary":"Get Virtual Collections","description":"Get virtual collections endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n list[VirtualCollectionSchema]: List of virtual collections","operationId":"get_virtual_collections_api_collections_virtual_get","security":[{"OAuth2PasswordBearer":["collections.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"type","in":"query","required":true,"schema":{"type":"string","title":"Type"}},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/VirtualCollectionSchema"},"title":"Response Get Virtual Collections Api Collections Virtual Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/collections/{id}":{"get":{"tags":["collections"],"summary":"Get Collection","description":"Get collections endpoint\n\nArgs:\n request (Request): Fastapi Request object\n id (int, optional): Collection id. Defaults to None.\n\nReturns:\n CollectionSchema: Collection","operationId":"get_collection_api_collections__id__get","security":[{"OAuth2PasswordBearer":["collections.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["collections"],"summary":"Update Collection","description":"Update collection endpoint\n\nArgs:\n request (Request): Fastapi Request object\n\nReturns:\n CollectionSchema: Updated collection","operationId":"update_collection_api_collections__id__put","security":[{"OAuth2PasswordBearer":["collections.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"remove_cover","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Remove Cover"}},{"name":"is_public","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_update_collection_api_collections__id__put"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["collections"],"summary":"Delete Collection","description":"Delete a collection by ID.","operationId":"delete_collection_api_collections__id__delete","security":[{"OAuth2PasswordBearer":["collections.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Collection internal id.","title":"Id"},"description":"Collection internal id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/collections/virtual/{id}":{"get":{"tags":["collections"],"summary":"Get Virtual Collection","description":"Get virtual collections endpoint\n\nArgs:\n request (Request): Fastapi Request object\n id (str): Virtual collection id\n\nReturns:\n VirtualCollectionSchema: Virtual collection","operationId":"get_virtual_collection_api_collections_virtual__id__get","security":[{"OAuth2PasswordBearer":["collections.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VirtualCollectionSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/collections/smart/{id}":{"get":{"tags":["collections"],"summary":"Get Smart Collection","description":"Get smart collection endpoint\n\nArgs:\n request (Request): Fastapi Request object\n id (int): Smart collection id\n\nReturns:\n SmartCollectionSchema: Smart collection","operationId":"get_smart_collection_api_collections_smart__id__get","security":[{"OAuth2PasswordBearer":["collections.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartCollectionSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["collections"],"summary":"Update Smart Collection","description":"Update smart collection endpoint\n\nArgs:\n request (Request): Fastapi Request object\n id (int): Smart collection id\n\nReturns:\n SmartCollectionSchema: Updated smart collection","operationId":"update_smart_collection_api_collections_smart__id__put","security":[{"OAuth2PasswordBearer":["collections.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","title":"Id"}},{"name":"is_public","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Public"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SmartCollectionSchema"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["collections"],"summary":"Delete Smart Collection","description":"Delete a smart collection by ID.","operationId":"delete_smart_collection_api_collections_smart__id__delete","security":[{"OAuth2PasswordBearer":["collections.write"]},{"HTTPBasic":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Smart collection internal id.","title":"Id"},"description":"Smart collection internal id."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/gamelist/export":{"post":{"tags":["gamelist"],"summary":"Export Gamelist","description":"Export platforms/ROMs to gamelist.xml format and write to platform directories","operationId":"export_gamelist_api_gamelist_export_post","security":[{"OAuth2PasswordBearer":["roms.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"platform_ids","in":"query","required":true,"schema":{"type":"array","items":{"type":"integer"},"description":"List of platform IDs to export","title":"Platform Ids"},"description":"List of platform IDs to export"},{"name":"local_export","in":"query","required":false,"schema":{"type":"boolean","description":"Use local paths instead of URLs","default":false,"title":"Local Export"},"description":"Use local paths instead of URLs"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/netplay/list":{"get":{"tags":["netplay"],"summary":"Get Rooms","operationId":"get_rooms_api_netplay_list_get","security":[{"OAuth2PasswordBearer":["assets.read"]},{"HTTPBasic":[]}],"parameters":[{"name":"game_id","in":"query","required":true,"schema":{"type":"string","title":"Game Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/RoomsResponse"},"title":"Response Get Rooms Api Netplay List Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AddFirmwareResponse":{"properties":{"uploaded":{"type":"integer","title":"Uploaded"},"firmware":{"items":{"$ref":"#/components/schemas/FirmwareSchema"},"type":"array","title":"Firmware"}},"type":"object","required":["uploaded","firmware"],"title":"AddFirmwareResponse"},"Body_add_collection_api_collections_post":{"properties":{"artwork":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Artwork"}},"type":"object","title":"Body_add_collection_api_collections_post"},"Body_add_firmware_api_firmware_post":{"properties":{"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files"}},"type":"object","required":["files"],"title":"Body_add_firmware_api_firmware_post"},"Body_add_platform_api_platforms_post":{"properties":{"fs_slug":{"type":"string","title":"Fs Slug","description":"Platform slug."}},"type":"object","required":["fs_slug"],"title":"Body_add_platform_api_platforms_post"},"Body_add_user_api_users_post":{"properties":{"username":{"type":"string","title":"Username"},"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"},"role":{"type":"string","title":"Role"}},"type":"object","required":["username","email","password","role"],"title":"Body_add_user_api_users_post"},"Body_create_user_from_invite_api_users_register_post":{"properties":{"username":{"type":"string","title":"Username"},"email":{"type":"string","title":"Email"},"password":{"type":"string","title":"Password"},"token":{"type":"string","title":"Token"}},"type":"object","required":["username","email","password","token"],"title":"Body_create_user_from_invite_api_users_register_post"},"Body_delete_firmware_api_firmware_delete_post":{"properties":{"firmware":{"items":{"type":"integer"},"type":"array","title":"Firmware","description":"List of firmware ids to delete from database."},"delete_from_fs":{"items":{"type":"integer"},"type":"array","title":"Delete From Fs","description":"List of firmware ids to delete from filesystem."}},"type":"object","required":["firmware"],"title":"Body_delete_firmware_api_firmware_delete_post"},"Body_delete_roms_api_roms_delete_post":{"properties":{"roms":{"items":{"type":"integer"},"type":"array","title":"Roms","description":"List of rom ids to delete from database."},"delete_from_fs":{"items":{"type":"integer"},"type":"array","title":"Delete From Fs","description":"List of rom ids to delete from filesystem."}},"type":"object","required":["roms"],"title":"Body_delete_roms_api_roms_delete_post"},"Body_delete_saves_api_saves_delete_post":{"properties":{"saves":{"items":{"type":"integer"},"type":"array","title":"Saves","description":"List of save ids to delete from database."}},"type":"object","required":["saves"],"title":"Body_delete_saves_api_saves_delete_post"},"Body_delete_states_api_states_delete_post":{"properties":{"states":{"items":{"type":"integer"},"type":"array","title":"States","description":"List of states ids to delete from database."}},"type":"object","required":["states"],"title":"Body_delete_states_api_states_delete_post"},"Body_refresh_retro_achievements_api_users__id__ra_refresh_post":{"properties":{"incremental":{"type":"boolean","title":"Incremental","description":"Whether to only retrieve RetroAchievements progression incrementally.","default":false}},"type":"object","title":"Body_refresh_retro_achievements_api_users__id__ra_refresh_post"},"Body_request_password_reset_api_forgot_password_post":{"properties":{"username":{"type":"string","title":"Username"}},"type":"object","required":["username"],"title":"Body_request_password_reset_api_forgot_password_post"},"Body_reset_password_api_reset_password_post":{"properties":{"token":{"type":"string","title":"Token"},"new_password":{"type":"string","title":"New Password"}},"type":"object","required":["token","new_password"],"title":"Body_reset_password_api_reset_password_post"},"Body_token_api_token_post":{"properties":{"grant_type":{"type":"string","title":"Grant Type","default":"password"},"scope":{"type":"string","title":"Scope","default":""},"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Password"},"client_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Id"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"}},"type":"object","title":"Body_token_api_token_post"},"Body_update_collection_api_collections__id__put":{"properties":{"artwork":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Artwork"}},"type":"object","title":"Body_update_collection_api_collections__id__put"},"Body_update_platform_api_platforms__id__put":{"properties":{"aspect_ratio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aspect Ratio","description":"Cover aspect ratio."},"custom_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Name","description":"Custom platform name."}},"type":"object","title":"Body_update_platform_api_platforms__id__put"},"Body_update_rom_api_roms__id__put":{"properties":{"artwork":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Artwork","description":"Custom artwork to set as cover."}},"type":"object","title":"Body_update_rom_api_roms__id__put"},"Body_update_rom_user_api_roms__id__props_put":{"properties":{"update_last_played":{"type":"boolean","title":"Update Last Played","description":"Whether to update the last played date.","default":false},"remove_last_played":{"type":"boolean","title":"Remove Last Played","description":"Whether to remove the last played date.","default":false}},"type":"object","title":"Body_update_rom_user_api_roms__id__props_put"},"BulkOperationResponse":{"properties":{"successful_items":{"type":"integer","title":"Successful Items"},"failed_items":{"type":"integer","title":"Failed Items"},"errors":{"items":{"type":"string"},"type":"array","title":"Errors"}},"type":"object","required":["successful_items","failed_items","errors"],"title":"BulkOperationResponse"},"CleanupStats":{"properties":{"platforms_in_db":{"type":"integer","title":"Platforms In Db"},"roms_in_db":{"type":"integer","title":"Roms In Db"},"platforms_in_fs":{"type":"integer","title":"Platforms In Fs"},"roms_in_fs":{"type":"integer","title":"Roms In Fs"},"removed_fs_platforms":{"type":"integer","title":"Removed Fs Platforms"},"removed_fs_roms":{"type":"integer","title":"Removed Fs Roms"}},"type":"object","required":["platforms_in_db","roms_in_db","platforms_in_fs","roms_in_fs","removed_fs_platforms","removed_fs_roms"],"title":"CleanupStats"},"CleanupTaskMeta":{"properties":{"cleanup_stats":{"anyOf":[{"$ref":"#/components/schemas/CleanupStats"},{"type":"null"}]}},"type":"object","required":["cleanup_stats"],"title":"CleanupTaskMeta"},"CleanupTaskStatusResponse":{"properties":{"task_name":{"type":"string","title":"Task Name"},"task_id":{"type":"string","title":"Task Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"enqueued_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enqueued At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ended At"},"task_type":{"type":"string","const":"cleanup","title":"Task Type"},"meta":{"$ref":"#/components/schemas/CleanupTaskMeta"}},"type":"object","required":["task_name","task_id","status","created_at","enqueued_at","started_at","ended_at","task_type","meta"],"title":"CleanupTaskStatusResponse"},"CollectionSchema":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"rom_ids":{"items":{"type":"integer"},"type":"array","uniqueItems":true,"title":"Rom Ids"},"rom_count":{"type":"integer","title":"Rom Count"},"path_cover_small":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Small"},"path_cover_large":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Large"},"path_covers_small":{"items":{"type":"string"},"type":"array","title":"Path Covers Small"},"path_covers_large":{"items":{"type":"string"},"type":"array","title":"Path Covers Large"},"is_public":{"type":"boolean","title":"Is Public","default":false},"is_favorite":{"type":"boolean","title":"Is Favorite","default":false},"is_virtual":{"type":"boolean","title":"Is Virtual","default":false},"is_smart":{"type":"boolean","title":"Is Smart","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"id":{"type":"integer","title":"Id"},"url_cover":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Cover"},"user_id":{"type":"integer","title":"User Id"},"user__username":{"type":"string","title":"User Username"}},"type":"object","required":["name","description","rom_ids","rom_count","path_cover_small","path_cover_large","path_covers_small","path_covers_large","created_at","updated_at","id","url_cover","user_id","user__username"],"title":"CollectionSchema"},"ConfigResponse":{"properties":{"CONFIG_FILE_MOUNTED":{"type":"boolean","title":"Config File Mounted"},"CONFIG_FILE_WRITABLE":{"type":"boolean","title":"Config File Writable"},"EXCLUDED_PLATFORMS":{"items":{"type":"string"},"type":"array","title":"Excluded Platforms"},"EXCLUDED_SINGLE_EXT":{"items":{"type":"string"},"type":"array","title":"Excluded Single Ext"},"EXCLUDED_SINGLE_FILES":{"items":{"type":"string"},"type":"array","title":"Excluded Single Files"},"EXCLUDED_MULTI_FILES":{"items":{"type":"string"},"type":"array","title":"Excluded Multi Files"},"EXCLUDED_MULTI_PARTS_EXT":{"items":{"type":"string"},"type":"array","title":"Excluded Multi Parts Ext"},"EXCLUDED_MULTI_PARTS_FILES":{"items":{"type":"string"},"type":"array","title":"Excluded Multi Parts Files"},"PLATFORMS_BINDING":{"additionalProperties":{"type":"string"},"type":"object","title":"Platforms Binding"},"PLATFORMS_VERSIONS":{"additionalProperties":{"type":"string"},"type":"object","title":"Platforms Versions"},"SKIP_HASH_CALCULATION":{"type":"boolean","title":"Skip Hash Calculation"},"EJS_DEBUG":{"type":"boolean","title":"Ejs Debug"},"EJS_CACHE_LIMIT":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ejs Cache Limit"},"EJS_DISABLE_AUTO_UNLOAD":{"type":"boolean","title":"Ejs Disable Auto Unload"},"EJS_DISABLE_BATCH_BOOTUP":{"type":"boolean","title":"Ejs Disable Batch Bootup"},"EJS_NETPLAY_ENABLED":{"type":"boolean","title":"Ejs Netplay Enabled"},"EJS_NETPLAY_ICE_SERVERS":{"items":{"$ref":"#/components/schemas/NetplayICEServer"},"type":"array","title":"Ejs Netplay Ice Servers"},"EJS_SETTINGS":{"additionalProperties":{"additionalProperties":{"type":"string"},"type":"object"},"type":"object","title":"Ejs Settings"},"EJS_CONTROLS":{"additionalProperties":{"$ref":"#/components/schemas/EjsControls"},"type":"object","title":"Ejs Controls"},"SCAN_METADATA_PRIORITY":{"items":{"type":"string"},"type":"array","title":"Scan Metadata Priority"},"SCAN_ARTWORK_PRIORITY":{"items":{"type":"string"},"type":"array","title":"Scan Artwork Priority"},"SCAN_REGION_PRIORITY":{"items":{"type":"string"},"type":"array","title":"Scan Region Priority"},"SCAN_LANGUAGE_PRIORITY":{"items":{"type":"string"},"type":"array","title":"Scan Language Priority"},"SCAN_MEDIA":{"items":{"type":"string"},"type":"array","title":"Scan Media"}},"type":"object","required":["CONFIG_FILE_MOUNTED","CONFIG_FILE_WRITABLE","EXCLUDED_PLATFORMS","EXCLUDED_SINGLE_EXT","EXCLUDED_SINGLE_FILES","EXCLUDED_MULTI_FILES","EXCLUDED_MULTI_PARTS_EXT","EXCLUDED_MULTI_PARTS_FILES","PLATFORMS_BINDING","PLATFORMS_VERSIONS","SKIP_HASH_CALCULATION","EJS_DEBUG","EJS_CACHE_LIMIT","EJS_DISABLE_AUTO_UNLOAD","EJS_DISABLE_BATCH_BOOTUP","EJS_NETPLAY_ENABLED","EJS_NETPLAY_ICE_SERVERS","EJS_SETTINGS","EJS_CONTROLS","SCAN_METADATA_PRIORITY","SCAN_ARTWORK_PRIORITY","SCAN_REGION_PRIORITY","SCAN_LANGUAGE_PRIORITY","SCAN_MEDIA"],"title":"ConfigResponse"},"ConversionStats":{"properties":{"processed":{"type":"integer","title":"Processed"},"errors":{"type":"integer","title":"Errors"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["processed","errors","total"],"title":"ConversionStats"},"ConversionTaskMeta":{"properties":{"conversion_stats":{"anyOf":[{"$ref":"#/components/schemas/ConversionStats"},{"type":"null"}]}},"type":"object","required":["conversion_stats"],"title":"ConversionTaskMeta"},"ConversionTaskStatusResponse":{"properties":{"task_name":{"type":"string","title":"Task Name"},"task_id":{"type":"string","title":"Task Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"enqueued_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enqueued At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ended At"},"task_type":{"type":"string","const":"conversion","title":"Task Type"},"meta":{"$ref":"#/components/schemas/ConversionTaskMeta"}},"type":"object","required":["task_name","task_id","status","created_at","enqueued_at","started_at","ended_at","task_type","meta"],"title":"ConversionTaskStatusResponse"},"CustomLimitOffsetPage_SimpleRomSchema_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/SimpleRomSchema"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0.0,"title":"Total"},"limit":{"type":"integer","minimum":1.0,"title":"Limit"},"offset":{"type":"integer","minimum":0.0,"title":"Offset"},"char_index":{"additionalProperties":{"type":"integer"},"type":"object","title":"Char Index"},"rom_id_index":{"items":{"type":"integer"},"type":"array","title":"Rom Id Index"},"filter_values":{"$ref":"#/components/schemas/RomFiltersDict"}},"type":"object","required":["items","total","limit","offset","char_index","rom_id_index","filter_values"],"title":"CustomLimitOffsetPage[SimpleRomSchema]"},"DetailedRomSchema":{"properties":{"id":{"type":"integer","title":"Id"},"igdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Igdb Id"},"sgdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sgdb Id"},"moby_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Moby Id"},"ss_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ss Id"},"ra_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ra Id"},"launchbox_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Launchbox Id"},"hasheous_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hasheous Id"},"tgdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tgdb Id"},"flashpoint_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flashpoint Id"},"hltb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hltb Id"},"gamelist_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gamelist Id"},"platform_id":{"type":"integer","title":"Platform Id"},"platform_slug":{"type":"string","title":"Platform Slug"},"platform_fs_slug":{"type":"string","title":"Platform Fs Slug"},"platform_custom_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Custom Name"},"platform_display_name":{"type":"string","title":"Platform Display Name"},"fs_name":{"type":"string","title":"Fs Name"},"fs_name_no_tags":{"type":"string","title":"Fs Name No Tags"},"fs_name_no_ext":{"type":"string","title":"Fs Name No Ext"},"fs_extension":{"type":"string","title":"Fs Extension"},"fs_path":{"type":"string","title":"Fs Path"},"fs_size_bytes":{"type":"integer","title":"Fs Size Bytes"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"alternative_names":{"items":{"type":"string"},"type":"array","title":"Alternative Names"},"youtube_video_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Youtube Video Id"},"metadatum":{"$ref":"#/components/schemas/RomMetadataSchema"},"igdb_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomIGDBMetadata"},{"type":"null"}]},"moby_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomMobyMetadata"},{"type":"null"}]},"ss_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomSSMetadata"},{"type":"null"}]},"launchbox_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomLaunchboxMetadata"},{"type":"null"}]},"hasheous_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomHasheousMetadata"},{"type":"null"}]},"flashpoint_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomFlashpointMetadata"},{"type":"null"}]},"hltb_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomHLTBMetadata"},{"type":"null"}]},"gamelist_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomGamelistMetadata"},{"type":"null"}]},"manual_metadata":{"anyOf":[{"$ref":"#/components/schemas/ManualMetadata"},{"type":"null"}]},"path_cover_small":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Small"},"path_cover_large":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Large"},"url_cover":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Cover"},"has_manual":{"type":"boolean","title":"Has Manual"},"path_manual":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Manual"},"url_manual":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Manual"},"is_identifying":{"type":"boolean","title":"Is Identifying","default":false},"is_unidentified":{"type":"boolean","title":"Is Unidentified"},"is_identified":{"type":"boolean","title":"Is Identified"},"revision":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revision"},"regions":{"items":{"type":"string"},"type":"array","title":"Regions"},"languages":{"items":{"type":"string"},"type":"array","title":"Languages"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"crc_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Crc Hash"},"md5_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Md5 Hash"},"sha1_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sha1 Hash"},"has_simple_single_file":{"type":"boolean","title":"Has Simple Single File"},"has_nested_single_file":{"type":"boolean","title":"Has Nested Single File"},"has_multiple_files":{"type":"boolean","title":"Has Multiple Files"},"files":{"items":{"$ref":"#/components/schemas/RomFileSchema"},"type":"array","title":"Files"},"full_path":{"type":"string","title":"Full Path"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"missing_from_fs":{"type":"boolean","title":"Missing From Fs"},"has_notes":{"type":"boolean","title":"Has Notes"},"siblings":{"items":{"$ref":"#/components/schemas/SiblingRomSchema"},"type":"array","title":"Siblings"},"rom_user":{"$ref":"#/components/schemas/RomUserSchema"},"merged_screenshots":{"items":{"type":"string"},"type":"array","title":"Merged Screenshots"},"merged_ra_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomRAMetadata"},{"type":"null"}]},"user_saves":{"items":{"$ref":"#/components/schemas/SaveSchema"},"type":"array","title":"User Saves"},"user_states":{"items":{"$ref":"#/components/schemas/StateSchema"},"type":"array","title":"User States"},"user_screenshots":{"items":{"$ref":"#/components/schemas/ScreenshotSchema"},"type":"array","title":"User Screenshots"},"user_collections":{"items":{"$ref":"#/components/schemas/UserCollectionSchema"},"type":"array","title":"User Collections"},"all_user_notes":{"items":{"$ref":"#/components/schemas/UserNoteSchema"},"type":"array","title":"All User Notes"}},"type":"object","required":["id","igdb_id","sgdb_id","moby_id","ss_id","ra_id","launchbox_id","hasheous_id","tgdb_id","flashpoint_id","hltb_id","gamelist_id","platform_id","platform_slug","platform_fs_slug","platform_custom_name","platform_display_name","fs_name","fs_name_no_tags","fs_name_no_ext","fs_extension","fs_path","fs_size_bytes","name","slug","summary","alternative_names","youtube_video_id","metadatum","igdb_metadata","moby_metadata","ss_metadata","launchbox_metadata","hasheous_metadata","flashpoint_metadata","hltb_metadata","gamelist_metadata","manual_metadata","path_cover_small","path_cover_large","url_cover","has_manual","path_manual","url_manual","is_unidentified","is_identified","revision","regions","languages","tags","crc_hash","md5_hash","sha1_hash","has_simple_single_file","has_nested_single_file","has_multiple_files","files","full_path","created_at","updated_at","missing_from_fs","has_notes","siblings","rom_user","merged_screenshots","merged_ra_metadata","user_saves","user_states","user_screenshots","user_collections","all_user_notes"],"title":"DetailedRomSchema"},"EarnedAchievement":{"properties":{"id":{"type":"string","title":"Id"},"date":{"type":"string","title":"Date"},"date_hardcore":{"type":"string","title":"Date Hardcore"}},"type":"object","required":["id","date"],"title":"EarnedAchievement"},"EjsControls":{"properties":{"_0":{"additionalProperties":{"$ref":"#/components/schemas/EjsControlsButton"},"type":"object","title":"0"},"_1":{"additionalProperties":{"$ref":"#/components/schemas/EjsControlsButton"},"type":"object","title":"1"},"_2":{"additionalProperties":{"$ref":"#/components/schemas/EjsControlsButton"},"type":"object","title":"2"},"_3":{"additionalProperties":{"$ref":"#/components/schemas/EjsControlsButton"},"type":"object","title":"3"}},"type":"object","required":["_0","_1","_2","_3"],"title":"EjsControls"},"EjsControlsButton":{"properties":{"value":{"type":"string","title":"Value"},"value2":{"type":"string","title":"Value2"}},"type":"object","title":"EjsControlsButton"},"EmulationDict":{"properties":{"DISABLE_EMULATOR_JS":{"type":"boolean","title":"Disable Emulator Js"},"DISABLE_RUFFLE_RS":{"type":"boolean","title":"Disable Ruffle Rs"}},"type":"object","required":["DISABLE_EMULATOR_JS","DISABLE_RUFFLE_RS"],"title":"EmulationDict"},"FilesystemDict":{"properties":{"FS_PLATFORMS":{"items":{"type":"string"},"type":"array","title":"Fs Platforms"}},"type":"object","required":["FS_PLATFORMS"],"title":"FilesystemDict"},"FirmwareSchema":{"properties":{"id":{"type":"integer","title":"Id"},"file_name":{"type":"string","title":"File Name"},"file_name_no_tags":{"type":"string","title":"File Name No Tags"},"file_name_no_ext":{"type":"string","title":"File Name No Ext"},"file_extension":{"type":"string","title":"File Extension"},"file_path":{"type":"string","title":"File Path"},"file_size_bytes":{"type":"integer","title":"File Size Bytes"},"full_path":{"type":"string","title":"Full Path"},"is_verified":{"type":"boolean","title":"Is Verified"},"crc_hash":{"type":"string","title":"Crc Hash"},"md5_hash":{"type":"string","title":"Md5 Hash"},"sha1_hash":{"type":"string","title":"Sha1 Hash"},"missing_from_fs":{"type":"boolean","title":"Missing From Fs"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","file_name","file_name_no_tags","file_name_no_ext","file_extension","file_path","file_size_bytes","full_path","is_verified","crc_hash","md5_hash","sha1_hash","missing_from_fs","created_at","updated_at"],"title":"FirmwareSchema"},"FrontendDict":{"properties":{"UPLOAD_TIMEOUT":{"type":"integer","title":"Upload Timeout"},"DISABLE_USERPASS_LOGIN":{"type":"boolean","title":"Disable Userpass Login"},"YOUTUBE_BASE_URL":{"type":"string","title":"Youtube Base Url"}},"type":"object","required":["UPLOAD_TIMEOUT","DISABLE_USERPASS_LOGIN","YOUTUBE_BASE_URL"],"title":"FrontendDict"},"GenericTaskMeta":{"properties":{},"type":"object","title":"GenericTaskMeta"},"GenericTaskStatusResponse":{"properties":{"task_name":{"type":"string","title":"Task Name"},"task_id":{"type":"string","title":"Task Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"enqueued_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enqueued At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ended At"},"task_type":{"type":"string","const":"generic","title":"Task Type"},"meta":{"$ref":"#/components/schemas/GenericTaskMeta"}},"type":"object","required":["task_name","task_id","status","created_at","enqueued_at","started_at","ended_at","task_type","meta"],"title":"GenericTaskStatusResponse"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HeartbeatResponse":{"properties":{"SYSTEM":{"$ref":"#/components/schemas/SystemDict"},"METADATA_SOURCES":{"$ref":"#/components/schemas/MetadataSourcesDict"},"FILESYSTEM":{"$ref":"#/components/schemas/FilesystemDict"},"EMULATION":{"$ref":"#/components/schemas/EmulationDict"},"FRONTEND":{"$ref":"#/components/schemas/FrontendDict"},"OIDC":{"$ref":"#/components/schemas/OIDCDict"},"TASKS":{"$ref":"#/components/schemas/TasksDict"}},"type":"object","required":["SYSTEM","METADATA_SOURCES","FILESYSTEM","EMULATION","FRONTEND","OIDC","TASKS"],"title":"HeartbeatResponse"},"IGDBAgeRating":{"properties":{"rating":{"type":"string","title":"Rating"},"category":{"type":"string","title":"Category"},"rating_cover_url":{"type":"string","title":"Rating Cover Url"}},"type":"object","required":["rating","category","rating_cover_url"],"title":"IGDBAgeRating"},"IGDBMetadataMultiplayerMode":{"properties":{"campaigncoop":{"type":"boolean","title":"Campaigncoop"},"dropin":{"type":"boolean","title":"Dropin"},"lancoop":{"type":"boolean","title":"Lancoop"},"offlinecoop":{"type":"boolean","title":"Offlinecoop"},"offlinecoopmax":{"type":"integer","title":"Offlinecoopmax"},"offlinemax":{"type":"integer","title":"Offlinemax"},"onlinecoop":{"type":"integer","title":"Onlinecoop"},"onlinecoopmax":{"type":"integer","title":"Onlinecoopmax"},"onlinemax":{"type":"integer","title":"Onlinemax"},"splitscreen":{"type":"boolean","title":"Splitscreen"},"splitscreenonline":{"type":"boolean","title":"Splitscreenonline"},"platform":{"$ref":"#/components/schemas/IGDBMetadataPlatform"}},"type":"object","required":["campaigncoop","dropin","lancoop","offlinecoop","offlinecoopmax","offlinemax","onlinecoop","onlinecoopmax","onlinemax","splitscreen","splitscreenonline","platform"],"title":"IGDBMetadataMultiplayerMode"},"IGDBMetadataPlatform":{"properties":{"igdb_id":{"type":"integer","title":"Igdb Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["igdb_id","name"],"title":"IGDBMetadataPlatform"},"IGDBRelatedGame":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug"},"type":{"type":"string","title":"Type"},"cover_url":{"type":"string","title":"Cover Url"}},"type":"object","required":["id","name","slug","type","cover_url"],"title":"IGDBRelatedGame"},"InviteLinkSchema":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"InviteLinkSchema"},"JobStatus":{"type":"string","enum":["queued","finished","failed","started","deferred","scheduled","stopped","canceled"],"title":"JobStatus","description":"The Status of Job within its lifecycle at any given time."},"LaunchboxImage":{"properties":{"url":{"type":"string","title":"Url"},"type":{"type":"string","title":"Type"},"region":{"type":"string","title":"Region"}},"type":"object","required":["url"],"title":"LaunchboxImage"},"ManualMetadata":{"properties":{"genres":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Genres"},"franchises":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Franchises"},"companies":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Companies"},"game_modes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Game Modes"},"age_ratings":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Age Ratings"},"first_release_date":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"First Release Date"},"youtube_video_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Youtube Video Id"}},"type":"object","title":"ManualMetadata"},"MetadataSourcesDict":{"properties":{"ANY_SOURCE_ENABLED":{"type":"boolean","title":"Any Source Enabled"},"IGDB_API_ENABLED":{"type":"boolean","title":"Igdb Api Enabled"},"SS_API_ENABLED":{"type":"boolean","title":"Ss Api Enabled"},"MOBY_API_ENABLED":{"type":"boolean","title":"Moby Api Enabled"},"STEAMGRIDDB_API_ENABLED":{"type":"boolean","title":"Steamgriddb Api Enabled"},"RA_API_ENABLED":{"type":"boolean","title":"Ra Api Enabled"},"LAUNCHBOX_API_ENABLED":{"type":"boolean","title":"Launchbox Api Enabled"},"HASHEOUS_API_ENABLED":{"type":"boolean","title":"Hasheous Api Enabled"},"PLAYMATCH_API_ENABLED":{"type":"boolean","title":"Playmatch Api Enabled"},"TGDB_API_ENABLED":{"type":"boolean","title":"Tgdb Api Enabled"},"FLASHPOINT_API_ENABLED":{"type":"boolean","title":"Flashpoint Api Enabled"},"HLTB_API_ENABLED":{"type":"boolean","title":"Hltb Api Enabled"}},"type":"object","required":["ANY_SOURCE_ENABLED","IGDB_API_ENABLED","SS_API_ENABLED","MOBY_API_ENABLED","STEAMGRIDDB_API_ENABLED","RA_API_ENABLED","LAUNCHBOX_API_ENABLED","HASHEOUS_API_ENABLED","PLAYMATCH_API_ENABLED","TGDB_API_ENABLED","FLASHPOINT_API_ENABLED","HLTB_API_ENABLED"],"title":"MetadataSourcesDict"},"MobyMetadataPlatform":{"properties":{"moby_id":{"type":"integer","title":"Moby Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["moby_id","name"],"title":"MobyMetadataPlatform"},"NetplayICEServer":{"properties":{"urls":{"type":"string","title":"Urls"},"username":{"type":"string","title":"Username"},"credential":{"type":"string","title":"Credential"}},"type":"object","required":["urls"],"title":"NetplayICEServer"},"OIDCDict":{"properties":{"ENABLED":{"type":"boolean","title":"Enabled"},"PROVIDER":{"type":"string","title":"Provider"}},"type":"object","required":["ENABLED","PROVIDER"],"title":"OIDCDict"},"PlatformSchema":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"fs_slug":{"type":"string","title":"Fs Slug"},"rom_count":{"type":"integer","title":"Rom Count"},"name":{"type":"string","title":"Name"},"igdb_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Igdb Slug"},"moby_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Moby Slug"},"hltb_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hltb Slug"},"custom_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Custom Name"},"igdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Igdb Id"},"sgdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sgdb Id"},"moby_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Moby Id"},"launchbox_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Launchbox Id"},"ss_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ss Id"},"ra_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ra Id"},"hasheous_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hasheous Id"},"tgdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tgdb Id"},"flashpoint_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Flashpoint Id"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"generation":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Generation"},"family_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family Name"},"family_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family Slug"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"url_logo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Logo"},"firmware":{"items":{"$ref":"#/components/schemas/FirmwareSchema"},"type":"array","title":"Firmware"},"aspect_ratio":{"type":"string","title":"Aspect Ratio","default":"2 / 3"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"fs_size_bytes":{"type":"integer","title":"Fs Size Bytes"},"is_unidentified":{"type":"boolean","title":"Is Unidentified"},"is_identified":{"type":"boolean","title":"Is Identified"},"missing_from_fs":{"type":"boolean","title":"Missing From Fs"},"display_name":{"type":"string","title":"Display Name","readOnly":true}},"type":"object","required":["id","slug","fs_slug","rom_count","name","igdb_slug","moby_slug","hltb_slug","created_at","updated_at","fs_size_bytes","is_unidentified","is_identified","missing_from_fs","display_name"],"title":"PlatformSchema"},"RAGameRomAchievement":{"properties":{"ra_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ra Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"points":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Points"},"num_awarded":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Num Awarded"},"num_awarded_hardcore":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Num Awarded Hardcore"},"badge_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Badge Id"},"badge_url_lock":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Badge Url Lock"},"badge_path_lock":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Badge Path Lock"},"badge_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Badge Url"},"badge_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Badge Path"},"display_order":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Display Order"},"type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type"}},"type":"object","required":["ra_id","title","description","points","num_awarded","num_awarded_hardcore","badge_id","badge_url_lock","badge_path_lock","badge_url","badge_path","display_order","type"],"title":"RAGameRomAchievement"},"RAProgression":{"properties":{"total":{"type":"integer","title":"Total"},"results":{"items":{"$ref":"#/components/schemas/RAUserGameProgression"},"type":"array","title":"Results"}},"type":"object","title":"RAProgression"},"RAUserGameProgression":{"properties":{"rom_ra_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rom Ra Id"},"max_possible":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Possible"},"num_awarded":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Num Awarded"},"num_awarded_hardcore":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Num Awarded Hardcore"},"most_recent_awarded_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Most Recent Awarded Date"},"earned_achievements":{"items":{"$ref":"#/components/schemas/EarnedAchievement"},"type":"array","title":"Earned Achievements"}},"type":"object","required":["rom_ra_id","max_possible","num_awarded","num_awarded_hardcore","earned_achievements"],"title":"RAUserGameProgression"},"Role":{"type":"string","enum":["viewer","editor","admin"],"title":"Role"},"RomFileCategory":{"type":"string","enum":["game","dlc","hack","manual","patch","update","mod","demo","translation","prototype","cheat"],"title":"RomFileCategory"},"RomFileSchema":{"properties":{"id":{"type":"integer","title":"Id"},"rom_id":{"type":"integer","title":"Rom Id"},"file_name":{"type":"string","title":"File Name"},"file_path":{"type":"string","title":"File Path"},"file_size_bytes":{"type":"integer","title":"File Size Bytes"},"full_path":{"type":"string","title":"Full Path"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"last_modified":{"type":"string","format":"date-time","title":"Last Modified"},"crc_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Crc Hash"},"md5_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Md5 Hash"},"sha1_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sha1 Hash"},"category":{"anyOf":[{"$ref":"#/components/schemas/RomFileCategory"},{"type":"null"}]}},"type":"object","required":["id","rom_id","file_name","file_path","file_size_bytes","full_path","created_at","updated_at","last_modified","crc_hash","md5_hash","sha1_hash","category"],"title":"RomFileSchema"},"RomFiltersDict":{"properties":{"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"franchises":{"items":{"type":"string"},"type":"array","title":"Franchises"},"collections":{"items":{"type":"string"},"type":"array","title":"Collections"},"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"game_modes":{"items":{"type":"string"},"type":"array","title":"Game Modes"},"age_ratings":{"items":{"type":"string"},"type":"array","title":"Age Ratings"},"player_counts":{"items":{"type":"string"},"type":"array","title":"Player Counts"},"regions":{"items":{"type":"string"},"type":"array","title":"Regions"},"languages":{"items":{"type":"string"},"type":"array","title":"Languages"},"platforms":{"items":{"type":"integer"},"type":"array","title":"Platforms"}},"type":"object","required":["genres","franchises","collections","companies","game_modes","age_ratings","player_counts","regions","languages","platforms"],"title":"RomFiltersDict"},"RomFlashpointMetadata":{"properties":{"franchises":{"items":{"type":"string"},"type":"array","title":"Franchises"},"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"first_release_date":{"type":"string","title":"First Release Date"},"game_modes":{"items":{"type":"string"},"type":"array","title":"Game Modes"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"RomFlashpointMetadata"},"RomGamelistMetadata":{"properties":{"box2d_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box2D Url"},"box2d_back_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box2D Back Url"},"box3d_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box3D Url"},"fanart_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fanart Url"},"image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image Url"},"manual_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manual Url"},"marquee_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marquee Url"},"miximage_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Miximage Url"},"physical_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Physical Url"},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url"},"thumbnail_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumbnail Url"},"title_screen_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title Screen Url"},"video_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Url"},"rating":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rating"},"first_release_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Release Date"},"companies":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Companies"},"franchises":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Franchises"},"genres":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Genres"},"player_count":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Player Count"},"md5_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Md5 Hash"},"box3d_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box3D Path"},"miximage_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Miximage Path"},"physical_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Physical Path"},"marquee_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marquee Path"},"video_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Path"}},"type":"object","title":"RomGamelistMetadata"},"RomHLTBMetadata":{"properties":{"main_story":{"type":"integer","title":"Main Story"},"main_story_count":{"type":"integer","title":"Main Story Count"},"main_plus_extra":{"type":"integer","title":"Main Plus Extra"},"main_plus_extra_count":{"type":"integer","title":"Main Plus Extra Count"},"completionist":{"type":"integer","title":"Completionist"},"completionist_count":{"type":"integer","title":"Completionist Count"},"all_styles":{"type":"integer","title":"All Styles"},"all_styles_count":{"type":"integer","title":"All Styles Count"},"release_year":{"type":"integer","title":"Release Year"},"review_score":{"type":"integer","title":"Review Score"},"review_count":{"type":"integer","title":"Review Count"},"popularity":{"type":"integer","title":"Popularity"},"completions":{"type":"integer","title":"Completions"}},"type":"object","title":"RomHLTBMetadata"},"RomHasheousMetadata":{"properties":{"tosec_match":{"type":"boolean","title":"Tosec Match"},"mame_arcade_match":{"type":"boolean","title":"Mame Arcade Match"},"mame_mess_match":{"type":"boolean","title":"Mame Mess Match"},"nointro_match":{"type":"boolean","title":"Nointro Match"},"redump_match":{"type":"boolean","title":"Redump Match"},"whdload_match":{"type":"boolean","title":"Whdload Match"},"ra_match":{"type":"boolean","title":"Ra Match"},"fbneo_match":{"type":"boolean","title":"Fbneo Match"},"puredos_match":{"type":"boolean","title":"Puredos Match"}},"type":"object","title":"RomHasheousMetadata"},"RomIGDBMetadata":{"properties":{"total_rating":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Total Rating"},"aggregated_rating":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Aggregated Rating"},"first_release_date":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"First Release Date"},"youtube_video_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Youtube Video Id"},"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"franchises":{"items":{"type":"string"},"type":"array","title":"Franchises"},"alternative_names":{"items":{"type":"string"},"type":"array","title":"Alternative Names"},"collections":{"items":{"type":"string"},"type":"array","title":"Collections"},"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"game_modes":{"items":{"type":"string"},"type":"array","title":"Game Modes"},"age_ratings":{"items":{"$ref":"#/components/schemas/IGDBAgeRating"},"type":"array","title":"Age Ratings"},"platforms":{"items":{"$ref":"#/components/schemas/IGDBMetadataPlatform"},"type":"array","title":"Platforms"},"multiplayer_modes":{"items":{"$ref":"#/components/schemas/IGDBMetadataMultiplayerMode"},"type":"array","title":"Multiplayer Modes"},"player_count":{"type":"string","title":"Player Count"},"expansions":{"items":{"$ref":"#/components/schemas/IGDBRelatedGame"},"type":"array","title":"Expansions"},"dlcs":{"items":{"$ref":"#/components/schemas/IGDBRelatedGame"},"type":"array","title":"Dlcs"},"remasters":{"items":{"$ref":"#/components/schemas/IGDBRelatedGame"},"type":"array","title":"Remasters"},"remakes":{"items":{"$ref":"#/components/schemas/IGDBRelatedGame"},"type":"array","title":"Remakes"},"expanded_games":{"items":{"$ref":"#/components/schemas/IGDBRelatedGame"},"type":"array","title":"Expanded Games"},"ports":{"items":{"$ref":"#/components/schemas/IGDBRelatedGame"},"type":"array","title":"Ports"},"similar_games":{"items":{"$ref":"#/components/schemas/IGDBRelatedGame"},"type":"array","title":"Similar Games"}},"type":"object","title":"RomIGDBMetadata"},"RomLaunchboxMetadata":{"properties":{"first_release_date":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"First Release Date"},"max_players":{"type":"integer","title":"Max Players"},"release_type":{"type":"string","title":"Release Type"},"cooperative":{"type":"boolean","title":"Cooperative"},"youtube_video_id":{"type":"string","title":"Youtube Video Id"},"community_rating":{"type":"number","title":"Community Rating"},"community_rating_count":{"type":"integer","title":"Community Rating Count"},"wikipedia_url":{"type":"string","title":"Wikipedia Url"},"esrb":{"type":"string","title":"Esrb"},"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"images":{"items":{"$ref":"#/components/schemas/LaunchboxImage"},"type":"array","title":"Images"}},"type":"object","title":"RomLaunchboxMetadata"},"RomMetadataSchema":{"properties":{"rom_id":{"type":"integer","title":"Rom Id"},"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"franchises":{"items":{"type":"string"},"type":"array","title":"Franchises"},"collections":{"items":{"type":"string"},"type":"array","title":"Collections"},"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"game_modes":{"items":{"type":"string"},"type":"array","title":"Game Modes"},"age_ratings":{"items":{"type":"string"},"type":"array","title":"Age Ratings"},"player_count":{"type":"string","title":"Player Count"},"first_release_date":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"First Release Date"},"average_rating":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Average Rating"}},"type":"object","required":["rom_id","genres","franchises","collections","companies","game_modes","age_ratings","player_count","first_release_date","average_rating"],"title":"RomMetadataSchema"},"RomMobyMetadata":{"properties":{"moby_score":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Moby Score"},"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"alternate_titles":{"items":{"type":"string"},"type":"array","title":"Alternate Titles"},"platforms":{"items":{"$ref":"#/components/schemas/MobyMetadataPlatform"},"type":"array","title":"Platforms"}},"type":"object","title":"RomMobyMetadata"},"RomRAMetadata":{"properties":{"first_release_date":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"First Release Date"},"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"achievements":{"items":{"$ref":"#/components/schemas/RAGameRomAchievement"},"type":"array","title":"Achievements"}},"type":"object","title":"RomRAMetadata"},"RomSSMetadata":{"properties":{"bezel_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bezel Url"},"box2d_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box2D Url"},"box2d_side_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box2D Side Url"},"box2d_back_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box2D Back Url"},"box3d_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box3D Url"},"fanart_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fanart Url"},"fullbox_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fullbox Url"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"},"manual_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Manual Url"},"marquee_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marquee Url"},"miximage_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Miximage Url"},"physical_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Physical Url"},"screenshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Screenshot Url"},"steamgrid_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Steamgrid Url"},"title_screen_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title Screen Url"},"video_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Url"},"video_normalized_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Normalized Url"},"bezel_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bezel Path"},"box2d_back_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box2D Back Path"},"box3d_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Box3D Path"},"fanart_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fanart Path"},"miximage_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Miximage Path"},"physical_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Physical Path"},"marquee_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marquee Path"},"logo_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Path"},"video_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Path"},"ss_score":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ss Score"},"first_release_date":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"First Release Date"},"alternative_names":{"items":{"type":"string"},"type":"array","title":"Alternative Names"},"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"franchises":{"items":{"type":"string"},"type":"array","title":"Franchises"},"game_modes":{"items":{"type":"string"},"type":"array","title":"Game Modes"},"genres":{"items":{"type":"string"},"type":"array","title":"Genres"},"player_count":{"type":"string","title":"Player Count"}},"type":"object","title":"RomSSMetadata"},"RomUserSchema":{"properties":{"id":{"type":"integer","title":"Id"},"user_id":{"type":"integer","title":"User Id"},"rom_id":{"type":"integer","title":"Rom Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"last_played":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Played"},"is_main_sibling":{"type":"boolean","title":"Is Main Sibling"},"backlogged":{"type":"boolean","title":"Backlogged"},"now_playing":{"type":"boolean","title":"Now Playing"},"hidden":{"type":"boolean","title":"Hidden"},"rating":{"type":"integer","title":"Rating"},"difficulty":{"type":"integer","title":"Difficulty"},"completion":{"type":"integer","title":"Completion"},"status":{"anyOf":[{"$ref":"#/components/schemas/RomUserStatus"},{"type":"null"}]},"user__username":{"type":"string","title":"User Username"}},"type":"object","required":["id","user_id","rom_id","created_at","updated_at","last_played","is_main_sibling","backlogged","now_playing","hidden","rating","difficulty","completion","status","user__username"],"title":"RomUserSchema"},"RomUserStatus":{"type":"string","enum":["incomplete","finished","completed_100","retired","never_playing"],"title":"RomUserStatus"},"RoomsResponse":{"properties":{"room_name":{"type":"string","title":"Room Name"},"current":{"type":"integer","title":"Current"},"max":{"type":"integer","title":"Max"},"player_name":{"type":"string","title":"Player Name"},"hasPassword":{"type":"boolean","title":"Haspassword"}},"type":"object","required":["room_name","current","max","player_name","hasPassword"],"title":"RoomsResponse"},"SGDBResource":{"properties":{"thumb":{"type":"string","title":"Thumb"},"url":{"type":"string","title":"Url"},"type":{"type":"string","title":"Type"}},"type":"object","required":["thumb","url","type"],"title":"SGDBResource"},"SaveSchema":{"properties":{"id":{"type":"integer","title":"Id"},"rom_id":{"type":"integer","title":"Rom Id"},"user_id":{"type":"integer","title":"User Id"},"file_name":{"type":"string","title":"File Name"},"file_name_no_tags":{"type":"string","title":"File Name No Tags"},"file_name_no_ext":{"type":"string","title":"File Name No Ext"},"file_extension":{"type":"string","title":"File Extension"},"file_path":{"type":"string","title":"File Path"},"file_size_bytes":{"type":"integer","title":"File Size Bytes"},"full_path":{"type":"string","title":"Full Path"},"download_path":{"type":"string","title":"Download Path"},"missing_from_fs":{"type":"boolean","title":"Missing From Fs"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"emulator":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emulator"},"screenshot":{"anyOf":[{"$ref":"#/components/schemas/ScreenshotSchema"},{"type":"null"}]}},"type":"object","required":["id","rom_id","user_id","file_name","file_name_no_tags","file_name_no_ext","file_extension","file_path","file_size_bytes","full_path","download_path","missing_from_fs","created_at","updated_at","emulator","screenshot"],"title":"SaveSchema"},"ScanStats":{"properties":{"total_platforms":{"type":"integer","title":"Total Platforms"},"total_roms":{"type":"integer","title":"Total Roms"},"scanned_platforms":{"type":"integer","title":"Scanned Platforms"},"new_platforms":{"type":"integer","title":"New Platforms"},"identified_platforms":{"type":"integer","title":"Identified Platforms"},"scanned_roms":{"type":"integer","title":"Scanned Roms"},"new_roms":{"type":"integer","title":"New Roms"},"identified_roms":{"type":"integer","title":"Identified Roms"},"scanned_firmware":{"type":"integer","title":"Scanned Firmware"},"new_firmware":{"type":"integer","title":"New Firmware"}},"type":"object","required":["total_platforms","total_roms","scanned_platforms","new_platforms","identified_platforms","scanned_roms","new_roms","identified_roms","scanned_firmware","new_firmware"],"title":"ScanStats"},"ScanTaskMeta":{"properties":{"scan_stats":{"anyOf":[{"$ref":"#/components/schemas/ScanStats"},{"type":"null"}]}},"type":"object","required":["scan_stats"],"title":"ScanTaskMeta"},"ScanTaskStatusResponse":{"properties":{"task_name":{"type":"string","title":"Task Name"},"task_id":{"type":"string","title":"Task Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"enqueued_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enqueued At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ended At"},"task_type":{"type":"string","const":"scan","title":"Task Type"},"meta":{"$ref":"#/components/schemas/ScanTaskMeta"}},"type":"object","required":["task_name","task_id","status","created_at","enqueued_at","started_at","ended_at","task_type","meta"],"title":"ScanTaskStatusResponse"},"ScreenshotSchema":{"properties":{"id":{"type":"integer","title":"Id"},"rom_id":{"type":"integer","title":"Rom Id"},"user_id":{"type":"integer","title":"User Id"},"file_name":{"type":"string","title":"File Name"},"file_name_no_tags":{"type":"string","title":"File Name No Tags"},"file_name_no_ext":{"type":"string","title":"File Name No Ext"},"file_extension":{"type":"string","title":"File Extension"},"file_path":{"type":"string","title":"File Path"},"file_size_bytes":{"type":"integer","title":"File Size Bytes"},"full_path":{"type":"string","title":"Full Path"},"download_path":{"type":"string","title":"Download Path"},"missing_from_fs":{"type":"boolean","title":"Missing From Fs"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","rom_id","user_id","file_name","file_name_no_tags","file_name_no_ext","file_extension","file_path","file_size_bytes","full_path","download_path","missing_from_fs","created_at","updated_at"],"title":"ScreenshotSchema"},"SearchCoverSchema":{"properties":{"name":{"type":"string","title":"Name"},"resources":{"items":{"$ref":"#/components/schemas/SGDBResource"},"type":"array","title":"Resources"}},"type":"object","required":["name","resources"],"title":"SearchCoverSchema"},"SearchRomSchema":{"properties":{"id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Id"},"igdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Igdb Id"},"moby_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Moby Id"},"ss_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ss Id"},"sgdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sgdb Id"},"flashpoint_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flashpoint Id"},"launchbox_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Launchbox Id"},"platform_id":{"type":"integer","title":"Platform Id"},"name":{"type":"string","title":"Name"},"slug":{"type":"string","title":"Slug","default":""},"summary":{"type":"string","title":"Summary","default":""},"igdb_url_cover":{"type":"string","title":"Igdb Url Cover","default":""},"moby_url_cover":{"type":"string","title":"Moby Url Cover","default":""},"ss_url_cover":{"type":"string","title":"Ss Url Cover","default":""},"sgdb_url_cover":{"type":"string","title":"Sgdb Url Cover","default":""},"flashpoint_url_cover":{"type":"string","title":"Flashpoint Url Cover","default":""},"launchbox_url_cover":{"type":"string","title":"Launchbox Url Cover","default":""},"is_unidentified":{"type":"boolean","title":"Is Unidentified"},"is_identified":{"type":"boolean","title":"Is Identified"}},"type":"object","required":["platform_id","name","is_unidentified","is_identified"],"title":"SearchRomSchema"},"SiblingRomSchema":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"fs_name_no_tags":{"type":"string","title":"Fs Name No Tags"},"fs_name_no_ext":{"type":"string","title":"Fs Name No Ext"},"sort_comparator":{"type":"string","title":"Sort Comparator","readOnly":true}},"type":"object","required":["id","name","fs_name_no_tags","fs_name_no_ext","sort_comparator"],"title":"SiblingRomSchema"},"SimpleRomSchema":{"properties":{"id":{"type":"integer","title":"Id"},"igdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Igdb Id"},"sgdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sgdb Id"},"moby_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Moby Id"},"ss_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ss Id"},"ra_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ra Id"},"launchbox_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Launchbox Id"},"hasheous_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hasheous Id"},"tgdb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tgdb Id"},"flashpoint_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flashpoint Id"},"hltb_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Hltb Id"},"gamelist_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gamelist Id"},"platform_id":{"type":"integer","title":"Platform Id"},"platform_slug":{"type":"string","title":"Platform Slug"},"platform_fs_slug":{"type":"string","title":"Platform Fs Slug"},"platform_custom_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Custom Name"},"platform_display_name":{"type":"string","title":"Platform Display Name"},"fs_name":{"type":"string","title":"Fs Name"},"fs_name_no_tags":{"type":"string","title":"Fs Name No Tags"},"fs_name_no_ext":{"type":"string","title":"Fs Name No Ext"},"fs_extension":{"type":"string","title":"Fs Extension"},"fs_path":{"type":"string","title":"Fs Path"},"fs_size_bytes":{"type":"integer","title":"Fs Size Bytes"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slug"},"summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary"},"alternative_names":{"items":{"type":"string"},"type":"array","title":"Alternative Names"},"youtube_video_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Youtube Video Id"},"metadatum":{"$ref":"#/components/schemas/RomMetadataSchema"},"igdb_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomIGDBMetadata"},{"type":"null"}]},"moby_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomMobyMetadata"},{"type":"null"}]},"ss_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomSSMetadata"},{"type":"null"}]},"launchbox_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomLaunchboxMetadata"},{"type":"null"}]},"hasheous_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomHasheousMetadata"},{"type":"null"}]},"flashpoint_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomFlashpointMetadata"},{"type":"null"}]},"hltb_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomHLTBMetadata"},{"type":"null"}]},"gamelist_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomGamelistMetadata"},{"type":"null"}]},"manual_metadata":{"anyOf":[{"$ref":"#/components/schemas/ManualMetadata"},{"type":"null"}]},"path_cover_small":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Small"},"path_cover_large":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Large"},"url_cover":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Cover"},"has_manual":{"type":"boolean","title":"Has Manual"},"path_manual":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Manual"},"url_manual":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Manual"},"is_identifying":{"type":"boolean","title":"Is Identifying","default":false},"is_unidentified":{"type":"boolean","title":"Is Unidentified"},"is_identified":{"type":"boolean","title":"Is Identified"},"revision":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revision"},"regions":{"items":{"type":"string"},"type":"array","title":"Regions"},"languages":{"items":{"type":"string"},"type":"array","title":"Languages"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"crc_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Crc Hash"},"md5_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Md5 Hash"},"sha1_hash":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sha1 Hash"},"has_simple_single_file":{"type":"boolean","title":"Has Simple Single File"},"has_nested_single_file":{"type":"boolean","title":"Has Nested Single File"},"has_multiple_files":{"type":"boolean","title":"Has Multiple Files"},"files":{"items":{"$ref":"#/components/schemas/RomFileSchema"},"type":"array","title":"Files"},"full_path":{"type":"string","title":"Full Path"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"missing_from_fs":{"type":"boolean","title":"Missing From Fs"},"has_notes":{"type":"boolean","title":"Has Notes"},"siblings":{"items":{"$ref":"#/components/schemas/SiblingRomSchema"},"type":"array","title":"Siblings"},"rom_user":{"$ref":"#/components/schemas/RomUserSchema"},"merged_screenshots":{"items":{"type":"string"},"type":"array","title":"Merged Screenshots"},"merged_ra_metadata":{"anyOf":[{"$ref":"#/components/schemas/RomRAMetadata"},{"type":"null"}]}},"type":"object","required":["id","igdb_id","sgdb_id","moby_id","ss_id","ra_id","launchbox_id","hasheous_id","tgdb_id","flashpoint_id","hltb_id","gamelist_id","platform_id","platform_slug","platform_fs_slug","platform_custom_name","platform_display_name","fs_name","fs_name_no_tags","fs_name_no_ext","fs_extension","fs_path","fs_size_bytes","name","slug","summary","alternative_names","youtube_video_id","metadatum","igdb_metadata","moby_metadata","ss_metadata","launchbox_metadata","hasheous_metadata","flashpoint_metadata","hltb_metadata","gamelist_metadata","manual_metadata","path_cover_small","path_cover_large","url_cover","has_manual","path_manual","url_manual","is_unidentified","is_identified","revision","regions","languages","tags","crc_hash","md5_hash","sha1_hash","has_simple_single_file","has_nested_single_file","has_multiple_files","files","full_path","created_at","updated_at","missing_from_fs","has_notes","siblings","rom_user","merged_screenshots","merged_ra_metadata"],"title":"SimpleRomSchema"},"SmartCollectionSchema":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""},"rom_ids":{"items":{"type":"integer"},"type":"array","uniqueItems":true,"title":"Rom Ids"},"rom_count":{"type":"integer","title":"Rom Count"},"path_cover_small":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Small"},"path_cover_large":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Large"},"path_covers_small":{"items":{"type":"string"},"type":"array","title":"Path Covers Small"},"path_covers_large":{"items":{"type":"string"},"type":"array","title":"Path Covers Large"},"is_public":{"type":"boolean","title":"Is Public","default":false},"is_favorite":{"type":"boolean","title":"Is Favorite","default":false},"is_virtual":{"type":"boolean","title":"Is Virtual","default":false},"is_smart":{"type":"boolean","title":"Is Smart","default":true},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"id":{"type":"integer","title":"Id"},"filter_criteria":{"additionalProperties":true,"type":"object","title":"Filter Criteria"},"filter_summary":{"type":"string","title":"Filter Summary"},"user_id":{"type":"integer","title":"User Id"},"user__username":{"type":"string","title":"User Username"}},"type":"object","required":["name","rom_ids","rom_count","path_cover_small","path_cover_large","path_covers_small","path_covers_large","created_at","updated_at","id","filter_criteria","filter_summary","user_id","user__username"],"title":"SmartCollectionSchema"},"StateSchema":{"properties":{"id":{"type":"integer","title":"Id"},"rom_id":{"type":"integer","title":"Rom Id"},"user_id":{"type":"integer","title":"User Id"},"file_name":{"type":"string","title":"File Name"},"file_name_no_tags":{"type":"string","title":"File Name No Tags"},"file_name_no_ext":{"type":"string","title":"File Name No Ext"},"file_extension":{"type":"string","title":"File Extension"},"file_path":{"type":"string","title":"File Path"},"file_size_bytes":{"type":"integer","title":"File Size Bytes"},"full_path":{"type":"string","title":"Full Path"},"download_path":{"type":"string","title":"Download Path"},"missing_from_fs":{"type":"boolean","title":"Missing From Fs"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"emulator":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Emulator"},"screenshot":{"anyOf":[{"$ref":"#/components/schemas/ScreenshotSchema"},{"type":"null"}]}},"type":"object","required":["id","rom_id","user_id","file_name","file_name_no_tags","file_name_no_ext","file_extension","file_path","file_size_bytes","full_path","download_path","missing_from_fs","created_at","updated_at","emulator","screenshot"],"title":"StateSchema"},"StatsReturn":{"properties":{"PLATFORMS":{"type":"integer","title":"Platforms"},"ROMS":{"type":"integer","title":"Roms"},"SAVES":{"type":"integer","title":"Saves"},"STATES":{"type":"integer","title":"States"},"SCREENSHOTS":{"type":"integer","title":"Screenshots"},"TOTAL_FILESIZE_BYTES":{"type":"integer","title":"Total Filesize Bytes"}},"type":"object","required":["PLATFORMS","ROMS","SAVES","STATES","SCREENSHOTS","TOTAL_FILESIZE_BYTES"],"title":"StatsReturn"},"SystemDict":{"properties":{"VERSION":{"type":"string","title":"Version"},"SHOW_SETUP_WIZARD":{"type":"boolean","title":"Show Setup Wizard"}},"type":"object","required":["VERSION","SHOW_SETUP_WIZARD"],"title":"SystemDict"},"TaskExecutionResponse":{"properties":{"task_name":{"type":"string","title":"Task Name"},"task_id":{"type":"string","title":"Task Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"enqueued_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enqueued At"}},"type":"object","required":["task_name","task_id","status","created_at","enqueued_at"],"title":"TaskExecutionResponse"},"TaskInfo":{"properties":{"name":{"type":"string","title":"Name"},"type":{"$ref":"#/components/schemas/TaskType"},"manual_run":{"type":"boolean","title":"Manual Run"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description"},"enabled":{"type":"boolean","title":"Enabled"},"cron_string":{"type":"string","title":"Cron String"}},"type":"object","required":["name","type","manual_run","title","description","enabled","cron_string"],"title":"TaskInfo"},"TaskType":{"type":"string","enum":["scan","conversion","cleanup","update","watcher","generic"],"title":"TaskType","description":"Enumeration of task types for categorization and UI display."},"TasksDict":{"properties":{"ENABLE_SCHEDULED_RESCAN":{"type":"boolean","title":"Enable Scheduled Rescan"},"SCHEDULED_RESCAN_CRON":{"type":"string","title":"Scheduled Rescan Cron"},"ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB":{"type":"boolean","title":"Enable Scheduled Update Switch Titledb"},"SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON":{"type":"string","title":"Scheduled Update Switch Titledb Cron"},"ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA":{"type":"boolean","title":"Enable Scheduled Update Launchbox Metadata"},"SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON":{"type":"string","title":"Scheduled Update Launchbox Metadata Cron"},"ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP":{"type":"boolean","title":"Enable Scheduled Convert Images To Webp"},"SCHEDULED_CONVERT_IMAGES_TO_WEBP_CRON":{"type":"string","title":"Scheduled Convert Images To Webp Cron"}},"type":"object","required":["ENABLE_SCHEDULED_RESCAN","SCHEDULED_RESCAN_CRON","ENABLE_SCHEDULED_UPDATE_SWITCH_TITLEDB","SCHEDULED_UPDATE_SWITCH_TITLEDB_CRON","ENABLE_SCHEDULED_UPDATE_LAUNCHBOX_METADATA","SCHEDULED_UPDATE_LAUNCHBOX_METADATA_CRON","ENABLE_SCHEDULED_CONVERT_IMAGES_TO_WEBP","SCHEDULED_CONVERT_IMAGES_TO_WEBP_CRON"],"title":"TasksDict"},"TinfoilFeedFileSchema":{"properties":{"url":{"type":"string","title":"Url"},"size":{"type":"integer","title":"Size"}},"type":"object","required":["url","size"],"title":"TinfoilFeedFileSchema"},"TinfoilFeedSchema":{"properties":{"files":{"items":{"$ref":"#/components/schemas/TinfoilFeedFileSchema"},"type":"array","title":"Files"},"directories":{"items":{"type":"string"},"type":"array","title":"Directories"},"titledb":{"additionalProperties":{"additionalProperties":true,"type":"object"},"type":"object","title":"Titledb"},"success":{"type":"string","title":"Success"},"error":{"type":"string","title":"Error"}},"type":"object","required":["files","directories"],"title":"TinfoilFeedSchema"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type"},"expires":{"type":"integer","title":"Expires"}},"type":"object","required":["access_token","token_type","expires"],"title":"TokenResponse"},"UpdateStats":{"properties":{"processed":{"type":"integer","title":"Processed"},"total":{"type":"integer","title":"Total"}},"type":"object","required":["processed","total"],"title":"UpdateStats"},"UpdateTaskMeta":{"properties":{"update_stats":{"anyOf":[{"$ref":"#/components/schemas/UpdateStats"},{"type":"null"}]}},"type":"object","required":["update_stats"],"title":"UpdateTaskMeta"},"UpdateTaskStatusResponse":{"properties":{"task_name":{"type":"string","title":"Task Name"},"task_id":{"type":"string","title":"Task Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"enqueued_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enqueued At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ended At"},"task_type":{"type":"string","const":"update","title":"Task Type"},"meta":{"$ref":"#/components/schemas/UpdateTaskMeta"}},"type":"object","required":["task_name","task_id","status","created_at","enqueued_at","started_at","ended_at","task_type","meta"],"title":"UpdateTaskStatusResponse"},"UserCollectionSchema":{"properties":{"id":{"type":"integer","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"UserCollectionSchema"},"UserForm":{"properties":{"username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"},"password":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Password"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"},"ra_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ra Username"},"avatar":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Avatar"},"ui_settings":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ui Settings"}},"type":"object","title":"UserForm"},"UserNoteSchema":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"content":{"type":"string","title":"Content"},"is_public":{"type":"boolean","title":"Is Public"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"user_id":{"type":"integer","title":"User Id"},"username":{"type":"string","title":"Username"}},"type":"object","required":["id","title","content","is_public","created_at","updated_at","user_id","username"],"title":"UserNoteSchema"},"UserSchema":{"properties":{"id":{"type":"integer","title":"Id"},"username":{"type":"string","title":"Username"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"enabled":{"type":"boolean","title":"Enabled"},"role":{"$ref":"#/components/schemas/Role"},"oauth_scopes":{"items":{"type":"string"},"type":"array","title":"Oauth Scopes"},"avatar_path":{"type":"string","title":"Avatar Path"},"last_login":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login"},"last_active":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Active"},"ra_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ra Username"},"ra_progression":{"anyOf":[{"$ref":"#/components/schemas/RAProgression"},{"type":"null"}]},"ui_settings":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ui Settings"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","username","email","enabled","role","oauth_scopes","avatar_path","last_login","last_active","created_at","updated_at"],"title":"UserSchema"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VirtualCollectionSchema":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"rom_ids":{"items":{"type":"integer"},"type":"array","uniqueItems":true,"title":"Rom Ids"},"rom_count":{"type":"integer","title":"Rom Count"},"path_cover_small":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Small"},"path_cover_large":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path Cover Large"},"path_covers_small":{"items":{"type":"string"},"type":"array","title":"Path Covers Small"},"path_covers_large":{"items":{"type":"string"},"type":"array","title":"Path Covers Large"},"is_public":{"type":"boolean","title":"Is Public","default":false},"is_favorite":{"type":"boolean","title":"Is Favorite","default":false},"is_virtual":{"type":"boolean","title":"Is Virtual","default":true},"is_smart":{"type":"boolean","title":"Is Smart","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"id":{"type":"string","title":"Id"},"type":{"type":"string","title":"Type"}},"type":"object","required":["name","description","rom_ids","rom_count","path_cover_small","path_cover_large","path_covers_small","path_covers_large","created_at","updated_at","id","type"],"title":"VirtualCollectionSchema"},"WatcherTaskMeta":{"properties":{},"type":"object","title":"WatcherTaskMeta"},"WatcherTaskStatusResponse":{"properties":{"task_name":{"type":"string","title":"Task Name"},"task_id":{"type":"string","title":"Task Id"},"status":{"$ref":"#/components/schemas/JobStatus"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"enqueued_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enqueued At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"ended_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ended At"},"task_type":{"type":"string","const":"watcher","title":"Task Type"},"meta":{"$ref":"#/components/schemas/WatcherTaskMeta"}},"type":"object","required":["task_name","task_id","status","created_at","enqueued_at","started_at","ended_at","task_type","meta"],"title":"WatcherTaskStatusResponse"},"WebrcadeFeedCategorySchema":{"properties":{"title":{"type":"string","title":"Title"},"longTitle":{"type":"string","title":"Longtitle"},"background":{"type":"string","title":"Background"},"thumbnail":{"type":"string","title":"Thumbnail"},"description":{"type":"string","title":"Description"},"items":{"items":{"$ref":"#/components/schemas/WebrcadeFeedItemSchema"},"type":"array","title":"Items"}},"type":"object","required":["title","items"],"title":"WebrcadeFeedCategorySchema"},"WebrcadeFeedItemPropsSchema":{"properties":{"rom":{"type":"string","title":"Rom"}},"type":"object","required":["rom"],"title":"WebrcadeFeedItemPropsSchema"},"WebrcadeFeedItemSchema":{"properties":{"title":{"type":"string","title":"Title"},"longTitle":{"type":"string","title":"Longtitle"},"description":{"type":"string","title":"Description"},"type":{"type":"string","title":"Type"},"thumbnail":{"type":"string","title":"Thumbnail"},"background":{"type":"string","title":"Background"},"props":{"$ref":"#/components/schemas/WebrcadeFeedItemPropsSchema"}},"type":"object","required":["title","type","props"],"title":"WebrcadeFeedItemSchema"},"WebrcadeFeedSchema":{"properties":{"title":{"type":"string","title":"Title"},"longTitle":{"type":"string","title":"Longtitle"},"description":{"type":"string","title":"Description"},"thumbnail":{"type":"string","title":"Thumbnail"},"background":{"type":"string","title":"Background"},"categories":{"items":{"$ref":"#/components/schemas/WebrcadeFeedCategorySchema"},"type":"array","title":"Categories"}},"type":"object","required":["title","categories"],"title":"WebrcadeFeedSchema"}},"securitySchemes":{"OAuth2PasswordBearer":{"type":"oauth2","flows":{"password":{"scopes":{"me.read":"View your profile","roms.read":"View ROMs","platforms.read":"View platforms","assets.read":"View assets","firmware.read":"View firmware","roms.user.read":"View user-rom properties","collections.read":"View collections","me.write":"Modify your profile","assets.write":"Modify assets","roms.user.write":"Modify user-rom properties","collections.write":"Modify collections","roms.write":"Modify ROMs","platforms.write":"Modify platforms","firmware.write":"Modify firmware","users.read":"View users","users.write":"Modify users","tasks.run":"Run tasks"},"tokenUrl":"/token"}}},"HTTPBasic":{"type":"http","scheme":"basic"}}}}
\ No newline at end of file
diff --git a/src/bun/api/clients.ts b/src/bun/api/clients.ts
new file mode 100644
index 0000000..fcaf899
--- /dev/null
+++ b/src/bun/api/clients.ts
@@ -0,0 +1,38 @@
+import { config } from "./settings";
+import Elysia from "elysia";
+
+export const romm = new Elysia({ prefix: "/romm" })
+ .all("/*", async ({ request, params, set }) =>
+ {
+ if (!config.has('rommAddress') && !config.get('rommAddress'))
+ {
+ return new Response("Romm Address Not Found", { status: 404 });
+ }
+
+ const rommUrl = new URL(config.get('rommAddress')!);
+ const url = new URL(request.url);
+ url.pathname = url.pathname.replace(/^\/api\/romm/, '');
+ url.host = rommUrl.host;
+ url.port = rommUrl.port;
+ url.protocol = rommUrl.protocol;
+
+ // Forward headers (optional: remove host if needed)
+ const headers = new Headers(request.headers);
+ headers.delete('host');
+ headers.set("accept-encoding", "identity");
+
+ const rommResponse = await fetch(url, {
+ method: request.method,
+ headers,
+ body: await request.arrayBuffer(),
+ redirect: 'manual', // avoid ROMM redirects
+ });
+
+ set.status = rommResponse.status;
+ rommResponse.headers.forEach((value, key) =>
+ {
+ set.headers[key] = value;
+ });
+
+ return new Response(rommResponse.body, { status: rommResponse.status });
+ });
\ No newline at end of file
diff --git a/src/bun/api/rpc.ts b/src/bun/api/rpc.ts
new file mode 100644
index 0000000..eb2e933
--- /dev/null
+++ b/src/bun/api/rpc.ts
@@ -0,0 +1,42 @@
+import { RPC_PORT } from "../../shared/constants";
+import { settings } from "./settings";
+import { romm } from "./clients";
+import Elysia from "elysia";
+import { cors } from "@elysiajs/cors";
+import { host } from "../utils";
+
+const api = new Elysia({ prefix: "/api", serve: {} })
+ .use(cors())
+ .use(romm)
+ .use(settings);
+
+export type AppType = typeof api;
+
+export function RunAPIServer ()
+{
+ console.log("Launching API Server on port ", RPC_PORT);
+ return {
+ apiServer: api.listen({
+ port: RPC_PORT,
+ hostname: host,
+ development: process.env.NODE_ENV === 'development',
+ fetch (req, server)
+ {
+ if (server.upgrade(req, {
+ data: undefined
+ }))
+ {
+ return;
+ }
+ return api.fetch(req);
+ },
+ websocket: {
+ message (ws, message)
+ {
+
+
+ },
+ }
+ })
+ };
+}
\ No newline at end of file
diff --git a/src/bun/api/settings.ts b/src/bun/api/settings.ts
new file mode 100644
index 0000000..118d41c
--- /dev/null
+++ b/src/bun/api/settings.ts
@@ -0,0 +1,29 @@
+import z from "zod";
+import { SettingsSchema, SettingsType } from "../../shared/constants";
+import Conf from "conf";
+import projectPackage from '../../../package.json';
+import Elysia from "elysia";
+
+export const config = new Conf({
+ projectName: projectPackage.name,
+ projectSuffix: 'bun',
+ schema: Object.fromEntries(Object.entries(SettingsSchema.shape).map(([key, schema]) => [key, schema.toJSONSchema() as any])) as any,
+ defaults: SettingsSchema.parse({}),
+});
+console.log("Config Path Located At: ", config.path);
+
+export const settings = new Elysia({ prefix: '/settings' })
+ .get("/:id", async ({ params: { id } }) =>
+ {
+ const value = config.get(id);
+ return { value: value };
+ }, {
+ params: z.object({ id: z.keyof(SettingsSchema) }),
+ }).post('/:id',
+ async ({ params: { id }, body: { value }, }) =>
+ {
+ config.set(id, value);
+ }, {
+ params: z.object({ id: z.keyof(SettingsSchema) }),
+ body: z.object({ value: z.any() })
+ });
diff --git a/src/bun/index.ts b/src/bun/index.ts
index 35266d7..4356ed2 100644
--- a/src/bun/index.ts
+++ b/src/bun/index.ts
@@ -1,39 +1,55 @@
-import { BrowserWindow, Updater } from "electrobun/bun";
+import { RunBunServer } from './server';
+import { RunAPIServer } from './api/rpc';
+import { spawnBrowser } from './utils/browser-spawner';
+import { BuildParams } from './utils/browser-params';
-const DEV_SERVER_PORT = 5173;
-const DEV_SERVER_URL = `http://localhost:${DEV_SERVER_PORT}/Dashboard`;
+const api = RunAPIServer();
+let bunServer: { stop: () => void; url: URL; } | undefined;
-// Check if Vite dev server is running for HMR
-async function getMainViewUrl(): Promise {
- const channel = await Updater.localInfo.channel();
- if (channel === "dev") {
- try {
- await fetch(DEV_SERVER_URL, { method: "HEAD" });
- console.log(`HMR enabled: Using Vite dev server at ${DEV_SERVER_URL}`);
- return DEV_SERVER_URL;
- } catch {
- console.log("Vite dev server not running. Run 'bun run dev:hmr' for HMR support.");
- }
- }
- return "views://mainview/index.html";
+if (!Bun.env.PUBLIC_ACCESS)
+{
+ bunServer = RunBunServer();
}
-// Create the main application window
-const url = await getMainViewUrl();
+function cleanup ()
+{
+ bunServer?.stop();
+ api.apiServer.stop();
+ process.exit(0);
+}
-const mainWindow = new BrowserWindow({
- title: "GameFlow",
- url,
- renderer: 'cef',
- styleMask: {
- Borderless: true,
- },
- frame: {
- width: 1280,
- height: 800,
- x: 200,
- y: 200,
- },
-});
+try
+{
+ const webviewWorker = new Worker(process.env.IS_BINARY ? "./webview-worker.ts" : new URL("./webview-worker", import.meta.url).href, {
+ smol: true,
+ });
+ webviewWorker.addEventListener('error', console.error);
+ await new Promise(resolve => webviewWorker.addEventListener('close', resolve));
+ cleanup();
+}
+catch (error)
+{
+ console.error(error);
-console.log("React Tailwind Vite app started!");
\ No newline at end of file
+ const browserParams = await BuildParams();
+
+ if (!browserParams)
+ {
+ console.error("Could not find valid browser");
+ process.exit();
+ }
+
+ const browser = spawnBrowser({
+ browser: browserParams.browser.type,
+ args: browserParams.args,
+ env: browserParams.env,
+ detached: true,
+ execPath: browserParams.browser.path,
+ source: browserParams.browser.source,
+ ipc (message)
+ {
+ console.log(message);
+ },
+ onExit: cleanup
+ });
+}
\ No newline at end of file
diff --git a/src/bun/server.ts b/src/bun/server.ts
new file mode 100644
index 0000000..2003f3b
--- /dev/null
+++ b/src/bun/server.ts
@@ -0,0 +1,22 @@
+import { SERVER_PORT } from "../shared/constants";
+import path from 'node:path';
+import { host } from "./utils";
+
+export function RunBunServer ()
+{
+ console.log("Launching Server on port ", SERVER_PORT);
+ return Bun.serve({
+ port: SERVER_PORT,
+ hostname: host,
+ routes: {
+ "/": Bun.file("./dist/index.html"),
+ // Serve a file by lazily loading it into memory
+ "/favicon.ico": Bun.file("./dist/favicon.ico"),
+ },
+ fetch: async (req) =>
+ {
+ const url = new URL(req.url);
+ return new Response(Bun.file(`./${path.join('dist', url.pathname)}`));
+ },
+ });
+}
\ No newline at end of file
diff --git a/src/bun/types.d.ts b/src/bun/types.d.ts
new file mode 100644
index 0000000..fa77aaa
--- /dev/null
+++ b/src/bun/types.d.ts
@@ -0,0 +1,19 @@
+declare const IS_BINARY: string;
+
+declare module 'download-chromium' {
+ export default function download ({
+ platform,
+ revision = '499413',
+ log = false,
+ onProgress = undefined,
+ installPath = '{__dirname}/.local-chromium' }: {
+ platform?: 'linux' | 'mac' | 'win32' | 'win64',
+ revision?: string,
+ log?: boolean,
+ installPath?: string,
+ onProgress?: (percent: number, transferred: number, total: number) => void;
+ }): Promise
+ {
+
+ };
+}
\ No newline at end of file
diff --git a/src/bun/utils.ts b/src/bun/utils.ts
new file mode 100644
index 0000000..acd0053
--- /dev/null
+++ b/src/bun/utils.ts
@@ -0,0 +1,19 @@
+
+import { networkInterfaces } from 'node:os';
+
+const localIp = Object.values(networkInterfaces())
+ .flat()
+ .find((iface) => iface?.family === 'IPv4' && !iface.internal)?.address || 'localhost';
+
+export const host = process.env.PUBLIC_ACCESS ? localIp : 'localhost';
+
+export function checkRunning (pid: number)
+{
+ try
+ {
+ return process.kill(pid, 0);
+ } catch (error: any)
+ {
+ return error.code === 'EPERM';
+ }
+}
\ No newline at end of file
diff --git a/src/bun/utils/browser-params.ts b/src/bun/utils/browser-params.ts
new file mode 100644
index 0000000..4afa59f
--- /dev/null
+++ b/src/bun/utils/browser-params.ts
@@ -0,0 +1,91 @@
+import { SERVER_URL } from "../../shared/constants";
+import os from 'node:os';
+import path, { dirname } from 'node:path';
+import { getBrowserPath } from "./get-browser";
+import { config } from "../api/settings";
+import { host } from "../utils";
+
+export async function BuildParams ()
+{
+ const validBrowser = await getBrowserPath({
+ browserOrder: ['chrome', 'chromium']
+ });
+
+ if (!validBrowser)
+ {
+ return undefined;
+ }
+
+ const args: string[] = [];
+ const browserEnv = {
+ GOOGLE_API_KEY: 'no',
+ GOOGLE_DEFAULT_CLIENT_ID: 'no',
+ GOOGLE_DEFAULT_CLIENT_SECRET: 'no',
+ };
+
+ if (validBrowser.type === 'chrome' || validBrowser.type === 'chromium')
+ {
+ const isEdge = validBrowser.path.toLowerCase().includes('edge') || validBrowser.path.toLowerCase().includes('msedge');
+ console.log(`[Browser] Detected: ${validBrowser.type} from ${validBrowser.source} - ${isEdge ? 'Edge' : 'Chrome/Chromium'}`);
+
+ args.push(`--app=${SERVER_URL(host)}`);
+ args.push(`--app-id=gameflow`);
+ args.push(`--force-app-mode`);
+ args.push('--no-default-browser-check');
+ args.push('--no-first-run');
+ args.push('--disable-infobars');
+ args.push("--disable-extensions");
+ args.push("--disable-plugins");
+ args.push(`--user-data-dir=${path.join(dirname(config.path), 'browser-data')}`);
+ args.push('--disable-sync'); //Disable syncing to a Google account
+ args.push('--disable-sync-preferences');
+ args.push('--disable-component-update');
+ args.push('--allow-insecure-localhost');
+ args.push('--auto-accept-camera-and-microphone-capture');
+ args.push(`--window-size=${config.get('windowSize.width')},${config.get('windowSize.height')}`);
+ args.push('--password-store=basic');
+ args.push('--block-new-web-contents');
+ args.push('--bwsi');
+ args.push('--ash-no-nudges');
+ args.push('--autoplay-policy=no-user-gesture-required'); // allow autoplay of videos
+ args.push('--disabled-features=WindowControlsOverlay,navigationControls,Translate,msUndersideButton');
+ args.push(`--profile-directory=Default`);
+
+ if (config.has('windowPosition'))
+ {
+ args.push(`--window-position=${config.get('windowPosition.x')},${config.get('windowPosition.y')}`);
+ }
+
+ if (isEdge)
+ {
+ // Disable Edge sync and cloud features
+ args.push('--disable-sync');
+ args.push('--disable-background-networking');
+ args.push('--disable-client-side-phishing-detection');
+ args.push('--disable-component-extensions-with-background-pages');
+ args.push('--disable-default-apps');
+ args.push('--disable-extensions-except=');
+ args.push('--disable-feature=TranslateUI');
+ args.push('--disable-background-timer-throttling');
+ args.push('--disable-backgrounding-occluded-windows');
+ args.push('--disable-breakpad');
+ args.push('--disable-client-side-phishing-detection');
+ args.push('--disable-component-update');
+ args.push('--disable-hang-monitor');
+ args.push('--disable-ipc-flooding-protection');
+ args.push('--disable-popup-blocking');
+ args.push('--disable-prompt-on-repost');
+ args.push('--disable-renderer-backgrounding');
+ args.push('--metrics-recording-only');
+ args.push('--no-service-autorun');
+ }
+
+ if (os.platform() === 'linux')
+ {
+ args.push("--disable-web-security");
+ args.push("--no-sandbox");
+ }
+ }
+
+ return { env: browserEnv, args, browser: validBrowser };
+}
\ No newline at end of file
diff --git a/src/bun/utils/browser-spawner.ts b/src/bun/utils/browser-spawner.ts
new file mode 100644
index 0000000..5f59d12
--- /dev/null
+++ b/src/bun/utils/browser-spawner.ts
@@ -0,0 +1,166 @@
+import { type Subprocess } from "bun";
+
+export type RunBrowserType = "chrome" | "chromium" | "firefox" | "edge";
+export type RunBrowserSource = "running" | "system" | "flatpak";
+
+/**
+ * Options for spawning a browser process.
+ *
+ * @property browser - The browser type to spawn
+ * @property args - Optional command-line arguments to pass to the browser
+ * @property env - Optional environment variables to set for the browser process
+ * @property detached - If true, the browser process runs independently of the parent
+ * @property execPath - Full path to the browser executable (required)
+ * @property source - How the browser was discovered (running, system, or flatpak)
+ */
+interface SpawnBrowserOptions
+{
+ browser: RunBrowserType;
+ args?: string[];
+ env?: Record;
+ detached?: boolean;
+ execPath: string; // Required: browser executable path from get-browser.ts
+ source: RunBrowserSource; // How the browser was discovered (running, system, or flatpak)
+ onExit?: () => void; // Called when the browser exists duh
+ ipc?: (message: string) => void;
+}
+
+/**
+ * Spawns a browser process with proper handling for different installation types.
+ *
+ * Behavior depends on the browser source:
+ * - "running": Browser is already running, spawns additional instance
+ * - "system": Native system installation, spawned directly with execPath
+ * - "flatpak": Flatpak containerized browser, spawned via `flatpak run` with proper arguments
+ *
+ * For Flatpak browsers, uses Steam-style argument ordering:
+ * `flatpak run [OPTIONS] [APP_ID] @@u @@ [USER_ARGS]`
+ *
+ * @param options - Spawn options including browser type, path, source, and arguments
+ * @returns A Bun Subprocess instance
+ * @throws Error if execPath is not provided or if browser configuration is invalid
+ *
+ * @example
+ * const browser = await getBrowserPath();
+ * if (browser) {
+ * const proc = spawnBrowser({
+ * browser: browser.type,
+ * args: ["--no-sandbox", "https://example.com"],
+ * source: browser.source,
+ * execPath: browser.path,
+ * detached: true
+ * });
+ * }
+ */
+export function spawnBrowser ({
+ browser,
+ args = [],
+ env = {},
+ detached = false,
+ execPath,
+ source,
+ onExit,
+ ipc
+}: SpawnBrowserOptions): Subprocess
+{
+
+ // Configuration for both Flatpak and Native
+ // Contains Flatpak app IDs, internal container paths, and fallback binary names
+ const config: Record = {
+ chrome: {
+ id: "com.google.Chrome",
+ internalCmd: "/app/bin/chrome", // Explicit command inside container
+ bin: ["google-chrome", "google-chrome-stable", "chrome"]
+ },
+ chromium: {
+ id: "org.chromium.Chromium",
+ internalCmd: "/app/bin/chromium",
+ bin: ["chromium", "chromium-browser"]
+ },
+ firefox: {
+ id: "org.mozilla.firefox",
+ internalCmd: "/app/bin/firefox",
+ bin: ["firefox"]
+ },
+ edge: {
+ id: "com.microsoft.Edge",
+ internalCmd: "/app/bin/edge", // Varies, but usually standard for Edge
+ bin: ["microsoft-edge", "microsoft-edge-stable"]
+ }
+ };
+
+ const target = config[browser];
+ const useFlatpak = source === "flatpak";
+
+ let cmd: string[];
+ let finalEnv: Record | undefined;
+
+ if (useFlatpak)
+ {
+ // --- Flatpak Mode (Steam Style) ---
+ // Structure: flatpak run [ENV] [FLATPAK_OPTS] [APP_ID] @@u @@ [USER_ARGS]
+ // The @@u @@ syntax enables file forwarding for URL arguments
+
+ const envFlags = Object.entries(env).map(([k, v]) => `--env=${k}=${v}`);
+
+ // We explicitly set the command to ensure we don't rely on the default entrypoint failing
+ const flatpakOpts = [
+ "run",
+ "--branch=stable",
+ `--arch=${process.arch === "x64" ? "x86_64" : process.arch}`, // map node arch to flatpak arch
+ `--command=${target.internalCmd}`,
+ "--file-forwarding",
+ ...envFlags // Inject env vars here
+ ];
+
+ // Combine: flatpak run ... com.google.Chrome @@u @@ [USER_ARGS]
+ cmd = [
+ "flatpak",
+ ...flatpakOpts,
+ target.id,
+ "@@u",
+ "@@",
+ ...args
+ ];
+
+ // Clear env for the spawner so it doesn't pollute the flatpak command wrapper
+ finalEnv = undefined;
+ console.log(`[Browser] Launching Flatpak: ${cmd.join(" ")}`);
+
+ } else
+ {
+ // --- Native Mode ---
+ // Use the provided execPath directly
+ cmd = [execPath, ...args];
+ finalEnv = { ...process.env, ...env } as Record;
+ console.log(`[Browser] Launching Native: ${execPath}`);
+ }
+
+ const processSub = Bun.spawn(cmd, {
+ env: finalEnv,
+ stdin: "ignore",
+ stdout: "inherit",
+ stderr: "inherit",
+ ipc,
+ onExit (_proc, exitCode)
+ {
+ if (exitCode !== 0 && exitCode !== null)
+ {
+ console.error(`[Browser] Exited with code: ${exitCode}`);
+ }
+ onExit?.();
+ },
+ });
+
+ if (detached) processSub.unref();
+
+ return processSub;
+}
+
+
+// --- Test Run ---
+// spawnBrowser({
+// browser: "chrome",
+// args: ["--window-size=1024,640", "--force-device-scale-factor=1.25"],
+// detached: true
+// });
\ No newline at end of file
diff --git a/src/bun/utils/get-browser.ts b/src/bun/utils/get-browser.ts
new file mode 100644
index 0000000..73370a2
--- /dev/null
+++ b/src/bun/utils/get-browser.ts
@@ -0,0 +1,611 @@
+import { spawnSync } from "bun";
+import { platform } from "node:os";
+import { RunBrowserType } from "./browser-spawner";
+
+export type GetBrowserType = "chrome" | "chromium" | "firefox";
+export type GetBrowserSource = "running" | "system" | "flatpak";
+
+/**
+ * Browser discovery priority configuration
+ */
+interface BrowserPriorityConfig
+{
+ /** Include currently running browser processes in search */
+ includeRunning?: boolean;
+ /** Browser types to search for, in priority order */
+ browserOrder?: GetBrowserType[];
+ /** Include system default browser on Windows */
+ includeSystemDefault?: boolean;
+ /** Include Flatpak browsers on Linux */
+ includeFlatpak?: boolean;
+}
+
+/**
+ * Browser discovery result containing the executable path, browser type, and discovery source.
+ */
+interface BrowserResult
+{
+ /** Full path to the browser executable */
+ path: string;
+ /** Type of browser (chrome, chromium, or firefox) */
+ type: GetBrowserType;
+ /** Source of discovery (running process, system installation, or flatpak) */
+ source: GetBrowserSource;
+}
+
+/**
+ * Main function to find a valid browser executable.
+ *
+ * Searches for an available browser based on customizable priority configuration.
+ * Default priority order:
+ * 1. Currently running Chrome process (fastest return)
+ * 2. Windows: Default system browser (if on Windows)
+ * 3. Standard System Paths (Firefox > Chrome > Chromium by default)
+ * 4. Flatpak (Linux only)
+ *
+ * @param config - Optional priority configuration to customize search behavior
+ * @returns A promise that resolves to a BrowserResult containing the path, type, and source
+ * of the discovered browser, or null if no suitable browser is found.
+ *
+ * @example
+ * // Use default priority
+ * const browser = await getBrowserPath();
+ *
+ * @example
+ * // Prefer Chrome over Firefox, skip running processes
+ * const browser = await getBrowserPath({
+ * includeRunning: false,
+ * browserOrder: ['chrome', 'firefox', 'chromium']
+ * });
+ */
+export async function getBrowserPath (config?: BrowserPriorityConfig): Promise
+{
+ // Default configuration
+ const {
+ includeRunning = true,
+ browserOrder = ["firefox", "chrome", "chromium"],
+ includeSystemDefault = true,
+ includeFlatpak = true
+ } = config || {};
+
+ const currentPlatform = platform();
+
+ // 1. Check for currently running browser process
+ if (includeRunning)
+ {
+ const runningBrowser = await getRunningBrowserPath(browserOrder, currentPlatform);
+ if (runningBrowser)
+ {
+ console.log(`[Found] Running ${runningBrowser.type} process: ${runningBrowser.path}`);
+ return { ...runningBrowser, source: "running" };
+ }
+ }
+
+ // 2. Windows: Check default system browser
+ if (includeSystemDefault && currentPlatform === "win32")
+ {
+ const defaultBrowser = await getWindowsDefaultBrowser(browserOrder);
+ if (defaultBrowser && browserOrder.includes(defaultBrowser.type))
+ {
+ console.log(`[Found] Windows default browser: ${defaultBrowser.path} (${defaultBrowser.type})`);
+ return { ...defaultBrowser, source: "system" };
+ }
+ }
+
+ // 3. Check standard install paths with custom priority
+ for (const browser of browserOrder)
+ {
+ const path = await findSystemBrowser(browser, currentPlatform);
+ if (path)
+ {
+ console.log(`[Found] Installed ${browser}: ${path}`);
+ return { path, type: browser, source: "system" };
+ }
+ }
+
+ // 4. Check Flatpaks (Linux only)
+ if (includeFlatpak && currentPlatform === "linux")
+ {
+ for (const browser of browserOrder)
+ {
+ const path = await findFlatpakBrowser(browser);
+ if (path)
+ {
+ console.log(`[Found] Flatpak ${browser}: ${path}`);
+ return { path, type: browser, source: "flatpak" };
+ }
+ }
+ }
+
+ console.error("No suitable browser found.");
+ return null;
+}
+
+// --- Helper: Find Running Process ---
+
+/**
+ * Attempts to find the path of a currently running browser (Chrome, Chromium, or Firefox).
+ *
+ * Platform-specific implementations:
+ * - Windows: Uses PowerShell to query running processes
+ * - Linux: Uses pgrep to find the process and resolves /proc/[pid]/exe
+ * - macOS: Uses ps command to find Chrome or Firefox in process list
+ *
+ * @param os - The operating system ("win32", "linux", or "darwin")
+ * @returns An object with path and type of the running browser, or null if not found
+ */
+async function getRunningBrowserPath (browserOrder: GetBrowserType[], os: string): Promise<{ path: string, type: GetBrowserType; } | null>
+{
+ try
+ {
+ if (os === "win32")
+ {
+ // PowerShell is most reliable for getting full paths on Windows
+ // Check for Firefox first, then Chrome
+ for (const processName of browserOrder)
+ {
+ const cmd = spawnSync([
+ "powershell",
+ "-NoProfile",
+ "-Command",
+ `(Get-Process ${processName} -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Path)`
+ ]);
+ const path = cmd.stdout.toString().trim();
+ if (path && await Bun.file(path).exists())
+ {
+ const browserType: GetBrowserType = processName === 'firefox' ? 'firefox' : 'chrome';
+ console.log(`[Browser] Found running ${browserType}: ${path}`);
+ return { path, type: browserType };
+ }
+ }
+ return null;
+ }
+
+ if (os === "linux")
+ {
+ const names: Record = {
+ chrome: ['chrome', 'google-chrome', 'google-chrome-stable'],
+ chromium: ['chromium'],
+ firefox: ['firefox'],
+ edge: ['edge']
+ };
+
+ // Find PID of firefox or chrome, then resolve the symlink in /proc
+ for (const processName of browserOrder.flatMap(b => names[b]))
+ {
+ const pgrep = spawnSync(["pgrep", "-o", processName]); // -o = oldest (parent)
+ const pid = pgrep.stdout.toString().trim();
+
+ if (!pid) continue;
+
+ // Read the symlink for the executable path using readlink
+ const linkPath = `/proc/${pid}/exe`;
+
+ // Use shell readlink to resolve the symlink
+ const readLink = spawnSync(["readlink", "-f", linkPath]);
+ const finalPath = readLink.stdout.toString().trim();
+
+ if (finalPath && await Bun.file(finalPath).exists())
+ {
+ const browserType: GetBrowserType = processName === 'firefox' ? 'firefox' : 'chrome';
+ console.log(`[Browser] Found running ${browserType}: ${finalPath}`);
+ return { path: finalPath, type: browserType };
+ }
+ }
+ return null;
+ }
+
+ if (os === "darwin")
+ {
+ // macOS: ps command to list process paths
+ const cmd = spawnSync(["ps", "-A", "-o", "comm"]);
+ const output = cmd.stdout.toString();
+
+ // Check for Firefox first
+ const firefoxMatch = output.split('\n').find(line => line.includes("Firefox.app/Contents/MacOS/firefox"));
+ if (firefoxMatch)
+ {
+ console.log(`[Browser] Found running firefox: ${firefoxMatch.trim()}`);
+ return { path: firefoxMatch.trim(), type: 'firefox' };
+ }
+
+ // Check for Chrome
+ const chromeMatch = output.split('\n').find(line => line.includes("Google Chrome.app/Contents/MacOS/Google Chrome"));
+ if (chromeMatch)
+ {
+ console.log(`[Browser] Found running chrome: ${chromeMatch.trim()}`);
+ return { path: chromeMatch.trim(), type: 'chrome' };
+ }
+
+ return null;
+ }
+ } catch (e)
+ {
+ // Ignore errors checking running processes
+ return null;
+ }
+ return null;
+}
+
+// --- Helper: Get Windows Default Browser ---
+
+/**
+ * Detects the default browser set in Windows via registry queries.
+ *
+ * Queries multiple registry locations for Windows 11+ and Windows 10 compatibility:
+ * - URL associations (Windows 11+)
+ * - File extension associations (Windows 10)
+ * - Classic ProgID associations
+ *
+ * Falls back through multiple methods if the primary registry keys are unavailable.
+ *
+ * @returns An object with the default browser's path and type, or null if detection fails
+ */
+async function getWindowsDefaultBrowser (allowed: GetBrowserType[]): Promise<{ path: string, type: GetBrowserType; } | null>
+{
+ try
+ {
+ // Query the registry for the default browser
+ // Windows 10/11 store default browser association in multiple places
+ const registryKeys = [
+ // Windows 11+ (Preferred)
+ 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice',
+ // Windows 10 fallback
+ 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.html\\UserChoice',
+ // Classic method - looks at .html file association
+ 'HKEY_CLASSES_ROOT\\.html'
+ ];
+
+ for (const regKey of registryKeys)
+ {
+ try
+ {
+ const cmd = spawnSync(["reg", "query", regKey]);
+
+ if (cmd.success)
+ {
+ const output = cmd.stdout.toString().toLowerCase();
+
+ // Check which browser is the default
+ if ((output.includes('chrome') || output.includes('google')) && allowed.includes('chrome'))
+ {
+ const chromePath = await findSystemBrowser("chrome", "win32");
+ if (chromePath) return { path: chromePath, type: "chrome" };
+ }
+
+ if ((output.includes('msedge') || output.includes('edge')) && allowed.includes('chromium'))
+ {
+ const edgePath = await findSystemBrowser("chromium", "win32");
+ if (edgePath && edgePath.includes('msedge')) return { path: edgePath, type: "chromium" };
+ }
+
+ if (output.includes('firefox') && allowed.includes('firefox'))
+ {
+ const firefoxPath = await findSystemBrowser("firefox", "win32");
+ if (firefoxPath) return { path: firefoxPath, type: "firefox" };
+ }
+ }
+ } catch (e)
+ {
+ // Try next registry key
+ }
+ }
+
+ // Fallback: Try to get progId for .html files
+ try
+ {
+ const progIdCmd = spawnSync(["reg", "query", "HKEY_CLASSES_ROOT\\.html", "/ve"]);
+ if (progIdCmd.success)
+ {
+ const progId = progIdCmd.stdout.toString().match(/REG_SZ\s+(.+?)(?:\r?\n|$)/)?.[1]?.trim();
+
+ if (progId)
+ {
+ // Query the ProgID's shell\\open\\command to get the browser path
+ const cmdKey = `HKEY_CLASSES_ROOT\\${progId}\\shell\\open\\command`;
+ const openCmd = spawnSync(["reg", "query", cmdKey, "/ve"]);
+
+ if (openCmd.success)
+ {
+ const execPath = openCmd.stdout.toString().match(/REG_SZ\s+"?([^"\r\n]+\.exe)/i)?.[1];
+
+ if (execPath && await Bun.file(execPath).exists())
+ {
+ // Determine browser type
+ if (execPath.toLowerCase().includes('chrome') && allowed.includes('chrome'))
+ {
+ return { path: execPath, type: "chrome" };
+ } else if ((execPath.toLowerCase().includes('edge') || execPath.toLowerCase().includes('msedge')) && allowed.includes('chromium'))
+ {
+ return { path: execPath, type: "chromium" };
+ } else if (execPath.toLowerCase().includes('firefox') && allowed.includes('firefox'))
+ {
+ return { path: execPath, type: "firefox" };
+ }
+ }
+ }
+ }
+ }
+ } catch (e)
+ {
+ // Fallback failed
+ }
+ } catch (e)
+ {
+ // Default browser detection failed
+ }
+
+ return null;
+}
+
+// --- Helper: Find System Installed Browser ---
+
+/**
+ * Searches for a browser installation in standard system locations.
+ *
+ * Platform-specific behavior:
+ * - Windows: Checks registry and common installation directories (Program Files, AppData, etc.)
+ * - macOS: Checks Applications folder
+ * - Linux: Uses `which` command to find binary in $PATH
+ *
+ * @param browser - The browser type to search for
+ * @param os - The operating system ("win32", "linux", or "darwin")
+ * @returns The full path to the browser executable, or null if not found
+ */
+async function findSystemBrowser (browser: GetBrowserType, os: string): Promise
+{
+ if (os === "win32")
+ {
+ // First, try registry lookup (most reliable on Windows)
+ const registryPath = await findBrowserViaRegistry(browser);
+ if (registryPath) return registryPath;
+
+ // Fallback to standard install paths
+ const standardPaths = getStandardWindowsPaths(browser);
+
+ for (const fullPath of standardPaths)
+ {
+ if (await Bun.file(fullPath).exists()) return fullPath;
+ }
+ return null;
+ }
+
+ if (os === "linux" || os === "darwin")
+ {
+ // Common binary names
+ const binMap: Record = {
+ chrome: ["google-chrome", "google-chrome-stable", "chrome"],
+ chromium: ["chromium", "chromium-browser"],
+ firefox: ["firefox"]
+ };
+
+ if (os === "darwin")
+ {
+ // macOS standard paths
+ const macPaths = {
+ chrome: "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
+ chromium: "/Applications/Chromium.app/Contents/MacOS/Chromium",
+ firefox: "/Applications/Firefox.app/Contents/MacOS/firefox"
+ };
+ if (await Bun.file(macPaths[browser]).exists()) return macPaths[browser];
+ return null;
+ }
+
+ // Linux: use `which` to find in $PATH
+ for (const bin of binMap[browser])
+ {
+ const cmd = spawnSync(["which", bin]);
+ if (cmd.success)
+ {
+ const path = cmd.stdout.toString().trim();
+ if (path && await Bun.file(path).exists()) return path;
+ }
+ }
+ }
+ return null;
+}
+
+// --- Helper: Windows Registry Lookup ---
+
+/**
+ * Queries Windows registry for browser installation paths.
+ *
+ * Checks App Paths registry hives which are populated by browser installers:
+ * - HKEY_LOCAL_MACHINE (system-wide installations)
+ * - HKEY_LOCAL_MACHINE\WOW6432Node (32-bit applications on 64-bit systems)
+ * - HKEY_CURRENT_USER (user-specific installations)
+ *
+ * This is more reliable than hardcoded paths as it dynamically finds where
+ * the browser installer registered itself.
+ *
+ * @param browser - The browser type to search for
+ * @returns The full path to the browser executable from registry, or null if not found
+ */
+async function findBrowserViaRegistry (browser: GetBrowserType): Promise
+{
+ try
+ {
+ // Registry paths for browser installations
+ const registryPaths: Record = {
+ chrome: [
+ // Standard Chrome registry paths
+ 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe',
+ 'HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe',
+ // User-specific Chrome registry
+ 'HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe'
+ ],
+ chromium: [
+ 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chromium.exe',
+ 'HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chromium.exe'
+ ],
+ firefox: [
+ 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe',
+ 'HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\App Paths\\firefox.exe',
+ // Check Mozilla Firefox registry for install location
+ 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Mozilla\\Mozilla Firefox'
+ ]
+ };
+
+ for (const regPath of registryPaths[browser])
+ {
+ try
+ {
+ const cmd = spawnSync([
+ "reg",
+ "query",
+ regPath,
+ "/ve"
+ ]);
+
+ if (cmd.success)
+ {
+ const output = cmd.stdout.toString();
+ // Extract path from registry output (format: " (Default) REG_SZ C:\path\to\exe")
+ const match = output.match(/REG_SZ\s+(.+?)(?:\r?\n|$)/);
+ if (match && match[1])
+ {
+ const path = match[1].trim();
+ if (path && await Bun.file(path).exists())
+ {
+ return path;
+ }
+ }
+ }
+ } catch (e)
+ {
+ // Continue to next registry path
+ }
+ }
+ } catch (e)
+ {
+ // Registry lookup failed, will fallback to standard paths
+ }
+ return null;
+}
+
+// --- Helper: Standard Windows Browser Paths ---
+
+/**
+ * Generates a list of common Windows browser installation paths to check.
+ *
+ * Includes:
+ * - Program Files locations (64-bit and 32-bit)
+ * - LocalAppData (user-specific installations)
+ * - Microsoft Edge paths (treated as chromium)
+ * - Portable installations and custom locations
+ *
+ * @param browser - The browser type to generate paths for
+ * @returns An array of potential browser executable paths
+ */
+function getStandardWindowsPaths (browser: GetBrowserType): string[]
+{
+ const paths: string[] = [];
+ const prefixes = [
+ process.env.LOCALAPPDATA,
+ process.env.PROGRAMFILES,
+ process.env["PROGRAMFILES(X86)"]
+ ].filter(Boolean) as string[];
+
+ // Standard installation patterns
+ const browserPatterns: Record = {
+ chrome: [
+ "\\Google\\Chrome\\Application\\chrome.exe",
+ "\\Google\\Chrome\\chrome.exe"
+ ],
+ chromium: [
+ "\\Chromium\\Application\\chrome.exe",
+ "\\Chromium\\chromium.exe"
+ ],
+ firefox: [
+ "\\Mozilla Firefox\\firefox.exe",
+ "\\Mozilla\\Firefox\\firefox.exe",
+ "\\Firefox\\firefox.exe"
+ ]
+ };
+
+ // Add standard paths
+ for (const prefix of prefixes)
+ {
+ for (const pattern of browserPatterns[browser])
+ {
+ paths.push(`${prefix}${pattern}`);
+ }
+ }
+
+ // Add common user-specific paths (especially for Chrome Portable or custom installations)
+ const userProfile = process.env.USERPROFILE;
+ if (userProfile)
+ {
+ if (browser === "chrome")
+ {
+ paths.push(`${userProfile}\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe`);
+ paths.push(`${userProfile}\\AppData\\Roaming\\Google\\Chrome\\Application\\chrome.exe`);
+ } else if (browser === "firefox")
+ {
+ paths.push(`${userProfile}\\AppData\\Local\\Mozilla Firefox\\firefox.exe`);
+ paths.push(`${userProfile}\\AppData\\Roaming\\Mozilla Firefox\\firefox.exe`);
+ // Also check for Program Files under user profile (some custom installs)
+ paths.push(`${userProfile}\\AppData\\Local\\Programs\\Firefox\\firefox.exe`);
+ }
+ }
+
+ // Add alternative common locations for Edge (treated as chromium)
+ if (browser === "chromium")
+ {
+ const edgePaths = [
+ `${process.env.PROGRAMFILES}\\Microsoft\\Edge\\Application\\msedge.exe`,
+ `${process.env["PROGRAMFILES(X86)"]}\\Microsoft\\Edge\\Application\\msedge.exe`,
+ `${userProfile}\\AppData\\Local\\Microsoft\\Edge\\Application\\msedge.exe`
+ ].filter(p => p);
+ paths.push(...edgePaths);
+ }
+
+ return paths;
+}
+
+// --- Helper: Find Flatpak (Linux Only) ---
+
+/**
+ * Searches for a Flatpak browser installation on Linux.
+ *
+ * Checks if a Flatpak is installed by querying the flatpak command,
+ * then looks for the exported binary in standard Flatpak export directories.
+ *
+ * Flatpak paths checked:
+ * - /var/lib/flatpak/exports/bin/ (system-wide)
+ * - ~/.local/share/flatpak/exports/bin/ (user-specific)
+ *
+ * @param browser - The browser type to search for
+ * @returns The path to the Flatpak browser binary, or null if not found
+ */
+async function findFlatpakBrowser (browser: GetBrowserType): Promise
+{
+ // Check if flatpak is installed first
+ if (spawnSync(["which", "flatpak"]).exitCode !== 0) return null;
+
+ const flatpakIds = {
+ chrome: "com.google.Chrome",
+ chromium: "org.chromium.Chromium",
+ firefox: "org.mozilla.firefox"
+ };
+
+ const appId = flatpakIds[browser];
+
+ // Check if specific flatpak is installed
+ const checkCmd = spawnSync(["flatpak", "info", appId]);
+ if (checkCmd.success)
+ {
+ // We return the flatpak run command wrapper or the path?
+ // Usually tools expect an executable. For flatpak, we might need a wrapper script
+ // or just return "flatpak" with arguments.
+ // However, usually tools want a single path.
+ // We will return the internal path if accessible, or the flatpak binary path usually isn't enough.
+ // OPTION A: Return the standard export path if it exists
+ const exportPath = `/var/lib/flatpak/exports/bin/${appId}`;
+ if (await Bun.file(exportPath).exists()) return exportPath;
+
+ const userExportPath = `${process.env.HOME}/.local/share/flatpak/exports/bin/${appId}`;
+ if (await Bun.file(userExportPath).exists()) return userExportPath;
+ }
+ return null;
+}
\ No newline at end of file
diff --git a/src/bun/webview-worker.ts b/src/bun/webview-worker.ts
new file mode 100644
index 0000000..4eafaac
--- /dev/null
+++ b/src/bun/webview-worker.ts
@@ -0,0 +1,9 @@
+import Webview from "@rcompat/webview";
+import platform from "@rcompat/webview/windows-x64";
+import { SERVER_URL } from "../shared/constants";
+import { host } from "./utils";
+
+console.log("Launching Webview");
+const webview = new Webview({ debug: import.meta.env.NODE_ENV === 'development', platform });
+webview.navigate(SERVER_URL(host));
+webview.run();
\ No newline at end of file
diff --git a/src/clients/romm/@tanstack/react-query.gen.ts b/src/clients/romm/@tanstack/react-query.gen.ts
new file mode 100644
index 0000000..ae5aaab
--- /dev/null
+++ b/src/clients/romm/@tanstack/react-query.gen.ts
@@ -0,0 +1,2335 @@
+// This file is auto-generated by @hey-api/openapi-ts
+
+import { type DefaultError, type InfiniteData, infiniteQueryOptions, queryOptions, type UseMutationOptions } from '@tanstack/react-query';
+
+import { client } from '../client.gen';
+import { addCollectionApiCollectionsPost, addExclusionApiConfigExcludePost, addFirmwareApiFirmwarePost, addPlatformApiPlatformsPost, addPlatformBindingApiConfigSystemPlatformsPost, addPlatformVersionApiConfigSystemVersionsPost, addRomApiRomsPost, addRomManualsApiRomsIdManualsPost, addSaveApiSavesPost, addScreenshotApiScreenshotsPost, addSmartCollectionApiCollectionsSmartPost, addStateApiStatesPost, addUserApiUsersPost, authOpenidApiOauthOpenidGet, createInviteLinkApiUsersInviteLinkPost, createRomNoteApiRomsIdNotesPost, createSetupPlatformsApiSetupPlatformsPost, createUserFromInviteApiUsersRegisterPost, deleteCollectionApiCollectionsIdDelete, deleteExclusionApiConfigExcludeExclusionTypeExclusionValueDelete, deleteFirmwareApiFirmwareDeletePost, deletePlatformApiPlatformsIdDelete, deletePlatformBindingApiConfigSystemPlatformsFsSlugDelete, deletePlatformVersionApiConfigSystemVersionsFsSlugDelete, deleteRomManualsApiRomsIdManualsDelete, deleteRomNoteApiRomsIdNotesNoteIdDelete, deleteRomsApiRomsDeletePost, deleteSavesApiSavesDeletePost, deleteSmartCollectionApiCollectionsSmartIdDelete, deleteStatesApiStatesDeletePost, deleteUserApiUsersIdDelete, downloadRomsApiRomsDownloadGet, exportGamelistApiGamelistExportPost, fpkgiFeedApiFeedsFpkgiPlatformSlugGet, getCollectionApiCollectionsIdGet, getCollectionsApiCollectionsGet, getConfigApiConfigGet, getCurrentUserApiUsersMeGet, getFirmwareApiFirmwareIdGet, getFirmwareContentApiFirmwareIdContentFileNameGet, getPlatformApiPlatformsIdGet, getPlatformFirmwareApiFirmwareGet, getPlatformsApiPlatformsGet, getRawAssetApiRawAssetsPathGet, getRomApiRomsIdGet, getRomByHashApiRomsByHashGet, getRomByMetadataProviderApiRomsByMetadataProviderGet, getRomContentApiRomsIdContentFileNameGet, getRomfileApiRomsFilesIdGet, getRomfileContentApiRomsfilesIdContentFileNameGet, getRomFiltersApiRomsFiltersGet, getRomNotesApiRomsIdNotesGet, getRomsApiRomsGet, getRoomsApiNetplayListGet, getSaveApiSavesIdGet, getSavesApiSavesGet, getSetupLibraryInfoApiSetupLibraryGet, getSmartCollectionApiCollectionsSmartIdGet, getSmartCollectionsApiCollectionsSmartGet, getStateApiStatesIdGet, getStatesApiStatesGet, getSupportedPlatformsEndpointApiPlatformsSupportedGet, getTaskByIdApiTasksTaskIdGet, getTasksStatusApiTasksStatusGet, getUserApiUsersIdGet, getUsersApiUsersGet, getVirtualCollectionApiCollectionsVirtualIdGet, getVirtualCollectionsApiCollectionsVirtualGet, heartbeatApiHeartbeatGet, kekatsuDsFeedApiFeedsKekatsuPlatformSlugGet, listTasksApiTasksGet, loginApiLoginPost, loginViaOpenidApiLoginOpenidGet, logoutApiLogoutPost, metadataHeartbeatApiHeartbeatMetadataSourceGet, type Options, pkgiPs3FeedApiFeedsPkgiPs3ContentTypeGet, pkgiPspFeedApiFeedsPkgiPspContentTypeGet, pkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGet, platformsWebrcadeFeedApiFeedsWebrcadeGet, refreshRetroAchievementsApiUsersIdRaRefreshPost, requestPasswordResetApiForgotPasswordPost, resetPasswordApiResetPasswordPost, runAllTasksApiTasksRunPost, runSingleTaskApiTasksRunTaskNamePost, searchCoverApiSearchCoverGet, searchRomApiSearchRomsGet, statsApiStatsGet, tinfoilIndexFeedApiFeedsTinfoilGet, tokenApiTokenPost, updateCollectionApiCollectionsIdPut, updatePlatformApiPlatformsIdPut, updateRomApiRomsIdPut, updateRomNoteApiRomsIdNotesNoteIdPut, updateRomUserApiRomsIdPropsPut, updateSaveApiSavesIdPut, updateSmartCollectionApiCollectionsSmartIdPut, updateStateApiStatesIdPut, updateUserApiUsersIdPut } from '../sdk.gen';
+import type { AddCollectionApiCollectionsPostData, AddCollectionApiCollectionsPostError, AddCollectionApiCollectionsPostResponse, AddExclusionApiConfigExcludePostData, AddFirmwareApiFirmwarePostData, AddFirmwareApiFirmwarePostError, AddFirmwareApiFirmwarePostResponse, AddPlatformApiPlatformsPostData, AddPlatformApiPlatformsPostError, AddPlatformApiPlatformsPostResponse, AddPlatformBindingApiConfigSystemPlatformsPostData, AddPlatformVersionApiConfigSystemVersionsPostData, AddRomApiRomsPostData, AddRomApiRomsPostError, AddRomManualsApiRomsIdManualsPostData, AddRomManualsApiRomsIdManualsPostError, AddSaveApiSavesPostData, AddSaveApiSavesPostError, AddSaveApiSavesPostResponse, AddScreenshotApiScreenshotsPostData, AddScreenshotApiScreenshotsPostError, AddScreenshotApiScreenshotsPostResponse, AddSmartCollectionApiCollectionsSmartPostData, AddSmartCollectionApiCollectionsSmartPostError, AddSmartCollectionApiCollectionsSmartPostResponse, AddStateApiStatesPostData, AddStateApiStatesPostError, AddStateApiStatesPostResponse, AddUserApiUsersPostData, AddUserApiUsersPostError, AddUserApiUsersPostResponse, AuthOpenidApiOauthOpenidGetData, CreateInviteLinkApiUsersInviteLinkPostData, CreateInviteLinkApiUsersInviteLinkPostError, CreateInviteLinkApiUsersInviteLinkPostResponse, CreateRomNoteApiRomsIdNotesPostData, CreateRomNoteApiRomsIdNotesPostError, CreateRomNoteApiRomsIdNotesPostResponse, CreateSetupPlatformsApiSetupPlatformsPostData, CreateSetupPlatformsApiSetupPlatformsPostError, CreateUserFromInviteApiUsersRegisterPostData, CreateUserFromInviteApiUsersRegisterPostError, CreateUserFromInviteApiUsersRegisterPostResponse, DeleteCollectionApiCollectionsIdDeleteData, DeleteCollectionApiCollectionsIdDeleteError, DeleteExclusionApiConfigExcludeExclusionTypeExclusionValueDeleteData, DeleteExclusionApiConfigExcludeExclusionTypeExclusionValueDeleteError, DeleteFirmwareApiFirmwareDeletePostData, DeleteFirmwareApiFirmwareDeletePostError, DeleteFirmwareApiFirmwareDeletePostResponse, DeletePlatformApiPlatformsIdDeleteData, DeletePlatformApiPlatformsIdDeleteError, DeletePlatformBindingApiConfigSystemPlatformsFsSlugDeleteData, DeletePlatformBindingApiConfigSystemPlatformsFsSlugDeleteError, DeletePlatformVersionApiConfigSystemVersionsFsSlugDeleteData, DeletePlatformVersionApiConfigSystemVersionsFsSlugDeleteError, DeleteRomManualsApiRomsIdManualsDeleteData, DeleteRomManualsApiRomsIdManualsDeleteError, DeleteRomNoteApiRomsIdNotesNoteIdDeleteData, DeleteRomNoteApiRomsIdNotesNoteIdDeleteError, DeleteRomNoteApiRomsIdNotesNoteIdDeleteResponse, DeleteRomsApiRomsDeletePostData, DeleteRomsApiRomsDeletePostError, DeleteRomsApiRomsDeletePostResponse, DeleteSavesApiSavesDeletePostData, DeleteSavesApiSavesDeletePostError, DeleteSavesApiSavesDeletePostResponse, DeleteSmartCollectionApiCollectionsSmartIdDeleteData, DeleteSmartCollectionApiCollectionsSmartIdDeleteError, DeleteStatesApiStatesDeletePostData, DeleteStatesApiStatesDeletePostError, DeleteStatesApiStatesDeletePostResponse, DeleteUserApiUsersIdDeleteData, DeleteUserApiUsersIdDeleteError, DownloadRomsApiRomsDownloadGetData, DownloadRomsApiRomsDownloadGetError, ExportGamelistApiGamelistExportPostData, ExportGamelistApiGamelistExportPostError, FpkgiFeedApiFeedsFpkgiPlatformSlugGetData, FpkgiFeedApiFeedsFpkgiPlatformSlugGetError, GetCollectionApiCollectionsIdGetData, GetCollectionApiCollectionsIdGetError, GetCollectionApiCollectionsIdGetResponse, GetCollectionsApiCollectionsGetData, GetCollectionsApiCollectionsGetError, GetCollectionsApiCollectionsGetResponse, GetConfigApiConfigGetData, GetConfigApiConfigGetResponse, GetCurrentUserApiUsersMeGetData, GetCurrentUserApiUsersMeGetResponse, GetFirmwareApiFirmwareIdGetData, GetFirmwareApiFirmwareIdGetError, GetFirmwareApiFirmwareIdGetResponse, GetFirmwareContentApiFirmwareIdContentFileNameGetData, GetFirmwareContentApiFirmwareIdContentFileNameGetError, GetPlatformApiPlatformsIdGetData, GetPlatformApiPlatformsIdGetError, GetPlatformApiPlatformsIdGetResponse, GetPlatformFirmwareApiFirmwareGetData, GetPlatformFirmwareApiFirmwareGetError, GetPlatformFirmwareApiFirmwareGetResponse, GetPlatformsApiPlatformsGetData, GetPlatformsApiPlatformsGetError, GetPlatformsApiPlatformsGetResponse, GetRawAssetApiRawAssetsPathGetData, GetRawAssetApiRawAssetsPathGetError, GetRomApiRomsIdGetData, GetRomApiRomsIdGetError, GetRomApiRomsIdGetResponse, GetRomByHashApiRomsByHashGetData, GetRomByHashApiRomsByHashGetError, GetRomByHashApiRomsByHashGetResponse, GetRomByMetadataProviderApiRomsByMetadataProviderGetData, GetRomByMetadataProviderApiRomsByMetadataProviderGetError, GetRomByMetadataProviderApiRomsByMetadataProviderGetResponse, GetRomContentApiRomsIdContentFileNameGetData, GetRomContentApiRomsIdContentFileNameGetError, GetRomfileApiRomsFilesIdGetData, GetRomfileApiRomsFilesIdGetError, GetRomfileApiRomsFilesIdGetResponse, GetRomfileContentApiRomsfilesIdContentFileNameGetData, GetRomfileContentApiRomsfilesIdContentFileNameGetError, GetRomFiltersApiRomsFiltersGetData, GetRomFiltersApiRomsFiltersGetResponse, GetRomNotesApiRomsIdNotesGetData, GetRomNotesApiRomsIdNotesGetError, GetRomNotesApiRomsIdNotesGetResponse, GetRomsApiRomsGetData, GetRomsApiRomsGetError, GetRomsApiRomsGetResponse, GetRoomsApiNetplayListGetData, GetRoomsApiNetplayListGetError, GetRoomsApiNetplayListGetResponse, GetSaveApiSavesIdGetData, GetSaveApiSavesIdGetError, GetSaveApiSavesIdGetResponse, GetSavesApiSavesGetData, GetSavesApiSavesGetError, GetSavesApiSavesGetResponse, GetSetupLibraryInfoApiSetupLibraryGetData, GetSmartCollectionApiCollectionsSmartIdGetData, GetSmartCollectionApiCollectionsSmartIdGetError, GetSmartCollectionApiCollectionsSmartIdGetResponse, GetSmartCollectionsApiCollectionsSmartGetData, GetSmartCollectionsApiCollectionsSmartGetError, GetSmartCollectionsApiCollectionsSmartGetResponse, GetStateApiStatesIdGetData, GetStateApiStatesIdGetError, GetStateApiStatesIdGetResponse, GetStatesApiStatesGetData, GetStatesApiStatesGetError, GetStatesApiStatesGetResponse, GetSupportedPlatformsEndpointApiPlatformsSupportedGetData, GetSupportedPlatformsEndpointApiPlatformsSupportedGetResponse, GetTaskByIdApiTasksTaskIdGetData, GetTaskByIdApiTasksTaskIdGetError, GetTaskByIdApiTasksTaskIdGetResponse, GetTasksStatusApiTasksStatusGetData, GetTasksStatusApiTasksStatusGetResponse, GetUserApiUsersIdGetData, GetUserApiUsersIdGetError, GetUserApiUsersIdGetResponse, GetUsersApiUsersGetData, GetUsersApiUsersGetResponse, GetVirtualCollectionApiCollectionsVirtualIdGetData, GetVirtualCollectionApiCollectionsVirtualIdGetError, GetVirtualCollectionApiCollectionsVirtualIdGetResponse, GetVirtualCollectionsApiCollectionsVirtualGetData, GetVirtualCollectionsApiCollectionsVirtualGetError, GetVirtualCollectionsApiCollectionsVirtualGetResponse, HeartbeatApiHeartbeatGetData, HeartbeatApiHeartbeatGetResponse, KekatsuDsFeedApiFeedsKekatsuPlatformSlugGetData, KekatsuDsFeedApiFeedsKekatsuPlatformSlugGetError, ListTasksApiTasksGetData, ListTasksApiTasksGetResponse, LoginApiLoginPostData, LoginViaOpenidApiLoginOpenidGetData, LogoutApiLogoutPostData, MetadataHeartbeatApiHeartbeatMetadataSourceGetData, MetadataHeartbeatApiHeartbeatMetadataSourceGetError, MetadataHeartbeatApiHeartbeatMetadataSourceGetResponse, PkgiPs3FeedApiFeedsPkgiPs3ContentTypeGetData, PkgiPs3FeedApiFeedsPkgiPs3ContentTypeGetError, PkgiPspFeedApiFeedsPkgiPspContentTypeGetData, PkgiPspFeedApiFeedsPkgiPspContentTypeGetError, PkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGetData, PkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGetError, PlatformsWebrcadeFeedApiFeedsWebrcadeGetData, PlatformsWebrcadeFeedApiFeedsWebrcadeGetResponse, RefreshRetroAchievementsApiUsersIdRaRefreshPostData, RefreshRetroAchievementsApiUsersIdRaRefreshPostError, RequestPasswordResetApiForgotPasswordPostData, RequestPasswordResetApiForgotPasswordPostError, ResetPasswordApiResetPasswordPostData, ResetPasswordApiResetPasswordPostError, RunAllTasksApiTasksRunPostData, RunAllTasksApiTasksRunPostResponse, RunSingleTaskApiTasksRunTaskNamePostData, RunSingleTaskApiTasksRunTaskNamePostError, RunSingleTaskApiTasksRunTaskNamePostResponse, SearchCoverApiSearchCoverGetData, SearchCoverApiSearchCoverGetError, SearchCoverApiSearchCoverGetResponse, SearchRomApiSearchRomsGetData, SearchRomApiSearchRomsGetError, SearchRomApiSearchRomsGetResponse, StatsApiStatsGetData, StatsApiStatsGetResponse, TinfoilIndexFeedApiFeedsTinfoilGetData, TinfoilIndexFeedApiFeedsTinfoilGetError, TinfoilIndexFeedApiFeedsTinfoilGetResponse, TokenApiTokenPostData, TokenApiTokenPostError, TokenApiTokenPostResponse, UpdateCollectionApiCollectionsIdPutData, UpdateCollectionApiCollectionsIdPutError, UpdateCollectionApiCollectionsIdPutResponse, UpdatePlatformApiPlatformsIdPutData, UpdatePlatformApiPlatformsIdPutError, UpdatePlatformApiPlatformsIdPutResponse, UpdateRomApiRomsIdPutData, UpdateRomApiRomsIdPutError, UpdateRomApiRomsIdPutResponse, UpdateRomNoteApiRomsIdNotesNoteIdPutData, UpdateRomNoteApiRomsIdNotesNoteIdPutError, UpdateRomNoteApiRomsIdNotesNoteIdPutResponse, UpdateRomUserApiRomsIdPropsPutData, UpdateRomUserApiRomsIdPropsPutError, UpdateRomUserApiRomsIdPropsPutResponse, UpdateSaveApiSavesIdPutData, UpdateSaveApiSavesIdPutError, UpdateSaveApiSavesIdPutResponse, UpdateSmartCollectionApiCollectionsSmartIdPutData, UpdateSmartCollectionApiCollectionsSmartIdPutError, UpdateSmartCollectionApiCollectionsSmartIdPutResponse, UpdateStateApiStatesIdPutData, UpdateStateApiStatesIdPutError, UpdateStateApiStatesIdPutResponse, UpdateUserApiUsersIdPutData, UpdateUserApiUsersIdPutError, UpdateUserApiUsersIdPutResponse } from '../types.gen';
+
+export type QueryKey = [
+ Pick & {
+ _id: string;
+ _infinite?: boolean;
+ tags?: ReadonlyArray;
+ }
+];
+
+const createQueryKey = (id: string, options?: TOptions, infinite?: boolean, tags?: ReadonlyArray): [
+ QueryKey[0]
+] => {
+ const params: QueryKey[0] = { _id: id, baseUrl: options?.baseUrl || (options?.client ?? client).getConfig().baseUrl } as QueryKey[0];
+ if (infinite) {
+ params._infinite = infinite;
+ }
+ if (tags) {
+ params.tags = tags;
+ }
+ if (options?.body) {
+ params.body = options.body;
+ }
+ if (options?.headers) {
+ params.headers = options.headers;
+ }
+ if (options?.path) {
+ params.path = options.path;
+ }
+ if (options?.query) {
+ params.query = options.query;
+ }
+ return [params];
+};
+
+export const heartbeatApiHeartbeatGetQueryKey = (options?: Options) => createQueryKey('heartbeatApiHeartbeatGet', options);
+
+/**
+ * Heartbeat
+ *
+ * Endpoint to set the CSRF token in cache and return all the basic RomM config
+ *
+ * Returns:
+ * HeartbeatReturn: TypedDict structure with all the defined values in the HeartbeatReturn class.
+ */
+export const heartbeatApiHeartbeatGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await heartbeatApiHeartbeatGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: heartbeatApiHeartbeatGetQueryKey(options)
+});
+
+export const metadataHeartbeatApiHeartbeatMetadataSourceGetQueryKey = (options: Options) => createQueryKey('metadataHeartbeatApiHeartbeatMetadataSourceGet', options);
+
+/**
+ * Metadata Heartbeat
+ *
+ * Endpoint to return the heartbeat of the metadata sources
+ */
+export const metadataHeartbeatApiHeartbeatMetadataSourceGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await metadataHeartbeatApiHeartbeatMetadataSourceGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: metadataHeartbeatApiHeartbeatMetadataSourceGetQueryKey(options)
+});
+
+export const getSetupLibraryInfoApiSetupLibraryGetQueryKey = (options?: Options) => createQueryKey('getSetupLibraryInfoApiSetupLibraryGet', options);
+
+/**
+ * Get Setup Library Info
+ *
+ * Get library structure information for setup wizard.
+ *
+ * Only accessible during initial setup (no admin users) or with authentication.
+ *
+ * Returns:
+ * - detected_structure: "struct_a" (roms/{platform}), "struct_b" ({platform}/roms), or None
+ * - existing_platforms: list of objects with fs_slug and rom_count
+ * - supported_platforms: list of all supported platforms with metadata
+ */
+export const getSetupLibraryInfoApiSetupLibraryGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getSetupLibraryInfoApiSetupLibraryGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getSetupLibraryInfoApiSetupLibraryGetQueryKey(options)
+});
+
+/**
+ * Create Setup Platforms
+ *
+ * Create platform folders during setup wizard.
+ *
+ * Only accessible during initial setup (no admin users) or with authentication.
+ *
+ * Args:
+ * platform_slugs: List of platform fs_slugs to create
+ *
+ * Returns:
+ * - success: bool
+ * - created_count: number of platforms created
+ * - message: success or error message
+ */
+export const createSetupPlatformsApiSetupPlatformsPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await createSetupPlatformsApiSetupPlatformsPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Login
+ *
+ * Session login endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ * credentials: Defaults to Depends(HTTPBasic()).
+ *
+ * Raises:
+ * CredentialsException: Invalid credentials
+ * UserDisabledException: Auth is disabled
+ */
+export const loginApiLoginPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await loginApiLoginPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Logout
+ *
+ * Session logout endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ */
+export const logoutApiLogoutPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await logoutApiLogoutPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Token
+ *
+ * OAuth2 token endpoint
+ *
+ * Args:
+ * form_data (Annotated[OAuth2RequestForm, Depends): Form Data with OAuth2 info
+ *
+ * Raises:
+ * HTTPException: Missing refresh token
+ * HTTPException: Invalid refresh token
+ * HTTPException: Missing username or password
+ * HTTPException: Invalid username or password
+ * HTTPException: Client credentials are not yet supported
+ * HTTPException: Invalid or unsupported grant type
+ * HTTPException: Insufficient scope
+ *
+ * Returns:
+ * TokenResponse: TypedDict with the new generated token info
+ */
+export const tokenApiTokenPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await tokenApiTokenPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const loginViaOpenidApiLoginOpenidGetQueryKey = (options?: Options) => createQueryKey('loginViaOpenidApiLoginOpenidGet', options);
+
+/**
+ * Login Via Openid
+ *
+ * OIDC login endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ *
+ * Raises:
+ * OIDCDisabledException: OAuth is disabled
+ * OIDCNotConfiguredException: OAuth not configured
+ *
+ * Returns:
+ * RedirectResponse: Redirect to OIDC provider
+ */
+export const loginViaOpenidApiLoginOpenidGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await loginViaOpenidApiLoginOpenidGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: loginViaOpenidApiLoginOpenidGetQueryKey(options)
+});
+
+export const authOpenidApiOauthOpenidGetQueryKey = (options?: Options) => createQueryKey('authOpenidApiOauthOpenidGet', options);
+
+/**
+ * Auth Openid
+ *
+ * OIDC callback endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ *
+ * Raises:
+ * OIDCDisabledException: OAuth is disabled
+ * OIDCNotConfiguredException: OAuth not configured
+ * AuthCredentialsException: Invalid credentials
+ * UserDisabledException: Auth is disabled
+ *
+ * Returns:
+ * RedirectResponse: Redirect to home page
+ */
+export const authOpenidApiOauthOpenidGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await authOpenidApiOauthOpenidGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: authOpenidApiOauthOpenidGetQueryKey(options)
+});
+
+/**
+ * Request Password Reset
+ *
+ * Request a password reset link for the user.
+ *
+ * Args:
+ * username (str): Username of the user requesting the reset
+ * Returns:
+ * None: Returns 200 OK status
+ */
+export const requestPasswordResetApiForgotPasswordPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await requestPasswordResetApiForgotPasswordPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Reset Password
+ *
+ * Reset password using the token.
+ *
+ * Args:
+ * token (str): Reset token from the URL
+ * new_password (str): New user password
+ *
+ * Returns:
+ * None: Returns 200 OK status
+ */
+export const resetPasswordApiResetPasswordPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await resetPasswordApiResetPasswordPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getUsersApiUsersGetQueryKey = (options?: Options) => createQueryKey('getUsersApiUsersGet', options);
+
+/**
+ * Get Users
+ *
+ * Get all users endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ *
+ * Returns:
+ * list[UserSchema]: All users stored in the RomM's database
+ */
+export const getUsersApiUsersGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getUsersApiUsersGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getUsersApiUsersGetQueryKey(options)
+});
+
+/**
+ * Add User
+ *
+ * Create user endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Requests object
+ * username (str): User username
+ * password (str): User password
+ * email (str): User email
+ * role (str): RomM Role object represented as string
+ *
+ * Returns:
+ * UserSchema: Newly created user
+ */
+export const addUserApiUsersPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addUserApiUsersPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Create Invite Link
+ *
+ * Create an invite link for a user.
+ *
+ * Args:
+ * request (Request): FastAPI Request object
+ * role (str): The role of the user
+ *
+ * Returns:
+ * InviteLinkSchema: Invite link
+ */
+export const createInviteLinkApiUsersInviteLinkPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await createInviteLinkApiUsersInviteLinkPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Create User From Invite
+ *
+ * Create user endpoint with invite link
+ *
+ * Args:
+ * username (str): User username
+ * email (str): User email
+ * password (str): User password
+ * token (str): Invite link token
+ *
+ * Returns:
+ * UserSchema: Newly created user
+ */
+export const createUserFromInviteApiUsersRegisterPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await createUserFromInviteApiUsersRegisterPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getCurrentUserApiUsersMeGetQueryKey = (options?: Options) => createQueryKey('getCurrentUserApiUsersMeGet', options);
+
+/**
+ * Get Current User
+ *
+ * Get current user endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ *
+ * Returns:
+ * UserSchema | None: Current user
+ */
+export const getCurrentUserApiUsersMeGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getCurrentUserApiUsersMeGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getCurrentUserApiUsersMeGetQueryKey(options)
+});
+
+/**
+ * Delete User
+ *
+ * Delete a user by ID.
+ *
+ * Raises:
+ * HTTPException: User is not found in database
+ * HTTPException: User deleting itself
+ * HTTPException: User is the last admin user
+ */
+export const deleteUserApiUsersIdDeleteMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deleteUserApiUsersIdDelete({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getUserApiUsersIdGetQueryKey = (options: Options) => createQueryKey('getUserApiUsersIdGet', options);
+
+/**
+ * Get User
+ *
+ * Get user endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ *
+ * Returns:
+ * UserSchem: User stored in the RomM's database
+ */
+export const getUserApiUsersIdGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getUserApiUsersIdGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getUserApiUsersIdGetQueryKey(options)
+});
+
+/**
+ * Update User
+ *
+ * Update user endpoint
+ *
+ * Args:
+ * request (Request): Fastapi Requests object
+ * user_id (int): User internal id
+ * form_data (Annotated[UserUpdateForm, Depends): Form Data with user updated info
+ *
+ * Raises:
+ * HTTPException: User is not found in database
+ * HTTPException: Username already in use by another user
+ *
+ * Returns:
+ * UserSchema: Updated user info
+ */
+export const updateUserApiUsersIdPutMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await updateUserApiUsersIdPut({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Refresh RetroAchievements
+ *
+ * Refresh RetroAchievements progression data for a user.
+ */
+export const refreshRetroAchievementsApiUsersIdRaRefreshPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await refreshRetroAchievementsApiUsersIdRaRefreshPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getPlatformsApiPlatformsGetQueryKey = (options?: Options) => createQueryKey('getPlatformsApiPlatformsGet', options);
+
+/**
+ * Get Platforms
+ *
+ * Retrieve platforms.
+ */
+export const getPlatformsApiPlatformsGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getPlatformsApiPlatformsGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getPlatformsApiPlatformsGetQueryKey(options)
+});
+
+/**
+ * Add Platform
+ *
+ * Create a platform.
+ */
+export const addPlatformApiPlatformsPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addPlatformApiPlatformsPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getSupportedPlatformsEndpointApiPlatformsSupportedGetQueryKey = (options?: Options) => createQueryKey('getSupportedPlatformsEndpointApiPlatformsSupportedGet', options);
+
+/**
+ * Get Supported Platforms Endpoint
+ *
+ * Retrieve the list of supported platforms.
+ */
+export const getSupportedPlatformsEndpointApiPlatformsSupportedGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getSupportedPlatformsEndpointApiPlatformsSupportedGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getSupportedPlatformsEndpointApiPlatformsSupportedGetQueryKey(options)
+});
+
+/**
+ * Delete Platform
+ *
+ * Delete a platform by ID.
+ */
+export const deletePlatformApiPlatformsIdDeleteMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deletePlatformApiPlatformsIdDelete({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getPlatformApiPlatformsIdGetQueryKey = (options: Options) => createQueryKey('getPlatformApiPlatformsIdGet', options);
+
+/**
+ * Get Platform
+ *
+ * Retrieve a platform by ID.
+ */
+export const getPlatformApiPlatformsIdGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getPlatformApiPlatformsIdGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getPlatformApiPlatformsIdGetQueryKey(options)
+});
+
+/**
+ * Update Platform
+ *
+ * Update a platform.
+ */
+export const updatePlatformApiPlatformsIdPutMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await updatePlatformApiPlatformsIdPut({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getRomsApiRomsGetQueryKey = (options?: Options) => createQueryKey('getRomsApiRomsGet', options);
+
+/**
+ * Get Roms
+ *
+ * Retrieve roms.
+ */
+export const getRomsApiRomsGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomsApiRomsGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomsApiRomsGetQueryKey(options)
+});
+
+const createInfiniteParams = [0], 'body' | 'headers' | 'path' | 'query'>>(queryKey: QueryKey, page: K) => {
+ const params = { ...queryKey[0] };
+ if (page.body) {
+ params.body = {
+ ...queryKey[0].body as any,
+ ...page.body as any
+ };
+ }
+ if (page.headers) {
+ params.headers = {
+ ...queryKey[0].headers,
+ ...page.headers
+ };
+ }
+ if (page.path) {
+ params.path = {
+ ...queryKey[0].path as any,
+ ...page.path as any
+ };
+ }
+ if (page.query) {
+ params.query = {
+ ...queryKey[0].query as any,
+ ...page.query as any
+ };
+ }
+ return params as unknown as typeof page;
+};
+
+export const getRomsApiRomsGetInfiniteQueryKey = (options?: Options): QueryKey> => createQueryKey('getRomsApiRomsGet', options, true);
+
+/**
+ * Get Roms
+ *
+ * Retrieve roms.
+ */
+export const getRomsApiRomsGetInfiniteOptions = (options?: Options) => infiniteQueryOptions, QueryKey>, number | Pick>[0], 'body' | 'headers' | 'path' | 'query'>>(
+// @ts-ignore
+{
+ queryFn: async ({ pageParam, queryKey, signal }) => {
+ // @ts-ignore
+ const page: Pick>[0], 'body' | 'headers' | 'path' | 'query'> = typeof pageParam === 'object' ? pageParam : {
+ query: {
+ offset: pageParam
+ }
+ };
+ const params = createInfiniteParams(queryKey, page);
+ const { data } = await getRomsApiRomsGet({
+ ...options,
+ ...params,
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomsApiRomsGetInfiniteQueryKey(options)
+});
+
+/**
+ * Add Rom
+ *
+ * Upload a single rom.
+ */
+export const addRomApiRomsPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addRomApiRomsPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const downloadRomsApiRomsDownloadGetQueryKey = (options: Options) => createQueryKey('downloadRomsApiRomsDownloadGet', options);
+
+/**
+ * Download Roms
+ *
+ * Download a list of roms as a zip file.
+ */
+export const downloadRomsApiRomsDownloadGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await downloadRomsApiRomsDownloadGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: downloadRomsApiRomsDownloadGetQueryKey(options)
+});
+
+export const getRomByMetadataProviderApiRomsByMetadataProviderGetQueryKey = (options?: Options) => createQueryKey('getRomByMetadataProviderApiRomsByMetadataProviderGet', options);
+
+/**
+ * Get Rom By Metadata Provider
+ *
+ * Retrieve a rom by metadata ID.
+ */
+export const getRomByMetadataProviderApiRomsByMetadataProviderGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomByMetadataProviderApiRomsByMetadataProviderGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomByMetadataProviderApiRomsByMetadataProviderGetQueryKey(options)
+});
+
+export const getRomByHashApiRomsByHashGetQueryKey = (options?: Options) => createQueryKey('getRomByHashApiRomsByHashGet', options);
+
+/**
+ * Get Rom By Hash
+ */
+export const getRomByHashApiRomsByHashGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomByHashApiRomsByHashGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomByHashApiRomsByHashGetQueryKey(options)
+});
+
+export const getRomFiltersApiRomsFiltersGetQueryKey = (options?: Options) => createQueryKey('getRomFiltersApiRomsFiltersGet', options);
+
+/**
+ * Get Rom Filters
+ */
+export const getRomFiltersApiRomsFiltersGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomFiltersApiRomsFiltersGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomFiltersApiRomsFiltersGetQueryKey(options)
+});
+
+export const getRomApiRomsIdGetQueryKey = (options: Options) => createQueryKey('getRomApiRomsIdGet', options);
+
+/**
+ * Get Rom
+ *
+ * Retrieve a rom by ID.
+ */
+export const getRomApiRomsIdGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomApiRomsIdGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomApiRomsIdGetQueryKey(options)
+});
+
+/**
+ * Update Rom
+ *
+ * Update a rom.
+ */
+export const updateRomApiRomsIdPutMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await updateRomApiRomsIdPut({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getRomContentApiRomsIdContentFileNameGetQueryKey = (options: Options) => createQueryKey('getRomContentApiRomsIdContentFileNameGet', options);
+
+/**
+ * Get Rom Content
+ *
+ * Download a rom.
+ *
+ * This endpoint serves the content of the requested rom, as:
+ * - A single file for single file roms.
+ * - A zipped file for multi-part roms, including a .m3u file if applicable.
+ */
+export const getRomContentApiRomsIdContentFileNameGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomContentApiRomsIdContentFileNameGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomContentApiRomsIdContentFileNameGetQueryKey(options)
+});
+
+/**
+ * Delete Rom Manuals
+ *
+ * Delete manuals for a rom.
+ */
+export const deleteRomManualsApiRomsIdManualsDeleteMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deleteRomManualsApiRomsIdManualsDelete({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Add Rom Manuals
+ *
+ * Upload manuals for a rom.
+ */
+export const addRomManualsApiRomsIdManualsPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addRomManualsApiRomsIdManualsPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Delete Roms
+ *
+ * Delete roms.
+ */
+export const deleteRomsApiRomsDeletePostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deleteRomsApiRomsDeletePost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Update Rom User
+ *
+ * Update rom data associated to the current user.
+ */
+export const updateRomUserApiRomsIdPropsPutMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await updateRomUserApiRomsIdPropsPut({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getRomfileApiRomsFilesIdGetQueryKey = (options: Options) => createQueryKey('getRomfileApiRomsFilesIdGet', options);
+
+/**
+ * Get Romfile
+ *
+ * Retrieve a rom file by ID.
+ */
+export const getRomfileApiRomsFilesIdGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomfileApiRomsFilesIdGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomfileApiRomsFilesIdGetQueryKey(options)
+});
+
+export const getRomfileContentApiRomsfilesIdContentFileNameGetQueryKey = (options: Options) => createQueryKey('getRomfileContentApiRomsfilesIdContentFileNameGet', options);
+
+/**
+ * Get Romfile Content
+ *
+ * Download a rom file.
+ */
+export const getRomfileContentApiRomsfilesIdContentFileNameGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomfileContentApiRomsfilesIdContentFileNameGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomfileContentApiRomsfilesIdContentFileNameGetQueryKey(options)
+});
+
+export const getRomNotesApiRomsIdNotesGetQueryKey = (options: Options) => createQueryKey('getRomNotesApiRomsIdNotesGet', options);
+
+/**
+ * Get Rom Notes
+ *
+ * Get all notes for a ROM.
+ */
+export const getRomNotesApiRomsIdNotesGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getRomNotesApiRomsIdNotesGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getRomNotesApiRomsIdNotesGetQueryKey(options)
+});
+
+/**
+ * Create Rom Note
+ *
+ * Create a new note for a ROM.
+ */
+export const createRomNoteApiRomsIdNotesPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await createRomNoteApiRomsIdNotesPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Delete Rom Note
+ *
+ * Delete a ROM note.
+ */
+export const deleteRomNoteApiRomsIdNotesNoteIdDeleteMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deleteRomNoteApiRomsIdNotesNoteIdDelete({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Update Rom Note
+ *
+ * Update a ROM note.
+ */
+export const updateRomNoteApiRomsIdNotesNoteIdPutMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await updateRomNoteApiRomsIdNotesNoteIdPut({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const searchRomApiSearchRomsGetQueryKey = (options: Options) => createQueryKey('searchRomApiSearchRomsGet', options);
+
+/**
+ * Search Rom
+ *
+ * Search for rom in metadata providers
+ *
+ * Args:
+ * request (Request): FastAPI request
+ * rom_id (int): Rom ID
+ * source (str): Source of the rom
+ * search_term (str, optional): Search term. Defaults to None.
+ * search_by (str, optional): Search by name or ID. Defaults to "name".
+ * search_extended (bool, optional): Search extended info. Defaults to False.
+ *
+ * Returns:
+ * list[SearchRomSchema]: List of matched roms
+ */
+export const searchRomApiSearchRomsGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await searchRomApiSearchRomsGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: searchRomApiSearchRomsGetQueryKey(options)
+});
+
+export const searchCoverApiSearchCoverGetQueryKey = (options?: Options) => createQueryKey('searchCoverApiSearchCoverGet', options);
+
+/**
+ * Search Cover
+ */
+export const searchCoverApiSearchCoverGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await searchCoverApiSearchCoverGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: searchCoverApiSearchCoverGetQueryKey(options)
+});
+
+export const getSavesApiSavesGetQueryKey = (options?: Options) => createQueryKey('getSavesApiSavesGet', options);
+
+/**
+ * Get Saves
+ */
+export const getSavesApiSavesGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getSavesApiSavesGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getSavesApiSavesGetQueryKey(options)
+});
+
+/**
+ * Add Save
+ */
+export const addSaveApiSavesPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addSaveApiSavesPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getSaveApiSavesIdGetQueryKey = (options: Options) => createQueryKey('getSaveApiSavesIdGet', options);
+
+/**
+ * Get Save
+ */
+export const getSaveApiSavesIdGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getSaveApiSavesIdGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getSaveApiSavesIdGetQueryKey(options)
+});
+
+/**
+ * Update Save
+ */
+export const updateSaveApiSavesIdPutMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await updateSaveApiSavesIdPut({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Delete Saves
+ *
+ * Delete saves.
+ */
+export const deleteSavesApiSavesDeletePostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deleteSavesApiSavesDeletePost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getStatesApiStatesGetQueryKey = (options?: Options) => createQueryKey('getStatesApiStatesGet', options);
+
+/**
+ * Get States
+ */
+export const getStatesApiStatesGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getStatesApiStatesGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getStatesApiStatesGetQueryKey(options)
+});
+
+/**
+ * Add State
+ */
+export const addStateApiStatesPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addStateApiStatesPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const getStateApiStatesIdGetQueryKey = (options: Options) => createQueryKey('getStateApiStatesIdGet', options);
+
+/**
+ * Get State
+ */
+export const getStateApiStatesIdGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getStateApiStatesIdGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getStateApiStatesIdGetQueryKey(options)
+});
+
+/**
+ * Update State
+ */
+export const updateStateApiStatesIdPutMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await updateStateApiStatesIdPut({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Delete States
+ *
+ * Delete states.
+ */
+export const deleteStatesApiStatesDeletePostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deleteStatesApiStatesDeletePost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const listTasksApiTasksGetQueryKey = (options?: Options) => createQueryKey('listTasksApiTasksGet', options);
+
+/**
+ * List Tasks
+ *
+ * List all available tasks grouped by task type.
+ *
+ * Args:
+ * request (Request): FastAPI Request object
+ * Returns:
+ * GroupedTasksDict: Dictionary with tasks grouped by their type (scheduled, manual, watcher)
+ */
+export const listTasksApiTasksGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await listTasksApiTasksGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: listTasksApiTasksGetQueryKey(options)
+});
+
+export const getTasksStatusApiTasksStatusGetQueryKey = (options?: Options) => createQueryKey('getTasksStatusApiTasksStatusGet', options);
+
+/**
+ * Get Tasks Status
+ *
+ * Get all active, queued, completed, and failed tasks.
+ *
+ * Args:
+ * request (Request): FastAPI Request object
+ * Returns:
+ * list[TaskStatusResponse]: List of all tasks with their current status
+ */
+export const getTasksStatusApiTasksStatusGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getTasksStatusApiTasksStatusGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getTasksStatusApiTasksStatusGetQueryKey(options)
+});
+
+export const getTaskByIdApiTasksTaskIdGetQueryKey = (options: Options) => createQueryKey('getTaskByIdApiTasksTaskIdGet', options);
+
+/**
+ * Get Task By Id
+ *
+ * Get the status of a task by its job ID.
+ *
+ * Args:
+ * request (Request): FastAPI Request object
+ * task_id (str): Job ID of the task to retrieve status for
+ * Returns:
+ * TaskStatusResponse: Task status information
+ */
+export const getTaskByIdApiTasksTaskIdGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getTaskByIdApiTasksTaskIdGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getTaskByIdApiTasksTaskIdGetQueryKey(options)
+});
+
+/**
+ * Run All Tasks
+ *
+ * Run all runnable tasks endpoint
+ *
+ * Args:
+ * request (Request): FastAPI Request object
+ * Returns:
+ * TaskExecutionResponse: Task execution response with details
+ */
+export const runAllTasksApiTasksRunPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await runAllTasksApiTasksRunPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Run Single Task
+ *
+ * Run a single task endpoint.
+ *
+ * Args:
+ * request (Request): FastAPI Request object
+ * task_name (str): Name of the task to run
+ * Returns:
+ * TaskExecutionResponse: Task execution response with details
+ */
+export const runSingleTaskApiTasksRunTaskNamePostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await runSingleTaskApiTasksRunTaskNamePost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+export const platformsWebrcadeFeedApiFeedsWebrcadeGetQueryKey = (options?: Options) => createQueryKey('platformsWebrcadeFeedApiFeedsWebrcadeGet', options);
+
+/**
+ * Platforms Webrcade Feed
+ *
+ * Get webrcade feed endpoint
+ * https://docs.webrcade.com/feeds/format/
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ *
+ * Returns:
+ * WebrcadeFeedSchema: Webrcade feed object schema
+ */
+export const platformsWebrcadeFeedApiFeedsWebrcadeGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await platformsWebrcadeFeedApiFeedsWebrcadeGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: platformsWebrcadeFeedApiFeedsWebrcadeGetQueryKey(options)
+});
+
+export const tinfoilIndexFeedApiFeedsTinfoilGetQueryKey = (options?: Options) => createQueryKey('tinfoilIndexFeedApiFeedsTinfoilGet', options);
+
+/**
+ * Tinfoil Index Feed
+ *
+ * Get tinfoil custom index feed endpoint
+ * https://blawar.github.io/tinfoil/custom_index/
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ * slug (str, optional): Platform slug. Defaults to "switch".
+ *
+ * Returns:
+ * TinfoilFeedSchema: Tinfoil feed object schema
+ */
+export const tinfoilIndexFeedApiFeedsTinfoilGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await tinfoilIndexFeedApiFeedsTinfoilGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: tinfoilIndexFeedApiFeedsTinfoilGetQueryKey(options)
+});
+
+export const pkgiPs3FeedApiFeedsPkgiPs3ContentTypeGetQueryKey = (options: Options) => createQueryKey('pkgiPs3FeedApiFeedsPkgiPs3ContentTypeGet', options);
+
+/**
+ * Pkgi Ps3 Feed
+ *
+ * Get PKGi PS3 feed endpoint
+ * https://github.com/bucanero/pkgi-ps3
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ * content_type (str): Content type (game, dlc, demo, update, patch, mod, translation, prototype)
+ *
+ * Returns:
+ * Response: txt file with PKGi PS3 database format
+ */
+export const pkgiPs3FeedApiFeedsPkgiPs3ContentTypeGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await pkgiPs3FeedApiFeedsPkgiPs3ContentTypeGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: pkgiPs3FeedApiFeedsPkgiPs3ContentTypeGetQueryKey(options)
+});
+
+export const pkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGetQueryKey = (options: Options) => createQueryKey('pkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGet', options);
+
+/**
+ * Pkgi Psvita Feed
+ *
+ * Get PKGi PS Vita feed endpoint
+ * https://github.com/mmozeiko/pkgi
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ * content_type (str): Content type (game, dlc, demo, update, patch, mod, translation, prototype)
+ *
+ * Returns:
+ * Response: txt file with PKGi PS Vita database format
+ */
+export const pkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await pkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: pkgiPsvitaFeedApiFeedsPkgiPsvitaContentTypeGetQueryKey(options)
+});
+
+export const pkgiPspFeedApiFeedsPkgiPspContentTypeGetQueryKey = (options: Options) => createQueryKey('pkgiPspFeedApiFeedsPkgiPspContentTypeGet', options);
+
+/**
+ * Pkgi Psp Feed
+ *
+ * Get PKGi PSP feed endpoint
+ * https://github.com/bucanero/pkgi-psp
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ * content_type (str): Content type (game, dlc, demo, update, patch, mod, translation, prototype)
+ *
+ * Returns:
+ * Response: txt file with PKGi PSP database format
+ */
+export const pkgiPspFeedApiFeedsPkgiPspContentTypeGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await pkgiPspFeedApiFeedsPkgiPspContentTypeGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: pkgiPspFeedApiFeedsPkgiPspContentTypeGetQueryKey(options)
+});
+
+export const fpkgiFeedApiFeedsFpkgiPlatformSlugGetQueryKey = (options: Options) => createQueryKey('fpkgiFeedApiFeedsFpkgiPlatformSlugGet', options);
+
+/**
+ * Fpkgi Feed
+ *
+ * https://github.com/ItsJokerZz/FPKGi
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ * platform_slug (str): Platform slug (ps4, ps5)
+ *
+ * Returns:
+ * Response: JSON file in FPKGi format
+ */
+export const fpkgiFeedApiFeedsFpkgiPlatformSlugGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await fpkgiFeedApiFeedsFpkgiPlatformSlugGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: fpkgiFeedApiFeedsFpkgiPlatformSlugGetQueryKey(options)
+});
+
+export const kekatsuDsFeedApiFeedsKekatsuPlatformSlugGetQueryKey = (options: Options) => createQueryKey('kekatsuDsFeedApiFeedsKekatsuPlatformSlugGet', options);
+
+/**
+ * Kekatsu Ds Feed
+ *
+ * Get Kekatsu DS feed endpoint
+ * https://github.com/cavv-dev/Kekatsu-DS
+ *
+ * Args:
+ * request (Request): Fastapi Request object
+ * platform_slug (str): Platform slug (nds, nintendo-ds, ds, gba, etc.)
+ *
+ * Returns:
+ * Response: Text file with Kekatsu DS database format
+ */
+export const kekatsuDsFeedApiFeedsKekatsuPlatformSlugGetOptions = (options: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await kekatsuDsFeedApiFeedsKekatsuPlatformSlugGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: kekatsuDsFeedApiFeedsKekatsuPlatformSlugGetQueryKey(options)
+});
+
+export const getConfigApiConfigGetQueryKey = (options?: Options) => createQueryKey('getConfigApiConfigGet', options);
+
+/**
+ * Get Config
+ *
+ * Get config endpoint
+ *
+ * Returns:
+ * ConfigResponse: RomM's configuration
+ */
+export const getConfigApiConfigGetOptions = (options?: Options) => queryOptions>({
+ queryFn: async ({ queryKey, signal }) => {
+ const { data } = await getConfigApiConfigGet({
+ ...options,
+ ...queryKey[0],
+ signal,
+ throwOnError: true
+ });
+ return data;
+ },
+ queryKey: getConfigApiConfigGetQueryKey(options)
+});
+
+/**
+ * Add Platform Binding
+ *
+ * Add platform binding to the configuration
+ */
+export const addPlatformBindingApiConfigSystemPlatformsPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addPlatformBindingApiConfigSystemPlatformsPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Delete Platform Binding
+ *
+ * Delete platform binding from the configuration
+ */
+export const deletePlatformBindingApiConfigSystemPlatformsFsSlugDeleteMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await deletePlatformBindingApiConfigSystemPlatformsFsSlugDelete({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Add Platform Version
+ *
+ * Add platform version to the configuration
+ */
+export const addPlatformVersionApiConfigSystemVersionsPostMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions> = {
+ mutationFn: async (fnOptions) => {
+ const { data } = await addPlatformVersionApiConfigSystemVersionsPost({
+ ...options,
+ ...fnOptions,
+ throwOnError: true
+ });
+ return data;
+ }
+ };
+ return mutationOptions;
+};
+
+/**
+ * Delete Platform Version
+ *
+ * Delete platform version from the configuration
+ */
+export const deletePlatformVersionApiConfigSystemVersionsFsSlugDeleteMutation = (options?: Partial>): UseMutationOptions> => {
+ const mutationOptions: UseMutationOptions