From fb1c6196ed48318bbeb7b07dc19bbd061d9fc938 Mon Sep 17 00:00:00 2001 From: Neha Kumari Date: Mon, 13 Oct 2025 02:24:00 +0530 Subject: [PATCH 1/5] initial reactflow canvas setup --- .../visualizers/agent_ui/.gitignore | 24 + .../visualizers/agent_ui/README.md | 73 + .../visualizers/agent_ui/eslint.config.js | 23 + .../visualizers/agent_ui/index.html | 13 + .../visualizers/agent_ui/package-lock.json | 4823 +++++++++++++++++ .../visualizers/agent_ui/package.json | 35 + .../agent_ui/public/agent-proto.png | Bin 0 -> 111243 bytes .../visualizers/agent_ui/public/agent.svg | 4 + .../visualizers/agent_ui/src/App.css | 42 + .../visualizers/agent_ui/src/App.tsx | 416 ++ .../visualizers/agent_ui/src/agent_graph.json | 327 ++ .../src/assets/Manrope-VariableFont_wght.ttf | Bin 0 -> 164936 bytes .../agent_ui/src/assets/Planner.svg | 4 + .../visualizers/agent_ui/src/assets/agent.svg | 4 + .../agent_ui/src/assets/database.svg | 4 + .../visualizers/agent_ui/src/assets/end.svg | 4 + .../agent_ui/src/assets/generic.svg | 4 + .../visualizers/agent_ui/src/assets/input.svg | 4 + .../agent_ui/src/assets/mapper_bg.svg | 4484 +++++++++++++++ .../agent_ui/src/assets/memory.svg | 4 + .../agent_ui/src/assets/output.svg | 4 + .../agent_ui/src/assets/reflection.svg | 4 + .../agent_ui/src/assets/search.svg | 4 + .../visualizers/agent_ui/src/assets/start.svg | 4 + .../visualizers/agent_ui/src/assets/tool.svg | 4 + .../visualizers/agent_ui/src/customNode.tsx | 37 + .../visualizers/agent_ui/src/graphLoader.tsx | 61 + .../visualizers/agent_ui/src/index.css | 68 + .../visualizers/agent_ui/src/main.tsx | 10 + .../visualizers/agent_ui/src/utils.tsx | 48 + .../visualizers/agent_ui/tsconfig.app.json | 28 + .../visualizers/agent_ui/tsconfig.json | 7 + .../visualizers/agent_ui/tsconfig.node.json | 26 + .../visualizers/agent_ui/vite.config.ts | 7 + 34 files changed, 10604 insertions(+) create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/.gitignore create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/README.md create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/eslint.config.js create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/index.html create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/package-lock.json create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/package.json create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/public/agent-proto.png create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/public/agent.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/App.css create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/Manrope-VariableFont_wght.ttf create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/Planner.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/agent.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/database.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/end.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/generic.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/input.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/mapper_bg.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/memory.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/output.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/reflection.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/search.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/start.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/assets/tool.svg create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/index.css create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/main.tsx create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/tsconfig.app.json create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/tsconfig.json create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/tsconfig.node.json create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts diff --git a/src/repello_agent_wiz/visualizers/agent_ui/.gitignore b/src/repello_agent_wiz/visualizers/agent_ui/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/src/repello_agent_wiz/visualizers/agent_ui/README.md b/src/repello_agent_wiz/visualizers/agent_ui/README.md new file mode 100644 index 0000000..d2e7761 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/README.md @@ -0,0 +1,73 @@ +# React + TypeScript + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: + +```js +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + + // Remove tseslint.configs.recommended and replace with this + tseslint.configs.recommendedTypeChecked, + // Alternatively, use this for stricter rules + tseslint.configs.strictTypeChecked, + // Optionally, add this for stylistic rules + tseslint.configs.stylisticTypeChecked, + + // Other configs... + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` + +You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: + +```js +// eslint.config.js +import reactX from 'eslint-plugin-react-x' +import reactDom from 'eslint-plugin-react-dom' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + // Other configs... + // Enable lint rules for React + reactX.configs['recommended-typescript'], + // Enable lint rules for React DOM + reactDom.configs.recommended, + ], + languageOptions: { + parserOptions: { + project: ['./tsconfig.node.json', './tsconfig.app.json'], + tsconfigRootDir: import.meta.dirname, + }, + // other options... + }, + }, +]) +``` diff --git a/src/repello_agent_wiz/visualizers/agent_ui/eslint.config.js b/src/repello_agent_wiz/visualizers/agent_ui/eslint.config.js new file mode 100644 index 0000000..b19330b --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/eslint.config.js @@ -0,0 +1,23 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import tseslint from 'typescript-eslint' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{ts,tsx}'], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + }, + }, +]) diff --git a/src/repello_agent_wiz/visualizers/agent_ui/index.html b/src/repello_agent_wiz/visualizers/agent_ui/index.html new file mode 100644 index 0000000..8bdeca8 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/index.html @@ -0,0 +1,13 @@ + + + + + + + Agent Wizard + + +
+ + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/package-lock.json b/src/repello_agent_wiz/visualizers/agent_ui/package-lock.json new file mode 100644 index 0000000..8e77e4f --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/package-lock.json @@ -0,0 +1,4823 @@ +{ + "name": "agent_ui", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "agent_ui", + "version": "0.0.0", + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/material": "^7.3.4", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-flow-renderer": "^10.3.17", + "reactflow": "^11.11.4" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/node": "^24.6.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "typescript": "~5.9.3", + "typescript-eslint": "^8.45.0", + "vite": "^7.1.7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emotion/babel-plugin": { + "version": "11.13.5", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", + "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/serialize": "^1.3.3", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/cache": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz", + "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0", + "@emotion/sheet": "^1.4.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "stylis": "4.2.0" + } + }, + "node_modules/@emotion/hash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz", + "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==", + "license": "MIT" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", + "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", + "license": "MIT", + "dependencies": { + "@emotion/memoize": "^0.9.0" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", + "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "license": "MIT" + }, + "node_modules/@emotion/react": { + "version": "11.14.0", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", + "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2", + "@emotion/weak-memoize": "^0.4.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz", + "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==", + "license": "MIT", + "dependencies": { + "@emotion/hash": "^0.9.2", + "@emotion/memoize": "^0.9.0", + "@emotion/unitless": "^0.10.0", + "@emotion/utils": "^1.4.2", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz", + "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==", + "license": "MIT" + }, + "node_modules/@emotion/styled": { + "version": "11.14.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", + "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.13.5", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/serialize": "^1.3.3", + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", + "@emotion/utils": "^1.4.2" + }, + "peerDependencies": { + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz", + "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==", + "license": "MIT" + }, + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz", + "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@emotion/utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz", + "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==", + "license": "MIT" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz", + "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz", + "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz", + "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz", + "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz", + "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz", + "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz", + "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz", + "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz", + "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz", + "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz", + "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz", + "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz", + "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz", + "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz", + "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz", + "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz", + "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz", + "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz", + "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz", + "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz", + "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz", + "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz", + "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz", + "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz", + "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz", + "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz", + "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz", + "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.0.tgz", + "integrity": "sha512-WUFvV4WoIwW8Bv0KeKCIIEgdSiFOsulyN0xrMu+7z43q/hkOLXjvb5u7UC9jDxvRzcrbEmuZBX5yJZz1741jog==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.37.0.tgz", + "integrity": "sha512-jaS+NJ+hximswBG6pjNX0uEJZkrT0zwpVi3BA3vX22aFGjJjmgSTSmPpZCRKmoBL5VY/M6p0xsSJx7rk7sy5gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mui/core-downloads-tracker": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.4.tgz", + "integrity": "sha512-BIktMapG3r4iXwIhYNpvk97ZfYWTreBBQTWjQKbNbzI64+ULHfYavQEX2w99aSWHS58DvXESWIgbD9adKcUOBw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + } + }, + "node_modules/@mui/material": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.4.tgz", + "integrity": "sha512-gEQL9pbJZZHT7lYJBKQCS723v1MGys2IFc94COXbUIyCTWa+qC77a7hUax4Yjd5ggEm35dk4AyYABpKKWC4MLw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/core-downloads-tracker": "^7.3.4", + "@mui/system": "^7.3.3", + "@mui/types": "^7.4.7", + "@mui/utils": "^7.3.3", + "@popperjs/core": "^2.11.8", + "@types/react-transition-group": "^4.4.12", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1", + "react-is": "^19.1.1", + "react-transition-group": "^4.4.5" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@mui/material-pigment-css": "^7.3.3", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@mui/material-pigment-css": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.3.tgz", + "integrity": "sha512-OJM+9nj5JIyPUvsZ5ZjaeC9PfktmK+W5YaVLToLR8L0lB/DGmv1gcKE43ssNLSvpoW71Hct0necfade6+kW3zQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/utils": "^7.3.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.3.tgz", + "integrity": "sha512-CmFxvRJIBCEaWdilhXMw/5wFJ1+FT9f3xt+m2pPXhHPeVIbBg9MnMvNSJjdALvnQJMPw8jLhrUtXmN7QAZV2fw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@emotion/cache": "^11.14.0", + "@emotion/serialize": "^1.3.3", + "@emotion/sheet": "^1.4.0", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.3.tgz", + "integrity": "sha512-Lqq3emZr5IzRLKaHPuMaLBDVaGvxoh6z7HMWd1RPKawBM5uMRaQ4ImsmmgXWtwJdfZux5eugfDhXJUo2mliS8Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/private-theming": "^7.3.3", + "@mui/styled-engine": "^7.3.3", + "@mui/types": "^7.4.7", + "@mui/utils": "^7.3.3", + "clsx": "^2.1.1", + "csstype": "^3.1.3", + "prop-types": "^15.8.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.4.7", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.7.tgz", + "integrity": "sha512-8vVje9rdEr1rY8oIkYgP+Su5Kwl6ik7O3jQ0wl78JGSmiZhRHV+vkjooGdKD8pbtZbutXFVTWQYshu2b3sG9zw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.3.tgz", + "integrity": "sha512-kwNAUh7bLZ7mRz9JZ+6qfRnnxbE4Zuc+RzXnhSpRSxjTlSTj7b4JxRLXpG+MVtPVtqks5k/XC8No1Vs3x4Z2gg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4", + "@mui/types": "^7.4.7", + "@types/prop-types": "^15.7.15", + "clsx": "^2.1.1", + "prop-types": "^15.8.1", + "react-is": "^19.1.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@reactflow/background": { + "version": "11.3.14", + "resolved": "https://registry.npmjs.org/@reactflow/background/-/background-11.3.14.tgz", + "integrity": "sha512-Gewd7blEVT5Lh6jqrvOgd4G6Qk17eGKQfsDXgyRSqM+CTwDqRldG2LsWN4sNeno6sbqVIC2fZ+rAUBFA9ZEUDA==", + "license": "MIT", + "dependencies": { + "@reactflow/core": "11.11.4", + "classcat": "^5.0.3", + "zustand": "^4.4.1" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@reactflow/background/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@reactflow/controls": { + "version": "11.2.14", + "resolved": "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.14.tgz", + "integrity": "sha512-MiJp5VldFD7FrqaBNIrQ85dxChrG6ivuZ+dcFhPQUwOK3HfYgX2RHdBua+gx+40p5Vw5It3dVNp/my4Z3jF0dw==", + "license": "MIT", + "dependencies": { + "@reactflow/core": "11.11.4", + "classcat": "^5.0.3", + "zustand": "^4.4.1" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@reactflow/controls/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@reactflow/core": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/@reactflow/core/-/core-11.11.4.tgz", + "integrity": "sha512-H4vODklsjAq3AMq6Np4LE12i1I4Ta9PrDHuBR9GmL8uzTt2l2jh4CiQbEMpvMDcp7xi4be0hgXj+Ysodde/i7Q==", + "license": "MIT", + "dependencies": { + "@types/d3": "^7.4.0", + "@types/d3-drag": "^3.0.1", + "@types/d3-selection": "^3.0.3", + "@types/d3-zoom": "^3.0.1", + "classcat": "^5.0.3", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "zustand": "^4.4.1" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@reactflow/core/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@reactflow/minimap": { + "version": "11.7.14", + "resolved": "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.14.tgz", + "integrity": "sha512-mpwLKKrEAofgFJdkhwR5UQ1JYWlcAAL/ZU/bctBkuNTT1yqV+y0buoNVImsRehVYhJwffSWeSHaBR5/GJjlCSQ==", + "license": "MIT", + "dependencies": { + "@reactflow/core": "11.11.4", + "@types/d3-selection": "^3.0.3", + "@types/d3-zoom": "^3.0.1", + "classcat": "^5.0.3", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "zustand": "^4.4.1" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@reactflow/minimap/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@reactflow/node-resizer": { + "version": "2.2.14", + "resolved": "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.14.tgz", + "integrity": "sha512-fwqnks83jUlYr6OHcdFEedumWKChTHRGw/kbCxj0oqBd+ekfs+SIp4ddyNU0pdx96JIm5iNFS0oNrmEiJbbSaA==", + "license": "MIT", + "dependencies": { + "@reactflow/core": "11.11.4", + "classcat": "^5.0.4", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "zustand": "^4.4.1" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@reactflow/node-resizer/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@reactflow/node-toolbar": { + "version": "1.3.14", + "resolved": "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.14.tgz", + "integrity": "sha512-rbynXQnH/xFNu4P9H+hVqlEUafDCkEoCy0Dg9mG22Sg+rY/0ck6KkrAQrYrTgXusd+cEJOMK0uOOFCK2/5rSGQ==", + "license": "MIT", + "dependencies": { + "@reactflow/core": "11.11.4", + "classcat": "^5.0.3", + "zustand": "^4.4.1" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/@reactflow/node-toolbar/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.38.tgz", + "integrity": "sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.4.tgz", + "integrity": "sha512-BTm2qKNnWIQ5auf4deoetINJm2JzvihvGb9R6K/ETwKLql/Bb3Eg2H1FBp1gUb4YGbydMA3jcmQTR73q7J+GAA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.4.tgz", + "integrity": "sha512-P9LDQiC5vpgGFgz7GSM6dKPCiqR3XYN1WwJKA4/BUVDjHpYsf3iBEmVz62uyq20NGYbiGPR5cNHI7T1HqxNs2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.4.tgz", + "integrity": "sha512-QRWSW+bVccAvZF6cbNZBJwAehmvG9NwfWHwMy4GbWi/BQIA/laTIktebT2ipVjNncqE6GLPxOok5hsECgAxGZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.4.tgz", + "integrity": "sha512-hZgP05pResAkRJxL1b+7yxCnXPGsXU0fG9Yfd6dUaoGk+FhdPKCJ5L1Sumyxn8kvw8Qi5PvQ8ulenUbRjzeCTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.4.tgz", + "integrity": "sha512-xmc30VshuBNUd58Xk4TKAEcRZHaXlV+tCxIXELiE9sQuK3kG8ZFgSPi57UBJt8/ogfhAF5Oz4ZSUBN77weM+mQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.4.tgz", + "integrity": "sha512-WdSLpZFjOEqNZGmHflxyifolwAiZmDQzuOzIq9L27ButpCVpD7KzTRtEG1I0wMPFyiyUdOO+4t8GvrnBLQSwpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.4.tgz", + "integrity": "sha512-xRiOu9Of1FZ4SxVbB0iEDXc4ddIcjCv2aj03dmW8UrZIW7aIQ9jVJdLBIhxBI+MaTnGAKyvMwPwQnoOEvP7FgQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.4.tgz", + "integrity": "sha512-FbhM2p9TJAmEIEhIgzR4soUcsW49e9veAQCziwbR+XWB2zqJ12b4i/+hel9yLiD8pLncDH4fKIPIbt5238341Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.4.tgz", + "integrity": "sha512-4n4gVwhPHR9q/g8lKCyz0yuaD0MvDf7dV4f9tHt0C73Mp8h38UCtSCSE6R9iBlTbXlmA8CjpsZoujhszefqueg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.4.tgz", + "integrity": "sha512-u0n17nGA0nvi/11gcZKsjkLj1QIpAuPFQbR48Subo7SmZJnGxDpspyw2kbpuoQnyK+9pwf3pAoEXerJs/8Mi9g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.4.tgz", + "integrity": "sha512-0G2c2lpYtbTuXo8KEJkDkClE/+/2AFPdPAbmaHoE870foRFs4pBrDehilMcrSScrN/fB/1HTaWO4bqw+ewBzMQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.4.tgz", + "integrity": "sha512-teSACug1GyZHmPDv14VNbvZFX779UqWTsd7KtTM9JIZRDI5NUwYSIS30kzI8m06gOPB//jtpqlhmraQ68b5X2g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.4.tgz", + "integrity": "sha512-/MOEW3aHjjs1p4Pw1Xk4+3egRevx8Ji9N6HUIA1Ifh8Q+cg9dremvFCUbOX2Zebz80BwJIgCBUemjqhU5XI5Eg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.4.tgz", + "integrity": "sha512-1HHmsRyh845QDpEWzOFtMCph5Ts+9+yllCrREuBR/vg2RogAQGGBRC8lDPrPOMnrdOJ+mt1WLMOC2Kao/UwcvA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.4.tgz", + "integrity": "sha512-seoeZp4L/6D1MUyjWkOMRU6/iLmCU2EjbMTyAG4oIOs1/I82Y5lTeaxW0KBfkUdHAWN7j25bpkt0rjnOgAcQcA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.4.tgz", + "integrity": "sha512-Wi6AXf0k0L7E2gteNsNHUs7UMwCIhsCTs6+tqQ5GPwVRWMaflqGec4Sd8n6+FNFDw9vGcReqk2KzBDhCa1DLYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.4.tgz", + "integrity": "sha512-dtBZYjDmCQ9hW+WgEkaffvRRCKm767wWhxsFW3Lw86VXz/uJRuD438/XvbZT//B96Vs8oTA8Q4A0AfHbrxP9zw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.4.tgz", + "integrity": "sha512-1ox+GqgRWqaB1RnyZXL8PD6E5f7YyRUJYnCqKpNzxzP0TkaUh112NDrR9Tt+C8rJ4x5G9Mk8PQR3o7Ku2RKqKA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.4.tgz", + "integrity": "sha512-8GKr640PdFNXwzIE0IrkMWUNUomILLkfeHjXBi/nUvFlpZP+FA8BKGKpacjW6OUUHaNI6sUURxR2U2g78FOHWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.4.tgz", + "integrity": "sha512-AIy/jdJ7WtJ/F6EcfOb2GjR9UweO0n43jNObQMb6oGxkYTfLcnN7vYYpG+CN3lLxrQkzWnMOoNSHTW54pgbVxw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.4.tgz", + "integrity": "sha512-UF9KfsH9yEam0UjTwAgdK0anlQ7c8/pWPU2yVjyWcF1I1thABt6WXE47cI71pGiZ8wGvxohBoLnxM04L/wj8mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.4.tgz", + "integrity": "sha512-bf9PtUa0u8IXDVxzRToFQKsNCRz9qLYfR/MpECxl4mRoWYjAeFjgxj1XdZr2M/GNVpT05p+LgQOHopYDlUu6/w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/d3": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", + "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/d3-axis": "*", + "@types/d3-brush": "*", + "@types/d3-chord": "*", + "@types/d3-color": "*", + "@types/d3-contour": "*", + "@types/d3-delaunay": "*", + "@types/d3-dispatch": "*", + "@types/d3-drag": "*", + "@types/d3-dsv": "*", + "@types/d3-ease": "*", + "@types/d3-fetch": "*", + "@types/d3-force": "*", + "@types/d3-format": "*", + "@types/d3-geo": "*", + "@types/d3-hierarchy": "*", + "@types/d3-interpolate": "*", + "@types/d3-path": "*", + "@types/d3-polygon": "*", + "@types/d3-quadtree": "*", + "@types/d3-random": "*", + "@types/d3-scale": "*", + "@types/d3-scale-chromatic": "*", + "@types/d3-selection": "*", + "@types/d3-shape": "*", + "@types/d3-time": "*", + "@types/d3-time-format": "*", + "@types/d3-timer": "*", + "@types/d3-transition": "*", + "@types/d3-zoom": "*" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-axis": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", + "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-brush": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", + "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-chord": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", + "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-contour": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", + "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", + "license": "MIT", + "dependencies": { + "@types/d3-array": "*", + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", + "license": "MIT" + }, + "node_modules/@types/d3-dispatch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", + "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", + "license": "MIT" + }, + "node_modules/@types/d3-drag": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", + "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "license": "MIT", + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-force": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", + "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", + "license": "MIT" + }, + "node_modules/@types/d3-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", + "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", + "license": "MIT" + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "license": "MIT", + "dependencies": { + "@types/geojson": "*" + } + }, + "node_modules/@types/d3-hierarchy": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", + "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-polygon": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", + "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", + "license": "MIT" + }, + "node_modules/@types/d3-quadtree": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", + "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", + "license": "MIT" + }, + "node_modules/@types/d3-random": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", + "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", + "license": "MIT" + }, + "node_modules/@types/d3-selection": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", + "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", + "license": "MIT" + }, + "node_modules/@types/d3-shape": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", + "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-time-format": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", + "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/d3-transition": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", + "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", + "license": "MIT", + "dependencies": { + "@types/d3-selection": "*" + } + }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "license": "MIT", + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/geojson": { + "version": "7946.0.16", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", + "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.7.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.7.2.tgz", + "integrity": "sha512-/NbVmcGTP+lj5oa4yiYxxeBjRivKQ5Ns1eSZeB99ExsEQ6rX5XYU1Zy/gGxY/ilqtD4Etx9mKyrPxZRetiahhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.14.0" + } + }, + "node_modules/@types/parse-json": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", + "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.1.tgz", + "integrity": "sha512-/EEvYBdT3BflCWvTMO7YkYBHVE9Ci6XdqZciZANQgKpaiDRGOLIlRo91jbTNRQjgPFWVaRxcYc0luVNFitz57A==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.12", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz", + "integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/resize-observer-browser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz", + "integrity": "sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ==", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.0.tgz", + "integrity": "sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/type-utils": "8.46.0", + "@typescript-eslint/utils": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.0.tgz", + "integrity": "sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.0.tgz", + "integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.0", + "@typescript-eslint/types": "^8.46.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz", + "integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.0.tgz", + "integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.0.tgz", + "integrity": "sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/utils": "8.46.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz", + "integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz", + "integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.0", + "@typescript-eslint/tsconfig-utils": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz", + "integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz", + "integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.4.tgz", + "integrity": "sha512-La0KD0vGkVkSk6K+piWDKRUyg8Rl5iAIKRMH0vMJI0Eg47bq1eOxmoObAaQG37WMW9MSyk7Cs8EIWwJC1PtzKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.38", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.16.tgz", + "integrity": "sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.26.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", + "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.9", + "caniuse-lite": "^1.0.30001746", + "electron-to-chromium": "^1.5.227", + "node-releases": "^2.0.21", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001750", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001750.tgz", + "integrity": "sha512-cuom0g5sdX6rw00qOoLNSFCJ9/mYIsuSOA+yzpDw8eopiFqcVwQvZHqov0vmEighRxX++cfC0Vg1G+1Iy/mSpQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/classcat": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz", + "integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "license": "ISC", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.234", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz", + "integrity": "sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==", + "dev": true, + "license": "ISC" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/esbuild": { + "version": "0.25.10", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", + "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.10", + "@esbuild/android-arm": "0.25.10", + "@esbuild/android-arm64": "0.25.10", + "@esbuild/android-x64": "0.25.10", + "@esbuild/darwin-arm64": "0.25.10", + "@esbuild/darwin-x64": "0.25.10", + "@esbuild/freebsd-arm64": "0.25.10", + "@esbuild/freebsd-x64": "0.25.10", + "@esbuild/linux-arm": "0.25.10", + "@esbuild/linux-arm64": "0.25.10", + "@esbuild/linux-ia32": "0.25.10", + "@esbuild/linux-loong64": "0.25.10", + "@esbuild/linux-mips64el": "0.25.10", + "@esbuild/linux-ppc64": "0.25.10", + "@esbuild/linux-riscv64": "0.25.10", + "@esbuild/linux-s390x": "0.25.10", + "@esbuild/linux-x64": "0.25.10", + "@esbuild/netbsd-arm64": "0.25.10", + "@esbuild/netbsd-x64": "0.25.10", + "@esbuild/openbsd-arm64": "0.25.10", + "@esbuild/openbsd-x64": "0.25.10", + "@esbuild/openharmony-arm64": "0.25.10", + "@esbuild/sunos-x64": "0.25.10", + "@esbuild/win32-arm64": "0.25.10", + "@esbuild/win32-ia32": "0.25.10", + "@esbuild/win32-x64": "0.25.10" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.37.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.37.0.tgz", + "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.4.0", + "@eslint/core": "^0.16.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.37.0", + "@eslint/plugin-kit": "^0.4.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "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" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.23.tgz", + "integrity": "sha512-G4j+rv0NmbIR45kni5xJOrYvCtyD3/7LjpVH8MPPcudXDcNu8gv+4ATTDXTtbRR8rTCM5HxECvCSsRmxKnWDsA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.23", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.23.tgz", + "integrity": "sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-flow-renderer": { + "version": "10.3.17", + "resolved": "https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz", + "integrity": "sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ==", + "deprecated": "react-flow-renderer has been renamed to reactflow, please use this package from now on https://reactflow.dev/docs/guides/migrate-to-v11/", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.9", + "@types/d3": "^7.4.0", + "@types/resize-observer-browser": "^0.1.7", + "classcat": "^5.0.3", + "d3-drag": "^3.0.0", + "d3-selection": "^3.0.0", + "d3-zoom": "^3.0.0", + "zustand": "^3.7.2" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "16 || 17 || 18", + "react-dom": "16 || 17 || 18" + } + }, + "node_modules/react-is": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.0.tgz", + "integrity": "sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/reactflow": { + "version": "11.11.4", + "resolved": "https://registry.npmjs.org/reactflow/-/reactflow-11.11.4.tgz", + "integrity": "sha512-70FOtJkUWH3BAOsN+LU9lCrKoKbtOPnz2uq0CV2PLdNSwxTXOhCbsZr50GmZ+Rtw3jx8Uv7/vBFtCGixLfd4Og==", + "license": "MIT", + "dependencies": { + "@reactflow/background": "11.3.14", + "@reactflow/controls": "11.2.14", + "@reactflow/core": "11.11.4", + "@reactflow/minimap": "11.7.14", + "@reactflow/node-resizer": "2.2.14", + "@reactflow/node-toolbar": "1.3.14" + }, + "peerDependencies": { + "react": ">=17", + "react-dom": ">=17" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.52.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.4.tgz", + "integrity": "sha512-CLEVl+MnPAiKh5pl4dEWSyMTpuflgNQiLGhMv8ezD5W/qP8AKvmYpCOKRRNOh7oRKnauBZ4SyeYkMS+1VSyKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.4", + "@rollup/rollup-android-arm64": "4.52.4", + "@rollup/rollup-darwin-arm64": "4.52.4", + "@rollup/rollup-darwin-x64": "4.52.4", + "@rollup/rollup-freebsd-arm64": "4.52.4", + "@rollup/rollup-freebsd-x64": "4.52.4", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.4", + "@rollup/rollup-linux-arm-musleabihf": "4.52.4", + "@rollup/rollup-linux-arm64-gnu": "4.52.4", + "@rollup/rollup-linux-arm64-musl": "4.52.4", + "@rollup/rollup-linux-loong64-gnu": "4.52.4", + "@rollup/rollup-linux-ppc64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-gnu": "4.52.4", + "@rollup/rollup-linux-riscv64-musl": "4.52.4", + "@rollup/rollup-linux-s390x-gnu": "4.52.4", + "@rollup/rollup-linux-x64-gnu": "4.52.4", + "@rollup/rollup-linux-x64-musl": "4.52.4", + "@rollup/rollup-openharmony-arm64": "4.52.4", + "@rollup/rollup-win32-arm64-msvc": "4.52.4", + "@rollup/rollup-win32-ia32-msvc": "4.52.4", + "@rollup/rollup-win32-x64-gnu": "4.52.4", + "@rollup/rollup-win32-x64-msvc": "4.52.4", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stylis": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", + "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==", + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.0.tgz", + "integrity": "sha512-6+ZrB6y2bT2DX3K+Qd9vn7OFOJR+xSLDj+Aw/N3zBwUt27uTw2sw2TE2+UcY1RiyBZkaGbTkVg9SSdPNUG6aUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.46.0", + "@typescript-eslint/parser": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/utils": "8.46.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/undici-types": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", + "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/vite": { + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.9.tgz", + "integrity": "sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "dev": true, + "license": "ISC", + "optional": true, + "peer": true, + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "license": "MIT", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + } + } +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/package.json b/src/repello_agent_wiz/visualizers/agent_ui/package.json new file mode 100644 index 0000000..d9040ce --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/package.json @@ -0,0 +1,35 @@ +{ + "name": "agent_ui", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@emotion/react": "^11.14.0", + "@emotion/styled": "^11.14.1", + "@mui/material": "^7.3.4", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-flow-renderer": "^10.3.17", + "reactflow": "^11.11.4" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/node": "^24.6.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "typescript": "~5.9.3", + "typescript-eslint": "^8.45.0", + "vite": "^7.1.7" + } +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/public/agent-proto.png b/src/repello_agent_wiz/visualizers/agent_ui/public/agent-proto.png new file mode 100644 index 0000000000000000000000000000000000000000..f5a01764859ce331524075d6520ae314ac098245 GIT binary patch literal 111243 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

y_6gVtFM@=!Jt;i8Ff63@u%>xg63Zu#*49& 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%0Df5VxnEe$gSiK$ie$|$w;&Xw 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 afe|BKU2^17lu#$YJ({XIP`I*X(7ym#Aftf* literal 0 HcmV?d00001 diff --git a/src/repello_agent_wiz/visualizers/agent_ui/public/agent.svg b/src/repello_agent_wiz/visualizers/agent_ui/public/agent.svg new file mode 100644 index 0000000..227aa4f --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/public/agent.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/App.css b/src/repello_agent_wiz/visualizers/agent_ui/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx new file mode 100644 index 0000000..522338a --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx @@ -0,0 +1,416 @@ +// import { useState, useRef } from 'react'; +// import { Box, AppBar, Toolbar, Typography, Switch, Drawer, Card, List, ListItem, ButtonGroup, Button, Snackbar, TextField, InputAdornment } from '@mui/material'; +// import ReactFlow, { MiniMap, Controls, Background, ReactFlowProvider, useReactFlow } from 'react-flow-renderer'; +// import { loadGraph } from './graphLoader'; +// import CustomNode from './CustomNode'; +// import SearchIcon from './assets/search.svg'; +// import AgentIcon from './assets/agent.svg'; +// import ToolIcon from './assets/tool.svg'; +// import OrchestratorIcon from './assets/Planner.svg'; +// import StartIcon from './assets/start.svg'; +// import TeamIcon from './assets/generic.svg'; + +// // Node types mapping +// const nodeTypes = { customNode: CustomNode }; +// const { nodes: initialNodes, edges: initialEdges, framework } = loadGraph(); + +// function App() { +// const [themeDark, setThemeDark] = useState(false); +// const [drawerOpen, setDrawerOpen] = useState(false); +// const [selectedDetails, setSelectedDetails] = useState(null); +// const [snackbarOpen, setSnackbarOpen] = useState(false); +// const [search, setSearch] = useState(''); +// const [highlighted, setHighlighted] = useState(null); +// const reactFlowWrapper = useRef(null); + +// const {zoomTo, getZoom} = useReactFlow(); + + +// // Handlers +// const handleNodeClick = (_event: any, node: any) => { +// setSelectedDetails({ type: 'node', ...node.data }); +// setDrawerOpen(true); +// setHighlighted(node.id); +// }; +// const handleEdgeClick = (_event: any, edge: any) => { +// setSelectedDetails({ type: 'edge', ...edge }); +// setDrawerOpen(true); +// }; +// const handleCloseDrawer = () => { +// setDrawerOpen(false); +// setSelectedDetails(null); +// setHighlighted(null); +// }; +// const handleThemeToggle = () => setThemeDark((prev) => !prev); +// const handleSnackbarClose = () => setSnackbarOpen(false); + +// // Search logic +// const handleSearch = (e: any) => { +// setSearch(e.target.value); +// const found = initialNodes.find(n => n.id.toLowerCase().includes(e.target.value.toLowerCase())); +// setHighlighted(found ? found.id : null); +// // Zoom to node if found +// if (found) { +// zoomTo(found.id); +// } +// }; + +// // Custom node style for highlight +// const getNodeStyle = (id: string, color: string) => ({ +// border: highlighted === id ? '3px solid #E57373' : '2px solid #fff', +// boxShadow: highlighted === id ? '0 0 16px #E57373' : '0 2px 8px rgba(80,80,120,0.08)', +// background: color, +// borderRadius: 16, +// }); + +// return ( +// <> +// +// +// {/* Header */} +// +// +// Agent-Wiz Visualization ({framework}) +// +// +// +// + +// {/* Search Bar */} +// +// +// Search +// +// ), +// }} +// sx={{ width: 260 }} +// /> +// + +// {/* Main Content */} +// +// {/* Sidebar */} +// +// +// +// Agent Agent +// Tool Tool +// Orchestrator Orchestrator +// Start Start/End +// Team Team +// +// +// + +// {/* React Flow Canvas */} +// +// ({ +// ...n, +// style: getNodeStyle(n.id, n.data.color), +// }))} +// edges={initialEdges} +// nodeTypes={nodeTypes} +// fitView +// style={{ width: '100%', height: '100%' }} +// onNodeClick={handleNodeClick} +// onEdgeClick={handleEdgeClick} +// minZoom={0.3} +// maxZoom={2} +// snapToGrid +// snapGrid={[24, 24]} +// > +// n.data.color} /> +// +// +// +// + +// {/* Details Drawer */} +// +// +// Details +// {selectedDetails && selectedDetails.type === 'node' && ( +// +// {selectedDetails.label} +// +// Type: {selectedDetails.nodeType} +// {selectedDetails.functionName && Function: {selectedDetails.functionName}} +// {selectedDetails.docstring && Docstring: {selectedDetails.docstring}} +// {selectedDetails.sourceLocation && ( +// +// Source: {selectedDetails.sourceLocation.file} (Line {selectedDetails.sourceLocation.line}) +// +// )} +// {selectedDetails.metadata && Object.keys(selectedDetails.metadata).length > 0 && ( +// +// Metadata: +//

{JSON.stringify(selectedDetails.metadata, null, 2)}
+// +// )} +// +// +// )} +// {selectedDetails && selectedDetails.type === 'edge' && ( +// +// Edge: {selectedDetails.source} → {selectedDetails.target} +// +// Condition: {selectedDetails.label} +// {selectedDetails.data && Object.keys(selectedDetails.data).length > 0 && ( +// +// Metadata: +//
{JSON.stringify(selectedDetails.data, null, 2)}
+//
+// )} +//
+//
+// )} +// +// +// +// + +// {/* Bottom Controls */} +// +// +// +// +// +// +// +// +// +// +// +// ); +// } + +// export default App; + +import { useState, useRef } from 'react'; +import { Box, AppBar, Toolbar, Typography, Switch, Drawer, Card, List, ListItem, ButtonGroup, Button, Snackbar, TextField, InputAdornment } from '@mui/material'; +import ReactFlow, { MiniMap, Controls, Background, ReactFlowProvider } from 'react-flow-renderer'; +import { loadGraph } from './graphLoader'; +import CustomNode from './CustomNode'; +import SearchIcon from './assets/search.svg'; +import AgentIcon from './assets/agent.svg'; +import ToolIcon from './assets/tool.svg'; +import OrchestratorIcon from './assets/Planner.svg'; +import StartIcon from './assets/start.svg'; +import TeamIcon from './assets/generic.svg'; +import { useReactFlow } from 'reactflow'; +import type { Node, Edge } from 'react-flow-renderer'; + +type FlowCanvasProps = { + nodes: Node[]; + edges: Edge[]; + highlighted: string | null; + setHighlighted: React.Dispatch>; + handleNodeClick: (event: React.MouseEvent, node: Node) => void; + handleEdgeClick: (event: React.MouseEvent, edge: Edge) => void; +}; + +const nodeTypes = { customNode: CustomNode }; +const { nodes: initialNodes, edges: initialEdges, framework } = loadGraph(); + +function FlowCanvas({ + nodes, + edges, + highlighted, + setHighlighted, + handleNodeClick, + handleEdgeClick, +}: FlowCanvasProps) { + const { zoomTo } = useReactFlow(); + + // Search logic inside context + const [search, setSearch] = useState(''); + const handleSearch = (e: any) => { + setSearch(e.target.value); + const found = nodes.find((n: any) => n.id.toLowerCase().includes(e.target.value.toLowerCase())); + setHighlighted(found ? found.id : null); + if (found) zoomTo(Number(found.id)); + }; + + const getNodeStyle = (id: string, color: string) => ({ + border: highlighted === id ? '3px solid #E57373' : '2px solid #fff', + boxShadow: highlighted === id ? '0 0 16px #E57373' : '0 2px 8px rgba(80,80,120,0.08)', + background: color, + borderRadius: 16, + }); + + return ( + <> + {/* Search Bar */} + + + Search + + ), + }} + sx={{ width: 260 }} + /> + + ({ + ...n, + style: getNodeStyle(n.id, n.data.color), + }))} + edges={edges} + nodeTypes={nodeTypes} + fitView + style={{ width: '100%', height: '100%' }} + onNodeClick={handleNodeClick} + onEdgeClick={handleEdgeClick} + minZoom={0.3} + maxZoom={2} + snapToGrid + snapGrid={[24, 24]} + > + n.data.color} /> + + + + + ); +} + +function App() { + const [themeDark, setThemeDark] = useState(false); + const [drawerOpen, setDrawerOpen] = useState(false); + const [selectedDetails, setSelectedDetails] = useState(null); + const [snackbarOpen, setSnackbarOpen] = useState(false); + const [highlighted, setHighlighted] = useState(null); + + // Handlers + const handleNodeClick = (_event: any, node: any) => { + setSelectedDetails({ type: 'node', ...node.data }); + setDrawerOpen(true); + setHighlighted(node.id); + }; + const handleEdgeClick = (_event: any, edge: any) => { + setSelectedDetails({ type: 'edge', ...edge }); + setDrawerOpen(true); + }; + const handleCloseDrawer = () => { + setDrawerOpen(false); + setSelectedDetails(null); + setHighlighted(null); + }; + const handleThemeToggle = () => setThemeDark((prev) => !prev); + const handleSnackbarClose = () => setSnackbarOpen(false); + + return ( + + + {/* Header */} + + + Agent-Wiz Visualization ({framework}) + + + + + + {/* Main Content */} + + {/* Sidebar */} + + + + Agent Agent + Tool Tool + Orchestrator Orchestrator + Start Start/End + Team Team + + + + + {/* React Flow Canvas & Search */} + + + + + {/* Details Drawer */} + + + Details + {selectedDetails && selectedDetails.type === 'node' && ( + + {selectedDetails.label} + + Type: {selectedDetails.nodeType} + {selectedDetails.functionName && Function: {selectedDetails.functionName}} + {selectedDetails.docstring && Docstring: {selectedDetails.docstring}} + {selectedDetails.sourceLocation && ( + + Source: {selectedDetails.sourceLocation.file} (Line {selectedDetails.sourceLocation.line}) + + )} + {selectedDetails.metadata && Object.keys(selectedDetails.metadata).length > 0 && ( + + Metadata: +
{JSON.stringify(selectedDetails.metadata, null, 2)}
+
+ )} +
+
+ )} + {selectedDetails && selectedDetails.type === 'edge' && ( + + Edge: {selectedDetails.source} → {selectedDetails.target} + + Condition: {selectedDetails.label} + {selectedDetails.data && Object.keys(selectedDetails.data).length > 0 && ( + + Metadata: +
{JSON.stringify(selectedDetails.data, null, 2)}
+
+ )} +
+
+ )} + +
+
+
+ + {/* Bottom Controls */} + + + + + + + + +
+
+ ); +} + +export default App; \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json b/src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json new file mode 100644 index 0000000..43c1d6e --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json @@ -0,0 +1,327 @@ +{ + "nodes": [ + { + "name": "Start", + "function_name": null, + "docstring": null, + "node_type": "Start", + "source_location": null, + "metadata": {} + }, + { + "name": "End", + "function_name": null, + "docstring": null, + "node_type": "End", + "source_location": null, + "metadata": {} + }, + { + "name": "PlanningAgent", + "function_name": "Assistant", + "docstring": null, + "node_type": "Agent", + "source_location": null, + "metadata": {} + }, + { + "name": "WebSearchAgent", + "function_name": "Assistant", + "docstring": null, + "node_type": "Agent", + "source_location": null, + "metadata": {} + }, + { + "name": "WebSearchAgent_search_web_tool", + "function_name": "search_web_tool", + "docstring": null, + "node_type": "Tool", + "source_location": { + "file": "./examples/code/agent_chat/agent_chat2.py", + "line": 11, + "col": 0, + "end_line": 23, + "end_col": 27 + }, + "metadata": {} + }, + { + "name": "DataAnalystAgent", + "function_name": "Assistant", + "docstring": null, + "node_type": "Agent", + "source_location": null, + "metadata": {} + }, + { + "name": "DataAnalystAgent_percentage_change_tool", + "function_name": "percentage_change_tool", + "docstring": null, + "node_type": "Tool", + "source_location": { + "file": "./examples/code/agent_chat/agent_chat2.py", + "line": 26, + "col": 0, + "end_line": 27, + "end_col": 40 + }, + "metadata": {} + }, + { + "name": "Google_Search_Agent", + "function_name": "Assistant", + "docstring": null, + "node_type": "Agent", + "source_location": null, + "metadata": {} + }, + { + "name": "Google_Search_Agent_google_search", + "function_name": "google_search", + "docstring": null, + "node_type": "Tool", + "source_location": { + "file": "./examples/code/agent_chat/agent_chat.py", + "line": 10, + "col": 0, + "end_line": 61, + "end_col": 27 + }, + "metadata": {} + }, + { + "name": "Stock_Analysis_Agent", + "function_name": "Assistant", + "docstring": null, + "node_type": "Agent", + "source_location": null, + "metadata": {} + }, + { + "name": "Stock_Analysis_Agent_analyze_stock", + "function_name": "analyze_stock", + "docstring": null, + "node_type": "Tool", + "source_location": { + "file": "./examples/code/agent_chat/agent_chat.py", + "line": 64, + "col": 0, + "end_line": 155, + "end_col": 17 + }, + "metadata": {} + }, + { + "name": "Report_Agent", + "function_name": "Assistant", + "docstring": null, + "node_type": "Agent", + "source_location": null, + "metadata": {} + }, + { + "name": "team", + "function_name": null, + "docstring": null, + "node_type": "Team", + "source_location": null, + "metadata": { + "chat": "SelectorGroupChat" + } + } + ], + "edges": [ + { + "source": "Start", + "target": "PlanningAgent", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "PlanningAgent", + "target": "End", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Start", + "target": "WebSearchAgent", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "WebSearchAgent", + "target": "End", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "WebSearchAgent", + "target": "WebSearchAgent_search_web_tool", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Start", + "target": "DataAnalystAgent", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "DataAnalystAgent", + "target": "End", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "DataAnalystAgent", + "target": "DataAnalystAgent_percentage_change_tool", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Start", + "target": "Google_Search_Agent", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Google_Search_Agent", + "target": "End", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Google_Search_Agent", + "target": "Google_Search_Agent_google_search", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Start", + "target": "Stock_Analysis_Agent", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Stock_Analysis_Agent", + "target": "End", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Stock_Analysis_Agent", + "target": "Stock_Analysis_Agent_analyze_stock", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Start", + "target": "Report_Agent", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "Report_Agent", + "target": "End", + "condition": { + "type": "static" + }, + "metadata": {} + }, + { + "source": "team", + "target": "PlanningAgent", + "condition": { + "type": "member_of_team" + }, + "metadata": { + "chat": "SelectorGroupChat" + } + }, + { + "source": "team", + "target": "WebSearchAgent", + "condition": { + "type": "member_of_team" + }, + "metadata": { + "chat": "SelectorGroupChat" + } + }, + { + "source": "team", + "target": "DataAnalystAgent", + "condition": { + "type": "member_of_team" + }, + "metadata": { + "chat": "SelectorGroupChat" + } + }, + { + "source": "Stock_Analysis_Agent", + "target": "Google_Search_Agent", + "condition": { + "type": "group_sequence" + }, + "metadata": { + "chat": "RoundRobinGroupChat" + } + }, + { + "source": "Google_Search_Agent", + "target": "Report_Agent", + "condition": { + "type": "group_sequence" + }, + "metadata": { + "chat": "RoundRobinGroupChat" + } + }, + { + "source": "Report_Agent", + "target": "Stock_Analysis_Agent", + "condition": { + "type": "group_sequence" + }, + "metadata": { + "chat": "RoundRobinGroupChat" + } + } + ], + "metadata": { + "framework": "AgentChat" + } +} \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/Manrope-VariableFont_wght.ttf b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/Manrope-VariableFont_wght.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f39ca39c968c9d921b9c9e6e737ebdd2c1447a15 GIT binary patch literal 164936 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 M1-! literal 0 HcmV?d00001 diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/Planner.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/Planner.svg new file mode 100644 index 0000000..dcc62e1 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/Planner.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/agent.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/agent.svg new file mode 100644 index 0000000..227aa4f --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/agent.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/database.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/database.svg new file mode 100644 index 0000000..6e32786 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/database.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/end.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/end.svg new file mode 100644 index 0000000..1dc66fa --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/end.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/generic.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/generic.svg new file mode 100644 index 0000000..138a84d --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/generic.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/input.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/input.svg new file mode 100644 index 0000000..93c371e --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/input.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/mapper_bg.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/mapper_bg.svg new file mode 100644 index 0000000..350d7e8 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/mapper_bg.svg @@ -0,0 +1,4484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/memory.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/memory.svg new file mode 100644 index 0000000..0eda976 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/memory.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/output.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/output.svg new file mode 100644 index 0000000..69efb74 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/output.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/reflection.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/reflection.svg new file mode 100644 index 0000000..1b3a61d --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/reflection.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/search.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/search.svg new file mode 100644 index 0000000..cecded5 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/search.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/start.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/start.svg new file mode 100644 index 0000000..e90df5f --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/start.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/assets/tool.svg b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/tool.svg new file mode 100644 index 0000000..21f8bc5 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/assets/tool.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx new file mode 100644 index 0000000..ff32011 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx @@ -0,0 +1,37 @@ +import { memo } from 'react'; +import { Handle, Position } from 'react-flow-renderer'; + +export default memo(({ data }: any) => ( +
+ {data.nodeType} +
{data.label}
+
+ {data.functionName} +
+ + +
+)); \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx new file mode 100644 index 0000000..8cd87fb --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx @@ -0,0 +1,61 @@ +import graphData from './agent_graph.json'; + +type NodeType = 'agent' | 'tool' | 'orchestrator' | 'start' | 'end' | 'team'; + +const typeMeta: Record = { + agent: { icon: '/assets/agent.svg', color: '#B39DDB' }, + tool: { icon: '/assets/tool.svg', color: '#80CBC4' }, + orchestrator: { icon: '/assets/orchestrator.svg', color: '#FFB74D' }, + start: { icon: '/assets/start.svg', color: '#90CAF9' }, + end: { icon: '/assets/end.svg', color: '#90CAF9' }, + team: { icon: '/assets/team.svg', color: '#CE93D8' }, +}; + +function getTypeMeta(type: string) { + if (typeMeta.hasOwnProperty(type)) { + return typeMeta[type as NodeType]; + } + // fallback for unknown types + return { icon: '/assets/agent.svg', color: '#B39DDB' }; +} + +export function loadGraph() { + const nodes = graphData.nodes + .filter((n: any) => n.name) + .map((node: any, idx: number) => { + const typeKey = (node.node_type || '').toLowerCase(); + const meta = getTypeMeta(typeKey); + return { + id: node.name, + type: typeKey || 'agent', + data: { + label: node.name, + functionName: node.function_name, + docstring: node.docstring, + nodeType: node.node_type, + sourceLocation: node.source_location, + metadata: node.metadata, + icon: meta.icon, + color: meta.color, + }, + position: { x: 200 + idx * 180, y: 120 + (idx % 5) * 120 }, + }; + }); + + const edges = graphData.edges + .filter((e: any) => e.source && e.target) + .map((edge: any, idx: number) => ({ + id: `e${edge.source}-${edge.target}-${idx}`, + source: edge.source, + target: edge.target, + label: edge.condition?.type || '', + data: edge.metadata, + animated: edge.metadata?.alert ? true : false, + style: { + stroke: edge.metadata?.alert ? '#E57373' : '#1976d2', + strokeWidth: edge.metadata?.alert ? 3 : 2, + }, + })); + + return { nodes, edges, framework: graphData.metadata?.framework || 'unknown' }; +} \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/index.css b/src/repello_agent_wiz/visualizers/agent_ui/src/index.css new file mode 100644 index 0000000..08a3ac9 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/main.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/main.tsx new file mode 100644 index 0000000..bef5202 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.tsx' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx new file mode 100644 index 0000000..5c169fa --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx @@ -0,0 +1,48 @@ +const accentColors = { + agent: '#164EAF', // Repello blue + tool: '#FFB026', // Repello orange + orchestrator: '#A738D6', // Repello purple + default: '#EBEBEB' +}; + +export { accentColors }; + +// CustomNode.jsx +// import { Handle } from 'react-flow-renderer'; +// import agentIcon from './assets/agent.svg'; +// import toolIcon from './assets/tool.svg'; +// import orchestratorIcon from './assets/orchestrator.svg'; + +// const iconMap = { +// agent: agentIcon, +// tool: toolIcon, +// orchestrator: orchestratorIcon +// }; + +// export default function CustomNode({ data, type, selected }) { +// const color = accentColors[type] || accentColors.default; +// return ( +//
+// {type} +//
+//
{data.name}
+//
{data.node_type}
+// {data.function_name &&
{data.function_name}
} +//
+// +// +//
+// ); +// } \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.app.json b/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.app.json new file mode 100644 index 0000000..a9b5a59 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.app.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2022", + "useDefineForClassFields": true, + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.json b/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.node.json b/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.node.json new file mode 100644 index 0000000..8a67f62 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/tsconfig.node.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts b/src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts new file mode 100644 index 0000000..8b0f57b --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], +}) From 7313a4d046be07fbaddaf43dcfb4c99f4d5a18fe Mon Sep 17 00:00:00 2001 From: Neha Kumari Date: Fri, 17 Oct 2025 14:06:19 +0530 Subject: [PATCH 2/5] feat: replace d3 visualization with ReactFlow and HTTP server --- pyproject.toml | 1 + .../visualizers/agent_ui/README.md | 391 +++++++++++++++--- .../visualizers/agent_ui/index.html | 2 +- .../visualizers/agent_ui/package-lock.json | 320 ++++++++++++++ .../visualizers/agent_ui/package.json | 4 + .../visualizers/agent_ui/src/App.tsx | 373 ++++------------- .../visualizers/agent_ui/src/customNode.css | 63 +++ .../visualizers/agent_ui/src/customNode.tsx | 83 ++-- .../visualizers/agent_ui/src/graphLoader.tsx | 171 ++++++-- .../visualizers/agent_ui/vite.config.ts | 1 + .../visualizers/visualizer.py | 69 +++- 11 files changed, 1039 insertions(+), 439 deletions(-) create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css diff --git a/pyproject.toml b/pyproject.toml index 0595832..ac55eb2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,3 +38,4 @@ where = ["src"] [tool.setuptools.package-data] "repello_agent_wiz.analyzers" = ["*.txt"] "repello_agent_wiz.templates" = ["index.html", "assets/*"] +"repello_agent_wiz.visualizers" = ["agent_ui/dist/*", "agent_ui/dist/assets/*"] diff --git a/src/repello_agent_wiz/visualizers/agent_ui/README.md b/src/repello_agent_wiz/visualizers/agent_ui/README.md index d2e7761..6d34267 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/README.md +++ b/src/repello_agent_wiz/visualizers/agent_ui/README.md @@ -1,73 +1,344 @@ -# React + TypeScript + Vite +# Reactflow-based Agentic Workflow Visualization Migration Guide -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +## Summary of Changes -Currently, two official plugins are available: +This guide documents the migration from d3-based visualization to ReactFlow visualization for Agent-Wiz. -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh +## What Was Changed -## React Compiler +### 1. **graphLoader.tsx** - Dynamic JSON Loading +**File:** `src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx` -The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). +**Changes:** +- Added support for runtime JSON injection via `window.AGENT_GRAPH_DATA` +- Maintains backward compatibility with static JSON import as fallback +- The app now checks for runtime data first, then falls back to the bundled JSON -## Expanding the ESLint configuration +### 2. **visualizer.py** - React Build Integration +**File:** `src/repello_agent_wiz/visualizers/visualizer.py` -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: +**Changes:** +- Now copies React build files from `agent_ui/dist/` instead of d3 templates +- Injects graph JSON data as `window.AGENT_GRAPH_DATA` into the HTML +- Maintains the same CLI interface and behavior -```js -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... +**Key improvements:** +- Uses the same `{framework}_vis` output directory structure +- Injects data before the React app loads +- Opens in browser with `--open` flag just like before - // Remove tseslint.configs.recommended and replace with this - tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - tseslint.configs.stylisticTypeChecked, +### 3. **pyproject.toml** - Package Configuration +**File:** `pyproject.toml` - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) +**Changes:** +- Added React build files to package data: +```toml +"repello_agent_wiz.visualizers" = ["agent_ui/dist/*", "agent_ui/dist/assets/*"] ``` -You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x' -import reactDom from 'eslint-plugin-react-dom' - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) +This ensures the React build is included when the package is distributed. + +--- + +## How It Works + +### Current Flow (After Migration) + +1. **User runs CLI command:** + ```bash + agent-wiz visualize --input agentchat_graph.json --open + ``` + +2. **Python backend (`visualizer.py`):** + - Reads the graph JSON file + - Creates output directory: `{framework}_vis/` + - Copies React build files from `agent_ui/dist/` + - Injects graph data into HTML as `window.AGENT_GRAPH_DATA` + - Opens the HTML file in browser + +3. **React frontend (`agent_ui`):** + - Loads in browser + - Checks for `window.AGENT_GRAPH_DATA` (injected by Python) + - Renders the graph using ReactFlow + - Shows interactive visualization with search, details panel, etc. + +--- + +## Next Steps to Complete Integration + +### Step 1: Build the React App +You need to build the React app to generate the production-ready files in the `dist` folder: + +```bash +cd src/repello_agent_wiz/visualizers/agent_ui +npm install +npm run build +``` + +This will: +- Compile TypeScript to JavaScript +- Bundle all assets and dependencies +- Generate optimized production files in `dist/` +- Include the modified `graphLoader.tsx` with dynamic JSON support + +### Step 2: Test the Integration +After building, test that everything works: + +```bash +# Navigate back to project root by running the .venv and activating the python bin +cd Agent-Wiz/ +python -m venv .venv +source .venv/bin/activate + +# Test with an existing graph JSON +agent-wiz visualize --input agentchat_graph.json --open +``` + +This should: +- ✅ Create a directory called `agent_chat_vis/` (or based on framework name in JSON) +- ✅ Copy the React build files into it +- ✅ Inject the graph data +- ✅ Open the React-based visualization in the browser + +### Step 3: Verify the Visualization +When the browser opens, you should see: +- Interactive ReactFlow graph with the agent nodes +- Search functionality to find specific nodes +- Details panel showing node information when clicked +- MiniMap for navigation +- Theme toggle (dark/light mode) +- All the features from our React app + +### Step 4: Test with Different Frameworks +Test with other framework graphs to ensure compatibility: + +```bash +# Example with other graphs +agent-wiz visualize --input agentchat_graph.json --open +agent-wiz visualize --input examples/output/crewai_graph.json --open +agent-wiz visualize --input examples/output/langgraph_graph.json --open +``` + +--- + +## Troubleshooting + +### Issue: CORS Policy Blocking (Critical - Primary Issue Encountered) + +**Root Cause:** +Modern browsers (Chrome, Firefox, Safari, Edge) **block ES modules loaded via the `file://` protocol** for security reasons, even when using relative paths. This is a **security feature**, not a bug. The issue occurs because: + +1. **Line 8-9 in `dist/index.html`:** + ```html + + + ``` + The `type="module"` attribute triggers ES6 module loading, which requires CORS headers. + +2. **Browser Security Model:** + - When opening files with `file://` protocol, the origin is `null` + - Browsers don't send CORS headers for local file system requests + - ES modules require CORS headers to load, creating a deadlock + +3. **Why Relative Paths Don't Help:** + Even with `base: './'` in `vite.config.ts`, the paths are relative but still accessed via `file://` protocol, which lacks the HTTP infrastructure needed for module loading. + +**Technical Details:** +- **Affected Files:** All JavaScript bundles with `type="module"` attribute +- **Error Code:** `net::ERR_FAILED` +- **Origin:** `null` (file:// protocol has no origin) +- **Protocol Schemes Allowed:** `http`, `https`, `chrome-extension`, `data`, `isolated-app` +- **Vite Build System:** Generates ES modules by default, which require HTTP protocol + +**Resolution Implemented:** + +Modified `visualizer.py` (lines 53-87) to start an HTTP server when `--open` flag is used: + +```python +if open_browser: + # Start a simple HTTP server to avoid CORS issues with file:// protocol + port = 8765 + + class Handler(http.server.SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=str(output_dir.resolve()), **kwargs) + + def log_message(self, format, *args): + pass # Suppress server logs + + def start_server(): + with socketserver.TCPServer(("", port), Handler) as httpd: + httpd.serve_forever() + + # Start server in background thread + server_thread = threading.Thread(target=start_server, daemon=True) + server_thread.start() + + # Give server time to start + time.sleep(0.5) + + # Open browser + import webbrowser + url = f"http://localhost:{port}/index.html" + print(f"[✓] localhost started at {url}") + print(f"[i] Press Ctrl+C to exit \n") + webbrowser.open(url) + + # Keep the server running + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + print("\n[✓] Server stopped") ``` + +**Key Changes:** +1. **HTTP Server:** Uses Python's built-in `http.server.SimpleHTTPRequestHandler` + +**Result:** +- ✅ Files served via `http://localhost:8765` instead of `file://` +- ✅ CORS headers automatically provided by HTTP server +- ✅ ES modules load without security restrictions +- ✅ All assets (JS, CSS, SVG) load correctly +- ✅ No changes needed to React code or build configuration + +**Alternative Solutions (Not Implemented):** + +1. **Browser Flags (Not Recommended):** + ```bash + # Chrome with disabled security (INSECURE - DO NOT USE IN PRODUCTION) + chrome --disable-web-security --user-data-dir=/tmp/chrome + ``` + ❌ Security risk, requires user to modify browser settings + +2. **Build to Non-Module Script (Not Ideal):** + ```js + // vite.config.ts + build: { target: 'es2015', rollupOptions: { output: { format: 'iife' } } } + ``` + ❌ Loses module benefits, larger bundle size, compatibility issues + +3. **Inline All Assets (Impractical):** + ❌ Huge HTML files, poor performance, maintenance nightmare + +**Best Practice:** +Always serve modern web applications via HTTP/HTTPS. The implemented solution is industry-standard and aligns with how Vite, Create React App, and other modern tools handle local development and preview. + +--- + +### Issue: "React build not found" +**Solution:** Make sure you've run `npm run build` in the `agent_ui` directory. + +### Issue: "Graph not loading / showing empty" +**Solution:** +1. Check the browser console for errors +2. Verify the JSON structure matches expected format +3. Ensure `window.AGENT_GRAPH_DATA` is injected (view page source) + +### Issue: "Assets not loading (icons, styles)" +**Solution:** +1. Check that all files from `dist/` were copied +2. Verify the `assets/` folder is included in the output directory +3. Check the vite config for base path settings + +### Issue: "Package installation fails" +**Solution:** +If distributing as a Python package, ensure: +1. React build is up to date +2. `pyproject.toml` includes all necessary files +3. Run `pip install -e .` to reinstall in development mode + +--- + +## Development Workflow + +### For Python Changes +1. Modify `visualizer.py` +2. Test with: `agent-wiz visualize --input test.json --open` + +### For React Changes +1. Modify files in `agent_ui/src/` +2. Test locally: `cd agent_ui && npm run dev` +3. Build for production: `npm run build` +4. Test integration: `agent-wiz visualize --input test.json --open` + +--- + +## Dagre Layout Algorithm Integration + +### Overview + +The visualization system uses **Dagre** (Directed Acyclic Graph Rendering Engine) to automatically compute optimal node positions in the graph. This ensures clean, organized layouts without manual positioning. + +**File:** `src/graphLoader.tsx` (lines 47-70) + +### What is Dagre? + +Dagre is a JavaScript library that implements a **hierarchical graph layout algorithm**. It: +- Positions nodes to minimize edge crossings +- Arranges nodes in ranks (layers) based on their relationships +- Computes edge routing to avoid overlaps +- Supports customizable spacing and orientation + +**Key Concepts:** +- **Rank:** Vertical or horizontal layer where nodes are placed +- **Node Separation:** Minimum horizontal spacing between nodes in same rank +- **Rank Separation:** Minimum vertical spacing between ranks +- **Direction:** Graph orientation (LR = Left-to-Right, TB = Top-to-Bottom, etc.) + +--- + +## File Structure After Migration + +``` +Agent-Wiz/ +├── src/repello_agent_wiz/ +│ ├── visualizers/ +│ │ ├── agent_ui/ # React app source +│ │ │ ├── src/ # React components +│ │ │ │ ├── App.tsx +│ │ │ │ ├── graphLoader.tsx # Modified for dynamic loading +│ │ │ │ └── ... +│ │ │ ├── dist/ # Build output (used by Python) +│ │ │ │ ├── index.html +│ │ │ │ ├── assets/ +│ │ │ │ └── ... +│ │ │ ├── package.json +│ │ │ └── vite.config.ts +│ │ └── visualizer.py # Modified to use React build +│ └── cli.py # Unchanged (calls visualizer.py) +├── pyproject.toml # Modified to include React build +``` + +--- + +## Output Directory Structure + +When running `agent-wiz visualize --input agentchat_graph.json --open`, it creates: + +``` +agent_chat_vis/ +├── index.html # React app entry point with injected data +├── assets/ # Bundled JS, CSS, and other assets +│ ├── index-*.js # React app bundle +│ ├── index-*.css # Styles +│ └── ... +└── agent.svg # App icon +``` + +This directory is standalone and can be: +- Opened directly in any browser +- Hosted on a http server +- Shared with others +- Archived for later reference + +--- + +## Benefits of This Approach + +✅ **Modern UI:** ReactFlow provides a much better interactive experience than d3 +✅ **Maintainability:** React components are easier to maintain and extend +✅ **Backward Compatible:** Same CLI interface, no breaking changes for users +✅ **Dynamic Loading:** Can visualize any graph JSON without rebuilding +✅ **Professional Features:** Search, zoom, pan, details panel, theming, etc. +✅ **Fast Development:** Vite provides hot reload during development diff --git a/src/repello_agent_wiz/visualizers/agent_ui/index.html b/src/repello_agent_wiz/visualizers/agent_ui/index.html index 8bdeca8..6420e66 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/index.html +++ b/src/repello_agent_wiz/visualizers/agent_ui/index.html @@ -4,7 +4,7 @@ - Agent Wizard + Agent Workflow Visualization
diff --git a/src/repello_agent_wiz/visualizers/agent_ui/package-lock.json b/src/repello_agent_wiz/visualizers/agent_ui/package-lock.json index 8e77e4f..2aaf9f5 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/package-lock.json +++ b/src/repello_agent_wiz/visualizers/agent_ui/package-lock.json @@ -10,7 +10,10 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.4", "@mui/material": "^7.3.4", + "axios": "^1.12.2", + "dagre": "^0.8.5", "react": "^18.3.1", "react-dom": "^18.3.1", "react-flow-renderer": "^10.3.17", @@ -18,6 +21,7 @@ }, "devDependencies": { "@eslint/js": "^9.36.0", + "@types/dagre": "^0.7.53", "@types/node": "^24.6.0", "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", @@ -1172,6 +1176,32 @@ "url": "https://opencollective.com/mui-org" } }, + "node_modules/@mui/icons-material": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.4.tgz", + "integrity": "sha512-9n6Xcq7molXWYb680N2Qx+FRW8oT6j/LXF5PZFH3ph9X/Rct0B/BlLAsFI7iL9ySI6LVLuQIVtrLiPT82R7OZw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.28.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^7.3.4", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.4.tgz", @@ -2300,6 +2330,13 @@ "@types/d3-selection": "*" } }, + "node_modules/@types/dagre": { + "version": "0.7.53", + "resolved": "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.53.tgz", + "integrity": "sha512-f4gkWqzPZvYmKhOsDnhq/R8mO4UMcKdxZo+i5SCkOU1wvGeHJeUXGIHeE9pnwGyPMDof1Vx5ZQo4nxpeg2TTVQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -2731,6 +2768,23 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -2821,6 +2875,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2903,6 +2970,18 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3067,6 +3146,16 @@ "node": ">=12" } }, + "node_modules/dagre": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz", + "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==", + "license": "MIT", + "dependencies": { + "graphlib": "^2.1.8", + "lodash": "^4.17.15" + } + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -3091,6 +3180,15 @@ "dev": true, "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/dom-helpers": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", @@ -3101,6 +3199,20 @@ "csstype": "^3.0.2" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.234", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz", @@ -3117,6 +3229,51 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.10", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz", @@ -3490,6 +3647,42 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -3524,6 +3717,43 @@ "node": ">=6.9.0" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3550,6 +3780,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3557,6 +3799,15 @@ "dev": true, "license": "MIT" }, + "node_modules/graphlib": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", + "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3567,6 +3818,33 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", @@ -3808,6 +4086,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -3837,6 +4121,15 @@ "yallist": "^3.0.2" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3861,6 +4154,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4112,6 +4426,12 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/src/repello_agent_wiz/visualizers/agent_ui/package.json b/src/repello_agent_wiz/visualizers/agent_ui/package.json index d9040ce..f35a3cd 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/package.json +++ b/src/repello_agent_wiz/visualizers/agent_ui/package.json @@ -12,7 +12,10 @@ "dependencies": { "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.3.4", "@mui/material": "^7.3.4", + "axios": "^1.12.2", + "dagre": "^0.8.5", "react": "^18.3.1", "react-dom": "^18.3.1", "react-flow-renderer": "^10.3.17", @@ -20,6 +23,7 @@ }, "devDependencies": { "@eslint/js": "^9.36.0", + "@types/dagre": "^0.7.53", "@types/node": "^24.6.0", "@types/react": "^19.1.16", "@types/react-dom": "^19.1.9", diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx index 522338a..ea189ee 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx @@ -1,255 +1,54 @@ -// import { useState, useRef } from 'react'; -// import { Box, AppBar, Toolbar, Typography, Switch, Drawer, Card, List, ListItem, ButtonGroup, Button, Snackbar, TextField, InputAdornment } from '@mui/material'; -// import ReactFlow, { MiniMap, Controls, Background, ReactFlowProvider, useReactFlow } from 'react-flow-renderer'; -// import { loadGraph } from './graphLoader'; -// import CustomNode from './CustomNode'; -// import SearchIcon from './assets/search.svg'; -// import AgentIcon from './assets/agent.svg'; -// import ToolIcon from './assets/tool.svg'; -// import OrchestratorIcon from './assets/Planner.svg'; -// import StartIcon from './assets/start.svg'; -// import TeamIcon from './assets/generic.svg'; - -// // Node types mapping -// const nodeTypes = { customNode: CustomNode }; -// const { nodes: initialNodes, edges: initialEdges, framework } = loadGraph(); - -// function App() { -// const [themeDark, setThemeDark] = useState(false); -// const [drawerOpen, setDrawerOpen] = useState(false); -// const [selectedDetails, setSelectedDetails] = useState(null); -// const [snackbarOpen, setSnackbarOpen] = useState(false); -// const [search, setSearch] = useState(''); -// const [highlighted, setHighlighted] = useState(null); -// const reactFlowWrapper = useRef(null); - -// const {zoomTo, getZoom} = useReactFlow(); - - -// // Handlers -// const handleNodeClick = (_event: any, node: any) => { -// setSelectedDetails({ type: 'node', ...node.data }); -// setDrawerOpen(true); -// setHighlighted(node.id); -// }; -// const handleEdgeClick = (_event: any, edge: any) => { -// setSelectedDetails({ type: 'edge', ...edge }); -// setDrawerOpen(true); -// }; -// const handleCloseDrawer = () => { -// setDrawerOpen(false); -// setSelectedDetails(null); -// setHighlighted(null); -// }; -// const handleThemeToggle = () => setThemeDark((prev) => !prev); -// const handleSnackbarClose = () => setSnackbarOpen(false); - -// // Search logic -// const handleSearch = (e: any) => { -// setSearch(e.target.value); -// const found = initialNodes.find(n => n.id.toLowerCase().includes(e.target.value.toLowerCase())); -// setHighlighted(found ? found.id : null); -// // Zoom to node if found -// if (found) { -// zoomTo(found.id); -// } -// }; - -// // Custom node style for highlight -// const getNodeStyle = (id: string, color: string) => ({ -// border: highlighted === id ? '3px solid #E57373' : '2px solid #fff', -// boxShadow: highlighted === id ? '0 0 16px #E57373' : '0 2px 8px rgba(80,80,120,0.08)', -// background: color, -// borderRadius: 16, -// }); - -// return ( -// <> -// -// -// {/* Header */} -// -// -// Agent-Wiz Visualization ({framework}) -// -// -// -// - -// {/* Search Bar */} -// -// -// Search -// -// ), -// }} -// sx={{ width: 260 }} -// /> -// - -// {/* Main Content */} -// -// {/* Sidebar */} -// -// -// -// Agent Agent -// Tool Tool -// Orchestrator Orchestrator -// Start Start/End -// Team Team -// -// -// - -// {/* React Flow Canvas */} -// -// ({ -// ...n, -// style: getNodeStyle(n.id, n.data.color), -// }))} -// edges={initialEdges} -// nodeTypes={nodeTypes} -// fitView -// style={{ width: '100%', height: '100%' }} -// onNodeClick={handleNodeClick} -// onEdgeClick={handleEdgeClick} -// minZoom={0.3} -// maxZoom={2} -// snapToGrid -// snapGrid={[24, 24]} -// > -// n.data.color} /> -// -// -// -// - -// {/* Details Drawer */} -// -// -// Details -// {selectedDetails && selectedDetails.type === 'node' && ( -// -// {selectedDetails.label} -// -// Type: {selectedDetails.nodeType} -// {selectedDetails.functionName && Function: {selectedDetails.functionName}} -// {selectedDetails.docstring && Docstring: {selectedDetails.docstring}} -// {selectedDetails.sourceLocation && ( -// -// Source: {selectedDetails.sourceLocation.file} (Line {selectedDetails.sourceLocation.line}) -// -// )} -// {selectedDetails.metadata && Object.keys(selectedDetails.metadata).length > 0 && ( -// -// Metadata: -//
{JSON.stringify(selectedDetails.metadata, null, 2)}
-//
-// )} -//
-//
-// )} -// {selectedDetails && selectedDetails.type === 'edge' && ( -// -// Edge: {selectedDetails.source} → {selectedDetails.target} -// -// Condition: {selectedDetails.label} -// {selectedDetails.data && Object.keys(selectedDetails.data).length > 0 && ( -// -// Metadata: -//
{JSON.stringify(selectedDetails.data, null, 2)}
-//
-// )} -//
-//
-// )} -// -//
-//
-//
- -// {/* Bottom Controls */} -// -// -// -// -// -// -// -// -//
-//
-// -// ); -// } - -// export default App; - -import { useState, useRef } from 'react'; +import { useState, useCallback } from 'react'; import { Box, AppBar, Toolbar, Typography, Switch, Drawer, Card, List, ListItem, ButtonGroup, Button, Snackbar, TextField, InputAdornment } from '@mui/material'; -import ReactFlow, { MiniMap, Controls, Background, ReactFlowProvider } from 'react-flow-renderer'; +import ReactFlow, { MiniMap, Controls, Background, ReactFlowProvider, useReactFlow} from 'reactflow'; +import type {Node, Edge} from 'reactflow'; import { loadGraph } from './graphLoader'; -import CustomNode from './CustomNode'; import SearchIcon from './assets/search.svg'; import AgentIcon from './assets/agent.svg'; import ToolIcon from './assets/tool.svg'; import OrchestratorIcon from './assets/Planner.svg'; import StartIcon from './assets/start.svg'; import TeamIcon from './assets/generic.svg'; -import { useReactFlow } from 'reactflow'; -import type { Node, Edge } from 'react-flow-renderer'; - -type FlowCanvasProps = { - nodes: Node[]; - edges: Edge[]; - highlighted: string | null; - setHighlighted: React.Dispatch>; - handleNodeClick: (event: React.MouseEvent, node: Node) => void; - handleEdgeClick: (event: React.MouseEvent, edge: Edge) => void; -}; +import CustomNode from './customNode'; +import 'reactflow/dist/style.css'; const nodeTypes = { customNode: CustomNode }; const { nodes: initialNodes, edges: initialEdges, framework } = loadGraph(); -function FlowCanvas({ - nodes, - edges, - highlighted, - setHighlighted, - handleNodeClick, - handleEdgeClick, -}: FlowCanvasProps) { - const { zoomTo } = useReactFlow(); - - // Search logic inside context +function FlowCanvas({ nodes, edges, highlighted, onNodeClick, onEdgeClick }: { + nodes: Node[]; edges: Edge[]; highlighted: string | null; + onNodeClick: (e: any, node: any) => void; onEdgeClick: (e: any, edge: any) => void; +}) { const [search, setSearch] = useState(''); + const { setCenter, fitView } = useReactFlow(); + const handleSearch = (e: any) => { - setSearch(e.target.value); - const found = nodes.find((n: any) => n.id.toLowerCase().includes(e.target.value.toLowerCase())); - setHighlighted(found ? found.id : null); - if (found) zoomTo(Number(found.id)); + const q = e.target.value || ''; + setSearch(q); + + if (!q) { + // show all nodes by fitting view + fitView({ padding: 0.12 }); + return; + } + + const found = nodes.find((n: any) => n.data?.label?.toLowerCase().includes(q.toLowerCase()) || n.id.toLowerCase().includes(q.toLowerCase())); + if (found) { + // center and zoom to the node + setCenter(found.position.x + (found.width || 0) / 2, found.position.y + (found.height || 0) / 2, { zoom: 1.3, duration: 400 }); + } }; const getNodeStyle = (id: string, color: string) => ({ - border: highlighted === id ? '3px solid #E57373' : '2px solid #fff', - boxShadow: highlighted === id ? '0 0 16px #E57373' : '0 2px 8px rgba(80,80,120,0.08)', - background: color, - borderRadius: 16, + border: highlighted === id ? '3px solid rgba(229,87,87,0.95)' : '2px solid rgba(255,255,255,0.06)', + boxShadow: highlighted === id ? '0 8px 30px rgba(229,87,87,0.12)' : '0 2px 12px rgba(80,80,120,0.06)', + background: color || 'linear-gradient(180deg, #fff, #f7f7fb)', + borderRadius: 12, + padding: 6, }); return ( <> - {/* Search Bar */} - Search + Search ), }} - sx={{ width: 260 }} + sx={{ width: 320, maxWidth: '40vw' }} /> + + ({ - ...n, - style: getNodeStyle(n.id, n.data.color), - }))} + nodes={nodes.map(n => ({ ...n, style: getNodeStyle(n.id, n.data?.color) }))} edges={edges} nodeTypes={nodeTypes} fitView style={{ width: '100%', height: '100%' }} - onNodeClick={handleNodeClick} - onEdgeClick={handleEdgeClick} - minZoom={0.3} - maxZoom={2} + onNodeClick={onNodeClick} + onEdgeClick={onEdgeClick} + minZoom={0.2} + maxZoom={2.2} snapToGrid snapGrid={[24, 24]} > - n.data.color} /> + (n.data?.color || '#777')} zoomable /> @@ -291,115 +89,116 @@ function FlowCanvas({ ); } -function App() { +export default function App() { const [themeDark, setThemeDark] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false); const [selectedDetails, setSelectedDetails] = useState(null); const [snackbarOpen, setSnackbarOpen] = useState(false); const [highlighted, setHighlighted] = useState(null); - // Handlers - const handleNodeClick = (_event: any, node: any) => { - setSelectedDetails({ type: 'node', ...node.data }); + const handleNodeClick = useCallback((_e: any, node: any) => { + setSelectedDetails({ type: 'node', ...node.data, id: node.id, position: node.position }); setDrawerOpen(true); setHighlighted(node.id); - }; - const handleEdgeClick = (_event: any, edge: any) => { + }, []); + + const handleEdgeClick = useCallback((_e: any, edge: any) => { setSelectedDetails({ type: 'edge', ...edge }); setDrawerOpen(true); - }; - const handleCloseDrawer = () => { - setDrawerOpen(false); - setSelectedDetails(null); - setHighlighted(null); - }; - const handleThemeToggle = () => setThemeDark((prev) => !prev); + }, []); + + const handleCloseDrawer = () => { setDrawerOpen(false); setSelectedDetails(null); setHighlighted(null); }; + const handleThemeToggle = () => setThemeDark((p) => !p); const handleSnackbarClose = () => setSnackbarOpen(false); return ( - - {/* Header */} + - Agent-Wiz Visualization ({framework}) - + Agent-Workflow ({framework}) + + {themeDark ? 'Dark' : 'Light'} - {/* Main Content */} - {/* Sidebar */} - - + + + Agent + Agent + + - Agent Agent - Tool Tool - Orchestrator Orchestrator - Start Start/End - Team Team + Tool Tool + Orchestrator Orchestrator + Start Start/End + Team Team + + + + + + + - {/* React Flow Canvas & Search */} - {/* Details Drawer */} - - + + Details {selectedDetails && selectedDetails.type === 'node' && ( - {selectedDetails.label} + {selectedDetails.label || selectedDetails.id} Type: {selectedDetails.nodeType} {selectedDetails.functionName && Function: {selectedDetails.functionName}} {selectedDetails.docstring && Docstring: {selectedDetails.docstring}} {selectedDetails.sourceLocation && ( - - Source: {selectedDetails.sourceLocation.file} (Line {selectedDetails.sourceLocation.line}) - + Source: {selectedDetails.sourceLocation.file} (Line {selectedDetails.sourceLocation.line}) )} - {selectedDetails.metadata && Object.keys(selectedDetails.metadata).length > 0 && ( + {selectedDetails.metadata && Object.keys(selectedDetails.metadata || {}).length > 0 && ( Metadata: -
{JSON.stringify(selectedDetails.metadata, null, 2)}
+
{JSON.stringify(selectedDetails.metadata, null, 2)}
)}
)} + {selectedDetails && selectedDetails.type === 'edge' && ( Edge: {selectedDetails.source} → {selectedDetails.target} - Condition: {selectedDetails.label} - {selectedDetails.data && Object.keys(selectedDetails.data).length > 0 && ( + Condition: {selectedDetails.condition?.type} + {selectedDetails.metadata && Object.keys(selectedDetails.metadata || {}).length > 0 && ( Metadata: -
{JSON.stringify(selectedDetails.data, null, 2)}
+
{JSON.stringify(selectedDetails.metadata, null, 2)}
)}
)} +
- {/* Bottom Controls */} @@ -411,6 +210,4 @@ function App() {
); -} - -export default App; \ No newline at end of file +} \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css new file mode 100644 index 0000000..9da6164 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css @@ -0,0 +1,63 @@ +.aw-node { + display: flex; + gap: 10px; + align-items: center; + padding: 10px; + border-radius: 12px; + box-shadow: 0 8px 30px rgba(18, 26, 47, 0.06); + transition: transform 160ms ease, box-shadow 160ms ease, opacity 160ms ease; + min-width: 120px; + max-width: 480px; + background: rgba(255,255,255,0.98); + border: 1px solid rgba(16,24,40,0.04); + box-sizing: border-box; + } + + + .aw-node--agent { border-left: 6px solid #b39ddb; background: linear-gradient(180deg,#fff,#fbf8ff); } + .aw-node--tool { border-left: 6px solid #00BFA6; background: linear-gradient(180deg,#fff,#f7fffc); } + .aw-node--orchestrator { border-left: 6px solid #FFB300; background: linear-gradient(180deg,#fff,#fffaf3); } + .aw-node--start, .aw-node--end { + border-radius: 999px; + padding: 12px 14px; + justify-content: center; + min-width: 64px; + max-width: 160px; + background: linear-gradient(180deg,#fff,#f3f7ff); + border-left: none; + border: 2px solid rgba(25,118,210,0.12); + } + .aw-node--team { + border-left: 6px solid #7C4DFF; + background: linear-gradient(180deg,#fff,#f6f3ff); + padding: 12px; + } + + /* dim state */ + .aw-node--dim { opacity: 0.36; filter: grayscale(0.02); transform: scale(0.99); } + + /* left icon */ + .aw-node__left { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; } + .aw-node__icon { width: 36px; height: 36px; object-fit: contain; } + + /* body expands */ + .aw-node__body { flex: 1 1 auto; min-width: 120px; overflow: hidden; } + .aw-node__title { font-weight: 700; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } + .aw-node__subtitle { font-size: 11px; color: rgba(12,12,12,0.7); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } + .aw-node__doc { font-size: 11px; color: rgba(35,35,35,0.6); margin-top: 6px; max-height: 3.4em; overflow: hidden; } + + /* handles */ + .aw-handle { width: 10px !important; height: 10px !important; border-radius: 3px; background: #1976d2; } + + /* top/bottom offsets */ + .aw-handle--top { top: -6px !important; } + .aw-handle--bottom { bottom: -6px !important; } + + .aw-node:hover { transform: translateY(-4px); box-shadow: 0 12px 36px rgba(18,26,47,0.12) } + + @media (max-width: 700px) { + .aw-node { gap: 8px; padding: 8px; } + .aw-node__icon { width: 30px; height: 30px; } + .aw-node__title { font-size: 12px; } + } + \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx index ff32011..a55dec0 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx @@ -1,37 +1,50 @@ import { memo } from 'react'; -import { Handle, Position } from 'react-flow-renderer'; +import { Handle, Position } from 'reactflow'; +import type { NodeProps } from 'reactflow'; +import Box from '@mui/material/Box'; +import Typography from '@mui/material/Typography'; +import './customNode.css'; -export default memo(({ data }: any) => ( -
- {data.nodeType} -
{data.label}
-
- {data.functionName} -
- - -
-)); \ No newline at end of file +type Data = { + label?: string; + functionName?: string | null; + docstring?: string | null; + icon?: string; + color?: string; + nodeType?: string | null; + dimmed?: boolean; +}; + +export default memo(function CustomNode({ data }: NodeProps) { + const color = data.color ?? '#B39DDB'; + const dim = !!data.dimmed; + const type = (data.nodeType || '').toLowerCase(); + + // style classes by type to allow distinct shapes + const classes = ['aw-node', `aw-node--${type || 'agent'}`, dim ? 'aw-node--dim' : ''].join(' ').trim(); + + return ( + +
+ {data.label} +
+ +
+ {data.label} + {data.functionName && {data.functionName}} + {data.docstring && {data.docstring.slice(0, 140)}{data.docstring.length > 140 ? '…' : ''}} +
+ + {/* connector handles: top + bottom for simplicity */} + + +
+ ); +}); \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx index 8cd87fb..6048817 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx @@ -1,61 +1,144 @@ -import graphData from './agent_graph.json'; +import dagre from 'dagre'; +import agentIcon from './assets/agent.svg'; +import toolIcon from './assets/tool.svg'; +import plannerIcon from './assets/Planner.svg'; +import startIcon from './assets/start.svg'; +import endIcon from './assets/end.svg'; +import genericIcon from './assets/generic.svg'; + +// Support runtime injection via window.AGENT_GRAPH_DATA +declare global { + interface Window { + AGENT_GRAPH_DATA?: any; + } +} + +import fallbackData from './agent_graph.json'; +const raw = window.AGENT_GRAPH_DATA || fallbackData; + +export type RFNode = any; +export type RFEdge = any; type NodeType = 'agent' | 'tool' | 'orchestrator' | 'start' | 'end' | 'team'; +const repelloPalette = { + purple: '#7C4DFF', + teal: '#00BFA6', + amber: '#FFB300', + blue: '#1976D2', + softPurple: '#B39DDB', +}; + const typeMeta: Record = { - agent: { icon: '/assets/agent.svg', color: '#B39DDB' }, - tool: { icon: '/assets/tool.svg', color: '#80CBC4' }, - orchestrator: { icon: '/assets/orchestrator.svg', color: '#FFB74D' }, - start: { icon: '/assets/start.svg', color: '#90CAF9' }, - end: { icon: '/assets/end.svg', color: '#90CAF9' }, - team: { icon: '/assets/team.svg', color: '#CE93D8' }, + agent: { icon: agentIcon, color: repelloPalette.softPurple }, + tool: { icon: toolIcon, color: repelloPalette.teal }, + orchestrator: { icon: plannerIcon, color: repelloPalette.amber }, + start: { icon: startIcon, color: repelloPalette.blue }, + end: { icon: endIcon, color: repelloPalette.blue }, + team: { icon: genericIcon, color: repelloPalette.purple }, }; -function getTypeMeta(type: string) { - if (typeMeta.hasOwnProperty(type)) { - return typeMeta[type as NodeType]; +function lookup(type?: string) { + if (!type) return typeMeta.agent; + const key = type.toLowerCase(); + if ((Object.keys(typeMeta) as string[]).includes(key)) { + return typeMeta[key as NodeType]; } - // fallback for unknown types - return { icon: '/assets/agent.svg', color: '#B39DDB' }; + return typeMeta.agent; +} + +/** + * Using dagre to compute node positions for a neat system diagram. + * - graph: raw agent-graph JSON + * - opts: tuning for spacing + */ +function dagreLayout(nodes: RFNode[], edges: RFEdge[], opts = { rankdir: 'LR', nodeSep: 220, rankSep: 120 }) { + const g = new dagre.graphlib.Graph(); + g.setGraph({ rankdir: opts.rankdir, nodesep: opts.nodeSep, ranksep: opts.rankSep }); + g.setDefaultEdgeLabel(() => ({})); + + // Use approximate node sizes (React Flow will respect actual sizes but this is enough) + nodes.forEach((n) => g.setNode(n.id, { width: n.data.width ?? 220, height: n.data.height ?? 80 })); + edges.forEach((e) => g.setEdge(e.source, e.target)); + + dagre.layout(g); + + const positionedNodes = nodes.map((n) => { + const nd = g.node(n.id); + return { + ...n, + position: { + x: nd.x - (n.data.width ?? 220) / 2, + y: nd.y - (n.data.height ?? 80) / 2, + }, + }; + }); + + return { nodes: positionedNodes, edges }; } export function loadGraph() { - const nodes = graphData.nodes - .filter((n: any) => n.name) - .map((node: any, idx: number) => { - const typeKey = (node.node_type || '').toLowerCase(); - const meta = getTypeMeta(typeKey); + const graphData: any = raw || { nodes: [], edges: [], metadata: {} }; + + // Normalize nodes + const nodes: RFNode[] = + (graphData.nodes || []).map((node: any, i: number) => { + const nt = (node.node_type || node.nodeType || 'agent').toString(); + const meta = lookup(nt); + const nodeLabel = node.name ?? node.label ?? `node-${i}`; + + // smaller tool boxes visually subordinate to agents + const baseSize = nt.toLowerCase() === 'tool' ? { width: 160, height: 64 } : nt.toLowerCase().includes('start') || nt.toLowerCase().includes('end') ? { width: 80, height: 80 } : { width: 220, height: 92 }; + return { - id: node.name, - type: typeKey || 'agent', + id: nodeLabel, + type: 'customNode', data: { - label: node.name, - functionName: node.function_name, - docstring: node.docstring, - nodeType: node.node_type, - sourceLocation: node.source_location, - metadata: node.metadata, + label: nodeLabel, + functionName: node.function_name || null, + docstring: node.docstring || null, + nodeType: nt, + sourceLocation: node.source_location || null, + metadata: node.metadata || {}, icon: meta.icon, color: meta.color, }, - position: { x: 200 + idx * 180, y: 120 + (idx % 5) * 120 }, + selectable: true, + draggable: true, + // initial placeholder — replaced by dagre layout below + position: { x: 0 + (i % 4) * 200, y: 80 + Math.floor(i / 4) * 140 }, + ...baseSize, }; - }); - - const edges = graphData.edges - .filter((e: any) => e.source && e.target) - .map((edge: any, idx: number) => ({ - id: `e${edge.source}-${edge.target}-${idx}`, - source: edge.source, - target: edge.target, - label: edge.condition?.type || '', - data: edge.metadata, - animated: edge.metadata?.alert ? true : false, - style: { - stroke: edge.metadata?.alert ? '#E57373' : '#1976d2', - strokeWidth: edge.metadata?.alert ? 3 : 2, - }, - })); + }) || []; + + // Normalize edges + const edges: RFEdge[] = + (graphData.edges || []).map((edge: any, idx: number) => { + const cond = edge.condition?.type || 'static'; + const styleColor = cond === 'member_of_team' ? repelloPalette.purple : cond === 'group_sequence' ? repelloPalette.amber : '#2f4f8f'; + const animated = cond === 'async' || false; + const isDashed = cond === 'group_sequence'; - return { nodes, edges, framework: graphData.metadata?.framework || 'unknown' }; -} \ No newline at end of file + return { + id: edge.id || `e-${edge.source}-${edge.target}-${idx}`, + source: edge.source, + target: edge.target, + label: cond !== 'static' ? cond : undefined, + animated, + type: 'smoothstep', // curved edges to reduce overlaps + style: { stroke: styleColor, strokeWidth: isDashed ? 2 : 2.4, strokeDasharray: isDashed ? '6 4' : undefined }, + markerEnd: { + type: 'arrowclosed', + }, + data: edge.metadata || {}, + }; + }) || []; + + // semantic grouping pre-processing + // placing Start nodes left and End nodes right by tagging rank + // dagre will honor general spacing with rankdir LR by default + + const { nodes: positionedNodes, edges: positionedEdges } = dagreLayout(nodes, edges, { rankdir: 'LR', nodeSep: 240, rankSep: 140 }); + + return { nodes: positionedNodes, edges: positionedEdges, framework: graphData.metadata?.framework || 'unknown' }; +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts b/src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts index 8b0f57b..ae3c8d8 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts +++ b/src/repello_agent_wiz/visualizers/agent_ui/vite.config.ts @@ -4,4 +4,5 @@ import react from '@vitejs/plugin-react' // https://vite.dev/config/ export default defineConfig({ plugins: [react()], + base: './', // Use relative paths for file:// protocol compatibility }) diff --git a/src/repello_agent_wiz/visualizers/visualizer.py b/src/repello_agent_wiz/visualizers/visualizer.py index c3c3dd5..40f27e2 100644 --- a/src/repello_agent_wiz/visualizers/visualizer.py +++ b/src/repello_agent_wiz/visualizers/visualizer.py @@ -2,10 +2,14 @@ import json import importlib.resources as pkg_resources from pathlib import Path +import http.server +import socketserver +import threading +import time def generate_visualization(json_path: str, open_browser: bool = False): - import repello_agent_wiz.templates + import repello_agent_wiz.visualizers # Read framework name from JSON with open(json_path, "r") as f: @@ -15,24 +19,67 @@ def generate_visualization(json_path: str, open_browser: bool = False): output_dir = Path(f"{framework}_vis") output_dir.mkdir(exist_ok=True) - # Copy assets - assets_path = pkg_resources.files(repello_agent_wiz.templates).joinpath("assets") - target_assets_path = output_dir / "assets" - shutil.copytree(assets_path, target_assets_path, dirs_exist_ok=True) + # Copy the React build (dist folder contents) from agent_ui + dist_path = pkg_resources.files(repello_agent_wiz.visualizers).joinpath("agent_ui/dist") + + # Copy all files and folders from dist to output_dir + for item in ["index.html", "assets", "agent.svg"]: + src = dist_path.joinpath(item) + dest = output_dir / item + + if src.is_file(): + shutil.copy2(src, dest) + elif src.is_dir(): + if dest.exists(): + shutil.rmtree(dest) + shutil.copytree(src, dest) - # Copy index.html and inject graph JSON - index_template = pkg_resources.files(repello_agent_wiz.templates).joinpath("index.html") - index_text = index_template.read_text(encoding="utf-8") + # Read the index.html and inject the graph data + index_path = output_dir / "index.html" + index_text = index_path.read_text(encoding="utf-8") + # Inject graph data as a global variable before the main script json_string = json.dumps(graph, indent=2) - index_filled = index_text.replace("const data = {};", f"const data = {json_string};") + data_script = f'' + + # Insert the data script before the closing tag + index_filled = index_text.replace('', f'{data_script}\n ') - with open(output_dir / "index.html", "w") as f: + with open(index_path, "w", encoding="utf-8") as f: f.write(index_filled) print(f"[✓] Visualization HTML generated at: {output_dir}/index.html") if open_browser: + # Start a simple HTTP server to avoid CORS issues with file:// protocol + port = 8765 + + class Handler(http.server.SimpleHTTPRequestHandler): + def __init__(self, *args, **kwargs): + super().__init__(*args, directory=str(output_dir.resolve()), **kwargs) + + def log_message(self, format, *args): + pass # Suppress server logs + + def start_server(): + with socketserver.TCPServer(("", port), Handler) as httpd: + httpd.serve_forever() + + # Start server in background thread + server_thread = threading.Thread(target=start_server, daemon=True) + server_thread.start() + + time.sleep(0.5) + import webbrowser - webbrowser.open(f"file://{(output_dir / 'index.html').resolve()}") + url = f"http://localhost:{port}/index.html" + print(f"[✓]Localhost started at {url}") + print(f"[i] Press Ctrl+C to exit \n") + webbrowser.open(url) + + try: + while True: + time.sleep(1) + except KeyboardInterrupt: + print("\n[✓] Server stopped") From 83dc24def634e4034d0409e1e11cbe9aa80a2017 Mon Sep 17 00:00:00 2001 From: Neha Kumari Date: Mon, 27 Oct 2025 10:34:19 +0530 Subject: [PATCH 3/5] fix(agent_ui): delete agent_graph.json, update README.md --- .../visualizers/agent_ui/README.md | 39 ++- .../visualizers/agent_ui/src/agent_graph.json | 327 ------------------ .../visualizers/agent_ui/src/graphLoader.tsx | 3 +- 3 files changed, 35 insertions(+), 334 deletions(-) delete mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json diff --git a/src/repello_agent_wiz/visualizers/agent_ui/README.md b/src/repello_agent_wiz/visualizers/agent_ui/README.md index 6d34267..6c6ad5e 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/README.md +++ b/src/repello_agent_wiz/visualizers/agent_ui/README.md @@ -11,8 +11,7 @@ This guide documents the migration from d3-based visualization to ReactFlow visu **Changes:** - Added support for runtime JSON injection via `window.AGENT_GRAPH_DATA` -- Maintains backward compatibility with static JSON import as fallback -- The app now checks for runtime data first, then falls back to the bundled JSON +- The app now checks for runtime data first, then falls gracefully ### 2. **visualizer.py** - React Build Integration **File:** `src/repello_agent_wiz/visualizers/visualizer.py` @@ -45,9 +44,39 @@ This ensures the React build is included when the package is distributed. ### Current Flow (After Migration) 1. **User runs CLI command:** - ```bash - agent-wiz visualize --input agentchat_graph.json --open - ``` + +- Extract Agentic Workflow + +```bash +agent-wiz extract --framework agent_chat --directory ./examples/code/agent_chat --output agentchat_graph.json +``` + +This will generate a graph JSON with the following structure: + +```json +{ + "nodes": [...], + "edges": [...], + "metadata": { + "framework": "autogen" + } +} +``` + +- Then, Visualize the Agentic workflow + +```bash +agent-wiz visualize --input agentchat_graph.json --open +``` + +This will generate an html Reacflow based visualisation of the agentic workflow. The `open` flag (optional) and automatically opens the visualization in your default browser. + +- visualize other graphs [exit above server's graph and run this cmd to visualize other agentic worflow in the same terminal] + +```bash +agent-wiz visualize --input examples/output/crewai_graph.json --open +agent-wiz visualize --input examples/output/langgraph_graph.json --open +``` 2. **Python backend (`visualizer.py`):** - Reads the graph JSON file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json b/src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json deleted file mode 100644 index 43c1d6e..0000000 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/agent_graph.json +++ /dev/null @@ -1,327 +0,0 @@ -{ - "nodes": [ - { - "name": "Start", - "function_name": null, - "docstring": null, - "node_type": "Start", - "source_location": null, - "metadata": {} - }, - { - "name": "End", - "function_name": null, - "docstring": null, - "node_type": "End", - "source_location": null, - "metadata": {} - }, - { - "name": "PlanningAgent", - "function_name": "Assistant", - "docstring": null, - "node_type": "Agent", - "source_location": null, - "metadata": {} - }, - { - "name": "WebSearchAgent", - "function_name": "Assistant", - "docstring": null, - "node_type": "Agent", - "source_location": null, - "metadata": {} - }, - { - "name": "WebSearchAgent_search_web_tool", - "function_name": "search_web_tool", - "docstring": null, - "node_type": "Tool", - "source_location": { - "file": "./examples/code/agent_chat/agent_chat2.py", - "line": 11, - "col": 0, - "end_line": 23, - "end_col": 27 - }, - "metadata": {} - }, - { - "name": "DataAnalystAgent", - "function_name": "Assistant", - "docstring": null, - "node_type": "Agent", - "source_location": null, - "metadata": {} - }, - { - "name": "DataAnalystAgent_percentage_change_tool", - "function_name": "percentage_change_tool", - "docstring": null, - "node_type": "Tool", - "source_location": { - "file": "./examples/code/agent_chat/agent_chat2.py", - "line": 26, - "col": 0, - "end_line": 27, - "end_col": 40 - }, - "metadata": {} - }, - { - "name": "Google_Search_Agent", - "function_name": "Assistant", - "docstring": null, - "node_type": "Agent", - "source_location": null, - "metadata": {} - }, - { - "name": "Google_Search_Agent_google_search", - "function_name": "google_search", - "docstring": null, - "node_type": "Tool", - "source_location": { - "file": "./examples/code/agent_chat/agent_chat.py", - "line": 10, - "col": 0, - "end_line": 61, - "end_col": 27 - }, - "metadata": {} - }, - { - "name": "Stock_Analysis_Agent", - "function_name": "Assistant", - "docstring": null, - "node_type": "Agent", - "source_location": null, - "metadata": {} - }, - { - "name": "Stock_Analysis_Agent_analyze_stock", - "function_name": "analyze_stock", - "docstring": null, - "node_type": "Tool", - "source_location": { - "file": "./examples/code/agent_chat/agent_chat.py", - "line": 64, - "col": 0, - "end_line": 155, - "end_col": 17 - }, - "metadata": {} - }, - { - "name": "Report_Agent", - "function_name": "Assistant", - "docstring": null, - "node_type": "Agent", - "source_location": null, - "metadata": {} - }, - { - "name": "team", - "function_name": null, - "docstring": null, - "node_type": "Team", - "source_location": null, - "metadata": { - "chat": "SelectorGroupChat" - } - } - ], - "edges": [ - { - "source": "Start", - "target": "PlanningAgent", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "PlanningAgent", - "target": "End", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Start", - "target": "WebSearchAgent", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "WebSearchAgent", - "target": "End", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "WebSearchAgent", - "target": "WebSearchAgent_search_web_tool", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Start", - "target": "DataAnalystAgent", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "DataAnalystAgent", - "target": "End", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "DataAnalystAgent", - "target": "DataAnalystAgent_percentage_change_tool", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Start", - "target": "Google_Search_Agent", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Google_Search_Agent", - "target": "End", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Google_Search_Agent", - "target": "Google_Search_Agent_google_search", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Start", - "target": "Stock_Analysis_Agent", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Stock_Analysis_Agent", - "target": "End", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Stock_Analysis_Agent", - "target": "Stock_Analysis_Agent_analyze_stock", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Start", - "target": "Report_Agent", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "Report_Agent", - "target": "End", - "condition": { - "type": "static" - }, - "metadata": {} - }, - { - "source": "team", - "target": "PlanningAgent", - "condition": { - "type": "member_of_team" - }, - "metadata": { - "chat": "SelectorGroupChat" - } - }, - { - "source": "team", - "target": "WebSearchAgent", - "condition": { - "type": "member_of_team" - }, - "metadata": { - "chat": "SelectorGroupChat" - } - }, - { - "source": "team", - "target": "DataAnalystAgent", - "condition": { - "type": "member_of_team" - }, - "metadata": { - "chat": "SelectorGroupChat" - } - }, - { - "source": "Stock_Analysis_Agent", - "target": "Google_Search_Agent", - "condition": { - "type": "group_sequence" - }, - "metadata": { - "chat": "RoundRobinGroupChat" - } - }, - { - "source": "Google_Search_Agent", - "target": "Report_Agent", - "condition": { - "type": "group_sequence" - }, - "metadata": { - "chat": "RoundRobinGroupChat" - } - }, - { - "source": "Report_Agent", - "target": "Stock_Analysis_Agent", - "condition": { - "type": "group_sequence" - }, - "metadata": { - "chat": "RoundRobinGroupChat" - } - } - ], - "metadata": { - "framework": "AgentChat" - } -} \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx index 6048817..63f1e0c 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx @@ -13,8 +13,7 @@ declare global { } } -import fallbackData from './agent_graph.json'; -const raw = window.AGENT_GRAPH_DATA || fallbackData; +const raw = window.AGENT_GRAPH_DATA || { nodes: [], edges: [], metadata: {} }; export type RFNode = any; export type RFEdge = any; From b218d1f3578e3000629c83079b88eeac855b1590 Mon Sep 17 00:00:00 2001 From: Neha Kumari Date: Tue, 28 Oct 2025 16:26:45 +0530 Subject: [PATCH 4/5] feat(agent-ui): add drag functionality, curved arrows, floating edges and enhanced node sizing --- .../visualizers/agent_ui/src/App.tsx | 201 ++++++++++++++++-- .../visualizers/agent_ui/src/customNode.css | 117 ++++++++-- .../visualizers/agent_ui/src/customNode.tsx | 15 +- .../visualizers/agent_ui/src/graphLoader.tsx | 51 ++++- .../agent_ui/src/interactions/DnDContext.tsx | 28 +++ .../interactions/FloatingConnectionLine.tsx | 48 +++++ .../src/interactions/FloatingEdge.tsx | 39 ++++ .../visualizers/agent_ui/src/utils.tsx | 42 +--- 8 files changed, 440 insertions(+), 101 deletions(-) create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/interactions/DnDContext.tsx create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingConnectionLine.tsx create mode 100644 src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingEdge.tsx diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx index ea189ee..ba1a61f 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/App.tsx @@ -1,7 +1,7 @@ import { useState, useCallback } from 'react'; import { Box, AppBar, Toolbar, Typography, Switch, Drawer, Card, List, ListItem, ButtonGroup, Button, Snackbar, TextField, InputAdornment } from '@mui/material'; -import ReactFlow, { MiniMap, Controls, Background, ReactFlowProvider, useReactFlow} from 'reactflow'; -import type {Node, Edge} from 'reactflow'; +import ReactFlow, { MiniMap, Controls, Background, ReactFlowProvider, useReactFlow, useNodesState, useEdgesState, addEdge, ConnectionLineType} from 'reactflow'; +import type {Node, Edge, Connection} from 'reactflow'; import { loadGraph } from './graphLoader'; import SearchIcon from './assets/search.svg'; import AgentIcon from './assets/agent.svg'; @@ -10,17 +10,82 @@ import OrchestratorIcon from './assets/Planner.svg'; import StartIcon from './assets/start.svg'; import TeamIcon from './assets/generic.svg'; import CustomNode from './customNode'; +import FloatingEdge from './interactions/FloatingEdge'; +import FloatingConnectionLine from './interactions/FloatingConnectionLine'; +import { DnDProvider } from './interactions/DnDContext'; import 'reactflow/dist/style.css'; const nodeTypes = { customNode: CustomNode }; +const edgeTypes = { floating: FloatingEdge }; const { nodes: initialNodes, edges: initialEdges, framework } = loadGraph(); -function FlowCanvas({ nodes, edges, highlighted, onNodeClick, onEdgeClick }: { - nodes: Node[]; edges: Edge[]; highlighted: string | null; +let nodeIdCounter = initialNodes.length + 1; +const getId = () => `new-node-${nodeIdCounter++}`; + +function FlowCanvas({ nodes, edges, setNodes, setEdges, highlighted, onNodeClick, onEdgeClick, onNodesChange, onEdgesChange }: { + nodes: Node[]; edges: Edge[]; setNodes: any; setEdges: any; + highlighted: string | null; onNodeClick: (e: any, node: any) => void; onEdgeClick: (e: any, edge: any) => void; + onNodesChange: any; onEdgesChange: any; }) { const [search, setSearch] = useState(''); - const { setCenter, fitView } = useReactFlow(); + const { setCenter, fitView, screenToFlowPosition } = useReactFlow(); + + const onConnect = useCallback( + (params: Connection) => setEdges((eds: Edge[]) => addEdge(params, eds)), + [setEdges] + ); + + const onDragOver = useCallback((event: React.DragEvent) => { + event.preventDefault(); + event.dataTransfer.dropEffect = 'move'; + }, []); + + const onDrop = useCallback( + (event: React.DragEvent) => { + event.preventDefault(); + + const nodeType = event.dataTransfer.getData('application/reactflow'); + if (!nodeType) return; + + const position = screenToFlowPosition({ + x: event.clientX, + y: event.clientY, + }); + + const baseSize = nodeType === 'tool' ? { width: 240, height: 100 } : + nodeType === 'start' || nodeType === 'end' ? { width: 120, height: 120 } : + { width: 320, height: 140 }; + + const newNode = { + id: getId(), + type: 'customNode', + position, + data: { + label: `New ${nodeType}`, + nodeType: nodeType, + icon: nodeType === 'agent' ? AgentIcon : + nodeType === 'tool' ? ToolIcon : + nodeType === 'orchestrator' ? OrchestratorIcon : + nodeType === 'start' ? StartIcon : + nodeType === 'team' ? TeamIcon : AgentIcon, + color: nodeType === 'agent' ? '#B39DDB' : + nodeType === 'tool' ? '#00BFA6' : + nodeType === 'orchestrator' ? '#FFB300' : + nodeType === 'start' ? '#1976D2' : + nodeType === 'team' ? '#7C4DFF' : '#B39DDB', + width: baseSize.width, + height: baseSize.height, + }, + selectable: true, + draggable: true, + ...baseSize, + }; + + setNodes((nds: Node[]) => nds.concat(newNode)); + }, + [screenToFlowPosition, setNodes] + ); const handleSearch = (e: any) => { const q = e.target.value || ''; @@ -63,7 +128,29 @@ function FlowCanvas({ nodes, edges, highlighted, onNodeClick, onEdgeClick }: { ), }} - sx={{ width: 320, maxWidth: '40vw' }} + sx={{ + width: 320, + maxWidth: '40vw', + '& .MuiOutlinedInput-root': { + backgroundColor: 'background.paper', + '& fieldset': { + borderColor: 'rgba(255,255,255,0.23)', + }, + '&:hover fieldset': { + borderColor: 'rgba(255,255,255,0.4)', + }, + '&.Mui-focused fieldset': { + borderColor: 'rgba(255,255,255,0.6)', + }, + }, + '& .MuiInputBase-input': { + color: 'text.primary', + }, + '& .MuiInputBase-input::placeholder': { + color: 'text.secondary', + opacity: 0.7, + }, + }} /> @@ -72,14 +159,30 @@ function FlowCanvas({ nodes, edges, highlighted, onNodeClick, onEdgeClick }: { nodes={nodes.map(n => ({ ...n, style: getNodeStyle(n.id, n.data?.color) }))} edges={edges} nodeTypes={nodeTypes} + edgeTypes={edgeTypes} + connectionLineComponent={FloatingConnectionLine} + onNodesChange={onNodesChange} + onEdgesChange={onEdgesChange} + connectionLineType={ConnectionLineType.SmoothStep} + onConnect={onConnect} + onDrop={onDrop} + onDragOver={onDragOver} fitView + fitViewOptions={{ padding: 0.15, maxZoom: 1.2 }} style={{ width: '100%', height: '100%' }} onNodeClick={onNodeClick} onEdgeClick={onEdgeClick} - minZoom={0.2} - maxZoom={2.2} + minZoom={0.15} + maxZoom={2.5} snapToGrid snapGrid={[24, 24]} + panOnDrag + selectNodesOnDrag={false} + defaultEdgeOptions={{ + type: 'floating', + style: { strokeWidth: 4 }, + animated: false + }} > (n.data?.color || '#777')} zoomable /> @@ -89,7 +192,9 @@ function FlowCanvas({ nodes, edges, highlighted, onNodeClick, onEdgeClick }: { ); } -export default function App() { +function App() { + const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); + const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const [themeDark, setThemeDark] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false); const [selectedDetails, setSelectedDetails] = useState(null); @@ -111,9 +216,13 @@ export default function App() { const handleThemeToggle = () => setThemeDark((p) => !p); const handleSnackbarClose = () => setSnackbarOpen(false); + const onDragStart = (event: React.DragEvent, nodeType: string) => { + event.dataTransfer.setData('application/reactflow', nodeType); + event.dataTransfer.effectAllowed = 'move'; + }; + return ( - - + Agent-Workflow ({framework}) @@ -130,11 +239,50 @@ export default function App() { Agent - - Tool Tool - Orchestrator Orchestrator - Start Start/End - Team Team + + Drag to Canvas + + + onDragStart(e, 'agent')} + sx={{ cursor: 'grab', borderRadius: 1, mb: 0.5, '&:hover': { bgcolor: 'action.hover' }, '&:active': { cursor: 'grabbing' } }} + > + Agent + Agent + + onDragStart(e, 'tool')} + sx={{ cursor: 'grab', borderRadius: 1, mb: 0.5, '&:hover': { bgcolor: 'action.hover' }, '&:active': { cursor: 'grabbing' } }} + > + Tool + Tool + + onDragStart(e, 'orchestrator')} + sx={{ cursor: 'grab', borderRadius: 1, mb: 0.5, '&:hover': { bgcolor: 'action.hover' }, '&:active': { cursor: 'grabbing' } }} + > + Orchestrator + Orchestrator + + onDragStart(e, 'start')} + sx={{ cursor: 'grab', borderRadius: 1, mb: 0.5, '&:hover': { bgcolor: 'action.hover' }, '&:active': { cursor: 'grabbing' } }} + > + Start + Start + + onDragStart(e, 'team')} + sx={{ cursor: 'grab', borderRadius: 1, '&:hover': { bgcolor: 'action.hover' }, '&:active': { cursor: 'grabbing' } }} + > + Team + Team + @@ -148,11 +296,15 @@ export default function App() { @@ -202,12 +354,17 @@ export default function App() { - - - ); -} \ No newline at end of file +} + +export default () => ( + + + + + +); \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css index 9da6164..8ff9158 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.css @@ -1,22 +1,38 @@ .aw-node { display: flex; - gap: 10px; + gap: 12px; align-items: center; - padding: 10px; - border-radius: 12px; + padding: 12px 14px; + border-radius: 14px; box-shadow: 0 8px 30px rgba(18, 26, 47, 0.06); - transition: transform 160ms ease, box-shadow 160ms ease, opacity 160ms ease; - min-width: 120px; - max-width: 480px; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + min-width: 140px; + max-width: 520px; background: rgba(255,255,255,0.98); - border: 1px solid rgba(16,24,40,0.04); + border: 2px solid rgba(16,24,40,0.08); box-sizing: border-box; } - - .aw-node--agent { border-left: 6px solid #b39ddb; background: linear-gradient(180deg,#fff,#fbf8ff); } - .aw-node--tool { border-left: 6px solid #00BFA6; background: linear-gradient(180deg,#fff,#f7fffc); } - .aw-node--orchestrator { border-left: 6px solid #FFB300; background: linear-gradient(180deg,#fff,#fffaf3); } + .aw-node--tool { + border-left: 6px solid #00BFA6; + background: linear-gradient(180deg,#fff,#f7fffc); + box-shadow: 0 8px 30px rgba(0, 191, 166, 0.12); + } + + .aw-node--tool::before { + background: linear-gradient(135deg, #dff183, #00a085); + } + + .aw-node--orchestrator { + border-left: 6px solid #FFB300; + background: linear-gradient(180deg,#fff,#fffaf3); + box-shadow: 0 8px 30px rgba(255, 179, 0, 0.12); + } + + .aw-node--orchestrator::before { + background: linear-gradient(135deg, #FFB300, #ffa000); + } + .aw-node--start, .aw-node--end { border-radius: 999px; padding: 12px 14px; @@ -38,26 +54,81 @@ /* left icon */ .aw-node__left { flex: 0 0 auto; display: flex; align-items: center; justify-content: center; } - .aw-node__icon { width: 36px; height: 36px; object-fit: contain; } + .aw-node__icon { width: 40px; height: 40px; object-fit: contain; } /* body expands */ .aw-node__body { flex: 1 1 auto; min-width: 120px; overflow: hidden; } - .aw-node__title { font-weight: 700; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } - .aw-node__subtitle { font-size: 11px; color: rgba(12,12,12,0.7); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } - .aw-node__doc { font-size: 11px; color: rgba(35,35,35,0.6); margin-top: 6px; max-height: 3.4em; overflow: hidden; } + .aw-node__title { font-weight: 700; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } + .aw-node__subtitle { font-size: 12px; color: rgba(12,12,12,0.7); white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } + .aw-node__doc { font-size: 12px; color: rgba(35,35,35,0.6); margin-top: 8px; max-height: 4em; overflow: hidden; } - /* handles */ - .aw-handle { width: 10px !important; height: 10px !important; border-radius: 3px; background: #1976d2; } - - /* top/bottom offsets */ - .aw-handle--top { top: -6px !important; } - .aw-handle--bottom { bottom: -6px !important; } + + .aw-handle { width: 12px !important; height: 12px !important; border-radius: 3px; background: #1976d2; border: 2px solid white; } - .aw-node:hover { transform: translateY(-4px); box-shadow: 0 12px 36px rgba(18,26,47,0.12) } + .aw-handle--top { top: -7px !important; } + .aw-handle--bottom { bottom: -7px !important; } + + .aw-node:hover { + transform: translateY(-6px) scale(1.02); + cursor: grab; + } + + .aw-node--agent:hover { + box-shadow: 0 16px 48px rgba(179, 157, 219, 0.25), 0 0 0 1px rgba(179, 157, 219, 0.3); + } + + .aw-node--agent:hover::before { + opacity: 1; + } + + .aw-node--tool:hover { + box-shadow: 0 16px 48px rgba(0, 191, 166, 0.25), 0 0 0 1px rgba(0, 191, 166, 0.3); + } + + .aw-node--tool:hover::before { + opacity: 1; + } + + .aw-node--orchestrator:hover { + box-shadow: 0 16px 48px rgba(255, 179, 0, 0.25), 0 0 0 1px rgba(255, 179, 0, 0.3); + } + + .aw-node--orchestrator:hover::before { + opacity: 1; + } + + .aw-node--start:hover, .aw-node--end:hover { + box-shadow: 0 12px 36px rgba(25, 118, 210, 0.25), 0 0 0 1px rgba(25, 118, 210, 0.3); + } + + .aw-node--start:hover::before, .aw-node--end:hover::before { + opacity: 1; + } + + .aw-node--team:hover { + box-shadow: 0 16px 48px rgba(124, 77, 255, 0.25), 0 0 0 1px rgba(124, 77, 255, 0.3); + } + + .aw-node--team:hover::before { + opacity: 1; + } + + .aw-node { + cursor: grab; + } + + .aw-node:active { + cursor: grabbing; + transform: scale(1.015); + transition: transform 0.1s cubic-bezier(0.4, 0, 0.2, 1); + } + + .aw-handle { + pointer-events: auto; + } @media (max-width: 700px) { .aw-node { gap: 8px; padding: 8px; } .aw-node__icon { width: 30px; height: 30px; } .aw-node__title { font-size: 12px; } } - \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx index a55dec0..d321c2c 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/customNode.tsx @@ -24,13 +24,18 @@ export default memo(function CustomNode({ data }: NodeProps) { const classes = ['aw-node', `aw-node--${type || 'agent'}`, dim ? 'aw-node--dim' : ''].join(' ').trim(); return ( -
{data.label} @@ -43,8 +48,8 @@ export default memo(function CustomNode({ data }: NodeProps) {
{/* connector handles: top + bottom for simplicity */} - - + +
); }); \ No newline at end of file diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx index 63f1e0c..576d35e 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx @@ -56,19 +56,24 @@ function dagreLayout(nodes: RFNode[], edges: RFEdge[], opts = { rankdir: 'LR', n g.setGraph({ rankdir: opts.rankdir, nodesep: opts.nodeSep, ranksep: opts.rankSep }); g.setDefaultEdgeLabel(() => ({})); - // Use approximate node sizes (React Flow will respect actual sizes but this is enough) - nodes.forEach((n) => g.setNode(n.id, { width: n.data.width ?? 220, height: n.data.height ?? 80 })); + // Set node sizes for dagre (React Flow uses top-left anchor, dagre uses center) + nodes.forEach((n) => g.setNode(n.id, { + width: n.data.width ?? 320, + height: n.data.height ?? 140 + })); + edges.forEach((e) => g.setEdge(e.source, e.target)); dagre.layout(g); + // Convert dagre positions to React Flow positions const positionedNodes = nodes.map((n) => { const nd = g.node(n.id); return { ...n, position: { - x: nd.x - (n.data.width ?? 220) / 2, - y: nd.y - (n.data.height ?? 80) / 2, + x: nd.x - (n.data.width ?? 320) / 2, + y: nd.y - (n.data.height ?? 140) / 2, }, }; }); @@ -86,8 +91,8 @@ export function loadGraph() { const meta = lookup(nt); const nodeLabel = node.name ?? node.label ?? `node-${i}`; - // smaller tool boxes visually subordinate to agents - const baseSize = nt.toLowerCase() === 'tool' ? { width: 160, height: 64 } : nt.toLowerCase().includes('start') || nt.toLowerCase().includes('end') ? { width: 80, height: 80 } : { width: 220, height: 92 }; + // optimized node sizes for visibility and clarity + const baseSize = nt.toLowerCase() === 'tool' ? { width: 240, height: 100 } : nt.toLowerCase().includes('start') || nt.toLowerCase().includes('end') ? { width: 120, height: 120 } : { width: 320, height: 140 }; return { id: nodeLabel, @@ -101,10 +106,11 @@ export function loadGraph() { metadata: node.metadata || {}, icon: meta.icon, color: meta.color, + width: baseSize.width, + height: baseSize.height, }, selectable: true, draggable: true, - // initial placeholder — replaced by dagre layout below position: { x: 0 + (i % 4) * 200, y: 80 + Math.floor(i / 4) * 140 }, ...baseSize, }; @@ -124,10 +130,30 @@ export function loadGraph() { target: edge.target, label: cond !== 'static' ? cond : undefined, animated, - type: 'smoothstep', // curved edges to reduce overlaps - style: { stroke: styleColor, strokeWidth: isDashed ? 2 : 2.4, strokeDasharray: isDashed ? '6 4' : undefined }, + type: 'floating', + pathOptions: { + curvature: 0.6, // smooth curved edges + }, + style: { + stroke: styleColor, + strokeWidth: isDashed ? 3 : 4, + strokeDasharray: isDashed ? '8 5' : undefined, + opacity: 0.9 + }, markerEnd: { type: 'arrowclosed', + color: styleColor, + width: 32, + height: 32, + }, + labelStyle: { + fill: '#fff', + fontWeight: 600, + }, + labelShowBg: true, + labelBgStyle: { + fill: styleColor, + fillOpacity: 0.2, }, data: edge.metadata || {}, }; @@ -137,7 +163,12 @@ export function loadGraph() { // placing Start nodes left and End nodes right by tagging rank // dagre will honor general spacing with rankdir LR by default - const { nodes: positionedNodes, edges: positionedEdges } = dagreLayout(nodes, edges, { rankdir: 'LR', nodeSep: 240, rankSep: 140 }); + // Optimal spacing to reduce node overlap and improve visibility + const { nodes: positionedNodes, edges: positionedEdges } = dagreLayout(nodes, edges, { + rankdir: 'LR', + nodeSep: 380, // Horizontal spacing for better separation + rankSep: 240 // Vertical spacing to reduce overlaps + }); return { nodes: positionedNodes, edges: positionedEdges, framework: graphData.metadata?.framework || 'unknown' }; } diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/DnDContext.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/DnDContext.tsx new file mode 100644 index 0000000..3226cdc --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/DnDContext.tsx @@ -0,0 +1,28 @@ +// Drag and Drop Context +import { createContext, useContext, useState, type ReactNode } from 'react'; + +interface DnDContextType { + type: string | null; + setType: (type: string | null) => void; +} + +const DnDContext = createContext(undefined); + +export function DnDProvider({ children }: { children: ReactNode }) { + const [type, setType] = useState(null); + + return ( + + {children} + + ); +} + +export function useDnD(): DnDContextType { + const context = useContext(DnDContext); + if (!context) { + throw new Error('useDnD must be used within DnDProvider'); + } + return context; +} + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingConnectionLine.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingConnectionLine.tsx new file mode 100644 index 0000000..fa08ddb --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingConnectionLine.tsx @@ -0,0 +1,48 @@ +import { useMemo } from 'react'; +import { getBezierPath } from 'reactflow'; +import type { ConnectionLineComponentProps } from 'reactflow'; + +export default function FloatingConnectionLine({ + toX, + toY, + fromX, + fromY, + fromPosition, + toPosition, +}: ConnectionLineComponentProps) { + const edgePath = useMemo(() => { + const [path] = getBezierPath({ + sourceX: fromX, + sourceY: fromY, + targetX: toX, + targetY: toY, + sourcePosition: fromPosition, + targetPosition: toPosition, + }); + return path; + }, [fromX, fromY, toX, toY, fromPosition, toPosition]); + + return ( + + + + + ); +} + diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingEdge.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingEdge.tsx new file mode 100644 index 0000000..2388cb3 --- /dev/null +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/interactions/FloatingEdge.tsx @@ -0,0 +1,39 @@ +import { useMemo } from 'react'; +import { getBezierPath } from 'reactflow'; +import type { EdgeProps } from 'reactflow'; + +export default function FloatingEdge({ + id, + style, + markerEnd, + sourcePosition, + targetPosition, + sourceX, + sourceY, + targetX, + targetY, +}: EdgeProps) { + const edgePath = useMemo(() => { + const [path] = getBezierPath({ + sourceX, + sourceY, + targetX, + targetY, + sourcePosition, + targetPosition, + }); + return path; + }, [sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition]); + + return ( + + + + ); +} diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx index 5c169fa..5a4ab6d 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/utils.tsx @@ -5,44 +5,4 @@ const accentColors = { default: '#EBEBEB' }; -export { accentColors }; - -// CustomNode.jsx -// import { Handle } from 'react-flow-renderer'; -// import agentIcon from './assets/agent.svg'; -// import toolIcon from './assets/tool.svg'; -// import orchestratorIcon from './assets/orchestrator.svg'; - -// const iconMap = { -// agent: agentIcon, -// tool: toolIcon, -// orchestrator: orchestratorIcon -// }; - -// export default function CustomNode({ data, type, selected }) { -// const color = accentColors[type] || accentColors.default; -// return ( -//
-// {type} -//
-//
{data.name}
-//
{data.node_type}
-// {data.function_name &&
{data.function_name}
} -//
-// -// -//
-// ); -// } \ No newline at end of file +export { accentColors }; \ No newline at end of file From 8131390f24f65c09c1562464b454ed0b15644fb4 Mon Sep 17 00:00:00 2001 From: Neha Kumari Date: Tue, 28 Oct 2025 16:49:14 +0530 Subject: [PATCH 5/5] feat(agent-ui): adjust nodes styling and spacing --- .../visualizers/agent_ui/src/graphLoader.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx index 576d35e..82555bf 100644 --- a/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx +++ b/src/repello_agent_wiz/visualizers/agent_ui/src/graphLoader.tsx @@ -92,7 +92,7 @@ export function loadGraph() { const nodeLabel = node.name ?? node.label ?? `node-${i}`; // optimized node sizes for visibility and clarity - const baseSize = nt.toLowerCase() === 'tool' ? { width: 240, height: 100 } : nt.toLowerCase().includes('start') || nt.toLowerCase().includes('end') ? { width: 120, height: 120 } : { width: 320, height: 140 }; + const baseSize = nt.toLowerCase() === 'tool' ? { width: 540, height: 200 } : nt.toLowerCase().includes('start') || nt.toLowerCase().includes('end') ? { width: 520, height: 220 } : { width: 320, height: 140 }; return { id: nodeLabel, @@ -166,8 +166,8 @@ export function loadGraph() { // Optimal spacing to reduce node overlap and improve visibility const { nodes: positionedNodes, edges: positionedEdges } = dagreLayout(nodes, edges, { rankdir: 'LR', - nodeSep: 380, // Horizontal spacing for better separation - rankSep: 240 // Vertical spacing to reduce overlaps + nodeSep: 80, // Horizontal spacing for better separation + rankSep: 40 // Vertical spacing to reduce overlaps }); return { nodes: positionedNodes, edges: positionedEdges, framework: graphData.metadata?.framework || 'unknown' };