diff --git a/.github/workflows/build-project.yml b/.github/workflows/build-project.yml index 14e6ef28..369a1c1c 100644 --- a/.github/workflows/build-project.yml +++ b/.github/workflows/build-project.yml @@ -27,9 +27,6 @@ jobs: - name: Install dependencies run: cd flo_ai && uv sync - - name: Run Ruff - run: cd flo_ai && uv run pre-commit run --all-files - - name: Run build run: cd flo_ai && uv build diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 44cfaecd..3a6b5350 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,35 @@ repos: -- repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.7.3 - hooks: - # Run the linter. - - id: ruff - files: \.py$ - # Run the formatter. - - id: ruff-format - files: \.py$ - args: [--config, format.quote-style = 'single'] + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.7.3 + hooks: + # Run the linter. + - id: ruff + files: \.py$ + # Run the formatter. + - id: ruff-format + files: \.py$ + args: [--config, format.quote-style = 'single'] + + - repo: local + hooks: + - id: eslint + name: eslint + entry: bash -c 'cd wavefront/client && pnpm lint' + language: system + files: ^wavefront/client/.*\.(js|jsx|ts|tsx)$ + pass_filenames: false # let eslint use its own ignore & config + + - id: typescript-check + name: typescript-check + entry: bash -c 'cd wavefront/client && pnpm typecheck' + language: system + files: ^wavefront/client/.*\.(ts|tsx)$ + pass_filenames: false + + - id: prettier + name: prettier + entry: bash -c 'cd wavefront/client && pnpm format' + language: system + files: ^wavefront/client/ + pass_filenames: false diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..7a0e8c70 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "bradlc.vscode-tailwindcss", + "astral-sh.ty" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 9e26dfee..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/flo_ai/.vscode/settings.json b/flo_ai/.vscode/settings.json new file mode 100644 index 00000000..373e6cf3 --- /dev/null +++ b/flo_ai/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "python.defaultInterpreterPath": ".venv/bin/python", + "[python]": { + "editor.formatOnSave": true + } + } \ No newline at end of file diff --git a/install-dep-local.sh b/install-dep-local.sh new file mode 100755 index 00000000..b46b6cbf --- /dev/null +++ b/install-dep-local.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +# Script to install dependencies for flo_ai, wavefront/server (using uv) and wavefront/client (using pnpm) + +set -e # Exit on error + +# Colors for output +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo -e "${BLUE}Installing dependencies for all projects...${NC}\n" + +# Get the script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +# 1. Install pre-commit using uv in the root and run pre-commit install +echo -e "${YELLOW}[1/4] Installing pre-commit using uv...${NC}" +if command -v uv &> /dev/null; then + uv pip install pre-commit --system + echo -e "${GREEN}✓ pre-commit installed successfully${NC}" + echo -e "${YELLOW}Running pre-commit install...${NC}" + uv run pre-commit install + echo -e "${GREEN}✓ pre-commit hooks installed successfully${NC}\n" +else + echo -e "${YELLOW}Warning: uv not found. Please install uv first.${NC}\n" + exit 1 +fi + +# 2. Install dependencies for flo_ai using uv +echo -e "${YELLOW}[2/4] Installing dependencies for flo_ai using uv...${NC}" +cd flo_ai +if command -v uv &> /dev/null; then + uv sync + echo -e "${GREEN}✓ flo_ai dependencies installed successfully${NC}\n" +else + echo -e "${YELLOW}Warning: uv not found. Please install uv first.${NC}\n" + exit 1 +fi +cd .. + +# 3. Install dependencies for wavefront/server using uv +echo -e "${YELLOW}[3/4] Installing dependencies for wavefront/server using uv...${NC}" +cd wavefront/server +if command -v uv &> /dev/null; then + uv sync --all-packages + echo -e "${GREEN}✓ wavefront/server dependencies installed successfully${NC}\n" +else + echo -e "${YELLOW}Warning: uv not found. Please install uv first.${NC}\n" + exit 1 +fi +cd ../.. + +# 4. Install dependencies for wavefront/client using pnpm +echo -e "${YELLOW}[4/4] Installing dependencies for wavefront/client using pnpm...${NC}" +cd wavefront/client +if command -v pnpm &> /dev/null; then + pnpm install + echo -e "${GREEN}✓ wavefront/client dependencies installed successfully${NC}\n" +else + echo -e "${YELLOW}Warning: pnpm not found. Please install pnpm first.${NC}\n" + exit 1 +fi +cd ../.. + +echo -e "${GREEN}All dependencies installed successfully!${NC}" diff --git a/wavefront.code-workspace b/wavefront.code-workspace new file mode 100644 index 00000000..1cce9a09 --- /dev/null +++ b/wavefront.code-workspace @@ -0,0 +1,7 @@ +{ + "folders": [ + { "path": "flo_ai" }, + { "path": "wavefront" } + ] + } + \ No newline at end of file diff --git a/wavefront/.vscode/settings.json b/wavefront/.vscode/settings.json new file mode 100644 index 00000000..4df88247 --- /dev/null +++ b/wavefront/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "python.defaultInterpreterPath": "server/.venv/bin/python", + "[python]": { + "editor.formatOnSave": true + }, +} \ No newline at end of file diff --git a/wavefront/client/.env b/wavefront/client/.env index d2894826..9f5f0aca 100644 --- a/wavefront/client/.env +++ b/wavefront/client/.env @@ -1,5 +1,5 @@ -VITE_BASE_URL=http://localhost:8002/floconsole -VITE_APP_ENV=production +VITE_BASE_URL=https://console.dev.rootflo.ai/floconsole +VITE_APP_ENV=local VITE_FEATURE_API_SERVICES=true # NOTE: Add the new variables to the /config endpoint in the server.cjs file(For docker) diff --git a/wavefront/client/.prettierignore b/wavefront/client/.prettierignore new file mode 100644 index 00000000..aad2012f --- /dev/null +++ b/wavefront/client/.prettierignore @@ -0,0 +1,12 @@ +**/.git +**/.vite +**/node_modules +**/dist +**/build +**/coverage +**/logs +**/tmp +**/cache +**/temp +**/test +**/tests diff --git a/wavefront/client/.prettierrc.json b/wavefront/client/.prettierrc.json new file mode 100644 index 00000000..045ae6b4 --- /dev/null +++ b/wavefront/client/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "printWidth": 120, + "trailingComma": "es5", + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/wavefront/client/index.html b/wavefront/client/index.html index 7c7804d8..003b586f 100644 --- a/wavefront/client/index.html +++ b/wavefront/client/index.html @@ -1,18 +1,16 @@ + + + + + + + Rootflo Console + - - - - - - - Rootflo Console - - - -
- - - - \ No newline at end of file + +
+ + + diff --git a/wavefront/client/package.json b/wavefront/client/package.json index 3d1e33a1..09d50065 100644 --- a/wavefront/client/package.json +++ b/wavefront/client/package.json @@ -6,8 +6,10 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", + "preview": "vite preview", "lint": "eslint .", - "preview": "vite preview" + "format": "prettier --write .", + "typecheck": "tsc --noEmit" }, "dependencies": { "@hookform/resolvers": "^5.0.1", @@ -36,6 +38,7 @@ "dayjs": "^1.11.13", "js-yaml": "^4.1.0", "lucide-react": "^0.507.0", + "prettier-plugin-tailwindcss": "^0.7.2", "react": "^19.0.0", "react-dom": "^19.0.0", "react-hook-form": "^7.56.1", @@ -54,14 +57,16 @@ "@vitejs/plugin-react-swc": "^3.8.0", "autoprefixer": "^10.4.20", "eslint": "^9.22.0", + "eslint-plugin-prettier": "^5.5.4", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.19", "globals": "^16.0.0", "postcss": "^8.4.47", + "prettier": "^3.7.4", "tailwindcss": "^4.1.17", "typescript": "~5.7.2", "typescript-eslint": "^8.26.1", "vite": "^6.3.1" }, "packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad" -} \ No newline at end of file +} diff --git a/wavefront/client/pnpm-lock.yaml b/wavefront/client/pnpm-lock.yaml index d21410f1..9667fe23 100644 --- a/wavefront/client/pnpm-lock.yaml +++ b/wavefront/client/pnpm-lock.yaml @@ -5,7 +5,6 @@ settings: excludeLinksFromLockfile: false importers: - .: dependencies: '@hookform/resolvers': @@ -86,6 +85,9 @@ importers: lucide-react: specifier: ^0.507.0 version: 0.507.0(react@19.2.1) + prettier-plugin-tailwindcss: + specifier: ^0.7.2 + version: 0.7.2(prettier@3.7.4) react: specifier: ^19.0.0 version: 19.2.1 @@ -135,6 +137,9 @@ importers: eslint: specifier: ^9.22.0 version: 9.39.1(jiti@2.6.1) + eslint-plugin-prettier: + specifier: ^5.5.4 + version: 5.5.4(eslint@9.39.1(jiti@2.6.1))(prettier@3.7.4) eslint-plugin-react-hooks: specifier: ^5.2.0 version: 5.2.0(eslint@9.39.1(jiti@2.6.1)) @@ -147,6 +152,9 @@ importers: postcss: specifier: ^8.4.47 version: 8.5.6 + prettier: + specifier: ^3.7.4 + version: 3.7.4 tailwindcss: specifier: ^4.1.17 version: 4.1.17 @@ -161,412 +169,518 @@ importers: version: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) packages: - '@babel/runtime@7.28.4': - resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} - engines: {node: '>=6.9.0'} + resolution: + { integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== } + engines: { node: '>=6.9.0' } '@codemirror/autocomplete@6.20.0': - resolution: {integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg==} + resolution: + { integrity: sha512-bOwvTOIJcG5FVo5gUUupiwYh8MioPLQ4UcqbcRf7UQ98X90tCa9E1kZ3Z7tqwpZxYyOvh1YTYbmZE9RTfTp5hg== } '@codemirror/commands@6.10.0': - resolution: {integrity: sha512-2xUIc5mHXQzT16JnyOFkh8PvfeXuIut3pslWGfsGOhxP/lpgRm9HOl/mpzLErgt5mXDovqA0d11P21gofRLb9w==} + resolution: + { integrity: sha512-2xUIc5mHXQzT16JnyOFkh8PvfeXuIut3pslWGfsGOhxP/lpgRm9HOl/mpzLErgt5mXDovqA0d11P21gofRLb9w== } '@codemirror/lang-angular@0.1.4': - resolution: {integrity: sha512-oap+gsltb/fzdlTQWD6BFF4bSLKcDnlxDsLdePiJpCVNKWXSTAbiiQeYI3UmES+BLAdkmIC1WjyztC1pi/bX4g==} + resolution: + { integrity: sha512-oap+gsltb/fzdlTQWD6BFF4bSLKcDnlxDsLdePiJpCVNKWXSTAbiiQeYI3UmES+BLAdkmIC1WjyztC1pi/bX4g== } '@codemirror/lang-cpp@6.0.3': - resolution: {integrity: sha512-URM26M3vunFFn9/sm6rzqrBzDgfWuDixp85uTY49wKudToc2jTHUrKIGGKs+QWND+YLofNNZpxcNGRynFJfvgA==} + resolution: + { integrity: sha512-URM26M3vunFFn9/sm6rzqrBzDgfWuDixp85uTY49wKudToc2jTHUrKIGGKs+QWND+YLofNNZpxcNGRynFJfvgA== } '@codemirror/lang-css@6.3.1': - resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==} + resolution: + { integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg== } '@codemirror/lang-go@6.0.1': - resolution: {integrity: sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg==} + resolution: + { integrity: sha512-7fNvbyNylvqCphW9HD6WFnRpcDjr+KXX/FgqXy5H5ZS0eC5edDljukm/yNgYkwTsgp2busdod50AOTIy6Jikfg== } '@codemirror/lang-html@6.4.11': - resolution: {integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw==} + resolution: + { integrity: sha512-9NsXp7Nwp891pQchI7gPdTwBuSuT3K65NGTHWHNJ55HjYcHLllr0rbIZNdOzas9ztc1EUVBlHou85FFZS4BNnw== } '@codemirror/lang-java@6.0.2': - resolution: {integrity: sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ==} + resolution: + { integrity: sha512-m5Nt1mQ/cznJY7tMfQTJchmrjdjQ71IDs+55d1GAa8DGaB8JXWsVCkVT284C3RTASaY43YknrK2X3hPO/J3MOQ== } '@codemirror/lang-javascript@6.2.4': - resolution: {integrity: sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA==} + resolution: + { integrity: sha512-0WVmhp1QOqZ4Rt6GlVGwKJN3KW7Xh4H2q8ZZNGZaP6lRdxXJzmjm4FqvmOojVj6khWJHIb9sp7U/72W7xQgqAA== } '@codemirror/lang-jinja@6.0.0': - resolution: {integrity: sha512-47MFmRcR8UAxd8DReVgj7WJN1WSAMT7OJnewwugZM4XiHWkOjgJQqvEM1NpMj9ALMPyxmlziEI1opH9IaEvmaw==} + resolution: + { integrity: sha512-47MFmRcR8UAxd8DReVgj7WJN1WSAMT7OJnewwugZM4XiHWkOjgJQqvEM1NpMj9ALMPyxmlziEI1opH9IaEvmaw== } '@codemirror/lang-json@6.0.2': - resolution: {integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ==} + resolution: + { integrity: sha512-x2OtO+AvwEHrEwR0FyyPtfDUiloG3rnVTSZV1W8UteaLL8/MajQd8DpvUb2YVzC+/T18aSDv0H9mu+xw0EStoQ== } '@codemirror/lang-less@6.0.2': - resolution: {integrity: sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ==} + resolution: + { integrity: sha512-EYdQTG22V+KUUk8Qq582g7FMnCZeEHsyuOJisHRft/mQ+ZSZ2w51NupvDUHiqtsOy7It5cHLPGfHQLpMh9bqpQ== } '@codemirror/lang-liquid@6.3.0': - resolution: {integrity: sha512-fY1YsUExcieXRTsCiwX/bQ9+PbCTA/Fumv7C7mTUZHoFkibfESnaXwpr2aKH6zZVwysEunsHHkaIpM/pl3xETQ==} + resolution: + { integrity: sha512-fY1YsUExcieXRTsCiwX/bQ9+PbCTA/Fumv7C7mTUZHoFkibfESnaXwpr2aKH6zZVwysEunsHHkaIpM/pl3xETQ== } '@codemirror/lang-markdown@6.5.0': - resolution: {integrity: sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw==} + resolution: + { integrity: sha512-0K40bZ35jpHya6FriukbgaleaqzBLZfOh7HuzqbMxBXkbYMJDxfF39c23xOgxFezR+3G+tR2/Mup+Xk865OMvw== } '@codemirror/lang-php@6.0.2': - resolution: {integrity: sha512-ZKy2v1n8Fc8oEXj0Th0PUMXzQJ0AIR6TaZU+PbDHExFwdu+guzOA4jmCHS1Nz4vbFezwD7LyBdDnddSJeScMCA==} + resolution: + { integrity: sha512-ZKy2v1n8Fc8oEXj0Th0PUMXzQJ0AIR6TaZU+PbDHExFwdu+guzOA4jmCHS1Nz4vbFezwD7LyBdDnddSJeScMCA== } '@codemirror/lang-python@6.2.1': - resolution: {integrity: sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw==} + resolution: + { integrity: sha512-IRjC8RUBhn9mGR9ywecNhB51yePWCGgvHfY1lWN/Mrp3cKuHr0isDKia+9HnvhiWNnMpbGhWrkhuWOc09exRyw== } '@codemirror/lang-rust@6.0.2': - resolution: {integrity: sha512-EZaGjCUegtiU7kSMvOfEZpaCReowEf3yNidYu7+vfuGTm9ow4mthAparY5hisJqOHmJowVH3Upu+eJlUji6qqA==} + resolution: + { integrity: sha512-EZaGjCUegtiU7kSMvOfEZpaCReowEf3yNidYu7+vfuGTm9ow4mthAparY5hisJqOHmJowVH3Upu+eJlUji6qqA== } '@codemirror/lang-sass@6.0.2': - resolution: {integrity: sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q==} + resolution: + { integrity: sha512-l/bdzIABvnTo1nzdY6U+kPAC51czYQcOErfzQ9zSm9D8GmNPD0WTW8st/CJwBTPLO8jlrbyvlSEcN20dc4iL0Q== } '@codemirror/lang-sql@6.10.0': - resolution: {integrity: sha512-6ayPkEd/yRw0XKBx5uAiToSgGECo/GY2NoJIHXIIQh1EVwLuKoU8BP/qK0qH5NLXAbtJRLuT73hx7P9X34iO4w==} + resolution: + { integrity: sha512-6ayPkEd/yRw0XKBx5uAiToSgGECo/GY2NoJIHXIIQh1EVwLuKoU8BP/qK0qH5NLXAbtJRLuT73hx7P9X34iO4w== } '@codemirror/lang-vue@0.1.3': - resolution: {integrity: sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug==} + resolution: + { integrity: sha512-QSKdtYTDRhEHCfo5zOShzxCmqKJvgGrZwDQSdbvCRJ5pRLWBS7pD/8e/tH44aVQT6FKm0t6RVNoSUWHOI5vNug== } '@codemirror/lang-wast@6.0.2': - resolution: {integrity: sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q==} + resolution: + { integrity: sha512-Imi2KTpVGm7TKuUkqyJ5NRmeFWF7aMpNiwHnLQe0x9kmrxElndyH0K6H/gXtWwY6UshMRAhpENsgfpSwsgmC6Q== } '@codemirror/lang-xml@6.1.0': - resolution: {integrity: sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg==} + resolution: + { integrity: sha512-3z0blhicHLfwi2UgkZYRPioSgVTo9PV5GP5ducFH6FaHy0IAJRg+ixj5gTR1gnT/glAIC8xv4w2VL1LoZfs+Jg== } '@codemirror/lang-yaml@6.1.2': - resolution: {integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw==} + resolution: + { integrity: sha512-dxrfG8w5Ce/QbT7YID7mWZFKhdhsaTNOYjOkSIMt1qmC4VQnXSDSYVHHHn8k6kJUfIhtLo8t1JJgltlxWdsITw== } '@codemirror/language-data@6.5.2': - resolution: {integrity: sha512-CPkWBKrNS8stYbEU5kwBwTf3JB1kghlbh4FSAwzGW2TEscdeHHH4FGysREW86Mqnj3Qn09s0/6Ea/TutmoTobg==} + resolution: + { integrity: sha512-CPkWBKrNS8stYbEU5kwBwTf3JB1kghlbh4FSAwzGW2TEscdeHHH4FGysREW86Mqnj3Qn09s0/6Ea/TutmoTobg== } '@codemirror/language@6.11.3': - resolution: {integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA==} + resolution: + { integrity: sha512-9HBM2XnwDj7fnu0551HkGdrUrrqmYq/WC5iv6nbY2WdicXdGbhR/gfbZOH73Aqj4351alY1+aoG9rCNfiwS1RA== } '@codemirror/legacy-modes@6.5.2': - resolution: {integrity: sha512-/jJbwSTazlQEDOQw2FJ8LEEKVS72pU0lx6oM54kGpL8t/NJ2Jda3CZ4pcltiKTdqYSRk3ug1B3pil1gsjA6+8Q==} + resolution: + { integrity: sha512-/jJbwSTazlQEDOQw2FJ8LEEKVS72pU0lx6oM54kGpL8t/NJ2Jda3CZ4pcltiKTdqYSRk3ug1B3pil1gsjA6+8Q== } '@codemirror/lint@6.9.2': - resolution: {integrity: sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ==} + resolution: + { integrity: sha512-sv3DylBiIyi+xKwRCJAAsBZZZWo82shJ/RTMymLabAdtbkV5cSKwWDeCgtUq3v8flTaXS2y1kKkICuRYtUswyQ== } '@codemirror/search@6.5.11': - resolution: {integrity: sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA==} + resolution: + { integrity: sha512-KmWepDE6jUdL6n8cAAqIpRmLPBZ5ZKnicE8oGU/s3QrAVID+0VhLFrzUucVKHG5035/BSykhExDL/Xm7dHthiA== } '@codemirror/state@6.5.2': - resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==} + resolution: + { integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA== } '@codemirror/theme-one-dark@6.1.3': - resolution: {integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA==} + resolution: + { integrity: sha512-NzBdIvEJmx6fjeremiGp3t/okrLPYT0d9orIc7AFun8oZcRk58aejkqhv6spnz4MLAevrKNPMQYXEWMg4s+sKA== } '@codemirror/view@6.38.8': - resolution: {integrity: sha512-XcE9fcnkHCbWkjeKyi0lllwXmBLtyYb5dt89dJyx23I9+LSh5vZDIuk7OLG4VM1lgrXZQcY6cxyZyk5WVPRv/A==} + resolution: + { integrity: sha512-XcE9fcnkHCbWkjeKyi0lllwXmBLtyYb5dt89dJyx23I9+LSh5vZDIuk7OLG4VM1lgrXZQcY6cxyZyk5WVPRv/A== } '@esbuild/aix-ppc64@0.25.12': - resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA== } + engines: { node: '>=18' } cpu: [ppc64] os: [aix] '@esbuild/android-arm64@0.25.12': - resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg== } + engines: { node: '>=18' } cpu: [arm64] os: [android] '@esbuild/android-arm@0.25.12': - resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg== } + engines: { node: '>=18' } cpu: [arm] os: [android] '@esbuild/android-x64@0.25.12': - resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg== } + engines: { node: '>=18' } cpu: [x64] os: [android] '@esbuild/darwin-arm64@0.25.12': - resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg== } + engines: { node: '>=18' } cpu: [arm64] os: [darwin] '@esbuild/darwin-x64@0.25.12': - resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA== } + engines: { node: '>=18' } cpu: [x64] os: [darwin] '@esbuild/freebsd-arm64@0.25.12': - resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg== } + engines: { node: '>=18' } cpu: [arm64] os: [freebsd] '@esbuild/freebsd-x64@0.25.12': - resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ== } + engines: { node: '>=18' } cpu: [x64] os: [freebsd] '@esbuild/linux-arm64@0.25.12': - resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ== } + engines: { node: '>=18' } cpu: [arm64] os: [linux] '@esbuild/linux-arm@0.25.12': - resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw== } + engines: { node: '>=18' } cpu: [arm] os: [linux] '@esbuild/linux-ia32@0.25.12': - resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA== } + engines: { node: '>=18' } cpu: [ia32] os: [linux] '@esbuild/linux-loong64@0.25.12': - resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng== } + engines: { node: '>=18' } cpu: [loong64] os: [linux] '@esbuild/linux-mips64el@0.25.12': - resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw== } + engines: { node: '>=18' } cpu: [mips64el] os: [linux] '@esbuild/linux-ppc64@0.25.12': - resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA== } + engines: { node: '>=18' } cpu: [ppc64] os: [linux] '@esbuild/linux-riscv64@0.25.12': - resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w== } + engines: { node: '>=18' } cpu: [riscv64] os: [linux] '@esbuild/linux-s390x@0.25.12': - resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg== } + engines: { node: '>=18' } cpu: [s390x] os: [linux] '@esbuild/linux-x64@0.25.12': - resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw== } + engines: { node: '>=18' } cpu: [x64] os: [linux] '@esbuild/netbsd-arm64@0.25.12': - resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg== } + engines: { node: '>=18' } cpu: [arm64] os: [netbsd] '@esbuild/netbsd-x64@0.25.12': - resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ== } + engines: { node: '>=18' } cpu: [x64] os: [netbsd] '@esbuild/openbsd-arm64@0.25.12': - resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A== } + engines: { node: '>=18' } cpu: [arm64] os: [openbsd] '@esbuild/openbsd-x64@0.25.12': - resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw== } + engines: { node: '>=18' } cpu: [x64] os: [openbsd] '@esbuild/openharmony-arm64@0.25.12': - resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg== } + engines: { node: '>=18' } cpu: [arm64] os: [openharmony] '@esbuild/sunos-x64@0.25.12': - resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w== } + engines: { node: '>=18' } cpu: [x64] os: [sunos] '@esbuild/win32-arm64@0.25.12': - resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg== } + engines: { node: '>=18' } cpu: [arm64] os: [win32] '@esbuild/win32-ia32@0.25.12': - resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ== } + engines: { node: '>=18' } cpu: [ia32] os: [win32] '@esbuild/win32-x64@0.25.12': - resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA== } + engines: { node: '>=18' } cpu: [x64] os: [win32] '@eslint-community/eslint-utils@4.9.0': - resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + resolution: + { integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== } + engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/config-helpers@0.4.2': - resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/core@0.17.0': - resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/eslintrc@3.3.3': - resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/js@9.39.1': - resolution: {integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/object-schema@2.1.7': - resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@eslint/plugin-kit@0.4.1': - resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@floating-ui/core@1.7.3': - resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} + resolution: + { integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w== } '@floating-ui/dom@1.7.4': - resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} + resolution: + { integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA== } '@floating-ui/react-dom@2.1.6': - resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} + resolution: + { integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw== } peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' '@floating-ui/utils@0.2.10': - resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + resolution: + { integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== } '@hookform/resolvers@5.2.2': - resolution: {integrity: sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==} + resolution: + { integrity: sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA== } peerDependencies: react-hook-form: ^7.55.0 '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} + resolution: + { integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== } + engines: { node: '>=18.18.0' } '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} - engines: {node: '>=18.18.0'} + resolution: + { integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ== } + engines: { node: '>=18.18.0' } '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} + resolution: + { integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== } + engines: { node: '>=12.22' } '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} + resolution: + { integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== } + engines: { node: '>=18.18' } '@jridgewell/gen-mapping@0.3.13': - resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + resolution: + { integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== } '@jridgewell/remapping@2.3.5': - resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + resolution: + { integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== } '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} + resolution: + { integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== } + engines: { node: '>=6.0.0' } '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + resolution: + { integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== } '@jridgewell/trace-mapping@0.3.31': - resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + resolution: + { integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== } '@lezer/common@1.4.0': - resolution: {integrity: sha512-DVeMRoGrgn/k45oQNu189BoW4SZwgZFzJ1+1TV5j2NJ/KFC83oa/enRqZSGshyeMk5cPWMhsKs9nx+8o0unwGg==} + resolution: + { integrity: sha512-DVeMRoGrgn/k45oQNu189BoW4SZwgZFzJ1+1TV5j2NJ/KFC83oa/enRqZSGshyeMk5cPWMhsKs9nx+8o0unwGg== } '@lezer/cpp@1.1.3': - resolution: {integrity: sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w==} + resolution: + { integrity: sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w== } '@lezer/css@1.3.0': - resolution: {integrity: sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw==} + resolution: + { integrity: sha512-pBL7hup88KbI7hXnZV3PQsn43DHy6TWyzuyk2AO9UyoXcDltvIdqWKE1dLL/45JVZ+YZkHe1WVHqO6wugZZWcw== } '@lezer/go@1.0.1': - resolution: {integrity: sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ==} + resolution: + { integrity: sha512-xToRsYxwsgJNHTgNdStpcvmbVuKxTapV0dM0wey1geMMRc9aggoVyKgzYp41D2/vVOx+Ii4hmE206kvxIXBVXQ== } '@lezer/highlight@1.2.3': - resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==} + resolution: + { integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g== } '@lezer/html@1.3.12': - resolution: {integrity: sha512-RJ7eRWdaJe3bsiiLLHjCFT1JMk8m1YP9kaUbvu2rMLEoOnke9mcTVDyfOslsln0LtujdWespjJ39w6zo+RsQYw==} + resolution: + { integrity: sha512-RJ7eRWdaJe3bsiiLLHjCFT1JMk8m1YP9kaUbvu2rMLEoOnke9mcTVDyfOslsln0LtujdWespjJ39w6zo+RsQYw== } '@lezer/java@1.1.3': - resolution: {integrity: sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw==} + resolution: + { integrity: sha512-yHquUfujwg6Yu4Fd1GNHCvidIvJwi/1Xu2DaKl/pfWIA2c1oXkVvawH3NyXhCaFx4OdlYBVX5wvz2f7Aoa/4Xw== } '@lezer/javascript@1.5.4': - resolution: {integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA==} + resolution: + { integrity: sha512-vvYx3MhWqeZtGPwDStM2dwgljd5smolYD2lR2UyFcHfxbBQebqx8yjmFmxtJ/E6nN6u1D9srOiVWm3Rb4tmcUA== } '@lezer/json@1.0.3': - resolution: {integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ==} + resolution: + { integrity: sha512-BP9KzdF9Y35PDpv04r0VeSTKDeox5vVr3efE7eBbx3r4s3oNLfunchejZhjArmeieBH+nVOpgIiBJpEAv8ilqQ== } '@lezer/lr@1.4.4': - resolution: {integrity: sha512-LHL17Mq0OcFXm1pGQssuGTQFPPdxARjKM8f7GA5+sGtHi0K3R84YaSbmche0+RKWHnCsx9asEe5OWOI4FHfe4A==} + resolution: + { integrity: sha512-LHL17Mq0OcFXm1pGQssuGTQFPPdxARjKM8f7GA5+sGtHi0K3R84YaSbmche0+RKWHnCsx9asEe5OWOI4FHfe4A== } '@lezer/markdown@1.6.1': - resolution: {integrity: sha512-72ah+Sml7lD8Wn7lnz9vwYmZBo9aQT+I2gjK/0epI+gjdwUbWw3MJ/ZBGEqG1UfrIauRqH37/c5mVHXeCTGXtA==} + resolution: + { integrity: sha512-72ah+Sml7lD8Wn7lnz9vwYmZBo9aQT+I2gjK/0epI+gjdwUbWw3MJ/ZBGEqG1UfrIauRqH37/c5mVHXeCTGXtA== } '@lezer/php@1.0.5': - resolution: {integrity: sha512-W7asp9DhM6q0W6DYNwIkLSKOvxlXRrif+UXBMxzsJUuqmhE7oVU+gS3THO4S/Puh7Xzgm858UNaFi6dxTP8dJA==} + resolution: + { integrity: sha512-W7asp9DhM6q0W6DYNwIkLSKOvxlXRrif+UXBMxzsJUuqmhE7oVU+gS3THO4S/Puh7Xzgm858UNaFi6dxTP8dJA== } '@lezer/python@1.1.18': - resolution: {integrity: sha512-31FiUrU7z9+d/ElGQLJFXl+dKOdx0jALlP3KEOsGTex8mvj+SoE1FgItcHWK/axkxCHGUSpqIHt6JAWfWu9Rhg==} + resolution: + { integrity: sha512-31FiUrU7z9+d/ElGQLJFXl+dKOdx0jALlP3KEOsGTex8mvj+SoE1FgItcHWK/axkxCHGUSpqIHt6JAWfWu9Rhg== } '@lezer/rust@1.0.2': - resolution: {integrity: sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg==} + resolution: + { integrity: sha512-Lz5sIPBdF2FUXcWeCu1//ojFAZqzTQNRga0aYv6dYXqJqPfMdCAI0NzajWUd4Xijj1IKJLtjoXRPMvTKWBcqKg== } '@lezer/sass@1.1.0': - resolution: {integrity: sha512-3mMGdCTUZ/84ArHOuXWQr37pnf7f+Nw9ycPUeKX+wu19b7pSMcZGLbaXwvD2APMBDOGxPmpK/O6S1v1EvLoqgQ==} + resolution: + { integrity: sha512-3mMGdCTUZ/84ArHOuXWQr37pnf7f+Nw9ycPUeKX+wu19b7pSMcZGLbaXwvD2APMBDOGxPmpK/O6S1v1EvLoqgQ== } '@lezer/xml@1.0.6': - resolution: {integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww==} + resolution: + { integrity: sha512-CdDwirL0OEaStFue/66ZmFSeppuL6Dwjlk8qk153mSQwiSH/Dlri4GNymrNWnUmPl2Um7QfV1FO9KFUyX3Twww== } '@lezer/yaml@1.0.3': - resolution: {integrity: sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA==} + resolution: + { integrity: sha512-GuBLekbw9jDBDhGur82nuwkxKQ+a3W5H0GfaAthDXcAu+XdpS43VlnxA9E9hllkpSP5ellRDKjLLj7Lu9Wr6xA== } '@marijn/find-cluster-break@1.0.2': - resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==} + resolution: + { integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g== } + + '@pkgr/core@0.2.9': + resolution: + { integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== } + engines: { node: ^12.20.0 || ^14.18.0 || >=16.0.0 } '@radix-ui/number@1.1.1': - resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} + resolution: + { integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g== } '@radix-ui/primitive@1.1.3': - resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + resolution: + { integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg== } '@radix-ui/react-alert-dialog@1.1.15': - resolution: {integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw==} + resolution: + { integrity: sha512-oTVLkEw5GpdRe29BqJ0LSDFWI3qu0vR1M0mUkOQWDIUnY/QIkLpgDMWuKxP94c2NAC2LGcgVhG1ImF3jkZ5wXw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -579,7 +693,8 @@ packages: optional: true '@radix-ui/react-arrow@1.1.7': - resolution: {integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==} + resolution: + { integrity: sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -592,7 +707,8 @@ packages: optional: true '@radix-ui/react-checkbox@1.3.3': - resolution: {integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==} + resolution: + { integrity: sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -605,7 +721,8 @@ packages: optional: true '@radix-ui/react-collection@1.1.7': - resolution: {integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==} + resolution: + { integrity: sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -618,7 +735,8 @@ packages: optional: true '@radix-ui/react-compose-refs@1.1.2': - resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + resolution: + { integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -627,7 +745,8 @@ packages: optional: true '@radix-ui/react-context@1.1.2': - resolution: {integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==} + resolution: + { integrity: sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -636,7 +755,8 @@ packages: optional: true '@radix-ui/react-dialog@1.1.15': - resolution: {integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==} + resolution: + { integrity: sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -649,7 +769,8 @@ packages: optional: true '@radix-ui/react-direction@1.1.1': - resolution: {integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==} + resolution: + { integrity: sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -658,7 +779,8 @@ packages: optional: true '@radix-ui/react-dismissable-layer@1.1.11': - resolution: {integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==} + resolution: + { integrity: sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -671,7 +793,8 @@ packages: optional: true '@radix-ui/react-dropdown-menu@2.1.16': - resolution: {integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw==} + resolution: + { integrity: sha512-1PLGQEynI/3OX/ftV54COn+3Sud/Mn8vALg2rWnBLnRaGtJDduNW/22XjlGgPdpcIbiQxjKtb7BkcjP00nqfJw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -684,7 +807,8 @@ packages: optional: true '@radix-ui/react-focus-guards@1.1.3': - resolution: {integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==} + resolution: + { integrity: sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -693,7 +817,8 @@ packages: optional: true '@radix-ui/react-focus-scope@1.1.7': - resolution: {integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==} + resolution: + { integrity: sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -706,7 +831,8 @@ packages: optional: true '@radix-ui/react-id@1.1.1': - resolution: {integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==} + resolution: + { integrity: sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -715,7 +841,8 @@ packages: optional: true '@radix-ui/react-label@2.1.8': - resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==} + resolution: + { integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -728,7 +855,8 @@ packages: optional: true '@radix-ui/react-menu@2.1.16': - resolution: {integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg==} + resolution: + { integrity: sha512-72F2T+PLlphrqLcAotYPp0uJMr5SjP5SL01wfEspJbru5Zs5vQaSHb4VB3ZMJPimgHHCHG7gMOeOB9H3Hdmtxg== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -741,7 +869,8 @@ packages: optional: true '@radix-ui/react-popover@1.1.15': - resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==} + resolution: + { integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -754,7 +883,8 @@ packages: optional: true '@radix-ui/react-popper@1.2.8': - resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==} + resolution: + { integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -767,7 +897,8 @@ packages: optional: true '@radix-ui/react-portal@1.1.9': - resolution: {integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==} + resolution: + { integrity: sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -780,7 +911,8 @@ packages: optional: true '@radix-ui/react-presence@1.1.5': - resolution: {integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==} + resolution: + { integrity: sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -793,7 +925,8 @@ packages: optional: true '@radix-ui/react-primitive@2.1.3': - resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + resolution: + { integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -806,7 +939,8 @@ packages: optional: true '@radix-ui/react-primitive@2.1.4': - resolution: {integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==} + resolution: + { integrity: sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -819,7 +953,8 @@ packages: optional: true '@radix-ui/react-roving-focus@1.1.11': - resolution: {integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==} + resolution: + { integrity: sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -832,7 +967,8 @@ packages: optional: true '@radix-ui/react-select@2.2.6': - resolution: {integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==} + resolution: + { integrity: sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -845,7 +981,8 @@ packages: optional: true '@radix-ui/react-separator@1.1.8': - resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==} + resolution: + { integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -858,7 +995,8 @@ packages: optional: true '@radix-ui/react-slider@1.3.6': - resolution: {integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==} + resolution: + { integrity: sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -871,7 +1009,8 @@ packages: optional: true '@radix-ui/react-slot@1.2.3': - resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + resolution: + { integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -880,7 +1019,8 @@ packages: optional: true '@radix-ui/react-slot@1.2.4': - resolution: {integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==} + resolution: + { integrity: sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -889,7 +1029,8 @@ packages: optional: true '@radix-ui/react-switch@1.2.6': - resolution: {integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==} + resolution: + { integrity: sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -902,7 +1043,8 @@ packages: optional: true '@radix-ui/react-tabs@1.1.13': - resolution: {integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==} + resolution: + { integrity: sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -915,7 +1057,8 @@ packages: optional: true '@radix-ui/react-tooltip@1.2.8': - resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==} + resolution: + { integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -928,7 +1071,8 @@ packages: optional: true '@radix-ui/react-use-callback-ref@1.1.1': - resolution: {integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==} + resolution: + { integrity: sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -937,7 +1081,8 @@ packages: optional: true '@radix-ui/react-use-controllable-state@1.2.2': - resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + resolution: + { integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -946,7 +1091,8 @@ packages: optional: true '@radix-ui/react-use-effect-event@0.0.2': - resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + resolution: + { integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -955,7 +1101,8 @@ packages: optional: true '@radix-ui/react-use-escape-keydown@1.1.1': - resolution: {integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==} + resolution: + { integrity: sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -964,7 +1111,8 @@ packages: optional: true '@radix-ui/react-use-layout-effect@1.1.1': - resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + resolution: + { integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -973,7 +1121,8 @@ packages: optional: true '@radix-ui/react-use-previous@1.1.1': - resolution: {integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==} + resolution: + { integrity: sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -982,7 +1131,8 @@ packages: optional: true '@radix-ui/react-use-rect@1.1.1': - resolution: {integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==} + resolution: + { integrity: sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -991,7 +1141,8 @@ packages: optional: true '@radix-ui/react-use-size@1.1.1': - resolution: {integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==} + resolution: + { integrity: sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ== } peerDependencies: '@types/react': '*' react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc @@ -1000,7 +1151,8 @@ packages: optional: true '@radix-ui/react-visually-hidden@1.2.3': - resolution: {integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==} + resolution: + { integrity: sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug== } peerDependencies: '@types/react': '*' '@types/react-dom': '*' @@ -1013,10 +1165,12 @@ packages: optional: true '@radix-ui/rect@1.1.1': - resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + resolution: + { integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw== } '@replit/codemirror-lang-nix@6.0.1': - resolution: {integrity: sha512-lvzjoYn9nfJzBD5qdm3Ut6G3+Or2wEacYIDJ49h9+19WSChVnxv4ojf+rNmQ78ncuxIt/bfbMvDLMeMP0xze6g==} + resolution: + { integrity: sha512-lvzjoYn9nfJzBD5qdm3Ut6G3+Or2wEacYIDJ49h9+19WSChVnxv4ojf+rNmQ78ncuxIt/bfbMvDLMeMP0xze6g== } peerDependencies: '@codemirror/autocomplete': ^6.0.0 '@codemirror/language': ^6.0.0 @@ -1027,12 +1181,14 @@ packages: '@lezer/lr': ^1.0.0 '@replit/codemirror-lang-solidity@6.0.2': - resolution: {integrity: sha512-/dpTVH338KFV6SaDYYSadkB4bI/0B0QRF/bkt1XS3t3QtyR49mn6+2k0OUQhvt2ZSO7kt10J+OPilRAtgbmX0w==} + resolution: + { integrity: sha512-/dpTVH338KFV6SaDYYSadkB4bI/0B0QRF/bkt1XS3t3QtyR49mn6+2k0OUQhvt2ZSO7kt10J+OPilRAtgbmX0w== } peerDependencies: '@codemirror/language': ^6.0.0 '@replit/codemirror-lang-svelte@6.0.0': - resolution: {integrity: sha512-U2OqqgMM6jKelL0GNWbAmqlu1S078zZNoBqlJBW+retTc5M4Mha6/Y2cf4SVg6ddgloJvmcSpt4hHrVoM4ePRA==} + resolution: + { integrity: sha512-U2OqqgMM6jKelL0GNWbAmqlu1S078zZNoBqlJBW+retTc5M4Mha6/Y2cf4SVg6ddgloJvmcSpt4hHrVoM4ePRA== } peerDependencies: '@codemirror/autocomplete': ^6.0.0 '@codemirror/lang-css': ^6.0.1 @@ -1047,184 +1203,219 @@ packages: '@lezer/lr': ^1.0.0 '@rolldown/pluginutils@1.0.0-beta.27': - resolution: {integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==} + resolution: + { integrity: sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA== } '@rollup/rollup-android-arm-eabi@4.53.3': - resolution: {integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==} + resolution: + { integrity: sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w== } cpu: [arm] os: [android] '@rollup/rollup-android-arm64@4.53.3': - resolution: {integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==} + resolution: + { integrity: sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w== } cpu: [arm64] os: [android] '@rollup/rollup-darwin-arm64@4.53.3': - resolution: {integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==} + resolution: + { integrity: sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA== } cpu: [arm64] os: [darwin] '@rollup/rollup-darwin-x64@4.53.3': - resolution: {integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==} + resolution: + { integrity: sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ== } cpu: [x64] os: [darwin] '@rollup/rollup-freebsd-arm64@4.53.3': - resolution: {integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==} + resolution: + { integrity: sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w== } cpu: [arm64] os: [freebsd] '@rollup/rollup-freebsd-x64@4.53.3': - resolution: {integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==} + resolution: + { integrity: sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q== } cpu: [x64] os: [freebsd] '@rollup/rollup-linux-arm-gnueabihf@4.53.3': - resolution: {integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==} + resolution: + { integrity: sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw== } cpu: [arm] os: [linux] '@rollup/rollup-linux-arm-musleabihf@4.53.3': - resolution: {integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==} + resolution: + { integrity: sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg== } cpu: [arm] os: [linux] '@rollup/rollup-linux-arm64-gnu@4.53.3': - resolution: {integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==} + resolution: + { integrity: sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w== } cpu: [arm64] os: [linux] '@rollup/rollup-linux-arm64-musl@4.53.3': - resolution: {integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==} + resolution: + { integrity: sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A== } cpu: [arm64] os: [linux] '@rollup/rollup-linux-loong64-gnu@4.53.3': - resolution: {integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==} + resolution: + { integrity: sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g== } cpu: [loong64] os: [linux] '@rollup/rollup-linux-ppc64-gnu@4.53.3': - resolution: {integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==} + resolution: + { integrity: sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw== } cpu: [ppc64] os: [linux] '@rollup/rollup-linux-riscv64-gnu@4.53.3': - resolution: {integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==} + resolution: + { integrity: sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g== } cpu: [riscv64] os: [linux] '@rollup/rollup-linux-riscv64-musl@4.53.3': - resolution: {integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==} + resolution: + { integrity: sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A== } cpu: [riscv64] os: [linux] '@rollup/rollup-linux-s390x-gnu@4.53.3': - resolution: {integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==} + resolution: + { integrity: sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg== } cpu: [s390x] os: [linux] '@rollup/rollup-linux-x64-gnu@4.53.3': - resolution: {integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==} + resolution: + { integrity: sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w== } cpu: [x64] os: [linux] '@rollup/rollup-linux-x64-musl@4.53.3': - resolution: {integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==} + resolution: + { integrity: sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q== } cpu: [x64] os: [linux] '@rollup/rollup-openharmony-arm64@4.53.3': - resolution: {integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==} + resolution: + { integrity: sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw== } cpu: [arm64] os: [openharmony] '@rollup/rollup-win32-arm64-msvc@4.53.3': - resolution: {integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==} + resolution: + { integrity: sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw== } cpu: [arm64] os: [win32] '@rollup/rollup-win32-ia32-msvc@4.53.3': - resolution: {integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==} + resolution: + { integrity: sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA== } cpu: [ia32] os: [win32] '@rollup/rollup-win32-x64-gnu@4.53.3': - resolution: {integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==} + resolution: + { integrity: sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg== } cpu: [x64] os: [win32] '@rollup/rollup-win32-x64-msvc@4.53.3': - resolution: {integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==} + resolution: + { integrity: sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ== } cpu: [x64] os: [win32] '@standard-schema/utils@0.3.0': - resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + resolution: + { integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g== } '@swc/core-darwin-arm64@1.15.3': - resolution: {integrity: sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-AXfeQn0CvcQ4cndlIshETx6jrAM45oeUrK8YeEY6oUZU/qzz0Id0CyvlEywxkWVC81Ajpd8TQQ1fW5yx6zQWkQ== } + engines: { node: '>=10' } cpu: [arm64] os: [darwin] '@swc/core-darwin-x64@1.15.3': - resolution: {integrity: sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-p68OeCz1ui+MZYG4wmfJGvcsAcFYb6Sl25H9TxWl+GkBgmNimIiRdnypK9nBGlqMZAcxngNPtnG3kEMNnvoJ2A== } + engines: { node: '>=10' } cpu: [x64] os: [darwin] '@swc/core-linux-arm-gnueabihf@1.15.3': - resolution: {integrity: sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-Nuj5iF4JteFgwrai97mUX+xUOl+rQRHqTvnvHMATL/l9xE6/TJfPBpd3hk/PVpClMXG3Uvk1MxUFOEzM1JrMYg== } + engines: { node: '>=10' } cpu: [arm] os: [linux] '@swc/core-linux-arm64-gnu@1.15.3': - resolution: {integrity: sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-2Nc/s8jE6mW2EjXWxO/lyQuLKShcmTrym2LRf5Ayp3ICEMX6HwFqB1EzDhwoMa2DcUgmnZIalesq2lG3krrUNw== } + engines: { node: '>=10' } cpu: [arm64] os: [linux] '@swc/core-linux-arm64-musl@1.15.3': - resolution: {integrity: sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-j4SJniZ/qaZ5g8op+p1G9K1z22s/EYGg1UXIb3+Cg4nsxEpF5uSIGEE4mHUfA70L0BR9wKT2QF/zv3vkhfpX4g== } + engines: { node: '>=10' } cpu: [arm64] os: [linux] '@swc/core-linux-x64-gnu@1.15.3': - resolution: {integrity: sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-aKttAZnz8YB1VJwPQZtyU8Uk0BfMP63iDMkvjhJzRZVgySmqt/apWSdnoIcZlUoGheBrcqbMC17GGUmur7OT5A== } + engines: { node: '>=10' } cpu: [x64] os: [linux] '@swc/core-linux-x64-musl@1.15.3': - resolution: {integrity: sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-oe8FctPu1gnUsdtGJRO2rvOUIkkIIaHqsO9xxN0bTR7dFTlPTGi2Fhk1tnvXeyAvCPxLIcwD8phzKg6wLv9yug== } + engines: { node: '>=10' } cpu: [x64] os: [linux] '@swc/core-win32-arm64-msvc@1.15.3': - resolution: {integrity: sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-L9AjzP2ZQ/Xh58e0lTRMLvEDrcJpR7GwZqAtIeNLcTK7JVE+QineSyHp0kLkO1rttCHyCy0U74kDTj0dRz6raA== } + engines: { node: '>=10' } cpu: [arm64] os: [win32] '@swc/core-win32-ia32-msvc@1.15.3': - resolution: {integrity: sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-B8UtogMzErUPDWUoKONSVBdsgKYd58rRyv2sHJWKOIMCHfZ22FVXICR4O/VwIYtlnZ7ahERcjayBHDlBZpR0aw== } + engines: { node: '>=10' } cpu: [ia32] os: [win32] '@swc/core-win32-x64-msvc@1.15.3': - resolution: {integrity: sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-SpZKMR9QBTecHeqpzJdYEfgw30Oo8b/Xl6rjSzBt1g0ZsXyy60KLXrp6IagQyfTYqNYE/caDvwtF2FPn7pomog== } + engines: { node: '>=10' } cpu: [x64] os: [win32] '@swc/core@1.15.3': - resolution: {integrity: sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-Qd8eBPkUFL4eAONgGjycZXj1jFCBW8Fd+xF0PzdTlBCWQIV1xnUT7B93wUANtW3KGjl3TRcOyxwSx/u/jyKw/Q== } + engines: { node: '>=10' } peerDependencies: '@swc/helpers': '>=0.5.17' peerDependenciesMeta: @@ -1232,71 +1423,84 @@ packages: optional: true '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + resolution: + { integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== } '@swc/types@0.1.25': - resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} + resolution: + { integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g== } '@tailwindcss/node@4.1.17': - resolution: {integrity: sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg==} + resolution: + { integrity: sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg== } '@tailwindcss/oxide-android-arm64@4.1.17': - resolution: {integrity: sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ== } + engines: { node: '>= 10' } cpu: [arm64] os: [android] '@tailwindcss/oxide-darwin-arm64@4.1.17': - resolution: {integrity: sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg== } + engines: { node: '>= 10' } cpu: [arm64] os: [darwin] '@tailwindcss/oxide-darwin-x64@4.1.17': - resolution: {integrity: sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog== } + engines: { node: '>= 10' } cpu: [x64] os: [darwin] '@tailwindcss/oxide-freebsd-x64@4.1.17': - resolution: {integrity: sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g== } + engines: { node: '>= 10' } cpu: [x64] os: [freebsd] '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17': - resolution: {integrity: sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ== } + engines: { node: '>= 10' } cpu: [arm] os: [linux] '@tailwindcss/oxide-linux-arm64-gnu@4.1.17': - resolution: {integrity: sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ== } + engines: { node: '>= 10' } cpu: [arm64] os: [linux] '@tailwindcss/oxide-linux-arm64-musl@4.1.17': - resolution: {integrity: sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg== } + engines: { node: '>= 10' } cpu: [arm64] os: [linux] '@tailwindcss/oxide-linux-x64-gnu@4.1.17': - resolution: {integrity: sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ== } + engines: { node: '>= 10' } cpu: [x64] os: [linux] '@tailwindcss/oxide-linux-x64-musl@4.1.17': - resolution: {integrity: sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ== } + engines: { node: '>= 10' } cpu: [x64] os: [linux] '@tailwindcss/oxide-wasm32-wasi@4.1.17': - resolution: {integrity: sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg==} - engines: {node: '>=14.0.0'} + resolution: + { integrity: sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg== } + engines: { node: '>=14.0.0' } cpu: [wasm32] bundledDependencies: - '@napi-rs/wasm-runtime' @@ -1307,126 +1511,151 @@ packages: - tslib '@tailwindcss/oxide-win32-arm64-msvc@4.1.17': - resolution: {integrity: sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A== } + engines: { node: '>= 10' } cpu: [arm64] os: [win32] '@tailwindcss/oxide-win32-x64-msvc@4.1.17': - resolution: {integrity: sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw== } + engines: { node: '>= 10' } cpu: [x64] os: [win32] '@tailwindcss/oxide@4.1.17': - resolution: {integrity: sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA==} - engines: {node: '>= 10'} + resolution: + { integrity: sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA== } + engines: { node: '>= 10' } '@tailwindcss/vite@4.1.17': - resolution: {integrity: sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA==} + resolution: + { integrity: sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA== } peerDependencies: vite: ^5.2.0 || ^6 || ^7 '@tanstack/query-core@5.90.12': - resolution: {integrity: sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg==} + resolution: + { integrity: sha512-T1/8t5DhV/SisWjDnaiU2drl6ySvsHj1bHBCWNXd+/T+Hh1cf6JodyEYMd5sgwm+b/mETT4EV3H+zCVczCU5hg== } '@tanstack/react-query@5.90.12': - resolution: {integrity: sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg==} + resolution: + { integrity: sha512-graRZspg7EoEaw0a8faiUASCyJrqjKPdqJ9EwuDRUF9mEYJ1YPczI9H+/agJ0mOJkPCJDk0lsz5QTrLZ/jQ2rg== } peerDependencies: react: ^18 || ^19 '@tanstack/react-table@8.21.3': - resolution: {integrity: sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww== } + engines: { node: '>=12' } peerDependencies: react: '>=16.8' react-dom: '>=16.8' '@tanstack/table-core@8.21.3': - resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg== } + engines: { node: '>=12' } '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + resolution: + { integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== } '@types/js-yaml@4.0.9': - resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + resolution: + { integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== } '@types/json-schema@7.0.15': - resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + resolution: + { integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== } '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + resolution: + { integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ== } '@types/react-dom@19.2.3': - resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + resolution: + { integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== } peerDependencies: '@types/react': ^19.2.0 '@types/react@19.2.7': - resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} + resolution: + { integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg== } '@typescript-eslint/eslint-plugin@8.48.1': - resolution: {integrity: sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-X63hI1bxl5ohelzr0LY5coufyl0LJNthld+abwxpCoo6Gq+hSqhKwci7MUWkXo67mzgUK6YFByhmaHmUcuBJmA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: '@typescript-eslint/parser': ^8.48.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/parser@8.48.1': - resolution: {integrity: sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-PC0PDZfJg8sP7cmKe6L3QIL8GZwU5aRvUFedqSIpw3B+QjRSUZeeITC2M5XKeMXEzL6wccN196iy3JLwKNvDVA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/project-service@8.48.1': - resolution: {integrity: sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/scope-manager@8.48.1': - resolution: {integrity: sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@typescript-eslint/tsconfig-utils@8.48.1': - resolution: {integrity: sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/type-utils@8.48.1': - resolution: {integrity: sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-1jEop81a3LrJQLTf/1VfPQdhIY4PlGDBc/i67EVWObrtvcziysbLN3oReexHOM6N3jyXgCrkBsZpqwH0hiDOQg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/types@8.48.1': - resolution: {integrity: sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@typescript-eslint/typescript-estree@8.48.1': - resolution: {integrity: sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/utils@8.48.1': - resolution: {integrity: sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/visitor-keys@8.48.1': - resolution: {integrity: sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } '@uiw/codemirror-extensions-basic-setup@4.25.3': - resolution: {integrity: sha512-F1doRyD50CWScwGHG2bBUtUpwnOv/zqSnzkZqJcX5YAHQx6Z1CuX8jdnFMH6qktRrPU1tfpNYftTWu3QIoHiMA==} + resolution: + { integrity: sha512-F1doRyD50CWScwGHG2bBUtUpwnOv/zqSnzkZqJcX5YAHQx6Z1CuX8jdnFMH6qktRrPU1tfpNYftTWu3QIoHiMA== } peerDependencies: '@codemirror/autocomplete': '>=6.0.0' '@codemirror/commands': '>=6.0.0' @@ -1437,13 +1666,15 @@ packages: '@codemirror/view': '>=6.0.0' '@uiw/codemirror-extensions-langs@4.25.3': - resolution: {integrity: sha512-+7wuRZ9ZHXVlgaIuuSOSqLmEykeLQvg8EXfDAzM+HBQY7A/dLPKiZhUH5MbnpJk/CxfkS6wk3SumkV5JBnxbpw==} + resolution: + { integrity: sha512-+7wuRZ9ZHXVlgaIuuSOSqLmEykeLQvg8EXfDAzM+HBQY7A/dLPKiZhUH5MbnpJk/CxfkS6wk3SumkV5JBnxbpw== } peerDependencies: '@codemirror/language': '>=6.0.0' '@codemirror/language-data': '>=6.0.0' '@uiw/react-codemirror@4.25.3': - resolution: {integrity: sha512-1wtBZTXPIp8u6F/xjHvsUAYlEeF5Dic4xZBnqJyLzv7o7GjGYEUfSz9Z7bo9aK9GAx2uojG/AuBMfhA4uhvIVQ==} + resolution: + { integrity: sha512-1wtBZTXPIp8u6F/xjHvsUAYlEeF5Dic4xZBnqJyLzv7o7GjGYEUfSz9Z7bo9aK9GAx2uojG/AuBMfhA4uhvIVQ== } peerDependencies: '@babel/runtime': '>=7.11.0' '@codemirror/state': '>=6.0.0' @@ -1454,133 +1685,167 @@ packages: react-dom: '>=17.0.0' '@vitejs/plugin-react-swc@3.11.0': - resolution: {integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==} + resolution: + { integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w== } peerDependencies: vite: ^4 || ^5 || ^6 || ^7 acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + resolution: + { integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== } peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} + resolution: + { integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== } + engines: { node: '>=0.4.0' } hasBin: true ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + resolution: + { integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== } ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== } + engines: { node: '>=8' } argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + resolution: + { integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== } aria-hidden@1.2.6: - resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA== } + engines: { node: '>=10' } asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + resolution: + { integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== } autoprefixer@10.4.22: - resolution: {integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { integrity: sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg== } + engines: { node: ^10 || ^12 || >=14 } hasBin: true peerDependencies: postcss: ^8.1.0 axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} + resolution: + { integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA== } balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + resolution: + { integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== } baseline-browser-mapping@2.9.4: - resolution: {integrity: sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA==} + resolution: + { integrity: sha512-ZCQ9GEWl73BVm8bu5Fts8nt7MHdbt5vY9bP6WGnUh+r3l8M7CgfyTlwsgCbMC66BNxPr6Xoce3j66Ms5YUQTNA== } hasBin: true brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + resolution: + { integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== } brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + resolution: + { integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== } browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + resolution: + { integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== } + engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } hasBin: true call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== } + engines: { node: '>= 0.4' } callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== } + engines: { node: '>=6' } caniuse-lite@1.0.30001759: - resolution: {integrity: sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==} + resolution: + { integrity: sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw== } chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== } + engines: { node: '>=10' } class-variance-authority@0.7.1: - resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} + resolution: + { integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg== } clsx@2.1.1: - resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== } + engines: { node: '>=6' } cmdk@1.1.1: - resolution: {integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==} + resolution: + { integrity: sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg== } peerDependencies: react: ^18 || ^19 || ^19.0.0-rc react-dom: ^18 || ^19 || ^19.0.0-rc codemirror-lang-mermaid@0.5.0: - resolution: {integrity: sha512-Taw/2gPCyNArQJCxIP/HSUif+3zrvD+6Ugt7KJZ2dUKou/8r3ZhcfG8krNTZfV2iu8AuGnymKuo7bLPFyqsh/A==} + resolution: + { integrity: sha512-Taw/2gPCyNArQJCxIP/HSUif+3zrvD+6Ugt7KJZ2dUKou/8r3ZhcfG8krNTZfV2iu8AuGnymKuo7bLPFyqsh/A== } codemirror@6.0.2: - resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} + resolution: + { integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw== } color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + resolution: + { integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== } + engines: { node: '>=7.0.0' } color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + resolution: + { integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== } combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + resolution: + { integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== } + engines: { node: '>= 0.8' } concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + resolution: + { integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== } cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ== } + engines: { node: '>=18' } crelt@1.0.6: - resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + resolution: + { integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g== } cross-spawn@7.0.6: - resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== } + engines: { node: '>= 8' } csstype@3.2.3: - resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + resolution: + { integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== } dayjs@1.11.19: - resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==} + resolution: + { integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw== } debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} + resolution: + { integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== } + engines: { node: '>=6.0' } peerDependencies: supports-color: '*' peerDependenciesMeta: @@ -1588,85 +1853,120 @@ packages: optional: true deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + resolution: + { integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== } delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + resolution: + { integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== } + engines: { node: '>=0.4.0' } detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== } + engines: { node: '>=8' } detect-node-es@1.1.0: - resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} + resolution: + { integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== } dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== } + engines: { node: '>= 0.4' } electron-to-chromium@1.5.266: - resolution: {integrity: sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg==} + resolution: + { integrity: sha512-kgWEglXvkEfMH7rxP5OSZZwnaDWT7J9EoZCujhnpLbfi0bbNtRkgdX2E3gt0Uer11c61qCYktB3hwkAS325sJg== } enhanced-resolve@5.18.3: - resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} - engines: {node: '>=10.13.0'} + resolution: + { integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== } + engines: { node: '>=10.13.0' } es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== } + engines: { node: '>= 0.4' } es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== } + engines: { node: '>= 0.4' } es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== } + engines: { node: '>= 0.4' } es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== } + engines: { node: '>= 0.4' } esbuild@0.25.12: - resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg== } + engines: { node: '>=18' } hasBin: true escalade@3.2.0: - resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== } + engines: { node: '>=6' } escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== } + engines: { node: '>=10' } + + eslint-plugin-prettier@5.5.4: + resolution: + { integrity: sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg== } + engines: { node: ^14.18.0 || >=16.0.0 } + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg== } + engines: { node: '>=10' } peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 eslint-plugin-react-refresh@0.4.24: - resolution: {integrity: sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==} + resolution: + { integrity: sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w== } peerDependencies: eslint: '>=8.40' eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + resolution: + { integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== } + engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } eslint-visitor-keys@4.2.1: - resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } eslint@9.39.1: - resolution: {integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } hasBin: true peerDependencies: jiti: '*' @@ -1675,37 +1975,50 @@ packages: optional: true espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} + resolution: + { integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== } + engines: { node: '>=0.10' } esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + resolution: + { integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== } + engines: { node: '>=4.0' } estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + resolution: + { integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== } + engines: { node: '>=4.0' } esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== } + engines: { node: '>=0.10.0' } fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + resolution: + { integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== } + + fast-diff@1.3.0: + resolution: + { integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== } fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + resolution: + { integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== } fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + resolution: + { integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== } fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== } + engines: { node: '>=12.0.0' } peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -1713,23 +2026,28 @@ packages: optional: true file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} + resolution: + { integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== } + engines: { node: '>=16.0.0' } find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== } + engines: { node: '>=10' } flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} + resolution: + { integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== } + engines: { node: '>=16' } flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + resolution: + { integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== } follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} + resolution: + { integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== } + engines: { node: '>=4.0' } peerDependencies: debug: '*' peerDependenciesMeta: @@ -1737,306 +2055,446 @@ packages: optional: true form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} + resolution: + { integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== } + engines: { node: '>= 6' } fraction.js@5.3.4: - resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + resolution: + { integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== } fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + resolution: + { integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== } + engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } os: [darwin] function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + resolution: + { integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== } get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== } + engines: { node: '>= 0.4' } get-nonce@1.0.1: - resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== } + engines: { node: '>=6' } get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== } + engines: { node: '>= 0.4' } glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + resolution: + { integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== } + engines: { node: '>=10.13.0' } globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== } + engines: { node: '>=18' } globals@16.5.0: - resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} - engines: {node: '>=18'} + resolution: + { integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ== } + engines: { node: '>=18' } gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== } + engines: { node: '>= 0.4' } graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + resolution: + { integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== } graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + resolution: + { integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== } has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== } + engines: { node: '>=8' } has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== } + engines: { node: '>= 0.4' } has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== } + engines: { node: '>= 0.4' } hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== } + engines: { node: '>= 0.4' } ignore@5.3.2: - resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} - engines: {node: '>= 4'} + resolution: + { integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== } + engines: { node: '>= 4' } ignore@7.0.5: - resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} - engines: {node: '>= 4'} + resolution: + { integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== } + engines: { node: '>= 4' } import-fresh@3.3.1: - resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== } + engines: { node: '>=6' } imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} + resolution: + { integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== } + engines: { node: '>=0.8.19' } is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== } + engines: { node: '>=0.10.0' } is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== } + engines: { node: '>=0.10.0' } isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + resolution: + { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== } jiti@2.6.1: - resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + resolution: + { integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ== } hasBin: true js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + resolution: + { integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== } hasBin: true json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + resolution: + { integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== } json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + resolution: + { integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== } json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + resolution: + { integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== } keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + resolution: + { integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== } levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== } + engines: { node: '>= 0.8.0' } lightningcss-android-arm64@1.30.2: - resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [android] lightningcss-darwin-arm64@1.30.2: - resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [darwin] lightningcss-darwin-x64@1.30.2: - resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [darwin] lightningcss-freebsd-x64@1.30.2: - resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [freebsd] lightningcss-linux-arm-gnueabihf@1.30.2: - resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA== } + engines: { node: '>= 12.0.0' } cpu: [arm] os: [linux] lightningcss-linux-arm64-gnu@1.30.2: - resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [linux] lightningcss-linux-arm64-musl@1.30.2: - resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [linux] lightningcss-linux-x64-gnu@1.30.2: - resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [linux] lightningcss-linux-x64-musl@1.30.2: - resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [linux] lightningcss-win32-arm64-msvc@1.30.2: - resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ== } + engines: { node: '>= 12.0.0' } cpu: [arm64] os: [win32] lightningcss-win32-x64-msvc@1.30.2: - resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw== } + engines: { node: '>= 12.0.0' } cpu: [x64] os: [win32] lightningcss@1.30.2: - resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} - engines: {node: '>= 12.0.0'} + resolution: + { integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ== } + engines: { node: '>= 12.0.0' } locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== } + engines: { node: '>=10' } lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + resolution: + { integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== } lucide-react@0.507.0: - resolution: {integrity: sha512-XfgE6gvAHwAtnbUvWiTTHx4S3VGR+cUJHEc0vrh9Ogu672I1Tue2+Cp/8JJqpytgcBHAB1FVI297W4XGNwc2dQ==} + resolution: + { integrity: sha512-XfgE6gvAHwAtnbUvWiTTHx4S3VGR+cUJHEc0vrh9Ogu672I1Tue2+Cp/8JJqpytgcBHAB1FVI297W4XGNwc2dQ== } peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + resolution: + { integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ== } math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} + resolution: + { integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== } + engines: { node: '>= 0.4' } mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + resolution: + { integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== } + engines: { node: '>= 0.6' } mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + resolution: + { integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== } + engines: { node: '>= 0.6' } minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + resolution: + { integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== } minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} + resolution: + { integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== } + engines: { node: '>=16 || 14 >=14.17' } ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + resolution: + { integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== } nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + resolution: + { integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } hasBin: true natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + resolution: + { integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== } node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + resolution: + { integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== } normalize-range@0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== } + engines: { node: '>=0.10.0' } optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== } + engines: { node: '>= 0.8.0' } p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== } + engines: { node: '>=10' } p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== } + engines: { node: '>=10' } parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== } + engines: { node: '>=6' } path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== } + engines: { node: '>=8' } path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== } + engines: { node: '>=8' } picocolors@1.1.1: - resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + resolution: + { integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== } picomatch@4.0.3: - resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} - engines: {node: '>=12'} + resolution: + { integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== } + engines: { node: '>=12' } postcss-value-parser@4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + resolution: + { integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== } postcss@8.5.6: - resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} - engines: {node: ^10 || ^12 || >=14} + resolution: + { integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== } + engines: { node: ^10 || ^12 || >=14 } prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== } + engines: { node: '>= 0.8.0' } + + prettier-linter-helpers@1.0.0: + resolution: + { integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== } + engines: { node: '>=6.0.0' } + + prettier-plugin-tailwindcss@0.7.2: + resolution: + { integrity: sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA== } + engines: { node: '>=20.19' } + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-hermes': '*' + '@prettier/plugin-oxc': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-hermes': + optional: true + '@prettier/plugin-oxc': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-svelte: + optional: true + + prettier@3.7.4: + resolution: + { integrity: sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA== } + engines: { node: '>=14' } + hasBin: true proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + resolution: + { integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== } punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== } + engines: { node: '>=6' } react-dom@19.2.1: - resolution: {integrity: sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg==} + resolution: + { integrity: sha512-ibrK8llX2a4eOskq1mXKu/TGZj9qzomO+sNfO98M6d9zIPOEhlBkMkBUBLd1vgS0gQsLDBzA+8jJBVXDnfHmJg== } peerDependencies: react: ^19.2.1 react-hook-form@7.68.0: - resolution: {integrity: sha512-oNN3fjrZ/Xo40SWlHf1yCjlMK417JxoSJVUXQjGdvdRCU07NTFei1i1f8ApUAts+IVh14e4EdakeLEA+BEAs/Q==} - engines: {node: '>=18.0.0'} + resolution: + { integrity: sha512-oNN3fjrZ/Xo40SWlHf1yCjlMK417JxoSJVUXQjGdvdRCU07NTFei1i1f8ApUAts+IVh14e4EdakeLEA+BEAs/Q== } + engines: { node: '>=18.0.0' } peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 react-remove-scroll-bar@2.3.8: - resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q== } + engines: { node: '>=10' } peerDependencies: '@types/react': '*' react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -2045,8 +2503,9 @@ packages: optional: true react-remove-scroll@2.7.2: - resolution: {integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q== } + engines: { node: '>=10' } peerDependencies: '@types/react': '*' react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -2055,8 +2514,9 @@ packages: optional: true react-router@7.10.1: - resolution: {integrity: sha512-gHL89dRa3kwlUYtRQ+m8NmxGI6CgqN+k4XyGjwcFoQwwCWF6xXpOCUlDovkXClS0d0XJN/5q7kc5W3kiFEd0Yw==} - engines: {node: '>=20.0.0'} + resolution: + { integrity: sha512-gHL89dRa3kwlUYtRQ+m8NmxGI6CgqN+k4XyGjwcFoQwwCWF6xXpOCUlDovkXClS0d0XJN/5q7kc5W3kiFEd0Yw== } + engines: { node: '>=20.0.0' } peerDependencies: react: '>=18' react-dom: '>=18' @@ -2065,8 +2525,9 @@ packages: optional: true react-style-singleton@2.2.3: - resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ== } + engines: { node: '>=10' } peerDependencies: '@types/react': '*' react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -2075,111 +2536,142 @@ packages: optional: true react@19.2.1: - resolution: {integrity: sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-DGrYcCWK7tvYMnWh79yrPHt+vdx9tY+1gPZa7nJQtO/p8bLTDaHp4dzwEhQB7pZ4Xe3ok4XKuEPrVuc+wlpkmw== } + engines: { node: '>=0.10.0' } resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} + resolution: + { integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== } + engines: { node: '>=4' } rollup@4.53.3: - resolution: {integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + resolution: + { integrity: sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA== } + engines: { node: '>=18.0.0', npm: '>=8.0.0' } hasBin: true scheduler@0.27.0: - resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + resolution: + { integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q== } semver@7.7.3: - resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== } + engines: { node: '>=10' } hasBin: true set-cookie-parser@2.7.2: - resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + resolution: + { integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw== } shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== } + engines: { node: '>=8' } shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== } + engines: { node: '>=8' } source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== } + engines: { node: '>=0.10.0' } strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== } + engines: { node: '>=8' } style-mod@4.1.3: - resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} + resolution: + { integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ== } supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + resolution: + { integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== } + engines: { node: '>=8' } + + synckit@0.11.11: + resolution: + { integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw== } + engines: { node: ^14.18.0 || >=16.0.0 } tailwind-merge@3.4.0: - resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==} + resolution: + { integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g== } tailwindcss-animate@1.0.7: - resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==} + resolution: + { integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA== } peerDependencies: tailwindcss: '>=3.0.0 || insiders' tailwindcss@4.1.17: - resolution: {integrity: sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q==} + resolution: + { integrity: sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q== } tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} - engines: {node: '>=6'} + resolution: + { integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== } + engines: { node: '>=6' } tinyglobby@0.2.15: - resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} - engines: {node: '>=12.0.0'} + resolution: + { integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== } + engines: { node: '>=12.0.0' } ts-api-utils@2.1.0: - resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} - engines: {node: '>=18.12'} + resolution: + { integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ== } + engines: { node: '>=18.12' } peerDependencies: typescript: '>=4.8.4' tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + resolution: + { integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== } type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + resolution: + { integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== } + engines: { node: '>= 0.8.0' } typescript-eslint@8.48.1: - resolution: {integrity: sha512-FbOKN1fqNoXp1hIl5KYpObVrp0mCn+CLgn479nmu2IsRMrx2vyv74MmsBLVlhg8qVwNFGbXSp8fh1zp8pEoC2A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + resolution: + { integrity: sha512-FbOKN1fqNoXp1hIl5KYpObVrp0mCn+CLgn479nmu2IsRMrx2vyv74MmsBLVlhg8qVwNFGbXSp8fh1zp8pEoC2A== } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' typescript@5.7.3: - resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} - engines: {node: '>=14.17'} + resolution: + { integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw== } + engines: { node: '>=14.17' } hasBin: true undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + resolution: + { integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== } update-browserslist-db@1.2.2: - resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==} + resolution: + { integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA== } hasBin: true peerDependencies: browserslist: '>= 4.21.0' uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + resolution: + { integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== } use-callback-ref@1.3.3: - resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg== } + engines: { node: '>=10' } peerDependencies: '@types/react': '*' react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -2188,8 +2680,9 @@ packages: optional: true use-sidecar@1.1.3: - resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ== } + engines: { node: '>=10' } peerDependencies: '@types/react': '*' react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc @@ -2198,13 +2691,15 @@ packages: optional: true use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + resolution: + { integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== } peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 vite@6.4.1: - resolution: {integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + resolution: + { integrity: sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g== } + engines: { node: ^18.0.0 || ^20.0.0 || >=22.0.0 } hasBin: true peerDependencies: '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 @@ -2243,27 +2738,33 @@ packages: optional: true w3c-keyname@2.2.8: - resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + resolution: + { integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ== } which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} + resolution: + { integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== } + engines: { node: '>= 8' } hasBin: true word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} + resolution: + { integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== } + engines: { node: '>=0.10.0' } yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + resolution: + { integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== } + engines: { node: '>=10' } zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + resolution: + { integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== } zustand@5.0.9: - resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==} - engines: {node: '>=12.20.0'} + resolution: + { integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg== } + engines: { node: '>=12.20.0' } peerDependencies: '@types/react': '>=18.0.0' immer: '>=9.0.6' @@ -2280,7 +2781,6 @@ packages: optional: true snapshots: - '@babel/runtime@7.28.4': {} '@codemirror/autocomplete@6.20.0': @@ -2809,6 +3309,8 @@ snapshots: '@marijn/find-cluster-break@1.0.2': {} + '@pkgr/core@0.2.9': {} + '@radix-ui/number@1.1.1': {} '@radix-ui/primitive@1.1.3': {} @@ -3884,6 +4386,13 @@ snapshots: escape-string-regexp@4.0.0: {} + eslint-plugin-prettier@5.5.4(eslint@9.39.1(jiti@2.6.1))(prettier@3.7.4): + dependencies: + eslint: 9.39.1(jiti@2.6.1) + prettier: 3.7.4 + prettier-linter-helpers: 1.0.0 + synckit: 0.11.11 + eslint-plugin-react-hooks@5.2.0(eslint@9.39.1(jiti@2.6.1)): dependencies: eslint: 9.39.1(jiti@2.6.1) @@ -3962,6 +4471,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-diff@1.3.0: {} + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -4217,6 +4728,16 @@ snapshots: prelude-ls@1.2.1: {} + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier-plugin-tailwindcss@0.7.2(prettier@3.7.4): + dependencies: + prettier: 3.7.4 + + prettier@3.7.4: {} + proxy-from-env@1.1.0: {} punycode@2.3.1: {} @@ -4319,6 +4840,10 @@ snapshots: dependencies: has-flag: 4.0.0 + synckit@0.11.11: + dependencies: + '@pkgr/core': 0.2.9 + tailwind-merge@3.4.0: {} tailwindcss-animate@1.0.7(tailwindcss@4.1.17): diff --git a/wavefront/client/src/App.tsx b/wavefront/client/src/App.tsx index 083750d2..60e8ac45 100644 --- a/wavefront/client/src/App.tsx +++ b/wavefront/client/src/App.tsx @@ -1,7 +1,7 @@ -import { TOKEN_KEY } from "@app/lib/constants"; -import { useEffect } from "react"; -import AppRouter from "./router"; -import { useAuthStore } from "./store"; +import { TOKEN_KEY } from '@app/lib/constants'; +import { useEffect } from 'react'; +import AppRouter from './router'; +import { useAuthStore } from './store'; function App() { const { setAuthenticatedState } = useAuthStore(); diff --git a/wavefront/client/src/api/agent-service.ts b/wavefront/client/src/api/agent-service.ts index c5c6da5b..fa0a9e07 100644 --- a/wavefront/client/src/api/agent-service.ts +++ b/wavefront/client/src/api/agent-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { AgentData, AgentListData, @@ -6,23 +6,19 @@ import { AgentResponse, InferenceData, InferenceResponse, -} from "@app/types/agent"; -import { AxiosInstance } from "axios"; +} from '@app/types/agent'; +import { AxiosInstance } from 'axios'; export class AgentService { constructor(private http: AxiosInstance) {} - async createAgent( - name: string, - yamlContent: string, - namespace: string = "default" - ): Promise { + async createAgent(name: string, yamlContent: string, namespace: string = 'default'): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/agent-management/agents/${name}`, yamlContent, { headers: { - "Content-Type": "text/plain", + 'Content-Type': 'text/plain', }, params: { namespace, @@ -45,7 +41,7 @@ export class AgentService { yamlContent, { headers: { - "Content-Type": "text/plain", + 'Content-Type': 'text/plain', }, } ); @@ -82,12 +78,9 @@ export class AgentService { } async listAgents(namespace?: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/agent-management/agents`, - { - params: namespace ? { namespace } : undefined, - } - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/agent-management/agents`, { + params: namespace ? { namespace } : undefined, + }); return response; } diff --git a/wavefront/client/src/api/api-service-service.ts b/wavefront/client/src/api/api-service-service.ts index 406be5b8..2d875ace 100644 --- a/wavefront/client/src/api/api-service-service.ts +++ b/wavefront/client/src/api/api-service-service.ts @@ -1,11 +1,6 @@ -import { IApiResponse } from "@app/lib/axios"; -import { - ApiServiceData, - ApiServiceListData, - ApiServiceListResponse, - ApiServiceResponse, -} from "@app/types/api-service"; -import { AxiosInstance } from "axios"; +import { IApiResponse } from '@app/lib/axios'; +import { ApiServiceData, ApiServiceListData, ApiServiceListResponse, ApiServiceResponse } from '@app/types/api-service'; +import { AxiosInstance } from 'axios'; export class ApiServiceService { constructor(private http: AxiosInstance) {} @@ -16,7 +11,7 @@ export class ApiServiceService { yamlContent, { headers: { - "Content-Type": "text/plain", + 'Content-Type': 'text/plain', }, } ); @@ -24,22 +19,17 @@ export class ApiServiceService { } async getApiService(id: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/api-services/${id}` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/api-services/${id}`); return response; } - async updateApiService( - id: string, - yamlContent: string - ): Promise { + async updateApiService(id: string, yamlContent: string): Promise { const response: IApiResponse = await this.http.put( `/v1/:appId/floware/v1/api-services/${id}`, yamlContent, { headers: { - "Content-Type": "text/plain", + 'Content-Type': 'text/plain', }, } ); @@ -47,16 +37,12 @@ export class ApiServiceService { } async deleteApiService(id: string): Promise { - const response: IApiResponse = await this.http.delete( - `/v1/:appId/floware/v1/api-services/${id}` - ); + const response: IApiResponse = await this.http.delete(`/v1/:appId/floware/v1/api-services/${id}`); return response; } async listApiServices(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/api-services` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/api-services`); return response; } } diff --git a/wavefront/client/src/api/app-service.ts b/wavefront/client/src/api/app-service.ts index 18beb230..ce617c01 100644 --- a/wavefront/client/src/api/app-service.ts +++ b/wavefront/client/src/api/app-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { AppData, AppResponse, @@ -9,53 +9,38 @@ import { DeleteAppData, DeleteAppResponse, UpdateAppRequest, -} from "@app/types/app"; -import { AxiosInstance } from "axios"; +} from '@app/types/app'; +import { AxiosInstance } from 'axios'; export class AppService { constructor(private http: AxiosInstance) {} async getAllApps(): Promise> { - return this.http.get("/v1/apps"); + return this.http.get('/v1/apps'); } async getAppById(appId: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/apps/${appId}` - ); + const response: IApiResponse = await this.http.get(`/v1/apps/${appId}`); return response; } async createApp(appData: CreateAppRequest): Promise { - const response: IApiResponse = await this.http.post( - "/v1/apps", - appData - ); + const response: IApiResponse = await this.http.post('/v1/apps', appData); return response; } - async updateApp( - appId: string, - appData: UpdateAppRequest - ): Promise { - const response: IApiResponse = await this.http.patch( - `/v1/apps/${appId}`, - appData - ); + async updateApp(appId: string, appData: UpdateAppRequest): Promise { + const response: IApiResponse = await this.http.patch(`/v1/apps/${appId}`, appData); return response; } async deleteApp(appId: string): Promise { - const response: IApiResponse = await this.http.delete( - `/v1/apps/${appId}` - ); + const response: IApiResponse = await this.http.delete(`/v1/apps/${appId}`); return response; } async getAppStatus(appId: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/apps/${appId}/status` - ); + const response: IApiResponse = await this.http.get(`/v1/apps/${appId}/status`); return response; } } diff --git a/wavefront/client/src/api/authenticator-service.ts b/wavefront/client/src/api/authenticator-service.ts index 4bd693a6..d7924746 100644 --- a/wavefront/client/src/api/authenticator-service.ts +++ b/wavefront/client/src/api/authenticator-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { Authenticator, AuthenticatorData, @@ -10,15 +10,13 @@ import { AuthenticatorResponse, CreateAuthenticatorRequest, UpdateAuthenticatorRequest, -} from "@app/types/authenticator"; -import { AxiosInstance } from "axios"; +} from '@app/types/authenticator'; +import { AxiosInstance } from 'axios'; export class AuthenticatorService { constructor(private http: AxiosInstance) {} - async createAuthenticator( - data: CreateAuthenticatorRequest - ): Promise { + async createAuthenticator(data: CreateAuthenticatorRequest): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/authenticators`, data @@ -27,23 +25,16 @@ export class AuthenticatorService { } async getAuthenticator(authId: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/authenticators/${authId}` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/authenticators/${authId}`); return response; } async getAllAuthenticators(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/authenticators` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/authenticators`); return response; } - async updateAuthenticator( - authId: string, - data: UpdateAuthenticatorRequest - ): Promise { + async updateAuthenticator(authId: string, data: UpdateAuthenticatorRequest): Promise { const response: IApiResponse = await this.http.put( `/v1/:appId/floware/v1/authenticators/${authId}`, data @@ -58,23 +49,17 @@ export class AuthenticatorService { return response; } - async enableAuthenticator( - authId: string - ): Promise { - const response: IApiResponse = - await this.http.post( - `/v1/:appId/floware/v1/authenticators/${authId}/enable` - ); + async enableAuthenticator(authId: string): Promise { + const response: IApiResponse = await this.http.post( + `/v1/:appId/floware/v1/authenticators/${authId}/enable` + ); return response; } - async disableAuthenticator( - authId: string - ): Promise { - const response: IApiResponse = - await this.http.post( - `/v1/:appId/floware/v1/authenticators/${authId}/disable` - ); + async disableAuthenticator(authId: string): Promise { + const response: IApiResponse = await this.http.post( + `/v1/:appId/floware/v1/authenticators/${authId}/disable` + ); return response; } } diff --git a/wavefront/client/src/api/console-auth-service.ts b/wavefront/client/src/api/console-auth-service.ts index 5409f672..744f1449 100644 --- a/wavefront/client/src/api/console-auth-service.ts +++ b/wavefront/client/src/api/console-auth-service.ts @@ -1,5 +1,5 @@ -import { IApiResponse } from "@app/lib/axios"; -import { AxiosInstance } from "axios"; +import { IApiResponse } from '@app/lib/axios'; +import { AxiosInstance } from 'axios'; interface UserLogin { email: string; @@ -9,16 +9,14 @@ interface UserLogin { export class ConsoleAuthService { constructor(private http: AxiosInstance) {} - async authenticate( - user: UserLogin - ): Promise> { - return this.http.post("/v1/authenticate", { + async authenticate(user: UserLogin): Promise> { + return this.http.post('/v1/authenticate', { email: user.email, password: user.password, }); } async logout() { - return this.http.post("/v1/logout"); + return this.http.post('/v1/logout'); } } diff --git a/wavefront/client/src/api/data-pipeline-service.ts b/wavefront/client/src/api/data-pipeline-service.ts index 7b1418f2..425a2244 100644 --- a/wavefront/client/src/api/data-pipeline-service.ts +++ b/wavefront/client/src/api/data-pipeline-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { CreatePipelineRequest, FileContentData, @@ -17,8 +17,8 @@ import { TriggerDagRunResponse, UpdatePipelineRequest, UpdateScheduleRequest, -} from "@app/types/pipeline"; -import { AxiosInstance } from "axios"; +} from '@app/types/pipeline'; +import { AxiosInstance } from 'axios'; export class DataPipelineService { constructor(private http: AxiosInstance) {} @@ -30,54 +30,40 @@ export class DataPipelineService { return response; } - async getFileContent( - pipelineId: string, - filePath: string - ): Promise { + async getFileContent(pipelineId: string, filePath: string): Promise { const response: IApiResponse = await this.http.get( `/v1/:appId/floware/v1/pipelines/${pipelineId}/files/${filePath}` ); return response; } - async createFile( - pipelineId: string, - filePath: string, - content: string - ): Promise { + async createFile(pipelineId: string, filePath: string, content: string): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/pipelines/${pipelineId}/files/${filePath}`, content, { headers: { - "Content-Type": "text/plain; charset=utf-8", + 'Content-Type': 'text/plain; charset=utf-8', }, } ); return response; } - async updateFile( - pipelineId: string, - filePath: string, - content: string - ): Promise { + async updateFile(pipelineId: string, filePath: string, content: string): Promise { const response: IApiResponse = await this.http.put( `/v1/:appId/floware/v1/pipelines/${pipelineId}/files/${filePath}`, content, { headers: { - "Content-Type": "text/plain; charset=utf-8", + 'Content-Type': 'text/plain; charset=utf-8', }, } ); return response; } - async deleteFile( - pipelineId: string, - filePath: string - ): Promise { + async deleteFile(pipelineId: string, filePath: string): Promise { const response: IApiResponse = await this.http.delete( `/v1/:appId/floware/v1/pipelines/${pipelineId}/files/${filePath}` ); @@ -85,35 +71,24 @@ export class DataPipelineService { } async createPipeline(data: CreatePipelineRequest): Promise { - const response: IApiResponse = await this.http.post( - `/v1/:appId/floware/v1/pipelines`, - data - ); + const response: IApiResponse = await this.http.post(`/v1/:appId/floware/v1/pipelines`, data); return response; } async listPipelines(status?: PipelineStatus): Promise { const params = status ? { status } : undefined; - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/pipelines`, - { - params, - } - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/pipelines`, { + params, + }); return response; } async getPipeline(pipelineId: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/pipelines/${pipelineId}` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/pipelines/${pipelineId}`); return response; } - async updatePipeline( - pipelineId: string, - data: UpdatePipelineRequest - ): Promise { + async updatePipeline(pipelineId: string, data: UpdatePipelineRequest): Promise { const response: IApiResponse = await this.http.patch( `/v1/:appId/floware/v1/pipelines/${pipelineId}`, data @@ -121,10 +96,7 @@ export class DataPipelineService { return response; } - async updateSchedule( - pipelineId: string, - data: UpdateScheduleRequest - ): Promise { + async updateSchedule(pipelineId: string, data: UpdateScheduleRequest): Promise { const response: IApiResponse = await this.http.patch( `/v1/:appId/floware/v1/pipelines/${pipelineId}/schedule`, data @@ -132,30 +104,21 @@ export class DataPipelineService { return response; } - async publishPipeline( - namespace: string, - pipelineId: string - ): Promise { + async publishPipeline(namespace: string, pipelineId: string): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/namespaces/${namespace}/pipelines/${pipelineId}/publish` ); return response; } - async pausePipeline( - namespace: string, - pipelineId: string - ): Promise { + async pausePipeline(namespace: string, pipelineId: string): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/namespaces/${namespace}/pipelines/${pipelineId}/pause` ); return response; } - async unpausePipeline( - namespace: string, - pipelineId: string - ): Promise { + async unpausePipeline(namespace: string, pipelineId: string): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/namespaces/${namespace}/pipelines/${pipelineId}/unpause` ); @@ -174,10 +137,7 @@ export class DataPipelineService { return response; } - async deletePipeline( - namespace: string, - pipelineId: string - ): Promise { + async deletePipeline(namespace: string, pipelineId: string): Promise { const response: IApiResponse = await this.http.delete( `/v1/:appId/floware/v1/namespaces/${namespace}/pipelines/${pipelineId}` ); diff --git a/wavefront/client/src/api/datasources-service.ts b/wavefront/client/src/api/datasources-service.ts index cec909db..a36ec406 100644 --- a/wavefront/client/src/api/datasources-service.ts +++ b/wavefront/client/src/api/datasources-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { AllYamlsResponse, Datasource, @@ -12,8 +12,8 @@ import { TestDatasourceData, TestDatasourceResponse, YamlResponse, -} from "@app/types/datasource"; -import { AxiosInstance } from "axios"; +} from '@app/types/datasource'; +import { AxiosInstance } from 'axios'; export class DatasourcesService { constructor(private http: AxiosInstance) {} @@ -24,15 +24,12 @@ export class DatasourcesService { config: Record, description?: string ): Promise { - const response: IApiResponse = await this.http.post( - `/v1/:appId/floware/v1/datasources`, - { - name, - type, - config: JSON.stringify(config), - description, - } - ); + const response: IApiResponse = await this.http.post(`/v1/:appId/floware/v1/datasources`, { + name, + type, + config: JSON.stringify(config), + description, + }); return response; } @@ -76,58 +73,36 @@ export class DatasourcesService { return response; } - async getAllDatasources(): Promise< - IApiResponse<{ datasources: Datasource[] }> - > { + async getAllDatasources(): Promise> { return this.http.get(`/v1/:appId/floware/v1/datasources`); } - async getDatasourceResources( - datasourceId: string - ): Promise { + async getDatasourceResources(datasourceId: string): Promise { const response: IApiResponse = await this.http.get( `/v1/:appId/floware/v1/datasources/${datasourceId}/resources` ); return response; } - async createYaml( - dataSourceId: string, - yamlQuery: string - ): Promise { - const response = await this.http.put( - `/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries`, - { - dynamic_query: yamlQuery, - } - ); + async createYaml(dataSourceId: string, yamlQuery: string): Promise { + const response = await this.http.put(`/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries`, { + dynamic_query: yamlQuery, + }); return response; } async getAllYamls(dataSourceId: string): Promise { - const response = await this.http.get( - `/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries` - ); + const response = await this.http.get(`/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries`); return response; } - async readYaml( - dataSourceId: string, - yamlId: string - ): Promise { - const response = await this.http.get( - `/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries/${yamlId}` - ); + async readYaml(dataSourceId: string, yamlId: string): Promise { + const response = await this.http.get(`/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries/${yamlId}`); return response; } - async deleteYaml( - dataSourceId: string, - yamlId: string - ): Promise { - const response = await this.http.delete( - `/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries/${yamlId}` - ); + async deleteYaml(dataSourceId: string, yamlId: string): Promise { + const response = await this.http.delete(`/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries/${yamlId}`); return response; } @@ -136,12 +111,9 @@ export class DatasourcesService { yamlId: string, params: Record ): Promise { - const response = await this.http.post( - `/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries/${yamlId}/execute`, - { - params: params, - } - ); + const response = await this.http.post(`/v1/:appId/floware/v1/${dataSourceId}/dynamic-queries/${yamlId}/execute`, { + params: params, + }); return response; } } diff --git a/wavefront/client/src/api/knowledge-base-service.ts b/wavefront/client/src/api/knowledge-base-service.ts index b9177df5..3db1c598 100644 --- a/wavefront/client/src/api/knowledge-base-service.ts +++ b/wavefront/client/src/api/knowledge-base-service.ts @@ -1,5 +1,5 @@ -import { IApiResponse } from "@app/lib/axios"; -import { AxiosInstance } from "axios"; +import { IApiResponse } from '@app/lib/axios'; +import { AxiosInstance } from 'axios'; // Interface for creating a new knowledge base export interface NewKnowledgeBasePayload { @@ -47,8 +47,7 @@ export interface KnowledgeBaseDocumentsListData { resources: DocumentData[]; } -export type KnowledgeBaseDocumentsListResponse = - IApiResponse; +export type KnowledgeBaseDocumentsListResponse = IApiResponse; // Interface for RAG inference response export interface RagInferenceResultData { @@ -89,9 +88,7 @@ export type AllConfigsResponse = IApiResponse; export class KnowledgeBaseService { constructor(private http: AxiosInstance) {} - async createKnowledgeBase( - payload: NewKnowledgeBasePayload - ): Promise { + async createKnowledgeBase(payload: NewKnowledgeBasePayload): Promise { const response: KnowledgeBaseDetailResponse = await this.http.post( `/v1/:appId/floware/v1/knowledge-bases`, payload @@ -99,36 +96,28 @@ export class KnowledgeBaseService { return response; } - async listKnowledgeBases( - offset: number = 0, - limit: number = 10 - ): Promise { - const response: KnowledgeBaseListResponse = await this.http.get( - `/v1/:appId/floware/v1/knowledge-bases`, - { - params: { offset, limit }, - } - ); + async listKnowledgeBases(offset: number = 0, limit: number = 10): Promise { + const response: KnowledgeBaseListResponse = await this.http.get(`/v1/:appId/floware/v1/knowledge-bases`, { + params: { offset, limit }, + }); return response; } async getKnowledgeBase(kbId: string): Promise { - const response: KnowledgeBaseDetail = await this.http.get( - `/v1/:appId/floware/v1/knowledge-bases/${kbId}` - ); + const response: KnowledgeBaseDetail = await this.http.get(`/v1/:appId/floware/v1/knowledge-bases/${kbId}`); return response; } async uploadDocument(kbId: string, file: File): Promise> { const formData = new FormData(); - formData.append("file", file); + formData.append('file', file); const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/knowledge-bases/${kbId}/documents`, formData, { headers: { - "Content-Type": "multipart/form-data", + 'Content-Type': 'multipart/form-data', }, } ); @@ -203,19 +192,14 @@ export class KnowledgeBaseService { return response; } - async deleteSystemPrompt( - kbId: string, - inferenceId: string - ): Promise> { + async deleteSystemPrompt(kbId: string, inferenceId: string): Promise> { const response: IApiResponse = await this.http.delete( `/v1/:appId/floware/v1/knowledge-base/${kbId}/inference/${inferenceId}` ); return response; } - async listInferencesForKnowledgeBase( - kbId: string - ): Promise { + async listInferencesForKnowledgeBase(kbId: string): Promise { const response: InferenceListResponse = await this.http.get( `/v1/:appId/floware/v1/knowledge-base/${kbId}/inference` ); @@ -223,16 +207,11 @@ export class KnowledgeBaseService { } async deleteKnowledgeBase(kbId: string): Promise> { - const response: IApiResponse = await this.http.delete( - `/v1/:appId/floware/v1/knowledge-bases/${kbId}` - ); + const response: IApiResponse = await this.http.delete(`/v1/:appId/floware/v1/knowledge-bases/${kbId}`); return response; } - async deleteDocument( - kbId: string, - documentId: string - ): Promise> { + async deleteDocument(kbId: string, documentId: string): Promise> { const response: IApiResponse = await this.http.delete( `/v1/:appId/floware/v1/knowledge-bases/${kbId}/documents/${documentId}` ); @@ -240,9 +219,7 @@ export class KnowledgeBaseService { } async getAllConfigs(): Promise { - const response: AllConfigsResponse = await this.http.get( - `/v1/:appId/floware/v1/llm-inference-configs` - ); + const response: AllConfigsResponse = await this.http.get(`/v1/:appId/floware/v1/llm-inference-configs`); return response; } } diff --git a/wavefront/client/src/api/llm-inference-service.ts b/wavefront/client/src/api/llm-inference-service.ts index 2bc06eda..aee0f736 100644 --- a/wavefront/client/src/api/llm-inference-service.ts +++ b/wavefront/client/src/api/llm-inference-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { CreateLLMConfigRequest, LLMConfigListData, @@ -6,15 +6,13 @@ import { LLMConfigResponse, LLMInferenceConfig, UpdateLLMConfigRequest, -} from "@app/types/llm-inference-config"; -import { AxiosInstance } from "axios"; +} from '@app/types/llm-inference-config'; +import { AxiosInstance } from 'axios'; export class LLMInferenceService { constructor(private http: AxiosInstance) {} - async createLLMConfig( - data: CreateLLMConfigRequest - ): Promise { + async createLLMConfig(data: CreateLLMConfigRequest): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/llm-inference-configs`, data @@ -29,10 +27,7 @@ export class LLMInferenceService { return response; } - async updateLLMConfig( - configId: string, - data: UpdateLLMConfigRequest - ): Promise { + async updateLLMConfig(configId: string, data: UpdateLLMConfigRequest): Promise { const response: IApiResponse = await this.http.patch( `/v1/:appId/floware/v1/llm-inference-configs/${configId}`, data diff --git a/wavefront/client/src/api/message-processor-service.ts b/wavefront/client/src/api/message-processor-service.ts index 0588f1bb..28b4242e 100644 --- a/wavefront/client/src/api/message-processor-service.ts +++ b/wavefront/client/src/api/message-processor-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { CreateMessageProcessorRequest, ExecuteMessageProcessorData, @@ -9,15 +9,13 @@ import { MessageProcessorListResponse, MessageProcessorResponse, UpdateMessageProcessorRequest, -} from "@app/types/message-processor"; -import { AxiosInstance } from "axios"; +} from '@app/types/message-processor'; +import { AxiosInstance } from 'axios'; export class MessageProcessorService { constructor(private http: AxiosInstance) {} - async createMessageProcessor( - data: CreateMessageProcessorRequest - ): Promise { + async createMessageProcessor(data: CreateMessageProcessorRequest): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/message-processors`, data @@ -25,9 +23,7 @@ export class MessageProcessorService { return response; } - async getMessageProcessor( - processorId: string - ): Promise { + async getMessageProcessor(processorId: string): Promise { const response: IApiResponse = await this.http.get( `/v1/:appId/floware/v1/message-processors/${processorId}` ); @@ -45,9 +41,7 @@ export class MessageProcessorService { return response; } - async deleteMessageProcessor( - processorId: string - ): Promise { + async deleteMessageProcessor(processorId: string): Promise { const response: IApiResponse = await this.http.delete( `/v1/:appId/floware/v1/message-processors/${processorId}` ); @@ -55,8 +49,9 @@ export class MessageProcessorService { } async listMessageProcessors(): Promise { - const response: IApiResponse = - await this.http.get(`/v1/:appId/floware/v1/message-processors`); + const response: IApiResponse = await this.http.get( + `/v1/:appId/floware/v1/message-processors` + ); return response; } @@ -64,11 +59,10 @@ export class MessageProcessorService { processorId: string, data: ExecuteMessageProcessorRequest ): Promise { - const response: IApiResponse = - await this.http.post( - `/v1/:appId/floware/v1/message-processors/${processorId}/execute`, - data - ); + const response: IApiResponse = await this.http.post( + `/v1/:appId/floware/v1/message-processors/${processorId}/execute`, + data + ); return response; } } diff --git a/wavefront/client/src/api/model-inference-service.ts b/wavefront/client/src/api/model-inference-service.ts index 95ffac45..22874a51 100644 --- a/wavefront/client/src/api/model-inference-service.ts +++ b/wavefront/client/src/api/model-inference-service.ts @@ -1,5 +1,5 @@ -import { IApiResponse } from "@app/lib/axios"; -import { AxiosInstance } from "axios"; +import { IApiResponse } from '@app/lib/axios'; +import { AxiosInstance } from 'axios'; export interface PreprocessingStep { preprocess_filter: string; @@ -69,20 +69,17 @@ export class ModelInferenceService { }); } - async uploadModel( - modelType: string, - modelFile: File - ): Promise { + async uploadModel(modelType: string, modelFile: File): Promise { const formData = new FormData(); - formData.append("model_type", modelType); - formData.append("model_file", modelFile); + formData.append('model_type', modelType); + formData.append('model_file', modelFile); const response: ModelUploadResponse = await this.http.post( `/v1/:appId/floware/v1/model-repository/model`, formData, { headers: { - "Content-Type": "multipart/form-data", + 'Content-Type': 'multipart/form-data', }, } ); @@ -90,9 +87,7 @@ export class ModelInferenceService { } async listAllModels(): Promise { - const response: ModelListResponse = await this.http.get( - `/v1/:appId/floware/v1/model-repository/model` - ); + const response: ModelListResponse = await this.http.get(`/v1/:appId/floware/v1/model-repository/model`); return response; } @@ -107,12 +102,12 @@ export class ModelInferenceService { async runInferenceWithImageFile( modelId: string, imageFile: File, - options?: Omit + options?: Omit ): Promise { try { const base64Data = await this.fileToBase64(imageFile); const payload: InferencePayload = { - payload_type: "image", + payload_type: 'image', data: base64Data, ...options, }; @@ -123,10 +118,7 @@ export class ModelInferenceService { } } - async runInference( - modelId: string, - payload: InferencePayload - ): Promise { + async runInference(modelId: string, payload: InferencePayload): Promise { const response: ModelInferenceResponse = await this.http.post( `/v1/:appId/floware/v1/model-repository/model/${modelId}/infer`, payload diff --git a/wavefront/client/src/api/namespace-service.ts b/wavefront/client/src/api/namespace-service.ts index e165d1d0..7fadbb66 100644 --- a/wavefront/client/src/api/namespace-service.ts +++ b/wavefront/client/src/api/namespace-service.ts @@ -1,5 +1,5 @@ -import { IApiResponse } from "@app/lib/axios"; -import { AxiosInstance } from "axios"; +import { IApiResponse } from '@app/lib/axios'; +import { AxiosInstance } from 'axios'; export interface NamespaceItem { name: string; @@ -21,9 +21,7 @@ export class NamespaceService { constructor(private http: AxiosInstance) {} async listNamespaces(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/namespaces` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/namespaces`); return response; } } diff --git a/wavefront/client/src/api/stt-config-service.ts b/wavefront/client/src/api/stt-config-service.ts index 07fdd22f..2289c511 100644 --- a/wavefront/client/src/api/stt-config-service.ts +++ b/wavefront/client/src/api/stt-config-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { CreateSttConfigRequest, SttConfig, @@ -8,33 +8,23 @@ import { SttConfigListResponse, SttConfigResponse, UpdateSttConfigRequest, -} from "@app/types/stt-config"; -import { AxiosInstance } from "axios"; +} from '@app/types/stt-config'; +import { AxiosInstance } from 'axios'; export class SttConfigService { constructor(private http: AxiosInstance) {} - async createSttConfig( - data: CreateSttConfigRequest - ): Promise { - const response: IApiResponse = await this.http.post( - `/v1/:appId/floware/v1/stt-configs`, - data - ); + async createSttConfig(data: CreateSttConfigRequest): Promise { + const response: IApiResponse = await this.http.post(`/v1/:appId/floware/v1/stt-configs`, data); return response; } async getSttConfig(configId: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/stt-configs/${configId}` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/stt-configs/${configId}`); return response; } - async updateSttConfig( - configId: string, - data: UpdateSttConfigRequest - ): Promise { + async updateSttConfig(configId: string, data: UpdateSttConfigRequest): Promise { const response: IApiResponse = await this.http.put( `/v1/:appId/floware/v1/stt-configs/${configId}`, data @@ -50,9 +40,7 @@ export class SttConfigService { } async listAllSttConfigs(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/stt-configs` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/stt-configs`); return response; } } diff --git a/wavefront/client/src/api/telephony-config-service.ts b/wavefront/client/src/api/telephony-config-service.ts index af85e897..6fe523f7 100644 --- a/wavefront/client/src/api/telephony-config-service.ts +++ b/wavefront/client/src/api/telephony-config-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { CreateTelephonyConfigRequest, TelephonyConfig, @@ -8,15 +8,13 @@ import { TelephonyConfigListResponse, TelephonyConfigResponse, UpdateTelephonyConfigRequest, -} from "@app/types/telephony-config"; -import { AxiosInstance } from "axios"; +} from '@app/types/telephony-config'; +import { AxiosInstance } from 'axios'; export class TelephonyConfigService { constructor(private http: AxiosInstance) {} - async createTelephonyConfig( - data: CreateTelephonyConfigRequest - ): Promise { + async createTelephonyConfig(data: CreateTelephonyConfigRequest): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/telephony-configs`, data @@ -24,19 +22,14 @@ export class TelephonyConfigService { return response; } - async getTelephonyConfig( - configId: string - ): Promise { + async getTelephonyConfig(configId: string): Promise { const response: IApiResponse = await this.http.get( `/v1/:appId/floware/v1/telephony-configs/${configId}` ); return response; } - async updateTelephonyConfig( - configId: string, - data: UpdateTelephonyConfigRequest - ): Promise { + async updateTelephonyConfig(configId: string, data: UpdateTelephonyConfigRequest): Promise { const response: IApiResponse = await this.http.put( `/v1/:appId/floware/v1/telephony-configs/${configId}`, data @@ -44,9 +37,7 @@ export class TelephonyConfigService { return response; } - async deleteTelephonyConfig( - configId: string - ): Promise { + async deleteTelephonyConfig(configId: string): Promise { const response: IApiResponse = await this.http.delete( `/v1/:appId/floware/v1/telephony-configs/${configId}` ); diff --git a/wavefront/client/src/api/tool-service.ts b/wavefront/client/src/api/tool-service.ts index 0e6a51af..5ed8b3ea 100644 --- a/wavefront/client/src/api/tool-service.ts +++ b/wavefront/client/src/api/tool-service.ts @@ -1,33 +1,22 @@ -import { IApiResponse } from "@app/lib/axios"; -import { - ToolDetailsData, - ToolDetailsResponse, - ToolNamesData, - ToolNamesResponse, -} from "@app/types/tool"; -import { AxiosInstance } from "axios"; +import { IApiResponse } from '@app/lib/axios'; +import { ToolDetailsData, ToolDetailsResponse, ToolNamesData, ToolNamesResponse } from '@app/types/tool'; +import { AxiosInstance } from 'axios'; export class ToolService { constructor(private http: AxiosInstance) {} async getToolNames(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/tools/names` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/tools/names`); return response; } async getToolNamesAndDetails(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/tools/tool-details` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/tools/tool-details`); return response; } async getToolDetails(toolName: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/tools/${toolName}` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/tools/${toolName}`); return response; } } diff --git a/wavefront/client/src/api/tts-config-service.ts b/wavefront/client/src/api/tts-config-service.ts index ff44bd77..e21e9605 100644 --- a/wavefront/client/src/api/tts-config-service.ts +++ b/wavefront/client/src/api/tts-config-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { CreateTtsConfigRequest, TtsConfig, @@ -8,33 +8,23 @@ import { TtsConfigListResponse, TtsConfigResponse, UpdateTtsConfigRequest, -} from "@app/types/tts-config"; -import { AxiosInstance } from "axios"; +} from '@app/types/tts-config'; +import { AxiosInstance } from 'axios'; export class TtsConfigService { constructor(private http: AxiosInstance) {} - async createTtsConfig( - data: CreateTtsConfigRequest - ): Promise { - const response: IApiResponse = await this.http.post( - `/v1/:appId/floware/v1/tts-configs`, - data - ); + async createTtsConfig(data: CreateTtsConfigRequest): Promise { + const response: IApiResponse = await this.http.post(`/v1/:appId/floware/v1/tts-configs`, data); return response; } async getTtsConfig(configId: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/tts-configs/${configId}` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/tts-configs/${configId}`); return response; } - async updateTtsConfig( - configId: string, - data: UpdateTtsConfigRequest - ): Promise { + async updateTtsConfig(configId: string, data: UpdateTtsConfigRequest): Promise { const response: IApiResponse = await this.http.put( `/v1/:appId/floware/v1/tts-configs/${configId}`, data @@ -50,9 +40,7 @@ export class TtsConfigService { } async listAllTtsConfigs(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/tts-configs` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/tts-configs`); return response; } } diff --git a/wavefront/client/src/api/user-service.ts b/wavefront/client/src/api/user-service.ts index d5ed8b99..0e52327c 100644 --- a/wavefront/client/src/api/user-service.ts +++ b/wavefront/client/src/api/user-service.ts @@ -1,23 +1,23 @@ -import { IApiResponse } from "@app/lib/axios"; -import { IUser } from "@app/types/user"; -import { AxiosInstance } from "axios"; +import { IApiResponse } from '@app/lib/axios'; +import { IUser } from '@app/types/user'; +import { AxiosInstance } from 'axios'; export class UserService { constructor(private http: AxiosInstance) {} async whoAmI(): Promise> { - return this.http.get("/v1/whoami"); + return this.http.get('/v1/whoami'); } async resetPassword(token: string, password: string) { - return this.http.post("/v1/user/reset-password", { + return this.http.post('/v1/user/reset-password', { secret_token: token, new_password: password, }); } async resetPasswordEmailSend(email: string) { - return this.http.post("/v1/user/send-reset-password-email", null, { + return this.http.post('/v1/user/send-reset-password-email', null, { params: { email: email, }, diff --git a/wavefront/client/src/api/voice-agent-service.ts b/wavefront/client/src/api/voice-agent-service.ts index ddc703d6..9ac87811 100644 --- a/wavefront/client/src/api/voice-agent-service.ts +++ b/wavefront/client/src/api/voice-agent-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { CreateVoiceAgentRequest, UpdateVoiceAgentRequest, @@ -8,33 +8,23 @@ import { VoiceAgentListData, VoiceAgentListResponse, VoiceAgentResponse, -} from "@app/types/voice-agent"; -import { AxiosInstance } from "axios"; +} from '@app/types/voice-agent'; +import { AxiosInstance } from 'axios'; export class VoiceAgentService { constructor(private http: AxiosInstance) {} - async createVoiceAgent( - data: CreateVoiceAgentRequest - ): Promise { - const response: IApiResponse = await this.http.post( - `/v1/:appId/floware/v1/voice-agents`, - data - ); + async createVoiceAgent(data: CreateVoiceAgentRequest): Promise { + const response: IApiResponse = await this.http.post(`/v1/:appId/floware/v1/voice-agents`, data); return response; } async getVoiceAgent(agentId: string): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/voice-agents/${agentId}` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/voice-agents/${agentId}`); return response; } - async updateVoiceAgent( - agentId: string, - data: UpdateVoiceAgentRequest - ): Promise { + async updateVoiceAgent(agentId: string, data: UpdateVoiceAgentRequest): Promise { const response: IApiResponse = await this.http.patch( `/v1/:appId/floware/v1/voice-agents/${agentId}`, data @@ -50,20 +40,12 @@ export class VoiceAgentService { } async listAllVoiceAgents(): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/voice-agents` - ); + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/voice-agents`); return response; } - async initiateCall( - agentId: string, - data: { to_number: string; from_number?: string } - ): Promise { - const response = await this.http.post( - `/v1/:appId/floware/v1/voice-agents/${agentId}/initiate`, - data - ); + async initiateCall(agentId: string, data: { to_number: string; from_number?: string }): Promise { + const response = await this.http.post(`/v1/:appId/floware/v1/voice-agents/${agentId}/initiate`, data); return response; } } diff --git a/wavefront/client/src/api/workflow-service.ts b/wavefront/client/src/api/workflow-service.ts index 4dc653ef..c341d093 100644 --- a/wavefront/client/src/api/workflow-service.ts +++ b/wavefront/client/src/api/workflow-service.ts @@ -1,4 +1,4 @@ -import { IApiResponse } from "@app/lib/axios"; +import { IApiResponse } from '@app/lib/axios'; import { WorkflowData, WorkflowInferenceData, @@ -12,23 +12,19 @@ import { WorkflowRunListData, WorkflowRunListResponse, WorkflowRunResponse, -} from "@app/types/workflow"; -import { AxiosInstance } from "axios"; +} from '@app/types/workflow'; +import { AxiosInstance } from 'axios'; export class WorkflowService { constructor(private http: AxiosInstance) {} - async createWorkflow( - name: string, - yamlContent: string, - namespace: string = "default" - ): Promise { + async createWorkflow(name: string, yamlContent: string, namespace: string = 'default'): Promise { const response: IApiResponse = await this.http.post( `/v1/:appId/floware/v1/workflow-management/workflows/${name}`, yamlContent, { headers: { - "Content-Type": "text/plain", + 'Content-Type': 'text/plain', }, params: { namespace, @@ -45,16 +41,13 @@ export class WorkflowService { return response; } - async updateWorkflow( - id: string, - yamlContent: string - ): Promise { + async updateWorkflow(id: string, yamlContent: string): Promise { const response: IApiResponse = await this.http.put( `/v1/:appId/floware/v1/workflow-management/workflows/${id}`, yamlContent, { headers: { - "Content-Type": "text/plain", + 'Content-Type': 'text/plain', }, } ); @@ -96,10 +89,7 @@ export class WorkflowService { return response; } - async createWorkflowPipeline( - workflowId: string, - name: string - ): Promise { + async createWorkflowPipeline(workflowId: string, name: string): Promise { const requestBody: Record = { name, workflow_id: workflowId, @@ -112,8 +102,9 @@ export class WorkflowService { } async listWorkflowPipelines(): Promise { - const response: IApiResponse = - await this.http.get(`/v1/:appId/floware/v1/workflow-pipelines`); + const response: IApiResponse = await this.http.get( + `/v1/:appId/floware/v1/workflow-pipelines` + ); return response; } @@ -124,21 +115,14 @@ export class WorkflowService { return response; } - async getWorkflowRuns( - workflowPipelineId: string, - offset: number, - limit: number - ): Promise { - const response: IApiResponse = await this.http.get( - `/v1/:appId/floware/v1/workflow-runs`, - { - params: { - workflow_pipeline_id: workflowPipelineId, - offset, - limit, - }, - } - ); + async getWorkflowRuns(workflowPipelineId: string, offset: number, limit: number): Promise { + const response: IApiResponse = await this.http.get(`/v1/:appId/floware/v1/workflow-runs`, { + params: { + workflow_pipeline_id: workflowPipelineId, + offset, + limit, + }, + }); return response; } diff --git a/wavefront/client/src/assets/icons/index.ts b/wavefront/client/src/assets/icons/index.ts index a90f7a0f..90218e74 100644 --- a/wavefront/client/src/assets/icons/index.ts +++ b/wavefront/client/src/assets/icons/index.ts @@ -1,10 +1,10 @@ -export { default as AiAgentIcon } from "./ai-agent-icon"; -export { ApiActiveIcon, ApiIcon } from "./api-icon"; -export { default as DatasourcesIcon } from "./datasources"; -export { default as ModelInferenceIcon } from "./model-inference-icon"; -export { default as ModelRepositoryIcon } from "./model-repository-icon"; -export { default as PermissionIcon } from "./permission-icon"; -export { PhoneActiveIcon, PhoneIcon } from "./phone-icon"; -export { default as RagIcon } from "./rag-icon"; -export { default as RootfloIcon } from "./rootflo-icon"; -export { default as WorkflowIcon } from "./workflow-icon"; +export { default as AiAgentIcon } from './ai-agent-icon'; +export { ApiActiveIcon, ApiIcon } from './api-icon'; +export { default as DatasourcesIcon } from './datasources'; +export { default as ModelInferenceIcon } from './model-inference-icon'; +export { default as ModelRepositoryIcon } from './model-repository-icon'; +export { default as PermissionIcon } from './permission-icon'; +export { PhoneActiveIcon, PhoneIcon } from './phone-icon'; +export { default as RagIcon } from './rag-icon'; +export { default as RootfloIcon } from './rootflo-icon'; +export { default as WorkflowIcon } from './workflow-icon'; diff --git a/wavefront/client/src/components/AppCard.tsx b/wavefront/client/src/components/AppCard.tsx index f9b2ca1b..f4476080 100644 --- a/wavefront/client/src/components/AppCard.tsx +++ b/wavefront/client/src/components/AppCard.tsx @@ -1,8 +1,8 @@ -import { App } from "@app/types/app"; -import { Pencil, Trash2 } from "lucide-react"; -import React from "react"; -import { useNavigate } from "react-router"; -import dayjs from "dayjs"; +import { App } from '@app/types/app'; +import { Pencil, Trash2 } from 'lucide-react'; +import React from 'react'; +import { useNavigate } from 'react-router'; +import dayjs from 'dayjs'; interface AppCardProps { app: App; @@ -19,19 +19,19 @@ const AppCard: React.FC = ({ app, onClick, onDeleteClick }) => { return (
{ e.preventDefault(); onClick(app); }} > -
+

{app.app_name}

-

- {app.public_url} -

-
-
- {dayjs(app.updated_at).format("DD MMM YYYY")} +

{app.public_url}

+
{dayjs(app.updated_at).format('DD MMM YYYY')}
); }; diff --git a/wavefront/client/src/components/ChatBot.tsx b/wavefront/client/src/components/ChatBot.tsx index d94a14f3..c5aedb5d 100644 --- a/wavefront/client/src/components/ChatBot.tsx +++ b/wavefront/client/src/components/ChatBot.tsx @@ -1,18 +1,12 @@ -import { Button } from "@app/components/ui/button"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@app/components/ui/select"; -import { Spinner } from "@app/components/ui/spinner"; -import { Textarea } from "@app/components/ui/textarea"; -import { LLMInferenceConfig } from "@app/types/llm-inference-config"; -import clsx from "clsx"; -import { ChevronDown, Plus, X } from "lucide-react"; -import React, { useRef, useState, type RefObject } from "react"; -import Stream from "./Stream"; +import { Button } from '@app/components/ui/button'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@app/components/ui/select'; +import { Spinner } from '@app/components/ui/spinner'; +import { Textarea } from '@app/components/ui/textarea'; +import { LLMInferenceConfig } from '@app/types/llm-inference-config'; +import clsx from 'clsx'; +import { ChevronDown, Plus, X } from 'lucide-react'; +import React, { useRef, useState, type RefObject } from 'react'; +import Stream from './Stream'; // Helper function to format file size const formatFileSize = (bytes: number): string => { @@ -25,7 +19,7 @@ const formatFileSize = (bytes: number): string => { }; interface ChatBotProps { - chatHistory: { role: "user" | "assistant"; content: any }[]; + chatHistory: { role: 'user' | 'assistant'; content: any }[]; runningInference: boolean; selectedLLMConfigId: string; setSelectedLLMConfigId: React.Dispatch>; @@ -42,7 +36,7 @@ interface ChatBotProps { base64: string; base64Content: string; mimeType: string; - documentType: "pdf" | "txt"; + documentType: 'pdf' | 'txt'; }>; handleRemoveImage: (index: number) => void; handleRemoveDocument: (index: number) => void; @@ -108,71 +102,51 @@ const ChatBot = ({ }: ChatBotProps) => { const variablesModalRef = useRef(null); const [showLogic, setShowLogic] = useState(false); - const [selectValue, setSelectValue] = useState(""); + const [selectValue, setSelectValue] = useState(''); return (
- {listenEventsEnabled !== undefined && - setListenEventsEnabled !== undefined && ( -
-
- - -
-

- {listenEventsEnabled - ? "Stream real-time workflow execution events" - : "Standard inference response only"} -

+ /> +
- )} +

+ {listenEventsEnabled ? 'Stream real-time workflow execution events' : 'Standard inference response only'} +

+
+ )}
-
+
{chatHistory.map((chat, index) => ( -
-
+
+
- {typeof chat.content === "string" ? ( + {typeof chat.content === 'string' ? ( chat.content ) : chat.content?.image_base64 ? (
@@ -188,37 +162,28 @@ const ChatBot = ({ ) : chat.content?.document_type ? (
📄 - - {chat.content.metadata?.filename || "Document"} - + {chat.content.metadata?.filename || 'Document'}
) : ( JSON.stringify(chat.content, null, 2) )}
-

- {chat.role === "user" ? "You" : "Agent"} +

+ {chat.role === 'user' ? 'You' : 'Agent'}

))} {listenEventsEnabled && - ((streamingEvents && streamingEvents.length > 0) || - (chatHistory && chatHistory.length > 0)) && ( + ((streamingEvents && streamingEvents.length > 0) || (chatHistory && chatHistory.length > 0)) && (
@@ -272,18 +237,10 @@ const ChatBot = ({ key={index} className="group relative flex items-center gap-1 rounded-lg border border-gray-200 bg-white p-1 transition-colors hover:border-gray-300" > - {image.file.name} + {image.file.name}
-

- {image.file.name} -

-

- {formatFileSize(image.file.size)} -

+

{image.file.name}

+

{formatFileSize(image.file.size)}

@@ -391,20 +340,20 @@ const ChatBot = ({ - )}{" "} + )}{' '}
@@ -103,10 +90,7 @@ const Topbar = ({ user, apps = [] }: { user: IUser; apps: App[] }) => { My Account - + Log out ⇧⌘Q diff --git a/wavefront/client/src/components/ui/alert-dialog.tsx b/wavefront/client/src/components/ui/alert-dialog.tsx index b8675431..ccf34f34 100644 --- a/wavefront/client/src/components/ui/alert-dialog.tsx +++ b/wavefront/client/src/components/ui/alert-dialog.tsx @@ -34,7 +34,7 @@ const AlertDialogContent = React.forwardRef< >( ({ className, ...props }, ref) => ( -
+
) ); AlertTitle.displayName = 'AlertTitle'; diff --git a/wavefront/client/src/components/ui/breadcrumb.tsx b/wavefront/client/src/components/ui/breadcrumb.tsx index 1a74b640..dc569fd7 100644 --- a/wavefront/client/src/components/ui/breadcrumb.tsx +++ b/wavefront/client/src/components/ui/breadcrumb.tsx @@ -17,7 +17,7 @@ const BreadcrumbList = React.forwardRef { return ( - + {children} @@ -60,7 +60,7 @@ const CommandList = React.forwardRef< >(({ className, ...props }, ref) => ( )); @@ -105,7 +105,7 @@ const CommandItem = React.forwardRef< Close @@ -91,7 +91,7 @@ function DialogTitle({ className, ...props }: React.ComponentProps ); diff --git a/wavefront/client/src/components/ui/dropdown-menu.tsx b/wavefront/client/src/components/ui/dropdown-menu.tsx index 05fbc5a8..3b2d4443 100644 --- a/wavefront/client/src/components/ui/dropdown-menu.tsx +++ b/wavefront/client/src/components/ui/dropdown-menu.tsx @@ -25,7 +25,7 @@ const DropdownMenuSubTrigger = React.forwardRef< svg]:size-4 [&>svg]:shrink-0', + 'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm transition-colors outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>svg]:size-4 [&>svg]:shrink-0', inset && 'pl-8', className )} @@ -96,7 +96,7 @@ const DropdownMenuCheckboxItem = React.forwardRef< ) {
) { return (
); diff --git a/wavefront/client/src/components/ui/field.tsx b/wavefront/client/src/components/ui/field.tsx index b1019036..74617aa2 100644 --- a/wavefront/client/src/components/ui/field.tsx +++ b/wavefront/client/src/components/ui/field.tsx @@ -114,7 +114,7 @@ function FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {
) {

a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4', className )} diff --git a/wavefront/client/src/components/ui/input.tsx b/wavefront/client/src/components/ui/input.tsx index 8230b48c..dd0e4148 100644 --- a/wavefront/client/src/components/ui/input.tsx +++ b/wavefront/client/src/components/ui/input.tsx @@ -8,7 +8,7 @@ const Input = React.forwardRef>( span]:line-clamp-1', + 'border-input ring-offset-background data-[placeholder]:text-muted-foreground focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-sm focus:ring-1 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1', className )} {...props} @@ -94,7 +94,7 @@ const SelectLabel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); SelectLabel.displayName = SelectPrimitive.Label.displayName; @@ -105,7 +105,7 @@ const SelectItem = React.forwardRef< (({ className, ...props }, ref) => ( - + )); Slider.displayName = SliderPrimitive.Root.displayName; diff --git a/wavefront/client/src/components/ui/switch.tsx b/wavefront/client/src/components/ui/switch.tsx index c4da157c..343dca61 100644 --- a/wavefront/client/src/components/ui/switch.tsx +++ b/wavefront/client/src/components/ui/switch.tsx @@ -9,7 +9,7 @@ const Switch = React.forwardRef< >(({ className, ...props }, ref) => ( { const baseURL = import.meta.env.VITE_BASE_URL || getConfig().BASE_URL; const env = import.meta.env.VITE_APP_ENV || getConfig().APP_ENV; const isApiServicesEnabled = - import.meta.env.VITE_FEATURE_API_SERVICES === "true" || - getConfig().FEATURE_API_SERVICES === "true"; + import.meta.env.VITE_FEATURE_API_SERVICES === 'true' || getConfig().FEATURE_API_SERVICES === 'true'; export const appEnv = { baseURL, - isLocal: env === "local", - isDev: env === "development", - isStaging: env === "staging", - isProd: env === "production", + isLocal: env === 'local', + isDev: env === 'development', + isStaging: env === 'staging', + isProd: env === 'production', isApiServicesEnabled, }; diff --git a/wavefront/client/src/hooks/data/fetch-hooks.ts b/wavefront/client/src/hooks/data/fetch-hooks.ts index 7a5aea14..f5ad49c1 100644 --- a/wavefront/client/src/hooks/data/fetch-hooks.ts +++ b/wavefront/client/src/hooks/data/fetch-hooks.ts @@ -1,35 +1,24 @@ -import { - DocumentData, - InferenceData, - KbData, -} from "@app/api/knowledge-base-service"; -import { ModelData } from "@app/api/model-inference-service"; -import { NamespaceItem } from "@app/api/namespace-service"; -import { useQueryInit } from "@app/lib/react-query"; -import { AgentApi, AgentListItem } from "@app/types/agent"; -import { ApiServiceItem } from "@app/types/api-service"; -import { App } from "@app/types/app"; -import { Authenticator } from "@app/types/authenticator"; -import { Datasource, ReadYamlData, Yaml } from "@app/types/datasource"; -import { LLMInferenceConfig } from "@app/types/llm-inference-config"; -import { - MessageProcessor, - MessageProcessorListItem, -} from "@app/types/message-processor"; -import { Pipeline, PipelineFile, PipelineStatus } from "@app/types/pipeline"; -import { SttConfig } from "@app/types/stt-config"; -import { TelephonyConfig } from "@app/types/telephony-config"; -import { ToolDetails } from "@app/types/tool"; -import { TtsConfig } from "@app/types/tts-config"; -import { VoiceAgent } from "@app/types/voice-agent"; -import { - WorkflowListItem, - WorkflowPipelineListItem, - WorkflowRunListData, -} from "@app/types/workflow"; -import { UseQueryResult } from "@tanstack/react-query"; - -import { IUser } from "@app/types/user"; +import { DocumentData, InferenceData, KbData } from '@app/api/knowledge-base-service'; +import { ModelData } from '@app/api/model-inference-service'; +import { NamespaceItem } from '@app/api/namespace-service'; +import { useQueryInit } from '@app/lib/react-query'; +import { AgentApi, AgentListItem } from '@app/types/agent'; +import { ApiServiceItem } from '@app/types/api-service'; +import { App } from '@app/types/app'; +import { Authenticator } from '@app/types/authenticator'; +import { Datasource, ReadYamlData, Yaml } from '@app/types/datasource'; +import { LLMInferenceConfig } from '@app/types/llm-inference-config'; +import { MessageProcessor, MessageProcessorListItem } from '@app/types/message-processor'; +import { Pipeline, PipelineFile, PipelineStatus } from '@app/types/pipeline'; +import { SttConfig } from '@app/types/stt-config'; +import { TelephonyConfig } from '@app/types/telephony-config'; +import { ToolDetails } from '@app/types/tool'; +import { TtsConfig } from '@app/types/tts-config'; +import { VoiceAgent } from '@app/types/voice-agent'; +import { WorkflowListItem, WorkflowPipelineListItem, WorkflowRunListData } from '@app/types/workflow'; +import { UseQueryResult } from '@tanstack/react-query'; + +import { IUser } from '@app/types/user'; import { getAgentQueryFn, getAgentsQueryFn, @@ -71,7 +60,7 @@ import { getWorkflowRunsQueryFn, getWorkflowsQueryFn, readYamlQueryFn, -} from "./query-functions"; +} from './query-functions'; import { getAgentKey, getAgentsKey, @@ -113,28 +102,18 @@ import { getWorkflowRunsKey, getWorkflowsKey, readYamlKey, -} from "./query-keys"; +} from './query-keys'; -export const useGetAllApps = ( - enabled: boolean -): UseQueryResult => { +export const useGetAllApps = (enabled: boolean): UseQueryResult => { return useQueryInit(getAllAppsKey(), getAllAppsQueryFn, enabled); }; -export const useGetCurrentUser = ( - enabled: boolean -): UseQueryResult => { +export const useGetCurrentUser = (enabled: boolean): UseQueryResult => { return useQueryInit(getCurrentUserKey(), getCurrentUserQueryFn, enabled); }; -export const useGetAllDatasources = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getAllDatasourcesKey(appId || ""), - getAllDatasourcesQueryFn, - !!appId - ); +export const useGetAllDatasources = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getAllDatasourcesKey(appId || ''), getAllDatasourcesQueryFn, !!appId); }; export const useGetDatasource = ( @@ -142,7 +121,7 @@ export const useGetDatasource = ( datasourceId: string | undefined ): UseQueryResult => { return useQueryInit( - getDatasourceKey(appId || "", datasourceId || ""), + getDatasourceKey(appId || '', datasourceId || ''), () => getDatasourceQueryFn(datasourceId!), !!appId && !!datasourceId ); @@ -153,7 +132,7 @@ export const useGetAllYamls = ( datasourceId: string | undefined ): UseQueryResult => { return useQueryInit( - getAllYamlsKey(appId || "", datasourceId || ""), + getAllYamlsKey(appId || '', datasourceId || ''), () => getAllYamlsQueryFn(datasourceId!), !!appId && !!datasourceId ); @@ -165,7 +144,7 @@ export const useReadYaml = ( yamlId: string | undefined ): UseQueryResult => { return useQueryInit( - readYamlKey(appId || "", datasourceId || "", yamlId || ""), + readYamlKey(appId || '', datasourceId || '', yamlId || ''), () => readYamlQueryFn(datasourceId!, yamlId!), !!appId && !!datasourceId && !!yamlId ); @@ -176,51 +155,26 @@ export const useGetDatasourceResources = ( datasourceId: string | undefined ): UseQueryResult => { return useQueryInit( - getDatasourceResourcesKey(appId || "", datasourceId || ""), + getDatasourceResourcesKey(appId || '', datasourceId || ''), () => getDatasourceResourcesQueryFn(datasourceId!), !!appId && !!datasourceId ); }; -export const useGetAgents = ( - appId: string | undefined, - namespace?: string -): UseQueryResult => { - return useQueryInit( - getAgentsKey(appId || "", namespace), - () => getAgentsQueryFn(namespace), - !!appId - ); +export const useGetAgents = (appId: string | undefined, namespace?: string): UseQueryResult => { + return useQueryInit(getAgentsKey(appId || '', namespace), () => getAgentsQueryFn(namespace), !!appId); }; -export const useGetNamespaces = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getNamespacesKey(appId || ""), - getNamespacesQueryFn, - !!appId - ); +export const useGetNamespaces = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getNamespacesKey(appId || ''), getNamespacesQueryFn, !!appId); }; -export const useGetApiServices = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getApiServicesKey(appId || ""), - getApiServicesQueryFn, - !!appId - ); +export const useGetApiServices = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getApiServicesKey(appId || ''), getApiServicesQueryFn, !!appId); }; -export const useGetAuthenticators = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getAuthenticatorsKey(appId || ""), - getAuthenticatorsQueryFn, - !!appId - ); +export const useGetAuthenticators = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getAuthenticatorsKey(appId || ''), getAuthenticatorsQueryFn, !!appId); }; export const useGetAuthenticator = ( @@ -228,20 +182,14 @@ export const useGetAuthenticator = ( authId: string | undefined ): UseQueryResult => { return useQueryInit( - getAuthenticatorKey(appId || "", authId || ""), + getAuthenticatorKey(appId || '', authId || ''), () => getAuthenticatorQueryFn(authId!), !!appId && !!authId ); }; -export const useGetLLMConfigs = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getLLMConfigsKey(appId || ""), - getLLMConfigsQueryFn, - !!appId - ); +export const useGetLLMConfigs = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getLLMConfigsKey(appId || ''), getLLMConfigsQueryFn, !!appId); }; export const useGetLLMConfig = ( @@ -249,37 +197,25 @@ export const useGetLLMConfig = ( configId: string | undefined ): UseQueryResult => { return useQueryInit( - getLLMConfigKey(appId || "", configId || ""), + getLLMConfigKey(appId || '', configId || ''), () => getLLMConfigQueryFn(configId!), !!appId && !!configId ); }; -export const useGetModels = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit(getModelsKey(appId || ""), getModelsQueryFn, !!appId); +export const useGetModels = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getModelsKey(appId || ''), getModelsQueryFn, !!appId); }; export const useGetModel = ( appId: string | undefined, modelId: string | undefined ): UseQueryResult => { - return useQueryInit( - getModelKey(appId || "", modelId || ""), - () => getModelQueryFn(modelId!), - !!appId && !!modelId - ); + return useQueryInit(getModelKey(appId || '', modelId || ''), () => getModelQueryFn(modelId!), !!appId && !!modelId); }; -export const useGetKnowledgeBases = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getKnowledgeBasesKey(appId || ""), - getKnowledgeBasesQueryFn, - !!appId - ); +export const useGetKnowledgeBases = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getKnowledgeBasesKey(appId || ''), getKnowledgeBasesQueryFn, !!appId); }; export const useGetKnowledgeBase = ( @@ -287,7 +223,7 @@ export const useGetKnowledgeBase = ( kbId: string | undefined ): UseQueryResult => { return useQueryInit( - getKnowledgeBaseKey(appId || "", kbId || ""), + getKnowledgeBaseKey(appId || '', kbId || ''), () => getKnowledgeBaseQueryFn(kbId!), !!appId && !!kbId ); @@ -298,7 +234,7 @@ export const useGetKnowledgeBaseDocuments = ( kbId: string | undefined ): UseQueryResult => { return useQueryInit( - getKnowledgeBaseDocumentsKey(appId || "", kbId || ""), + getKnowledgeBaseDocumentsKey(appId || '', kbId || ''), () => getKnowledgeBaseDocumentsQueryFn(kbId!), !!appId && !!kbId ); @@ -309,7 +245,7 @@ export const useGetKnowledgeBaseInferences = ( kbId: string | undefined ): UseQueryResult => { return useQueryInit( - getKnowledgeBaseInferencesKey(appId || "", kbId || ""), + getKnowledgeBaseInferencesKey(appId || '', kbId || ''), () => getKnowledgeBaseInferencesQueryFn(kbId!), !!appId && !!kbId ); @@ -319,21 +255,13 @@ export const useGetWorkflows = ( appId: string | undefined, namespace?: string ): UseQueryResult => { - return useQueryInit( - getWorkflowsKey(appId || "", namespace), - () => getWorkflowsQueryFn(namespace), - !!appId - ); + return useQueryInit(getWorkflowsKey(appId || '', namespace), () => getWorkflowsQueryFn(namespace), !!appId); }; export const useGetWorkflowPipelines = ( appId: string | undefined ): UseQueryResult => { - return useQueryInit( - getWorkflowPipelinesKey(appId || ""), - getWorkflowPipelinesQueryFn, - !!appId - ); + return useQueryInit(getWorkflowPipelinesKey(appId || ''), getWorkflowPipelinesQueryFn, !!appId); }; export const useGetWorkflowRuns = ( @@ -343,50 +271,26 @@ export const useGetWorkflowRuns = ( limit: number = 10 ): UseQueryResult => { return useQueryInit( - getWorkflowRunsKey(appId || "", workflowPipelineId || "", offset, limit), + getWorkflowRunsKey(appId || '', workflowPipelineId || '', offset, limit), () => getWorkflowRunsQueryFn(workflowPipelineId!, offset, limit), !!appId && !!workflowPipelineId ); }; -export const useGetVoiceAgents = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getVoiceAgentsKey(appId || ""), - getVoiceAgentsQueryFn, - !!appId - ); +export const useGetVoiceAgents = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getVoiceAgentsKey(appId || ''), getVoiceAgentsQueryFn, !!appId); }; -export const useGetTtsConfigs = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getTtsConfigsKey(appId || ""), - getTtsConfigsQueryFn, - !!appId - ); +export const useGetTtsConfigs = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getTtsConfigsKey(appId || ''), getTtsConfigsQueryFn, !!appId); }; -export const useGetSttConfigs = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getSttConfigsKey(appId || ""), - getSttConfigsQueryFn, - !!appId - ); +export const useGetSttConfigs = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getSttConfigsKey(appId || ''), getSttConfigsQueryFn, !!appId); }; -export const useGetTelephonyConfigs = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit( - getTelephonyConfigsKey(appId || ""), - getTelephonyConfigsQueryFn, - !!appId - ); +export const useGetTelephonyConfigs = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getTelephonyConfigsKey(appId || ''), getTelephonyConfigsQueryFn, !!appId); }; export const useGetVoiceAgent = ( @@ -394,7 +298,7 @@ export const useGetVoiceAgent = ( agentId: string | undefined ): UseQueryResult => { return useQueryInit( - getVoiceAgentKey(appId || "", agentId || ""), + getVoiceAgentKey(appId || '', agentId || ''), () => getVoiceAgentQueryFn(agentId!), !!appId && !!agentId ); @@ -405,7 +309,7 @@ export const useGetTtsConfig = ( configId: string | undefined ): UseQueryResult => { return useQueryInit( - getTtsConfigKey(appId || "", configId || ""), + getTtsConfigKey(appId || '', configId || ''), () => getTtsConfigQueryFn(configId!), !!appId && !!configId ); @@ -416,7 +320,7 @@ export const useGetSttConfig = ( configId: string | undefined ): UseQueryResult => { return useQueryInit( - getSttConfigKey(appId || "", configId || ""), + getSttConfigKey(appId || '', configId || ''), () => getSttConfigQueryFn(configId!), !!appId && !!configId ); @@ -427,7 +331,7 @@ export const useGetTelephonyConfig = ( configId: string | undefined ): UseQueryResult => { return useQueryInit( - getTelephonyConfigKey(appId || "", configId || ""), + getTelephonyConfigKey(appId || '', configId || ''), () => getTelephonyConfigQueryFn(configId!), !!appId && !!configId ); @@ -437,17 +341,11 @@ export const useGetAgent = ( appId: string | undefined, agentId: string | undefined ): UseQueryResult => { - return useQueryInit( - getAgentKey(appId || "", agentId || ""), - () => getAgentQueryFn(agentId!), - !!appId && !!agentId - ); + return useQueryInit(getAgentKey(appId || '', agentId || ''), () => getAgentQueryFn(agentId!), !!appId && !!agentId); }; -export const useGetTools = ( - appId: string | undefined -): UseQueryResult => { - return useQueryInit(getToolsKey(appId || ""), getToolsQueryFn, !!appId); +export const useGetTools = (appId: string | undefined): UseQueryResult => { + return useQueryInit(getToolsKey(appId || ''), getToolsQueryFn, !!appId); }; export const useGetApiService = ( @@ -455,7 +353,7 @@ export const useGetApiService = ( serviceId: string | undefined ): UseQueryResult => { return useQueryInit( - getApiServiceKey(appId || "", serviceId || ""), + getApiServiceKey(appId || '', serviceId || ''), () => getApiServiceQueryFn(serviceId!), !!appId && !!serviceId ); @@ -464,11 +362,7 @@ export const useGetApiService = ( export const useGetMessageProcessors = ( appId: string | undefined ): UseQueryResult => { - return useQueryInit( - getMessageProcessorsKey(appId || ""), - getMessageProcessorsQueryFn, - !!appId - ); + return useQueryInit(getMessageProcessorsKey(appId || ''), getMessageProcessorsQueryFn, !!appId); }; export const useGetMessageProcessor = ( @@ -476,7 +370,7 @@ export const useGetMessageProcessor = ( processorId: string | undefined ): UseQueryResult => { return useQueryInit( - getMessageProcessorKey(appId || "", processorId || ""), + getMessageProcessorKey(appId || '', processorId || ''), () => getMessageProcessorQueryFn(processorId!), !!appId && !!processorId ); @@ -484,13 +378,9 @@ export const useGetMessageProcessor = ( export const useGetPipelines = ( appId: string | undefined, - statusFilter?: PipelineStatus | "all" + statusFilter?: PipelineStatus | 'all' ): UseQueryResult => { - return useQueryInit( - getPipelinesKey(appId || "", statusFilter), - () => getPipelinesQueryFn(statusFilter), - !!appId - ); + return useQueryInit(getPipelinesKey(appId || '', statusFilter), () => getPipelinesQueryFn(statusFilter), !!appId); }; export const useGetPipeline = ( @@ -498,7 +388,7 @@ export const useGetPipeline = ( pipelineId: string | undefined ): UseQueryResult => { return useQueryInit( - getPipelineKey(appId || "", pipelineId || ""), + getPipelineKey(appId || '', pipelineId || ''), () => getPipelineQueryFn(pipelineId!), !!appId && !!pipelineId ); @@ -509,19 +399,12 @@ export const useGetPipelineFiles = ( pipelineId: string | undefined ): UseQueryResult => { return useQueryInit( - getPipelineFilesKey(appId || "", pipelineId || ""), + getPipelineFilesKey(appId || '', pipelineId || ''), () => getPipelineFilesQueryFn(pipelineId!), !!appId && !!pipelineId ); }; -export const useGetAppById = ( - appId: string, - enabled: boolean = true -): UseQueryResult => { - return useQueryInit( - getAppByIdKey(appId), - () => getAppByIdFn(appId), - enabled - ); +export const useGetAppById = (appId: string, enabled: boolean = true): UseQueryResult => { + return useQueryInit(getAppByIdKey(appId), () => getAppByIdFn(appId), enabled); }; diff --git a/wavefront/client/src/hooks/data/mutation-functions.ts b/wavefront/client/src/hooks/data/mutation-functions.ts index f00da2a7..9c1874ea 100644 --- a/wavefront/client/src/hooks/data/mutation-functions.ts +++ b/wavefront/client/src/hooks/data/mutation-functions.ts @@ -1,4 +1,4 @@ -import floConsoleService from "@app/api"; +import floConsoleService from '@app/api'; /** * Agent mutation functions diff --git a/wavefront/client/src/hooks/data/mutation-hooks.ts b/wavefront/client/src/hooks/data/mutation-hooks.ts index e84e2be0..b211950a 100644 --- a/wavefront/client/src/hooks/data/mutation-hooks.ts +++ b/wavefront/client/src/hooks/data/mutation-hooks.ts @@ -1,15 +1,7 @@ -import { - QueryClient, - useMutation, - useQueryClient, -} from "@tanstack/react-query"; -import { getAgentKey, getAgentsKey, getAppByIdKey } from "./query-keys"; -import { - deleteAgentMutationFn, - updateAgentMutationFn, - updateAppFn, -} from "./mutation-functions"; -import { useNotifyStore } from "@app/store"; +import { QueryClient, useMutation, useQueryClient } from '@tanstack/react-query'; +import { getAgentKey, getAgentsKey, getAppByIdKey } from './query-keys'; +import { deleteAgentMutationFn, updateAgentMutationFn, updateAppFn } from './mutation-functions'; +import { useNotifyStore } from '@app/store'; /** * Hook for deleting an agent @@ -21,15 +13,15 @@ export const useDeleteAgent = (appId: string | undefined) => { return useMutation({ mutationFn: deleteAgentMutationFn, onSuccess: () => { - notifySuccess("Agent deleted successfully"); + notifySuccess('Agent deleted successfully'); // Invalidate all agents queries for this appId to refetch if (appId) { queryClient.invalidateQueries({ queryKey: getAgentsKey(appId) }); } }, onError: (error) => { - console.error("Error deleting agent:", error); - notifyError("Failed to delete agent"); + console.error('Error deleting agent:', error); + notifyError('Failed to delete agent'); }, }); }; @@ -37,17 +29,14 @@ export const useDeleteAgent = (appId: string | undefined) => { /** * Hook for updating an agent */ -export const useUpdateAgent = ( - appId: string | undefined, - agentId: string | undefined -) => { +export const useUpdateAgent = (appId: string | undefined, agentId: string | undefined) => { const queryClient = useQueryClient(); const { notifySuccess, notifyError } = useNotifyStore(); return useMutation({ mutationFn: updateAgentMutationFn, onSuccess: () => { - notifySuccess("Agent updated successfully"); + notifySuccess('Agent updated successfully'); // Invalidate agent queries to refetch updated data if (appId && agentId) { queryClient.invalidateQueries({ @@ -57,8 +46,8 @@ export const useUpdateAgent = ( } }, onError: (error) => { - console.error("Error updating agent:", error); - notifyError("Failed to update agent"); + console.error('Error updating agent:', error); + notifyError('Failed to update agent'); }, }); }; @@ -74,10 +63,10 @@ export const useUpdateApp = ( queryClient.invalidateQueries({ queryKey: getAppByIdKey(variables.appId), }); - notifySuccess("App updated successfully"); + notifySuccess('App updated successfully'); }, onError: () => { - notifyError("Failed to update app"); + notifyError('Failed to update app'); }, }); }; diff --git a/wavefront/client/src/hooks/data/query-functions.ts b/wavefront/client/src/hooks/data/query-functions.ts index 34e2195f..9542f837 100644 --- a/wavefront/client/src/hooks/data/query-functions.ts +++ b/wavefront/client/src/hooks/data/query-functions.ts @@ -1,31 +1,20 @@ -import floConsoleService from "@app/api"; -import { - DocumentData, - InferenceData, - KbData, -} from "@app/api/knowledge-base-service"; -import { ModelData } from "@app/api/model-inference-service"; -import { NamespaceItem } from "@app/api/namespace-service"; -import { AgentApi, AgentListItem } from "@app/types/agent"; -import { ApiServiceItem } from "@app/types/api-service"; -import { Authenticator } from "@app/types/authenticator"; -import { Datasource, ReadYamlData, Yaml } from "@app/types/datasource"; -import { LLMInferenceConfig } from "@app/types/llm-inference-config"; -import { - MessageProcessor, - MessageProcessorListItem, -} from "@app/types/message-processor"; -import { Pipeline, PipelineFile, PipelineStatus } from "@app/types/pipeline"; -import { SttConfig } from "@app/types/stt-config"; -import { TelephonyConfig } from "@app/types/telephony-config"; -import { ToolDetails } from "@app/types/tool"; -import { TtsConfig } from "@app/types/tts-config"; -import { VoiceAgent } from "@app/types/voice-agent"; -import { - WorkflowListItem, - WorkflowPipelineListItem, - WorkflowRunListData, -} from "@app/types/workflow"; +import floConsoleService from '@app/api'; +import { DocumentData, InferenceData, KbData } from '@app/api/knowledge-base-service'; +import { ModelData } from '@app/api/model-inference-service'; +import { NamespaceItem } from '@app/api/namespace-service'; +import { AgentApi, AgentListItem } from '@app/types/agent'; +import { ApiServiceItem } from '@app/types/api-service'; +import { Authenticator } from '@app/types/authenticator'; +import { Datasource, ReadYamlData, Yaml } from '@app/types/datasource'; +import { LLMInferenceConfig } from '@app/types/llm-inference-config'; +import { MessageProcessor, MessageProcessorListItem } from '@app/types/message-processor'; +import { Pipeline, PipelineFile, PipelineStatus } from '@app/types/pipeline'; +import { SttConfig } from '@app/types/stt-config'; +import { TelephonyConfig } from '@app/types/telephony-config'; +import { ToolDetails } from '@app/types/tool'; +import { TtsConfig } from '@app/types/tts-config'; +import { VoiceAgent } from '@app/types/voice-agent'; +import { WorkflowListItem, WorkflowPipelineListItem, WorkflowRunListData } from '@app/types/workflow'; const getAllAppsQueryFn = async () => { const { @@ -48,23 +37,16 @@ const getAllDatasourcesQueryFn = async () => { return data.datasources; }; -const getDatasourceQueryFn = async ( - datasourceId: string -): Promise => { - const response = await floConsoleService.datasourcesService.getDatasource( - datasourceId - ); +const getDatasourceQueryFn = async (datasourceId: string): Promise => { + const response = await floConsoleService.datasourcesService.getDatasource(datasourceId); if (response.data?.data) { const responseData = response.data.data as any; return { id: datasourceId, - name: responseData.name || "Unknown", - type: responseData.type || "unknown", - config: - typeof responseData.config === "string" - ? JSON.parse(responseData.config) - : responseData.config || {}, - description: responseData.description || "", + name: responseData.name || 'Unknown', + type: responseData.type || 'unknown', + config: typeof responseData.config === 'string' ? JSON.parse(responseData.config) : responseData.config || {}, + description: responseData.description || '', created_at: responseData.created_at, updated_at: responseData.updated_at, }; @@ -73,47 +55,32 @@ const getDatasourceQueryFn = async ( }; const getAllYamlsQueryFn = async (datasourceId: string): Promise => { - const response = await floConsoleService.datasourcesService.getAllYamls( - datasourceId - ); + const response = await floConsoleService.datasourcesService.getAllYamls(datasourceId); if (response.data?.data?.yamls) { return response.data.data.yamls; } return []; }; -const readYamlQueryFn = async ( - datasourceId: string, - yamlId: string -): Promise => { - const response = await floConsoleService.datasourcesService.readYaml( - datasourceId, - yamlId - ); +const readYamlQueryFn = async (datasourceId: string, yamlId: string): Promise => { + const response = await floConsoleService.datasourcesService.readYaml(datasourceId, yamlId); if (response.data?.data) { return response.data.data; } return null; }; -const getDatasourceResourcesQueryFn = async ( - datasourceId: string -): Promise => { - const response = - await floConsoleService.datasourcesService.getDatasourceResources( - datasourceId - ); +const getDatasourceResourcesQueryFn = async (datasourceId: string): Promise => { + const response = await floConsoleService.datasourcesService.getDatasourceResources(datasourceId); if (response.data?.data?.data?.resources) { return response.data.data.data.resources; } return []; }; -const getAgentsQueryFn = async ( - namespace?: string -): Promise => { +const getAgentsQueryFn = async (namespace?: string): Promise => { const response = await floConsoleService.agentService.listAgents(namespace); - if (response.data?.meta?.status === "success" && response.data.data?.data) { + if (response.data?.meta?.status === 'success' && response.data.data?.data) { return response.data.data.data.agents; } return []; @@ -121,7 +88,7 @@ const getAgentsQueryFn = async ( const getNamespacesQueryFn = async (): Promise => { const response = await floConsoleService.namespaceService.listNamespaces(); - if (response.data?.meta?.status === "success" && response.data.data?.data) { + if (response.data?.meta?.status === 'success' && response.data.data?.data) { return response.data.data.data.namespaces; } return []; @@ -129,32 +96,22 @@ const getNamespacesQueryFn = async (): Promise => { const getApiServicesQueryFn = async (): Promise => { const response = await floConsoleService.apiServiceService.listApiServices(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.services - ) { + if (response.data?.meta?.status === 'success' && response.data.data?.services) { return response.data.data.services; } return []; }; const getAuthenticatorsQueryFn = async (): Promise => { - const response = - await floConsoleService.authenticatorService.getAllAuthenticators(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.authenticators - ) { + const response = await floConsoleService.authenticatorService.getAllAuthenticators(); + if (response.data?.meta?.status === 'success' && response.data.data?.authenticators) { return response.data.data.authenticators; } return []; }; -const getAuthenticatorQueryFn = async ( - authId: string -): Promise => { - const response = - await floConsoleService.authenticatorService.getAuthenticator(authId); +const getAuthenticatorQueryFn = async (authId: string): Promise => { + const response = await floConsoleService.authenticatorService.getAuthenticator(authId); if (response.data?.data) { return response.data.data; } @@ -162,106 +119,72 @@ const getAuthenticatorQueryFn = async ( }; const getLLMConfigsQueryFn = async (): Promise => { - const response = - await floConsoleService.llmInferenceService.listAllLLMConfigs(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.configs - ) { + const response = await floConsoleService.llmInferenceService.listAllLLMConfigs(); + if (response.data?.meta?.status === 'success' && response.data.data?.configs) { return response.data.data.configs; } return []; }; const getModelsQueryFn = async (): Promise => { - const response = - await floConsoleService.modelInferenceService.listAllModels(); - if (response.data?.meta?.status === "success" && response.data.data?.data) { + const response = await floConsoleService.modelInferenceService.listAllModels(); + if (response.data?.meta?.status === 'success' && response.data.data?.data) { return response.data.data.data; } return []; }; const getModelQueryFn = async (modelId: string): Promise => { - const response = await floConsoleService.modelInferenceService.getModel( - modelId - ); - if (response.data?.meta?.status === "success" && response.data.data?.data) { + const response = await floConsoleService.modelInferenceService.getModel(modelId); + if (response.data?.meta?.status === 'success' && response.data.data?.data) { return response.data.data.data; } return null; }; const getKnowledgeBasesQueryFn = async (): Promise => { - const response = - await floConsoleService.knowledgeBaseService.listKnowledgeBases(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.resources - ) { + const response = await floConsoleService.knowledgeBaseService.listKnowledgeBases(); + if (response.data?.meta?.status === 'success' && response.data.data?.resources) { return response.data.data.resources; } return []; }; -const getKnowledgeBaseQueryFn = async ( - kbId: string -): Promise => { - const response = - await floConsoleService.knowledgeBaseService.getKnowledgeBase(kbId); +const getKnowledgeBaseQueryFn = async (kbId: string): Promise => { + const response = await floConsoleService.knowledgeBaseService.getKnowledgeBase(kbId); if (response.data?.data) { return response.data.data; } return null; }; -const getKnowledgeBaseDocumentsQueryFn = async ( - kbId: string -): Promise => { - const response = - await floConsoleService.knowledgeBaseService.listKnowledgeBaseDocuments( - kbId - ); +const getKnowledgeBaseDocumentsQueryFn = async (kbId: string): Promise => { + const response = await floConsoleService.knowledgeBaseService.listKnowledgeBaseDocuments(kbId); if (response.data?.data?.resources) { return response.data.data.resources; } return []; }; -const getKnowledgeBaseInferencesQueryFn = async ( - kbId: string -): Promise => { - const response = - await floConsoleService.knowledgeBaseService.listInferencesForKnowledgeBase( - kbId - ); +const getKnowledgeBaseInferencesQueryFn = async (kbId: string): Promise => { + const response = await floConsoleService.knowledgeBaseService.listInferencesForKnowledgeBase(kbId); if (response.data?.data?.resources) { return response.data.data.resources; } return []; }; -const getWorkflowsQueryFn = async ( - namespace?: string -): Promise => { - const response = await floConsoleService.workflowService.listWorkflows( - namespace - ); - if (response.data?.meta?.status === "success" && response.data.data?.data) { +const getWorkflowsQueryFn = async (namespace?: string): Promise => { + const response = await floConsoleService.workflowService.listWorkflows(namespace); + if (response.data?.meta?.status === 'success' && response.data.data?.data) { return response.data.data.data.workflows; } return []; }; -const getWorkflowPipelinesQueryFn = async (): Promise< - WorkflowPipelineListItem[] -> => { - const response = - await floConsoleService.workflowService.listWorkflowPipelines(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.workflow_pipelines - ) { +const getWorkflowPipelinesQueryFn = async (): Promise => { + const response = await floConsoleService.workflowService.listWorkflowPipelines(); + if (response.data?.meta?.status === 'success' && response.data.data?.workflow_pipelines) { return response.data.data.workflow_pipelines; } return []; @@ -272,12 +195,8 @@ const getWorkflowRunsQueryFn = async ( offset: number = 0, limit: number = 10 ): Promise => { - const response = await floConsoleService.workflowService.getWorkflowRuns( - workflowPipelineId, - offset, - limit - ); - if (response.data?.meta?.status === "success" && response.data.data) { + const response = await floConsoleService.workflowService.getWorkflowRuns(workflowPipelineId, offset, limit); + if (response.data?.meta?.status === 'success' && response.data.data) { return response.data.data; } return { @@ -290,12 +209,8 @@ const getWorkflowRunsQueryFn = async ( }; const getVoiceAgentsQueryFn = async (): Promise => { - const response = - await floConsoleService.voiceAgentService.listAllVoiceAgents(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.voice_agents - ) { + const response = await floConsoleService.voiceAgentService.listAllVoiceAgents(); + if (response.data?.meta?.status === 'success' && response.data.data?.voice_agents) { return response.data.data.voice_agents; } return []; @@ -303,10 +218,7 @@ const getVoiceAgentsQueryFn = async (): Promise => { const getTtsConfigsQueryFn = async (): Promise => { const response = await floConsoleService.ttsConfigService.listAllTtsConfigs(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.tts_configs - ) { + if (response.data?.meta?.status === 'success' && response.data.data?.tts_configs) { return response.data.data.tts_configs; } return []; @@ -314,68 +226,46 @@ const getTtsConfigsQueryFn = async (): Promise => { const getSttConfigsQueryFn = async (): Promise => { const response = await floConsoleService.sttConfigService.listAllSttConfigs(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.stt_configs - ) { + if (response.data?.meta?.status === 'success' && response.data.data?.stt_configs) { return response.data.data.stt_configs; } return []; }; const getTelephonyConfigsQueryFn = async (): Promise => { - const response = - await floConsoleService.telephonyConfigService.listAllTelephonyConfigs(); - if ( - response.data?.meta?.status === "success" && - response.data.data?.telephony_configs - ) { + const response = await floConsoleService.telephonyConfigService.listAllTelephonyConfigs(); + if (response.data?.meta?.status === 'success' && response.data.data?.telephony_configs) { return response.data.data.telephony_configs; } return []; }; -const getVoiceAgentQueryFn = async ( - agentId: string -): Promise => { - const response = await floConsoleService.voiceAgentService.getVoiceAgent( - agentId - ); +const getVoiceAgentQueryFn = async (agentId: string): Promise => { + const response = await floConsoleService.voiceAgentService.getVoiceAgent(agentId); if (response.data?.data) { return response.data.data; } return null; }; -const getTtsConfigQueryFn = async ( - configId: string -): Promise => { - const response = await floConsoleService.ttsConfigService.getTtsConfig( - configId - ); +const getTtsConfigQueryFn = async (configId: string): Promise => { + const response = await floConsoleService.ttsConfigService.getTtsConfig(configId); if (response.data?.data) { return response.data.data; } return null; }; -const getSttConfigQueryFn = async ( - configId: string -): Promise => { - const response = await floConsoleService.sttConfigService.getSttConfig( - configId - ); +const getSttConfigQueryFn = async (configId: string): Promise => { + const response = await floConsoleService.sttConfigService.getSttConfig(configId); if (response.data?.data) { return response.data.data; } return null; }; -const getTelephonyConfigQueryFn = async ( - configId: string -): Promise => { - const response = - await floConsoleService.telephonyConfigService.getTelephonyConfig(configId); +const getTelephonyConfigQueryFn = async (configId: string): Promise => { + const response = await floConsoleService.telephonyConfigService.getTelephonyConfig(configId); if (response.data?.data) { return response.data.data; } @@ -391,7 +281,7 @@ const getAgentQueryFn = async (agentId: string): Promise => { namespace: response.data.data.data.namespace, created_at: response.data.data.data.created_at, updated_at: response.data.data.data.updated_at, - yaml_content: response.data.data.data.yaml_content || "", + yaml_content: response.data.data.data.yaml_content || '', }; } return null; @@ -399,71 +289,47 @@ const getAgentQueryFn = async (agentId: string): Promise => { const getToolsQueryFn = async (): Promise => { const response = await floConsoleService.toolService.getToolNamesAndDetails(); - if ( - response.data?.data?.data?.tool_details && - Array.isArray(response.data.data.data.tool_details) - ) { + if (response.data?.data?.data?.tool_details && Array.isArray(response.data.data.data.tool_details)) { return response.data.data.data.tool_details; } return []; }; -const getMessageProcessorsQueryFn = async (): Promise< - MessageProcessorListItem[] -> => { - const response = - await floConsoleService.messageProcessorService.listMessageProcessors(); - if ( - response.data?.data?.processors && - Array.isArray(response.data.data.processors) - ) { +const getMessageProcessorsQueryFn = async (): Promise => { + const response = await floConsoleService.messageProcessorService.listMessageProcessors(); + if (response.data?.data?.processors && Array.isArray(response.data.data.processors)) { return response.data.data.processors; } return []; }; -const getMessageProcessorQueryFn = async ( - processorId: string -): Promise => { - const response = - await floConsoleService.messageProcessorService.getMessageProcessor( - processorId - ); +const getMessageProcessorQueryFn = async (processorId: string): Promise => { + const response = await floConsoleService.messageProcessorService.getMessageProcessor(processorId); if (response.data?.data?.processor) { return response.data.data.processor; } return null; }; -const getApiServiceQueryFn = async ( - serviceId: string -): Promise => { - const response = await floConsoleService.apiServiceService.getApiService( - serviceId - ); +const getApiServiceQueryFn = async (serviceId: string): Promise => { + const response = await floConsoleService.apiServiceService.getApiService(serviceId); if (response.data?.data) { return response.data.data; } return null; }; -const getLLMConfigQueryFn = async ( - configId: string -): Promise => { - const response = await floConsoleService.llmInferenceService.getLLMConfig( - configId - ); +const getLLMConfigQueryFn = async (configId: string): Promise => { + const response = await floConsoleService.llmInferenceService.getLLMConfig(configId); if (response.data?.data) { return response.data.data; } return null; }; -const getPipelinesQueryFn = async ( - statusFilter?: PipelineStatus | "all" -): Promise => { +const getPipelinesQueryFn = async (statusFilter?: PipelineStatus | 'all'): Promise => { const pipelineService = floConsoleService.dataPipelineService; - const response = await (statusFilter === "all" || !statusFilter + const response = await (statusFilter === 'all' || !statusFilter ? pipelineService.listPipelines() : pipelineService.listPipelines(statusFilter)); if (response.data?.data?.pipelines) { @@ -472,9 +338,7 @@ const getPipelinesQueryFn = async ( return []; }; -const getPipelineQueryFn = async ( - pipelineId: string -): Promise => { +const getPipelineQueryFn = async (pipelineId: string): Promise => { const pipelineService = floConsoleService.dataPipelineService; const response = await pipelineService.getPipeline(pipelineId); if (response.data?.data?.pipeline) { @@ -483,9 +347,7 @@ const getPipelineQueryFn = async ( return null; }; -const getPipelineFilesQueryFn = async ( - pipelineId: string -): Promise => { +const getPipelineFilesQueryFn = async (pipelineId: string): Promise => { const pipelineService = floConsoleService.dataPipelineService; const response = await pipelineService.listFiles(pipelineId); if (response.data?.data?.files) { diff --git a/wavefront/client/src/hooks/data/query-keys.ts b/wavefront/client/src/hooks/data/query-keys.ts index 850015d1..30e0d88e 100644 --- a/wavefront/client/src/hooks/data/query-keys.ts +++ b/wavefront/client/src/hooks/data/query-keys.ts @@ -1,151 +1,67 @@ const getAgentsKey = (appId: string, namespace?: string) => { if (namespace) { - return ["agents", appId, namespace]; + return ['agents', appId, namespace]; } - return ["agents", appId]; + return ['agents', appId]; }; -const getNamespacesKey = (appId: string) => ["namespaces", appId]; -const getAllAppsKey = () => ["apps"]; -const getAllDatasourcesKey = (appId: string) => ["datasources", appId]; -const getDatasourceKey = (appId: string, datasourceId: string) => [ - "datasource", - appId, - datasourceId, -]; -const getAllYamlsKey = (appId: string, datasourceId: string) => [ - "yamls", - appId, - datasourceId, -]; -const readYamlKey = (appId: string, datasourceId: string, yamlId: string) => [ - "yaml", - appId, - datasourceId, - yamlId, -]; +const getNamespacesKey = (appId: string) => ['namespaces', appId]; +const getAllAppsKey = () => ['apps']; +const getAllDatasourcesKey = (appId: string) => ['datasources', appId]; +const getDatasourceKey = (appId: string, datasourceId: string) => ['datasource', appId, datasourceId]; +const getAllYamlsKey = (appId: string, datasourceId: string) => ['yamls', appId, datasourceId]; +const readYamlKey = (appId: string, datasourceId: string, yamlId: string) => ['yaml', appId, datasourceId, yamlId]; const getDatasourceResourcesKey = (appId: string, datasourceId: string) => [ - "datasource-resources", + 'datasource-resources', appId, datasourceId, ]; -const getCurrentUserKey = () => ["whoami"]; -const getApiServicesKey = (appId: string) => ["api-services", appId]; -const getAuthenticatorsKey = (appId: string) => ["authenticators", appId]; -const getAuthenticatorKey = (appId: string, authId: string) => [ - "authenticator", - appId, - authId, -]; -const getLLMConfigsKey = (appId: string) => ["llm-configs", appId]; -const getLLMConfigKey = (appId: string, configId: string) => [ - "llm-config", - appId, - configId, -]; -const getModelsKey = (appId: string) => ["models", appId]; -const getModelKey = (appId: string, modelId: string) => [ - "model", - appId, - modelId, -]; -const getKnowledgeBasesKey = (appId: string) => ["knowledge-bases", appId]; -const getKnowledgeBaseKey = (appId: string, kbId: string) => [ - "knowledge-base", - appId, - kbId, -]; -const getKnowledgeBaseDocumentsKey = (appId: string, kbId: string) => [ - "knowledge-base-documents", - appId, - kbId, -]; -const getKnowledgeBaseInferencesKey = (appId: string, kbId: string) => [ - "knowledge-base-inferences", - appId, - kbId, -]; +const getCurrentUserKey = () => ['whoami']; +const getApiServicesKey = (appId: string) => ['api-services', appId]; +const getAuthenticatorsKey = (appId: string) => ['authenticators', appId]; +const getAuthenticatorKey = (appId: string, authId: string) => ['authenticator', appId, authId]; +const getLLMConfigsKey = (appId: string) => ['llm-configs', appId]; +const getLLMConfigKey = (appId: string, configId: string) => ['llm-config', appId, configId]; +const getModelsKey = (appId: string) => ['models', appId]; +const getModelKey = (appId: string, modelId: string) => ['model', appId, modelId]; +const getKnowledgeBasesKey = (appId: string) => ['knowledge-bases', appId]; +const getKnowledgeBaseKey = (appId: string, kbId: string) => ['knowledge-base', appId, kbId]; +const getKnowledgeBaseDocumentsKey = (appId: string, kbId: string) => ['knowledge-base-documents', appId, kbId]; +const getKnowledgeBaseInferencesKey = (appId: string, kbId: string) => ['knowledge-base-inferences', appId, kbId]; const getWorkflowsKey = (appId: string, namespace?: string) => { if (namespace) { - return ["workflows", appId, namespace]; + return ['workflows', appId, namespace]; } - return ["workflows", appId]; + return ['workflows', appId]; }; -const getWorkflowPipelinesKey = (appId: string) => [ - "workflow-pipelines", - appId, -]; -const getWorkflowRunsKey = ( - appId: string, - workflowPipelineId: string, - offset?: number, - limit?: number -) => { - const key: (string | number)[] = ["workflow-runs", appId, workflowPipelineId]; - if (offset !== undefined) key.push("offset", offset); - if (limit !== undefined) key.push("limit", limit); +const getWorkflowPipelinesKey = (appId: string) => ['workflow-pipelines', appId]; +const getWorkflowRunsKey = (appId: string, workflowPipelineId: string, offset?: number, limit?: number) => { + const key: (string | number)[] = ['workflow-runs', appId, workflowPipelineId]; + if (offset !== undefined) key.push('offset', offset); + if (limit !== undefined) key.push('limit', limit); return key; }; -const getVoiceAgentsKey = (appId: string) => ["voice-agents", appId]; -const getTtsConfigsKey = (appId: string) => ["tts-configs", appId]; -const getSttConfigsKey = (appId: string) => ["stt-configs", appId]; -const getTelephonyConfigsKey = (appId: string) => ["telephony-configs", appId]; -const getVoiceAgentKey = (appId: string, agentId: string) => [ - "voice-agent", - appId, - agentId, -]; -const getTtsConfigKey = (appId: string, configId: string) => [ - "tts-config", - appId, - configId, -]; -const getSttConfigKey = (appId: string, configId: string) => [ - "stt-config", - appId, - configId, -]; -const getTelephonyConfigKey = (appId: string, configId: string) => [ - "telephony-config", - appId, - configId, -]; -const getAgentKey = (appId: string, agentId: string) => [ - "agent", - appId, - agentId, -]; -const getToolsKey = (appId: string) => ["tools", appId]; -const getApiServiceKey = (appId: string, serviceId: string) => [ - "api-service", - appId, - serviceId, -]; -const getMessageProcessorsKey = (appId: string) => [ - "message-processors", - appId, -]; -const getMessageProcessorKey = (appId: string, processorId: string) => [ - "message-processor", - appId, - processorId, -]; +const getVoiceAgentsKey = (appId: string) => ['voice-agents', appId]; +const getTtsConfigsKey = (appId: string) => ['tts-configs', appId]; +const getSttConfigsKey = (appId: string) => ['stt-configs', appId]; +const getTelephonyConfigsKey = (appId: string) => ['telephony-configs', appId]; +const getVoiceAgentKey = (appId: string, agentId: string) => ['voice-agent', appId, agentId]; +const getTtsConfigKey = (appId: string, configId: string) => ['tts-config', appId, configId]; +const getSttConfigKey = (appId: string, configId: string) => ['stt-config', appId, configId]; +const getTelephonyConfigKey = (appId: string, configId: string) => ['telephony-config', appId, configId]; +const getAgentKey = (appId: string, agentId: string) => ['agent', appId, agentId]; +const getToolsKey = (appId: string) => ['tools', appId]; +const getApiServiceKey = (appId: string, serviceId: string) => ['api-service', appId, serviceId]; +const getMessageProcessorsKey = (appId: string) => ['message-processors', appId]; +const getMessageProcessorKey = (appId: string, processorId: string) => ['message-processor', appId, processorId]; const getPipelinesKey = (appId: string, statusFilter?: string) => { if (statusFilter) { - return ["pipelines", appId, statusFilter]; + return ['pipelines', appId, statusFilter]; } - return ["pipelines", appId]; + return ['pipelines', appId]; }; -const getPipelineKey = (appId: string, pipelineId: string) => [ - "pipeline", - appId, - pipelineId, -]; -const getPipelineFilesKey = (appId: string, pipelineId: string) => [ - "pipeline-files", - appId, - pipelineId, -]; -const getAppByIdKey = (appId: string) => ["app-by-id", appId]; +const getPipelineKey = (appId: string, pipelineId: string) => ['pipeline', appId, pipelineId]; +const getPipelineFilesKey = (appId: string, pipelineId: string) => ['pipeline-files', appId, pipelineId]; +const getAppByIdKey = (appId: string) => ['app-by-id', appId]; export { getAgentKey, diff --git a/wavefront/client/src/index.css b/wavefront/client/src/index.css index 417a8e1b..1c7af0d8 100644 --- a/wavefront/client/src/index.css +++ b/wavefront/client/src/index.css @@ -1,4 +1,4 @@ -@import "tailwindcss"; +@import 'tailwindcss'; html, body, @@ -12,8 +12,8 @@ body, } @font-face { - font-family: "sf-pro-display"; - src: url("/font/SFPRODISPLAYMEDIUM.OTF") format("opentype"); + font-family: 'sf-pro-display'; + src: url('/font/SFPRODISPLAYMEDIUM.OTF') format('opentype'); font-style: normal; } diff --git a/wavefront/client/src/lib/axios.ts b/wavefront/client/src/lib/axios.ts index 6a5123bf..f429f344 100644 --- a/wavefront/client/src/lib/axios.ts +++ b/wavefront/client/src/lib/axios.ts @@ -1,14 +1,10 @@ -import { appEnv } from "@app/config/env"; -import { TOKEN_KEY } from "@app/lib/constants"; -import { useAuthStore, useNotifyStore } from "@app/store"; -import axios, { - AxiosError, - AxiosResponse, - InternalAxiosRequestConfig, -} from "axios"; +import { appEnv } from '@app/config/env'; +import { TOKEN_KEY } from '@app/lib/constants'; +import { useAuthStore, useNotifyStore } from '@app/store'; +import axios, { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; export interface Meta { - status: "success" | "failure"; + status: 'success' | 'failure'; code: number; error?: string; } @@ -31,10 +27,10 @@ axiosInstance.interceptors.request.use( } // Replace :appId with the actual appId from the URL - if (config.url?.includes(":appId")) { + if (config.url?.includes(':appId')) { const pageUrl = new URL(window.location.href); - const appId = pageUrl.pathname.split("/")[2]; - config.url = config.url?.replace(":appId", appId || ""); + const appId = pageUrl.pathname.split('/')[2]; + config.url = config.url?.replace(':appId', appId || ''); } return config; @@ -52,8 +48,8 @@ axiosInstance.interceptors.response.use( const errorData = err.response as IApiResponse; useNotifyStore.setState({ visible: true, - type: "error", - message: errorData.data?.meta?.error || "Something went wrong", + type: 'error', + message: errorData.data?.meta?.error || 'Something went wrong', }); const errCode = err.response?.status; if (errCode === 401) { @@ -61,7 +57,7 @@ axiosInstance.interceptors.response.use( useAuthStore.setState({ authenticated: false, }); - window.location.href = "/login"; + window.location.href = '/login'; } return Promise.reject(err); diff --git a/wavefront/client/src/lib/constants.ts b/wavefront/client/src/lib/constants.ts index 0edfdce5..78e76347 100644 --- a/wavefront/client/src/lib/constants.ts +++ b/wavefront/client/src/lib/constants.ts @@ -1,2 +1,2 @@ -export const TOKEN_KEY = "authToken"; -export const CURRENT_PATH_KEY = "currentPath"; +export const TOKEN_KEY = 'authToken'; +export const CURRENT_PATH_KEY = 'currentPath'; diff --git a/wavefront/client/src/lib/utils.ts b/wavefront/client/src/lib/utils.ts index 10a87845..5bfc5af4 100644 --- a/wavefront/client/src/lib/utils.ts +++ b/wavefront/client/src/lib/utils.ts @@ -1,6 +1,6 @@ -import { clsx, type ClassValue } from "clsx"; -import { twMerge } from "tailwind-merge"; -import yaml from "js-yaml"; +import { clsx, type ClassValue } from 'clsx'; +import { twMerge } from 'tailwind-merge'; +import yaml from 'js-yaml'; export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); @@ -10,7 +10,7 @@ export const validateDynamicQueryYaml = (yaml_str: string) => { try { const data = yaml.load(yaml_str) as Record; // top require keys - const requiredTop = ["id", "name", "queries"]; + const requiredTop = ['id', 'name', 'queries']; for (const field of requiredTop) { if (!(field in data)) { @@ -19,12 +19,12 @@ export const validateDynamicQueryYaml = (yaml_str: string) => { } // ✅ queries must be a list if (!Array.isArray(data.queries)) { - return { valid: false, error: "queries must be a list" }; + return { valid: false, error: 'queries must be a list' }; } // each query must constain id,description,query for (let i = 0; i < data.queries.length; i++) { const q = data.queries[i]; - for (const field of ["id", "description", "query"]) { + for (const field of ['id', 'description', 'query']) { if (!(field in q)) { return { valid: false, @@ -32,47 +32,41 @@ export const validateDynamicQueryYaml = (yaml_str: string) => { }; } } - if ("parameters" in q) { - if (typeof q.parameters !== "object") { + if ('parameters' in q) { + if (typeof q.parameters !== 'object') { return { valid: false, - error: "parameters must be an object or array", + error: 'parameters must be an object or array', }; } - const allowed = ["string", "number", "boolean", "date"]; + const allowed = ['string', 'number', 'boolean', 'date']; // Handle array format: [{ name: 'param1', type: 'date' }, ...] if (Array.isArray(q.parameters)) { for (let j = 0; j < q.parameters.length; j++) { const param = q.parameters[j]; - if (typeof param !== "object" || param === null) { + if (typeof param !== 'object' || param === null) { return { valid: false, error: `Parameter ${j + 1} in query ${i + 1} must be an object`, }; } - if (!("name" in param)) { + if (!('name' in param)) { return { valid: false, - error: `Missing 'name' field in parameter ${j + 1} of query ${ - i + 1 - }`, + error: `Missing 'name' field in parameter ${j + 1} of query ${i + 1}`, }; } - if (!("type" in param)) { + if (!('type' in param)) { return { valid: false, - error: `Missing 'type' field in parameter ${j + 1} of query ${ - i + 1 - }`, + error: `Missing 'type' field in parameter ${j + 1} of query ${i + 1}`, }; } - if (typeof param.name !== "string") { + if (typeof param.name !== 'string') { return { valid: false, - error: `Parameter name must be a string in parameter ${ - j + 1 - } of query ${i + 1}`, + error: `Parameter name must be a string in parameter ${j + 1} of query ${i + 1}`, }; } if (!allowed.includes(param.type)) { @@ -80,15 +74,15 @@ export const validateDynamicQueryYaml = (yaml_str: string) => { valid: false, error: `Invalid parameter type '${param.type}' in parameter '${ param.name - }' of query ${i + 1}. Allowed types: ${allowed.join(", ")}`, + }' of query ${i + 1}. Allowed types: ${allowed.join(', ')}`, }; } } } } } - return { valid: true, error: "" }; + return { valid: true, error: '' }; } catch (err) { - return { valid: false, error: "Invalid YAML format" }; + return { valid: false, error: 'Invalid YAML format' }; } }; diff --git a/wavefront/client/src/not-found/index.tsx b/wavefront/client/src/not-found/index.tsx index 01ce093f..a6ee89ff 100644 --- a/wavefront/client/src/not-found/index.tsx +++ b/wavefront/client/src/not-found/index.tsx @@ -1,13 +1,7 @@ -import { Button } from "@app/components/ui/button"; -import { - Empty, - EmptyContent, - EmptyDescription, - EmptyHeader, - EmptyTitle, -} from "@app/components/ui/empty"; -import { useAuthStore } from "@app/store"; -import { useNavigate } from "react-router"; +import { Button } from '@app/components/ui/button'; +import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyTitle } from '@app/components/ui/empty'; +import { useAuthStore } from '@app/store'; +import { useNavigate } from 'react-router'; const NotFoundPage = () => { const navigate = useNavigate(); @@ -15,9 +9,9 @@ const NotFoundPage = () => { const handleGoBack = () => { if (authenticated) { - navigate("/apps"); + navigate('/apps'); } else { - navigate("/login"); + navigate('/login'); } }; @@ -27,12 +21,7 @@ const NotFoundPage = () => { 404 - Not Found The page you're looking for doesn't exist.
-
diff --git a/wavefront/client/src/pages/apps/[appId]/agents/[id].tsx b/wavefront/client/src/pages/apps/[appId]/agents/[id].tsx index 4dba0b34..e9fb06f1 100644 --- a/wavefront/client/src/pages/apps/[appId]/agents/[id].tsx +++ b/wavefront/client/src/pages/apps/[appId]/agents/[id].tsx @@ -1,6 +1,6 @@ -import floConsoleService from "@app/api"; -import ChatBot from "@app/components/ChatBot"; -import DeleteConfirmationDialog from "@app/components/DeleteConfirmationDialog"; +import floConsoleService from '@app/api'; +import ChatBot from '@app/components/ChatBot'; +import DeleteConfirmationDialog from '@app/components/DeleteConfirmationDialog'; import { Breadcrumb, BreadcrumbItem, @@ -8,28 +8,18 @@ import { BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, -} from "@app/components/ui/breadcrumb"; -import { Button } from "@app/components/ui/button"; -import { useDeleteAgent } from "@app/hooks"; -import { - useGetAgent, - useGetLLMConfigs, - useGetTools, -} from "@app/hooks/data/fetch-hooks"; -import { getAgentKey } from "@app/hooks/data/query-keys"; -import { useNotifyStore } from "@app/store"; -import { scrollToBottom } from "@app/utils/scroll"; -import { useQueryClient } from "@tanstack/react-query"; -import yaml from "js-yaml"; -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from "react"; -import { useNavigate, useParams } from "react-router"; -import EditAgentDialog from "./EditAgentDialog"; +} from '@app/components/ui/breadcrumb'; +import { Button } from '@app/components/ui/button'; +import { useDeleteAgent } from '@app/hooks'; +import { useGetAgent, useGetLLMConfigs, useGetTools } from '@app/hooks/data/fetch-hooks'; +import { getAgentKey } from '@app/hooks/data/query-keys'; +import { useNotifyStore } from '@app/store'; +import { scrollToBottom } from '@app/utils/scroll'; +import { useQueryClient } from '@tanstack/react-query'; +import yaml from 'js-yaml'; +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useNavigate, useParams } from 'react-router'; +import EditAgentDialog from './EditAgentDialog'; const AgentDetail: React.FC = () => { const { app: appId, id } = useParams<{ app: string; id: string }>(); @@ -39,7 +29,7 @@ const AgentDetail: React.FC = () => { const [showUploadMenu, setShowUploadMenu] = useState(false); const [showVariablesInput, setShowVariablesInput] = useState(false); - const [yamlContent, setYamlContent] = useState(""); + const [yamlContent, setYamlContent] = useState(''); const [saving, setSaving] = useState(false); const [editDialogOpen, setEditDialogOpen] = useState(false); const [deleteItem, setDeleteItem] = useState<{ @@ -48,12 +38,12 @@ const AgentDetail: React.FC = () => { } | null>(null); // Inference state - const [inferenceInput, setInferenceInput] = useState(""); - const [inferenceVariables, setInferenceVariables] = useState("{}"); + const [inferenceInput, setInferenceInput] = useState(''); + const [inferenceVariables, setInferenceVariables] = useState('{}'); const [runningInference, setRunningInference] = useState(false); // LLM Config selection state - const [selectedLLMConfigId, setSelectedLLMConfigId] = useState(""); + const [selectedLLMConfigId, setSelectedLLMConfigId] = useState(''); // Image upload state const [uploadedImages, setUploadedImages] = useState< @@ -73,24 +63,19 @@ const AgentDetail: React.FC = () => { base64: string; // Full data URL for display base64Content: string; // Just base64 content for API mimeType: string; - documentType: "pdf" | "txt"; + documentType: 'pdf' | 'txt'; }> >([]); const [uploadingDocument, setUploadingDocument] = useState(false); - const [chatHistory, setChatHistory] = useState< - { role: "user" | "assistant"; content: any }[] - >([]); + const [chatHistory, setChatHistory] = useState<{ role: 'user' | 'assistant'; content: any }[]>([]); // Datasource and tool selection state - const [selectedTools, setSelectedTools] = useState< - { id: string; value: string }[] - >([]); + const [selectedTools, setSelectedTools] = useState<{ id: string; value: string }[]>([]); const isUpdatingYamlRef = useRef(false); // Fetch data using hooks const { data: agent, isLoading: agentLoading } = useGetAgent(appId, id); - const { data: llmConfigs = [], isLoading: loadingConfigs } = - useGetLLMConfigs(appId); + const { data: llmConfigs = [], isLoading: loadingConfigs } = useGetLLMConfigs(appId); const { data: availableTools = [] } = useGetTools(appId); const deleteAgentMutation = useDeleteAgent(appId); @@ -123,14 +108,14 @@ const AgentDetail: React.FC = () => { const prefilledValuesString = prefillValues .filter((key) => tool.prefilled_value?.[key]) .map((key) => tool.prefilled_value?.[key]) // Only show the value, not the key - .join(", "); + .join(', '); return { name: tool.name, prefilled_values: prefilledValue, - display_name: `${tool.resource_name ? tool.resource_name + " - " : ""}${ + display_name: `${tool.resource_name ? tool.resource_name + ' - ' : ''}${ tool.name - }${prefilledValuesString ? ` (${prefilledValuesString})` : ""}`, + }${prefilledValuesString ? ` (${prefilledValuesString})` : ''}`, description: tool.description, }; }); @@ -139,21 +124,18 @@ const AgentDetail: React.FC = () => { const handleQuestionEntered = () => { if (inferenceInput.trim().length > 0) { handleRunInference(); - setInferenceInput(""); + setInferenceInput(''); requestAnimationFrame(() => { - setTimeout(() => scrollToBottom("message-container", "smooth"), 150); + setTimeout(() => scrollToBottom('message-container', 'smooth'), 150); }); } }; useEffect(() => { // Skip if we're updating YAML from agent data or if dependencies are not ready - if (isUpdatingYamlRef.current || !yamlContent || toolsDetails.length === 0) - return; + if (isUpdatingYamlRef.current || !yamlContent || toolsDetails.length === 0) return; - const tools = toolsDetails.filter((tool) => - selectedTools.some((selected) => selected.value === tool.display_name) - ); + const tools = toolsDetails.filter((tool) => selectedTools.some((selected) => selected.value === tool.display_name)); const parsedYaml = yaml.load(yamlContent) as any; if (parsedYaml && parsedYaml.agent) { if (!parsedYaml.agent.tools) { @@ -166,10 +148,7 @@ const AgentDetail: React.FC = () => { const prefilledParams: Record | undefined = tool.prefilled_values && tool.prefilled_values.length > 0 ? tool.prefilled_values.reduce( - ( - acc: Record, - obj: { [key: string]: string } - ) => { + (acc: Record, obj: { [key: string]: string }) => { // Each obj is like { datasource_id: "value" } return { ...acc, ...obj }; }, @@ -194,8 +173,7 @@ const AgentDetail: React.FC = () => { if (!newTool) return true; return ( existingTool.name !== newTool.name || - JSON.stringify(existingTool.prefilled_params || {}) !== - JSON.stringify(newTool.prefilled_params || {}) + JSON.stringify(existingTool.prefilled_params || {}) !== JSON.stringify(newTool.prefilled_params || {}) ); }); @@ -217,166 +195,145 @@ const AgentDetail: React.FC = () => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedTools, toolsDetails]); - const handleImageUpload = useCallback( - (event: React.ChangeEvent) => { - const files = event.target.files; - if (!files || files.length === 0) return; - - // Validate file type - const allowedTypes = [ - "image/jpeg", - "image/jpg", - "image/png", - "image/gif", - "image/webp", - ]; - const maxSize = 10 * 1024 * 1024; // 10MB - - // Validate all files before processing - for (let i = 0; i < files.length; i++) { - const file = files[i]; - if (!allowedTypes.includes(file.type)) { - notifyError( - `File ${file.name} is not a valid image type. Please select JPEG, PNG, GIF, or WebP files.` - ); - return; - } - if (file.size > maxSize) { - notifyError(`File ${file.name} exceeds 10MB limit`); - return; - } - } - - setUploadingImage(true); - - // Process all files - const filePromises = Array.from(files).map( - (file) => - new Promise<{ - file: File; - base64: string; - base64Content: string; - mimeType: string; - }>((resolve, reject) => { - const reader = new FileReader(); - - reader.onload = (e) => { - const base64 = e.target?.result as string; - // Extract just the base64 content without the data URL prefix - const base64Content = base64.split(",")[1] || base64; - resolve({ - file, - base64, - base64Content, - mimeType: file.type, - }); - }; - - reader.onerror = () => - reject(new Error(`Error reading ${file.name}`)); - reader.readAsDataURL(file); - }) - ); + const handleImageUpload = useCallback((event: React.ChangeEvent) => { + const files = event.target.files; + if (!files || files.length === 0) return; - Promise.all(filePromises) - .then((newImages) => { - setUploadedImages((prev) => [...prev, ...newImages]); - setUploadingImage(false); - notifySuccess(`${newImages.length} image(s) uploaded successfully`); - // Reset file input - event.target.value = ""; - // Close the upload menu after successful upload - setShowUploadMenu(false); - }) - .catch((error) => { - notifyError(error.message || "Error reading image files"); - setUploadingImage(false); - }); - }, - [] - ); + // Validate file type + const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp']; + const maxSize = 10 * 1024 * 1024; // 10MB - const handleRemoveImage = useCallback((index: number) => { - setUploadedImages((prev) => prev.filter((_, i) => i !== index)); - }, []); - - const handleDocumentUpload = useCallback( - (event: React.ChangeEvent) => { - const files = event.target.files; - if (!files || files.length === 0) return; - - // Validate file type - const allowedTypes = ["application/pdf", "text/plain"]; - const maxSize = 50 * 1024 * 1024; // 50MB - - // Validate all files before processing - for (let i = 0; i < files.length; i++) { - const file = files[i]; - if (!allowedTypes.includes(file.type)) { - notifyError( - `Invalid file type for ${file.name}. Please select PDF or TXT files only.` - ); - return; - } - if (file.size > maxSize) { - notifyError(`File ${file.name} is too large. Maximum size is 50MB.`); - return; - } + // Validate all files before processing + for (let i = 0; i < files.length; i++) { + const file = files[i]; + if (!allowedTypes.includes(file.type)) { + notifyError(`File ${file.name} is not a valid image type. Please select JPEG, PNG, GIF, or WebP files.`); + return; + } + if (file.size > maxSize) { + notifyError(`File ${file.name} exceeds 10MB limit`); + return; } + } - setUploadingDocument(true); + setUploadingImage(true); - // Process all files - const filePromises = Array.from(files).map((file) => { - return new Promise<{ + // Process all files + const filePromises = Array.from(files).map( + (file) => + new Promise<{ file: File; base64: string; base64Content: string; mimeType: string; - documentType: "pdf" | "txt"; }>((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { - const dataUrl = e.target?.result as string; - const base64 = dataUrl.split(",")[1]; - const documentType = - file.type === "application/pdf" ? "pdf" : "txt"; - + const base64 = e.target?.result as string; + // Extract just the base64 content without the data URL prefix + const base64Content = base64.split(',')[1] || base64; resolve({ file, - base64: dataUrl, - base64Content: base64, + base64, + base64Content, mimeType: file.type, - documentType, }); }; - reader.onerror = () => - reject(new Error(`Error reading ${file.name}`)); + reader.onerror = () => reject(new Error(`Error reading ${file.name}`)); reader.readAsDataURL(file); - }); + }) + ); + + Promise.all(filePromises) + .then((newImages) => { + setUploadedImages((prev) => [...prev, ...newImages]); + setUploadingImage(false); + notifySuccess(`${newImages.length} image(s) uploaded successfully`); + // Reset file input + event.target.value = ''; + // Close the upload menu after successful upload + setShowUploadMenu(false); + }) + .catch((error) => { + notifyError(error.message || 'Error reading image files'); + setUploadingImage(false); }); + }, []); - Promise.all(filePromises) - .then((newDocuments) => { - setUploadedDocuments((prev) => [...prev, ...newDocuments]); - setUploadingDocument(false); - notifySuccess( - `${newDocuments.length} document(s) uploaded successfully` - ); - // Reset file input - event.target.value = ""; - // Close the upload menu after successful upload - setShowUploadMenu(false); - }) - .catch((error) => { - notifyError(error.message || "Error reading document files"); - setUploadingDocument(false); - }); - }, - [] - ); + const handleRemoveImage = useCallback((index: number) => { + setUploadedImages((prev) => prev.filter((_, i) => i !== index)); + }, []); + + const handleDocumentUpload = useCallback((event: React.ChangeEvent) => { + const files = event.target.files; + if (!files || files.length === 0) return; + + // Validate file type + const allowedTypes = ['application/pdf', 'text/plain']; + const maxSize = 50 * 1024 * 1024; // 50MB + + // Validate all files before processing + for (let i = 0; i < files.length; i++) { + const file = files[i]; + if (!allowedTypes.includes(file.type)) { + notifyError(`Invalid file type for ${file.name}. Please select PDF or TXT files only.`); + return; + } + if (file.size > maxSize) { + notifyError(`File ${file.name} is too large. Maximum size is 50MB.`); + return; + } + } + + setUploadingDocument(true); + + // Process all files + const filePromises = Array.from(files).map((file) => { + return new Promise<{ + file: File; + base64: string; + base64Content: string; + mimeType: string; + documentType: 'pdf' | 'txt'; + }>((resolve, reject) => { + const reader = new FileReader(); + + reader.onload = (e) => { + const dataUrl = e.target?.result as string; + const base64 = dataUrl.split(',')[1]; + const documentType = file.type === 'application/pdf' ? 'pdf' : 'txt'; + + resolve({ + file, + base64: dataUrl, + base64Content: base64, + mimeType: file.type, + documentType, + }); + }; + + reader.onerror = () => reject(new Error(`Error reading ${file.name}`)); + reader.readAsDataURL(file); + }); + }); + + Promise.all(filePromises) + .then((newDocuments) => { + setUploadedDocuments((prev) => [...prev, ...newDocuments]); + setUploadingDocument(false); + notifySuccess(`${newDocuments.length} document(s) uploaded successfully`); + // Reset file input + event.target.value = ''; + // Close the upload menu after successful upload + setShowUploadMenu(false); + }) + .catch((error) => { + notifyError(error.message || 'Error reading document files'); + setUploadingDocument(false); + }); + }, []); const handleRemoveDocument = useCallback((index: number) => { setUploadedDocuments((prev) => prev.filter((_, i) => i !== index)); @@ -390,11 +347,11 @@ const AgentDetail: React.FC = () => { await floConsoleService.agentService.updateAgent(id, yamlContent); // Invalidate agent query to refetch updated data queryClient.invalidateQueries({ - queryKey: getAgentKey(appId || "", id || ""), + queryKey: getAgentKey(appId || '', id || ''), }); - notifySuccess("Agent updated successfully"); + notifySuccess('Agent updated successfully'); } catch (error) { - console.error("Error updating agent:", error); + console.error('Error updating agent:', error); } finally { setSaving(false); } @@ -426,9 +383,7 @@ const AgentDetail: React.FC = () => { uploadedDocuments.length === 0 && selectedTools.length === 0) ) { - notifyError( - "Please provide text input, upload an image/document, or select tools to run inference" - ); + notifyError('Please provide text input, upload an image/document, or select tools to run inference'); return; } @@ -439,7 +394,7 @@ const AgentDetail: React.FC = () => { try { variables = JSON.parse(inferenceVariables); } catch { - notifyError("Invalid JSON in variables field"); + notifyError('Invalid JSON in variables field'); setRunningInference(false); return; } @@ -468,12 +423,9 @@ const AgentDetail: React.FC = () => { image_base64: image.base64Content, mime_type: image.mimeType, }; - setChatHistory((prev) => [ - ...prev, - { role: "user", content: imageMessage }, - ]); + setChatHistory((prev) => [...prev, { role: 'user', content: imageMessage }]); conversationInputs.push({ - role: "user", + role: 'user', content: imageMessage, }); }); @@ -491,12 +443,9 @@ const AgentDetail: React.FC = () => { size: doc.file.size, }, }; - setChatHistory((prev) => [ - ...prev, - { role: "user", content: documentMessage }, - ]); + setChatHistory((prev) => [...prev, { role: 'user', content: documentMessage }]); conversationInputs.push({ - role: "user", + role: 'user', content: documentMessage, }); }); @@ -504,12 +453,9 @@ const AgentDetail: React.FC = () => { // Add text input last if provided if (finalTextInput) { - setChatHistory((prev) => [ - ...prev, - { role: "user", content: finalTextInput }, - ]); + setChatHistory((prev) => [...prev, { role: 'user', content: finalTextInput }]); conversationInputs.push({ - role: "user", + role: 'user', content: finalTextInput, }); } @@ -521,9 +467,8 @@ const AgentDetail: React.FC = () => { // Tools only - provide a generic instruction inputs = [ { - role: "user", - content: - "Please use the available tools to assist with the request.", + role: 'user', + content: 'Please use the available tools to assist with the request.', }, ]; } @@ -532,29 +477,22 @@ const AgentDetail: React.FC = () => { variables, inputs, selectedLLMConfigId || undefined, - selectedTools.length > 0 - ? selectedTools.map((tool) => tool.value) - : undefined + selectedTools.length > 0 ? selectedTools.map((tool) => tool.value) : undefined ); const responseData = (result as any).data?.data?.data; const agentResponse = - typeof responseData?.result === "string" - ? responseData.result - : JSON.stringify(responseData?.result, null, 2); - setChatHistory((prev) => [ - ...prev, - { role: "assistant", content: agentResponse }, - ]); + typeof responseData?.result === 'string' ? responseData.result : JSON.stringify(responseData?.result, null, 2); + setChatHistory((prev) => [...prev, { role: 'assistant', content: agentResponse }]); // Wait for DOM to update before scrolling requestAnimationFrame(() => { - setTimeout(() => scrollToBottom("message-container", "smooth"), 150); + setTimeout(() => scrollToBottom('message-container', 'smooth'), 150); }); //clearing the documents and images setUploadedDocuments([]); setUploadedImages([]); } catch (error) { - console.error("Error running inference:", error); - notifyError("Failed to run inference. Please try again."); + console.error('Error running inference:', error); + notifyError('Failed to run inference. Please try again.'); } finally { setRunningInference(false); } @@ -566,11 +504,7 @@ const AgentDetail: React.FC = () => { - @@ -595,19 +529,13 @@ const AgentDetail: React.FC = () => { {agentLoading ? ( -

- Loading agent... -
+
Loading agent...
) : !agent ? ( -
- Agent not found -
+
Agent not found
) : (
-

- {agent.name} -

+

{agent.name}

@@ -115,9 +101,7 @@ const AgentManagement: React.FC = () => {

Agents

-

- Manage AI agents for {selectedApp?.app_name} -

+

Manage AI agents for {selectedApp?.app_name}

{ All Namespaces {namespaces.map((ns) => ( - + {ns.name} ))} @@ -169,12 +149,7 @@ const AgentManagement: React.FC = () => { ) : ( <> {filteredAgents.map((agent) => ( - + ))} )} diff --git a/wavefront/client/src/pages/apps/[appId]/api-services/[id].tsx b/wavefront/client/src/pages/apps/[appId]/api-services/[id].tsx index d6b790b6..12b392af 100644 --- a/wavefront/client/src/pages/apps/[appId]/api-services/[id].tsx +++ b/wavefront/client/src/pages/apps/[appId]/api-services/[id].tsx @@ -1,5 +1,5 @@ -import floConsoleService from "@app/api"; -import DeleteConfirmationDialog from "@app/components/DeleteConfirmationDialog"; +import floConsoleService from '@app/api'; +import DeleteConfirmationDialog from '@app/components/DeleteConfirmationDialog'; import { Breadcrumb, BreadcrumbItem, @@ -7,41 +7,28 @@ import { BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, -} from "@app/components/ui/breadcrumb"; -import { Button } from "@app/components/ui/button"; -import { Checkbox } from "@app/components/ui/checkbox"; -import { - Form, - FormControl, - FormField, - FormItem, - FormLabel, - FormMessage, -} from "@app/components/ui/form"; -import { Input } from "@app/components/ui/input"; -import { Label } from "@app/components/ui/label"; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue, -} from "@app/components/ui/select"; -import { useGetApiService } from "@app/hooks"; -import { getApiServiceKey } from "@app/hooks/data/query-keys"; -import { useNotifyStore } from "@app/store"; -import { ApiServiceItem } from "@app/types/api-service"; -import { zodResolver } from "@hookform/resolvers/zod"; -import { useQueryClient } from "@tanstack/react-query"; -import { langs } from "@uiw/codemirror-extensions-langs"; -import CodeMirror from "@uiw/react-codemirror"; -import clsx from "clsx"; -import yaml from "js-yaml"; -import { Plus, Trash2 } from "lucide-react"; -import React, { useEffect, useState } from "react"; -import { useFieldArray, useForm } from "react-hook-form"; -import { useNavigate, useParams } from "react-router"; -import { z } from "zod"; +} from '@app/components/ui/breadcrumb'; +import { Button } from '@app/components/ui/button'; +import { Checkbox } from '@app/components/ui/checkbox'; +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@app/components/ui/form'; +import { Input } from '@app/components/ui/input'; +import { Label } from '@app/components/ui/label'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@app/components/ui/select'; +import { useGetApiService } from '@app/hooks'; +import { getApiServiceKey } from '@app/hooks/data/query-keys'; +import { useNotifyStore } from '@app/store'; +import { ApiServiceItem } from '@app/types/api-service'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useQueryClient } from '@tanstack/react-query'; +import { langs } from '@uiw/codemirror-extensions-langs'; +import CodeMirror from '@uiw/react-codemirror'; +import clsx from 'clsx'; +import yaml from 'js-yaml'; +import { Plus, Trash2 } from 'lucide-react'; +import React, { useEffect, useState } from 'react'; +import { useFieldArray, useForm } from 'react-hook-form'; +import { useNavigate, useParams } from 'react-router'; +import { z } from 'zod'; const keyValuePairSchema = z.object({ key: z.string(), @@ -53,7 +40,7 @@ const apiEndpointSchema = z.object({ version: z.string(), path: z.string(), backend_path: z.string(), - method: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH"]), + method: z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH']), additional_headers: z.array(keyValuePairSchema), backend_query_params: z.array(keyValuePairSchema), output_mapper_enabled: z.boolean(), @@ -61,12 +48,12 @@ const apiEndpointSchema = z.object({ }); const apiServiceFormSchema = z.object({ - id: z.string().min(1, "Service ID is required"), - base_url: z.string().min(1, "Base URL is required"), + id: z.string().min(1, 'Service ID is required'), + base_url: z.string().min(1, 'Base URL is required'), auth: z.object({ id: z.string(), version: z.string(), - type: z.enum(["basic", "bearer", "api_key", "none"]), + type: z.enum(['basic', 'bearer', 'api_key', 'none']), base_url: z.string().optional(), path: z.string().optional(), username: z.string().optional(), @@ -82,19 +69,19 @@ const apiServiceFormSchema = z.object({ type ApiServiceForm = z.infer; const initialFormState: ApiServiceForm = { - id: "", - base_url: "", + id: '', + base_url: '', auth: { - id: "basic-auth", - version: "v1", - type: "basic", - base_url: "", - path: "", - username: "", - password: "", - token: "", - api_key: "", - api_key_header: "X-API-Key", + id: 'basic-auth', + version: 'v1', + type: 'basic', + base_url: '', + path: '', + username: '', + password: '', + token: '', + api_key: '', + api_key_header: 'X-API-Key', additional_headers: [], }, apis: [], @@ -102,8 +89,8 @@ const initialFormState: ApiServiceForm = { const ApiServiceDetail: React.FC = () => { const [editing, setEditing] = useState(false); - const [view, setView] = useState<"form" | "yaml">("form"); - const [yamlContent, setYamlContent] = useState(""); + const [view, setView] = useState<'form' | 'yaml'>('form'); + const [yamlContent, setYamlContent] = useState(''); const [saving, setSaving] = useState(false); const [showDeleteConfirm, setShowDeleteConfirm] = useState(false); @@ -117,17 +104,17 @@ const ApiServiceDetail: React.FC = () => { const form = useForm({ resolver: zodResolver(apiServiceFormSchema), defaultValues: initialFormState, - mode: "onChange", + mode: 'onChange', }); const authHeadersFieldArray = useFieldArray({ control: form.control, - name: "auth.additional_headers", + name: 'auth.additional_headers', }); const apisFieldArray = useFieldArray({ control: form.control, - name: "apis", + name: 'apis', }); const generateYaml = (data: ApiServiceForm) => { @@ -208,64 +195,52 @@ const ApiServiceDetail: React.FC = () => { const s = parsed.service; const authHeaders = s.auth?.additional_headers || {}; - const auth_additional_headers = Object.entries(authHeaders).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const auth_additional_headers = Object.entries(authHeaders).map(([key, value]) => ({ + key, + value: String(value), + })); return { - id: s.id || "", - base_url: s.base_url || "", + id: s.id || '', + base_url: s.base_url || '', auth: { - id: s.auth?.id || "basic-auth", - version: s.auth?.version || "v1", - type: - (s.auth?.type as "basic" | "bearer" | "api_key" | "none") || - "basic", - base_url: s.auth?.base_url || "", - path: s.auth?.path || "", - username: s.auth?.username || "", - password: s.auth?.password || "", - token: s.auth?.token || "", - api_key: s.auth?.api_key || "", - api_key_header: s.auth?.api_key_header || "X-API-Key", + id: s.auth?.id || 'basic-auth', + version: s.auth?.version || 'v1', + type: (s.auth?.type as 'basic' | 'bearer' | 'api_key' | 'none') || 'basic', + base_url: s.auth?.base_url || '', + path: s.auth?.path || '', + username: s.auth?.username || '', + password: s.auth?.password || '', + token: s.auth?.token || '', + api_key: s.auth?.api_key || '', + api_key_header: s.auth?.api_key_header || 'X-API-Key', additional_headers: auth_additional_headers, }, apis: (s.apis || []).map((api: any) => { const apiHeaders = api.additional_headers || {}; - const api_additional_headers = Object.entries(apiHeaders).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const api_additional_headers = Object.entries(apiHeaders).map(([key, value]) => ({ + key, + value: String(value), + })); const backendQueryParams = api.backend_query_params || {}; - const backend_query_params = Object.entries(backendQueryParams).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const backend_query_params = Object.entries(backendQueryParams).map(([key, value]) => ({ + key, + value: String(value), + })); const outputMapper = api.output_mapper || {}; - const output_mapper = Object.entries(outputMapper).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const output_mapper = Object.entries(outputMapper).map(([key, value]) => ({ + key, + value: String(value), + })); return { - id: api.id || "", - version: api.version || "v1", - path: api.path || "", - backend_path: api.backend_path || "", - method: - (api.method as "GET" | "POST" | "PUT" | "DELETE" | "PATCH") || - "GET", + id: api.id || '', + version: api.version || 'v1', + path: api.path || '', + backend_path: api.backend_path || '', + method: (api.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH') || 'GET', additional_headers: api_additional_headers, backend_query_params: backend_query_params, output_mapper_enabled: api.output_mapper_enabled || false, @@ -274,19 +249,17 @@ const ApiServiceDetail: React.FC = () => { }), }; } catch (e) { - console.error("Error parsing YAML", e); + console.error('Error parsing YAML', e); return null; } }; const mapServiceToForm = (serviceData: ApiServiceItem): ApiServiceForm => { const authHeaders = serviceData.auth.additional_headers || {}; - const auth_additional_headers = Object.entries(authHeaders).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const auth_additional_headers = Object.entries(authHeaders).map(([key, value]) => ({ + key, + value: String(value), + })); return { id: serviceData.service_id, @@ -294,49 +267,41 @@ const ApiServiceDetail: React.FC = () => { auth: { id: serviceData.auth.id, version: serviceData.auth.version, - type: - (serviceData.auth.type as "basic" | "bearer" | "api_key" | "none") || - "basic", - base_url: serviceData.auth.base_url || "", - path: serviceData.auth.path || "", - username: serviceData.auth.username || "", - password: serviceData.auth.password || "", - token: serviceData.auth.token || "", - api_key: serviceData.auth.api_key || "", - api_key_header: serviceData.auth.api_key_header || "X-API-Key", + type: (serviceData.auth.type as 'basic' | 'bearer' | 'api_key' | 'none') || 'basic', + base_url: serviceData.auth.base_url || '', + path: serviceData.auth.path || '', + username: serviceData.auth.username || '', + password: serviceData.auth.password || '', + token: serviceData.auth.token || '', + api_key: serviceData.auth.api_key || '', + api_key_header: serviceData.auth.api_key_header || 'X-API-Key', additional_headers: auth_additional_headers, }, apis: (serviceData.apis || []).map((api) => { const apiHeaders = api.additional_headers || {}; - const api_additional_headers = Object.entries(apiHeaders).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const api_additional_headers = Object.entries(apiHeaders).map(([key, value]) => ({ + key, + value: String(value), + })); const backendQueryParams = api.backend_query_params || {}; - const backend_query_params = Object.entries(backendQueryParams).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const backend_query_params = Object.entries(backendQueryParams).map(([key, value]) => ({ + key, + value: String(value), + })); const outputMapper = api.output_mapper || {}; - const output_mapper = Object.entries(outputMapper).map( - ([key, value]) => ({ - key, - value: String(value), - }) - ); + const output_mapper = Object.entries(outputMapper).map(([key, value]) => ({ + key, + value: String(value), + })); return { id: api.id, version: api.version, path: api.path, - backend_path: api.backend_path || "", - method: api.method as "GET" | "POST" | "PUT" | "DELETE" | "PATCH", + backend_path: api.backend_path || '', + method: api.method as 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH', additional_headers: api_additional_headers, backend_query_params: backend_query_params, output_mapper_enabled: api.output_mapper_enabled || false, @@ -350,7 +315,7 @@ const ApiServiceDetail: React.FC = () => { useEffect(() => { if (!service) return; - let content = service.yaml_content || ""; + let content = service.yaml_content || ''; let parsedForm: ApiServiceForm | null = null; if (content) { @@ -359,9 +324,7 @@ const ApiServiceDetail: React.FC = () => { // If YAML exists but couldn't be parsed, fall back to mapping service data if (!parsedForm) { parsedForm = mapServiceToForm(service); - notifyError( - "YAML could not be parsed. Showing form populated from service data instead." - ); + notifyError('YAML could not be parsed. Showing form populated from service data instead.'); } } else { // Fallback: map service object to form @@ -378,14 +341,14 @@ const ApiServiceDetail: React.FC = () => { useEffect(() => { if (!appId) { - navigate("/apps"); + navigate('/apps'); return; } }, [appId, navigate]); // Sync Form -> YAML when switching to YAML view useEffect(() => { - if (view === "yaml" && editing) { + if (view === 'yaml' && editing) { const formValues = form.getValues(); const generated = generateYaml(formValues); setYamlContent(generated); @@ -394,7 +357,7 @@ const ApiServiceDetail: React.FC = () => { // Sync YAML -> Form when switching to Form view useEffect(() => { - if (view === "form" && yamlContent && editing) { + if (view === 'form' && yamlContent && editing) { const parsed = parseYaml(yamlContent); if (parsed) { form.reset(parsed); @@ -407,7 +370,7 @@ const ApiServiceDetail: React.FC = () => { // Ensure we have the latest content based on current view const formValues = data || form.getValues(); - const finalYaml = view === "form" ? generateYaml(formValues) : yamlContent; + const finalYaml = view === 'form' ? generateYaml(formValues) : yamlContent; setSaving(true); try { @@ -415,22 +378,19 @@ const ApiServiceDetail: React.FC = () => { // Invalidate query to refetch updated data queryClient.invalidateQueries({ - queryKey: getApiServiceKey(appId || "", id || ""), + queryKey: getApiServiceKey(appId || '', id || ''), }); - queryClient.invalidateQueries({ queryKey: ["api-services", appId] }); + queryClient.invalidateQueries({ queryKey: ['api-services', appId] }); setYamlContent(finalYaml); const parsed = parseYaml(finalYaml); if (parsed) form.reset(parsed); setEditing(false); - notifySuccess("API Service updated successfully"); + notifySuccess('API Service updated successfully'); } catch (error: any) { - console.error("Error updating API service:", error); - const errorMessage = - error?.response?.data?.meta?.error || - error?.message || - "Failed to update API service"; + console.error('Error updating API service:', error); + const errorMessage = error?.response?.data?.meta?.error || error?.message || 'Failed to update API service'; notifyError(errorMessage); } finally { setSaving(false); @@ -442,16 +402,16 @@ const ApiServiceDetail: React.FC = () => { try { await floConsoleService.apiServiceService.deleteApiService(id); - notifySuccess("API Service deleted successfully"); + notifySuccess('API Service deleted successfully'); navigate(`/apps/${appId}/api-services`); } catch (error) { - console.error("Error deleting API service:", error); - notifyError("Failed to delete API service"); + console.error('Error deleting API service:', error); + notifyError('Failed to delete API service'); } }; const handleAddHeader = () => { - authHeadersFieldArray.append({ key: "", value: "" }); + authHeadersFieldArray.append({ key: '', value: '' }); }; const handleRemoveHeader = (index: number) => { @@ -460,11 +420,11 @@ const ApiServiceDetail: React.FC = () => { const handleAddApi = () => { apisFieldArray.append({ - id: "", - version: "v1", - path: "", - backend_path: "", - method: "GET", + id: '', + version: 'v1', + path: '', + backend_path: '', + method: 'GET', additional_headers: [], backend_query_params: [], output_mapper_enabled: false, @@ -477,17 +437,12 @@ const ApiServiceDetail: React.FC = () => { }; const handleAddApiHeader = (apiIndex: number) => { - const currentHeaders = - form.getValues(`apis.${apiIndex}.additional_headers`) || []; - form.setValue(`apis.${apiIndex}.additional_headers`, [ - ...currentHeaders, - { key: "", value: "" }, - ]); + const currentHeaders = form.getValues(`apis.${apiIndex}.additional_headers`) || []; + form.setValue(`apis.${apiIndex}.additional_headers`, [...currentHeaders, { key: '', value: '' }]); }; const handleRemoveApiHeader = (apiIndex: number, headerIndex: number) => { - const currentHeaders = - form.getValues(`apis.${apiIndex}.additional_headers`) || []; + const currentHeaders = form.getValues(`apis.${apiIndex}.additional_headers`) || []; form.setValue( `apis.${apiIndex}.additional_headers`, currentHeaders.filter((_, i) => i !== headerIndex) @@ -495,20 +450,12 @@ const ApiServiceDetail: React.FC = () => { }; const handleAddBackendQueryParam = (apiIndex: number) => { - const currentParams = - form.getValues(`apis.${apiIndex}.backend_query_params`) || []; - form.setValue(`apis.${apiIndex}.backend_query_params`, [ - ...currentParams, - { key: "", value: "" }, - ]); + const currentParams = form.getValues(`apis.${apiIndex}.backend_query_params`) || []; + form.setValue(`apis.${apiIndex}.backend_query_params`, [...currentParams, { key: '', value: '' }]); }; - const handleRemoveBackendQueryParam = ( - apiIndex: number, - paramIndex: number - ) => { - const currentParams = - form.getValues(`apis.${apiIndex}.backend_query_params`) || []; + const handleRemoveBackendQueryParam = (apiIndex: number, paramIndex: number) => { + const currentParams = form.getValues(`apis.${apiIndex}.backend_query_params`) || []; form.setValue( `apis.${apiIndex}.backend_query_params`, currentParams.filter((_, i) => i !== paramIndex) @@ -516,17 +463,12 @@ const ApiServiceDetail: React.FC = () => { }; const handleAddOutputMapper = (apiIndex: number) => { - const currentMappers = - form.getValues(`apis.${apiIndex}.output_mapper`) || []; - form.setValue(`apis.${apiIndex}.output_mapper`, [ - ...currentMappers, - { key: "", value: "" }, - ]); + const currentMappers = form.getValues(`apis.${apiIndex}.output_mapper`) || []; + form.setValue(`apis.${apiIndex}.output_mapper`, [...currentMappers, { key: '', value: '' }]); }; const handleRemoveOutputMapper = (apiIndex: number, mapperIndex: number) => { - const currentMappers = - form.getValues(`apis.${apiIndex}.output_mapper`) || []; + const currentMappers = form.getValues(`apis.${apiIndex}.output_mapper`) || []; form.setValue( `apis.${apiIndex}.output_mapper`, currentMappers.filter((_, i) => i !== mapperIndex) @@ -534,16 +476,12 @@ const ApiServiceDetail: React.FC = () => { }; return ( -
+
- @@ -562,25 +500,18 @@ const ApiServiceDetail: React.FC = () => { - - {service?.name || service?.service_id || id} - + {service?.name || service?.service_id || id}
-

- {service?.name || service?.service_id} -

+

{service?.name || service?.service_id}

{editing ? ( <> - )} -
@@ -622,42 +548,33 @@ const ApiServiceDetail: React.FC = () => {
- {view === "form" ? ( + {view === 'form' ? (
{/* Service Details */}
-

- Service Details -

+

Service Details

{ Service ID - + @@ -683,11 +596,7 @@ const ApiServiceDetail: React.FC = () => { Base URL - + @@ -698,9 +607,7 @@ const ApiServiceDetail: React.FC = () => { {/* Authentication */}
-

- Authentication -

+

Authentication

{ render={({ field }) => ( Type - @@ -733,9 +636,7 @@ const ApiServiceDetail: React.FC = () => { Basic Auth - - Bearer Token - + Bearer Token API Key None @@ -751,11 +652,7 @@ const ApiServiceDetail: React.FC = () => { Version - + @@ -768,11 +665,7 @@ const ApiServiceDetail: React.FC = () => { Auth Base URL (Optional) - + @@ -785,18 +678,14 @@ const ApiServiceDetail: React.FC = () => { Auth Path (Optional) - + )} /> - {form.watch("auth.type") === "basic" && ( + {form.watch('auth.type') === 'basic' && ( <> { Password - + @@ -830,7 +715,7 @@ const ApiServiceDetail: React.FC = () => { /> )} - {form.watch("auth.type") === "bearer" && ( + {form.watch('auth.type') === 'bearer' && ( { )} /> )} - {form.watch("auth.type") === "api_key" && ( + {form.watch('auth.type') === 'api_key' && ( <> { Header Name - + @@ -884,16 +765,8 @@ const ApiServiceDetail: React.FC = () => { {/* Additional Headers */}
- -
@@ -906,11 +779,7 @@ const ApiServiceDetail: React.FC = () => { render={({ field }) => ( - + @@ -922,11 +791,7 @@ const ApiServiceDetail: React.FC = () => { render={({ field }) => ( - + @@ -950,16 +815,8 @@ const ApiServiceDetail: React.FC = () => { {/* APIs */}
-

- API Endpoints -

-
@@ -979,11 +836,7 @@ const ApiServiceDetail: React.FC = () => { Endpoint ID - + @@ -995,11 +848,7 @@ const ApiServiceDetail: React.FC = () => { render={({ field }) => ( Method - @@ -1009,12 +858,8 @@ const ApiServiceDetail: React.FC = () => { GET POST PUT - - DELETE - - - PATCH - + DELETE + PATCH @@ -1028,11 +873,7 @@ const ApiServiceDetail: React.FC = () => { Version - + @@ -1045,11 +886,7 @@ const ApiServiceDetail: React.FC = () => { Path - + @@ -1062,11 +899,7 @@ const ApiServiceDetail: React.FC = () => { Backend Path - + @@ -1077,9 +910,7 @@ const ApiServiceDetail: React.FC = () => { {/* API Additional Headers */}
- +
- {( - form.watch( - `apis.${index}.additional_headers` - ) || [] - ).map((_header: any, hIndex: number) => ( -
- ( - - - - - - - )} - /> - ( - - - - - - - )} - /> - -
- ))} + {(form.watch(`apis.${index}.additional_headers`) || []).map( + (_header: any, hIndex: number) => ( +
+ ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + +
+ ) + )}
{/* Backend Query Params */}
- +
- {( - form.watch( - `apis.${index}.backend_query_params` - ) || [] - ).map((_param: any, pIndex: number) => ( -
- ( - - - - - - - )} - /> - ( - - - - - - - )} - /> - -
- ))} + {(form.watch(`apis.${index}.backend_query_params`) || []).map( + (_param: any, pIndex: number) => ( +
+ ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + +
+ ) + )}
@@ -1229,7 +1029,7 @@ const ApiServiceDetail: React.FC = () => { control={form.control} name={`apis.${index}.output_mapper_enabled`} render={({ field }) => ( - + { disabled={!editing} /> - - Enable Output Mapper - + Enable Output Mapper )} />
- {form.watch( - `apis.${index}.output_mapper_enabled` - ) && ( + {form.watch(`apis.${index}.output_mapper_enabled`) && (
- {form.watch( - `apis.${index}.output_mapper_enabled` - ) && ( + {form.watch(`apis.${index}.output_mapper_enabled`) && (
- {( - form.watch(`apis.${index}.output_mapper`) || - [] - ).map((_mapper: any, mIndex: number) => ( -
- ( - - - - - - - )} - /> - ( - - - - - - - )} - /> - -
- ))} + {(form.watch(`apis.${index}.output_mapper`) || []).map( + (_mapper: any, mIndex: number) => ( +
+ ( + + + + + + + )} + /> + ( + + + + + + + )} + /> + +
+ ) + )}
)}
@@ -1350,8 +1130,8 @@ const ApiServiceDetail: React.FC = () => { onChange={(value: string) => setYamlContent(value)} theme="dark" className={clsx( - "w-full rounded-lg border border-gray-300 bg-white px-3 py-2 font-mono text-sm text-black outline-none", - !editing && "pointer-events-none opacity-80" + 'w-full rounded-lg border border-gray-300 bg-white px-3 py-2 font-mono text-sm text-black outline-none', + !editing && 'pointer-events-none opacity-80' )} placeholder="Enter your API service YAML configuration..." /> diff --git a/wavefront/client/src/pages/apps/[appId]/api-services/index.tsx b/wavefront/client/src/pages/apps/[appId]/api-services/index.tsx index bb315b25..6b09f73a 100644 --- a/wavefront/client/src/pages/apps/[appId]/api-services/index.tsx +++ b/wavefront/client/src/pages/apps/[appId]/api-services/index.tsx @@ -1,31 +1,31 @@ -import floConsoleService from "@app/api"; -import ApiServiceCard from "@app/components/ApiServiceCard"; -import DeleteConfirmationDialog from "@app/components/DeleteConfirmationDialog"; -import { ResourceCardSkeleton } from "@app/components/ResourceCard"; +import floConsoleService from '@app/api'; +import ApiServiceCard from '@app/components/ApiServiceCard'; +import DeleteConfirmationDialog from '@app/components/DeleteConfirmationDialog'; +import { ResourceCardSkeleton } from '@app/components/ResourceCard'; import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, -} from "@app/components/ui/breadcrumb"; -import { Button } from "@app/components/ui/button"; -import { Input } from "@app/components/ui/input"; -import { useGetApiServices } from "@app/hooks"; -import { getApiServicesKey } from "@app/hooks/data/query-keys"; -import { useDashboardStore, useNotifyStore } from "@app/store"; -import { ApiServiceItem } from "@app/types/api-service"; -import { useQueryClient } from "@tanstack/react-query"; -import React, { useState } from "react"; -import { useNavigate, useParams } from "react-router"; -import CreateApiServiceDialog from "./CreateApiServiceDialog"; -import { EmptyStateCard } from "@app/components/EmptyCard"; +} from '@app/components/ui/breadcrumb'; +import { Button } from '@app/components/ui/button'; +import { Input } from '@app/components/ui/input'; +import { useGetApiServices } from '@app/hooks'; +import { getApiServicesKey } from '@app/hooks/data/query-keys'; +import { useDashboardStore, useNotifyStore } from '@app/store'; +import { ApiServiceItem } from '@app/types/api-service'; +import { useQueryClient } from '@tanstack/react-query'; +import React, { useState } from 'react'; +import { useNavigate, useParams } from 'react-router'; +import CreateApiServiceDialog from './CreateApiServiceDialog'; +import { EmptyStateCard } from '@app/components/EmptyCard'; const ApiServiceManagement: React.FC = () => { const { app: appId } = useParams<{ app: string }>(); const navigate = useNavigate(); const queryClient = useQueryClient(); - const [searchTerm, setSearchTerm] = useState(""); + const [searchTerm, setSearchTerm] = useState(''); const [deleteItem, setDeleteItem] = useState(null); const [deleting, setDeleting] = useState(false); const [createDialogOpen, setCreateDialogOpen] = useState(false); @@ -33,14 +33,11 @@ const ApiServiceManagement: React.FC = () => { const { selectedApp } = useDashboardStore(); const { notifySuccess, notifyError } = useNotifyStore(); - const { data: apiServices = [], isLoading: loading } = - useGetApiServices(appId); + const { data: apiServices = [], isLoading: loading } = useGetApiServices(appId); const filteredApiServices = apiServices.filter( (service) => - (service.name || service.service_id) - .toLowerCase() - .includes(searchTerm.toLowerCase()) || + (service.name || service.service_id).toLowerCase().includes(searchTerm.toLowerCase()) || service.service_id.toLowerCase().includes(searchTerm.toLowerCase()) ); @@ -49,7 +46,7 @@ const ApiServiceManagement: React.FC = () => { }; const handleCreateSuccess = () => { - queryClient.invalidateQueries({ queryKey: getApiServicesKey(appId || "") }); + queryClient.invalidateQueries({ queryKey: getApiServicesKey(appId || '') }); setCreateDialogOpen(false); }; @@ -67,17 +64,15 @@ const ApiServiceManagement: React.FC = () => { setDeleting(true); try { - await floConsoleService.apiServiceService.deleteApiService( - deleteItem.service_id - ); - notifySuccess("API Service deleted successfully"); + await floConsoleService.apiServiceService.deleteApiService(deleteItem.service_id); + notifySuccess('API Service deleted successfully'); queryClient.invalidateQueries({ - queryKey: getApiServicesKey(appId || ""), + queryKey: getApiServicesKey(appId || ''), }); setDeleteItem(null); } catch (error) { - console.error("Error deleting API service:", error); - notifyError("Failed to delete API service"); + console.error('Error deleting API service:', error); + notifyError('Failed to delete API service'); } finally { setDeleting(false); } @@ -93,11 +88,7 @@ const ApiServiceManagement: React.FC = () => { - @@ -119,12 +110,8 @@ const ApiServiceManagement: React.FC = () => {
-

- API Services -

-

- Manage API Connectors for {selectedApp?.app_name} -

+

API Services

+

Manage API Connectors for {selectedApp?.app_name}

{ {loading ? ( <> {Array.from({ length: 20 }).map((_, index) => ( - + ))} ) : filteredApiServices.length === 0 ? ( diff --git a/wavefront/client/src/pages/apps/[appId]/authenticators/CreateAuthenticatorDialog.tsx b/wavefront/client/src/pages/apps/[appId]/authenticators/CreateAuthenticatorDialog.tsx index 1feebad2..cd4c293a 100644 --- a/wavefront/client/src/pages/apps/[appId]/authenticators/CreateAuthenticatorDialog.tsx +++ b/wavefront/client/src/pages/apps/[appId]/authenticators/CreateAuthenticatorDialog.tsx @@ -430,7 +430,7 @@ const CreateAuthenticatorDialog: React.FC = ({ placeholder="Optional description for this authenticator" rows={3} maxLength={500} - className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[80px] w-full rounded-md border px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50" + className="border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[80px] w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50" {...field} /> diff --git a/wavefront/client/src/pages/apps/[appId]/authenticators/[authId].tsx b/wavefront/client/src/pages/apps/[appId]/authenticators/[authId].tsx index 0bd7ebf4..98315451 100644 --- a/wavefront/client/src/pages/apps/[appId]/authenticators/[authId].tsx +++ b/wavefront/client/src/pages/apps/[appId]/authenticators/[authId].tsx @@ -1,16 +1,11 @@ -import floConsoleService from "@app/api"; -import { - cleanParameters, - getProviderBadge, - getProviderConfig, - mergeParameters, -} from "@app/config/authenticators"; -import { useGetAuthenticator } from "@app/hooks/data/fetch-hooks"; -import { useNotifyStore } from "@app/store"; -import { useQueryClient } from "@tanstack/react-query"; -import clsx from "clsx"; -import React, { useEffect, useState } from "react"; -import { useNavigate, useParams } from "react-router"; +import floConsoleService from '@app/api'; +import { cleanParameters, getProviderBadge, getProviderConfig, mergeParameters } from '@app/config/authenticators'; +import { useGetAuthenticator } from '@app/hooks/data/fetch-hooks'; +import { useNotifyStore } from '@app/store'; +import { useQueryClient } from '@tanstack/react-query'; +import clsx from 'clsx'; +import React, { useEffect, useState } from 'react'; +import { useNavigate, useParams } from 'react-router'; const AuthenticatorDetailPage: React.FC = () => { const { app, authId } = useParams<{ app: string; authId: string }>(); @@ -24,20 +19,17 @@ const AuthenticatorDetailPage: React.FC = () => { const [togglingEnabled, setTogglingEnabled] = useState(false); // Form state - const [authDesc, setAuthDesc] = useState(""); + const [authDesc, setAuthDesc] = useState(''); const [parameters, setParameters] = useState>({}); // Fetch authenticator - const { data: authenticator, isLoading: authenticatorLoading } = - useGetAuthenticator(app, authId); + const { data: authenticator, isLoading: authenticatorLoading } = useGetAuthenticator(app, authId); // Initialize form with authenticator data useEffect(() => { if (authenticator) { - setAuthDesc(authenticator.auth_desc || ""); - setParameters( - mergeParameters(authenticator.auth_type, authenticator.config) - ); + setAuthDesc(authenticator.auth_desc || ''); + setParameters(mergeParameters(authenticator.auth_type, authenticator.config)); } }, [authenticator]); @@ -45,11 +37,7 @@ const AuthenticatorDetailPage: React.FC = () => { setParameters((prev) => ({ ...prev, [key]: value })); }; - const setNestedParameter = ( - parentKey: string, - childKey: string, - value: any - ) => { + const setNestedParameter = (parentKey: string, childKey: string, value: any) => { setParameters((prev) => ({ ...prev, [parentKey]: { @@ -61,10 +49,8 @@ const AuthenticatorDetailPage: React.FC = () => { const handleCancel = () => { if (authenticator) { - setAuthDesc(authenticator.auth_desc || ""); - setParameters( - mergeParameters(authenticator.auth_type, authenticator.config) - ); + setAuthDesc(authenticator.auth_desc || ''); + setParameters(mergeParameters(authenticator.auth_type, authenticator.config)); } setIsEditing(false); }; @@ -78,16 +64,14 @@ const AuthenticatorDetailPage: React.FC = () => { auth_desc: authDesc.trim() || null, config: cleanParameters(parameters), }); - notifySuccess("Authenticator updated successfully"); + notifySuccess('Authenticator updated successfully'); setIsEditing(false); queryClient.invalidateQueries({ - queryKey: ["authenticator", app, authId], + queryKey: ['authenticator', app, authId], }); - queryClient.invalidateQueries({ queryKey: ["authenticators", app] }); + queryClient.invalidateQueries({ queryKey: ['authenticators', app] }); } catch (error: any) { - notifyError( - error?.response?.data?.meta?.error || "Failed to update authenticator" - ); + notifyError(error?.response?.data?.meta?.error || 'Failed to update authenticator'); } finally { setSaveLoading(false); } @@ -98,12 +82,10 @@ const AuthenticatorDetailPage: React.FC = () => { try { await floConsoleService.authenticatorService.deleteAuthenticator(authId); - notifySuccess("Authenticator deleted successfully"); + notifySuccess('Authenticator deleted successfully'); navigate(`/apps/${app}/authenticators`); } catch (error: any) { - notifyError( - error?.response?.data?.meta?.error || "Failed to delete authenticator" - ); + notifyError(error?.response?.data?.meta?.error || 'Failed to delete authenticator'); } }; @@ -113,24 +95,18 @@ const AuthenticatorDetailPage: React.FC = () => { setTogglingEnabled(true); try { if (authenticator.is_enabled) { - await floConsoleService.authenticatorService.disableAuthenticator( - authId - ); - notifySuccess("Authenticator disabled successfully"); + await floConsoleService.authenticatorService.disableAuthenticator(authId); + notifySuccess('Authenticator disabled successfully'); } else { - await floConsoleService.authenticatorService.enableAuthenticator( - authId - ); - notifySuccess("Authenticator enabled successfully"); + await floConsoleService.authenticatorService.enableAuthenticator(authId); + notifySuccess('Authenticator enabled successfully'); } queryClient.invalidateQueries({ - queryKey: ["authenticator", app, authId], + queryKey: ['authenticator', app, authId], }); - queryClient.invalidateQueries({ queryKey: ["authenticators", app] }); + queryClient.invalidateQueries({ queryKey: ['authenticators', app] }); } catch (error: any) { - notifyError( - error?.response?.data?.meta?.error || "Failed to toggle authenticator" - ); + notifyError(error?.response?.data?.meta?.error || 'Failed to toggle authenticator'); } finally { setTogglingEnabled(false); } @@ -146,59 +122,43 @@ const AuthenticatorDetailPage: React.FC = () => { if (!paramConfig) return null; // Handle nested object parameters (like password_policy) - if (paramConfig.type === "object" && paramConfig.fields) { + if (paramConfig.type === 'object' && paramConfig.fields) { return (
- {paramConfig.description && ( -

{paramConfig.description}

- )} + {paramConfig.description &&

{paramConfig.description}

}
- {Object.entries(paramConfig.fields).map( - ([nestedKey, nestedConfig]) => ( -
- - {nestedConfig.description && ( -

- {nestedConfig.description} -

- )} - {renderNestedField(key, nestedKey, nestedConfig, disabled)} -
- ) - )} + {Object.entries(paramConfig.fields).map(([nestedKey, nestedConfig]) => ( +
+ + {nestedConfig.description &&

{nestedConfig.description}

} + {renderNestedField(key, nestedKey, nestedConfig, disabled)} +
+ ))}
); } // Handle array parameters (like scopes) - if (paramConfig.type === "array") { - const arrayValue = Array.isArray(parameters[key]) - ? parameters[key].join(", ") - : ""; + if (paramConfig.type === 'array') { + const arrayValue = Array.isArray(parameters[key]) ? parameters[key].join(', ') : ''; return (
- {paramConfig.description && ( -

- {paramConfig.description} -

- )} + {paramConfig.description &&

{paramConfig.description}

} { const values = e.target.value - .split(",") + .split(',') .map((v) => v.trim()) .filter(Boolean); setParameter(key, values); @@ -206,19 +166,17 @@ const AuthenticatorDetailPage: React.FC = () => { disabled={disabled} placeholder={paramConfig.placeholder} className={clsx( - "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:outline-none focus:ring-1 focus:ring-black", - disabled && "cursor-not-allowed bg-gray-50 text-gray-500" + 'w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:ring-1 focus:ring-black focus:outline-none', + disabled && 'cursor-not-allowed bg-gray-50 text-gray-500' )} /> -

- Separate multiple values with commas -

+

Separate multiple values with commas

); } // Handle boolean parameters - if (paramConfig.type === "boolean") { + if (paramConfig.type === 'boolean') { return (
{ onChange={(e) => setParameter(key, e.target.checked)} disabled={disabled} className={clsx( - "h-4 w-4 rounded border-gray-300 text-black focus:ring-black", - disabled && "cursor-not-allowed opacity-50" + 'h-4 w-4 rounded border-gray-300 text-black focus:ring-black', + disabled && 'cursor-not-allowed opacity-50' )} />
- {paramConfig.description && ( -

{paramConfig.description}

- )} + {paramConfig.description &&

{paramConfig.description}

}
); } // Handle number parameters - if (paramConfig.type === "number") { + if (paramConfig.type === 'number') { return (
- {paramConfig.description && ( -

- {paramConfig.description} -

- )} + {paramConfig.description &&

{paramConfig.description}

} - setParameter(key, e.target.value ? Number(e.target.value) : "") - } + value={parameters[key] ?? ''} + onChange={(e) => setParameter(key, e.target.value ? Number(e.target.value) : '')} disabled={disabled} min={paramConfig.min} max={paramConfig.max} step={paramConfig.step} placeholder={paramConfig.placeholder} className={clsx( - "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:outline-none focus:ring-1 focus:ring-black", - disabled && "cursor-not-allowed bg-gray-50 text-gray-500" + 'w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:ring-1 focus:ring-black focus:outline-none', + disabled && 'cursor-not-allowed bg-gray-50 text-gray-500' )} />
@@ -276,24 +226,20 @@ const AuthenticatorDetailPage: React.FC = () => { } // Handle select parameters - if (paramConfig.type === "select" && paramConfig.options) { + if (paramConfig.type === 'select' && paramConfig.options) { return (
- {paramConfig.description && ( -

- {paramConfig.description} -

- )} + {paramConfig.description &&

{paramConfig.description}

} setParameter(key, e.target.value)} disabled={disabled} placeholder={paramConfig.placeholder} className={clsx( - "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:outline-none focus:ring-1 focus:ring-black", - disabled && "cursor-not-allowed bg-gray-50 text-gray-500" + 'w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:ring-1 focus:ring-black focus:outline-none', + disabled && 'cursor-not-allowed bg-gray-50 text-gray-500' )} />
); }; - const renderNestedField = ( - parentKey: string, - childKey: string, - config: any, - disabled: boolean - ) => { + const renderNestedField = (parentKey: string, childKey: string, config: any, disabled: boolean) => { const value = parameters[parentKey]?.[childKey]; - if (config.type === "boolean") { + if (config.type === 'boolean') { return ( - setNestedParameter(parentKey, childKey, e.target.checked) - } + onChange={(e) => setNestedParameter(parentKey, childKey, e.target.checked)} disabled={disabled} className={clsx( - "h-4 w-4 rounded border-gray-300 text-black focus:ring-black", - disabled && "cursor-not-allowed opacity-50" + 'h-4 w-4 rounded border-gray-300 text-black focus:ring-black', + disabled && 'cursor-not-allowed opacity-50' )} /> ); } - if (config.type === "number") { + if (config.type === 'number') { return ( - setNestedParameter( - parentKey, - childKey, - e.target.value ? Number(e.target.value) : "" - ) - } + value={value ?? ''} + onChange={(e) => setNestedParameter(parentKey, childKey, e.target.value ? Number(e.target.value) : '')} disabled={disabled} min={config.min} max={config.max} step={config.step} className={clsx( - "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:outline-none focus:ring-1 focus:ring-black", - disabled && "cursor-not-allowed bg-gray-50 text-gray-500" + 'w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:ring-1 focus:ring-black focus:outline-none', + disabled && 'cursor-not-allowed bg-gray-50 text-gray-500' )} /> ); @@ -384,15 +313,13 @@ const AuthenticatorDetailPage: React.FC = () => { return ( - setNestedParameter(parentKey, childKey, e.target.value) - } + value={value || ''} + onChange={(e) => setNestedParameter(parentKey, childKey, e.target.value)} disabled={disabled} placeholder={config.placeholder} className={clsx( - "w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:outline-none focus:ring-1 focus:ring-black", - disabled && "cursor-not-allowed bg-gray-50 text-gray-500" + 'w-full rounded-md border border-gray-300 px-3 py-2 text-sm focus:border-black focus:ring-1 focus:ring-black focus:outline-none', + disabled && 'cursor-not-allowed bg-gray-50 text-gray-500' )} /> ); @@ -412,9 +339,7 @@ const AuthenticatorDetailPage: React.FC = () => { return (
-
- Authenticator not found -
+
Authenticator not found
); @@ -438,48 +363,33 @@ const AuthenticatorDetailPage: React.FC = () => {
-

- {authenticator.auth_name} -

- +

{authenticator.auth_name}

+ {config?.name || authenticator.auth_type}
- - Status: - + Status: - {authenticator.is_enabled ? "Enabled" : "Disabled"} + {authenticator.is_enabled ? 'Enabled' : 'Disabled'}
@@ -514,11 +424,11 @@ const AuthenticatorDetailPage: React.FC = () => { onClick={handleSave} disabled={saveLoading} className={clsx( - "rounded-md bg-black px-4 py-2 text-sm font-medium text-white hover:bg-gray-800", - saveLoading && "cursor-not-allowed opacity-50" + 'rounded-md bg-black px-4 py-2 text-sm font-medium text-white hover:bg-gray-800', + saveLoading && 'cursor-not-allowed opacity-50' )} > - {saveLoading ? "Saving..." : "Save Changes"} + {saveLoading ? 'Saving...' : 'Save Changes'} )} @@ -529,9 +439,7 @@ const AuthenticatorDetailPage: React.FC = () => {
{/* Description */}
- +