diff --git a/.github/workflows/lint_test_build.yml b/.github/workflows/lint_test_build.yml deleted file mode 100644 index 368a8401..00000000 --- a/.github/workflows/lint_test_build.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: Lint, tests and build - -on: - push: - branches-ignore: ["main"] - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: "22" - - - name: Install dependencies - run: npm install - - - name: Lint - run: npm run lint:check - - tests: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: "22" - - - name: Install dependencies - run: npm install - - - name: Tests - run: npm run test - - build: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: "22" - - - name: Install dependencies - run: npm install - - - name: Build - run: npm run build diff --git a/.github/workflows/lint_test_compile.yml b/.github/workflows/lint_test_compile.yml new file mode 100644 index 00000000..cd0d3e4f --- /dev/null +++ b/.github/workflows/lint_test_compile.yml @@ -0,0 +1,54 @@ +name: Lint, tests and build + +on: + push: + branches-ignore: ["main"] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Deno + uses: denoland/setup-deno@v2 + with: + deno-version: "2.x" + + - name: Deno check + run: deno check + + - name: Deno lint + run: deno lint + + - name: Deno fmt (check) + run: deno fmt --check + + tests: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: denoland/setup-deno@v2 + with: + deno-version: "2.x" + + - name: Tests + run: deno task test + + compile: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: denoland/setup-deno@v2 + with: + deno-version: "2.x" + + - name: Compile + run: deno task compile:all diff --git a/deno.json b/deno.json index 3bf27b13..2eaa1708 100644 --- a/deno.json +++ b/deno.json @@ -7,9 +7,11 @@ "build:app": "deno task --config packages/app/deno.json build", "compile:cli": "deno task --config packages/cli/deno.json compile", "compile": "deno task --config packages/app/deno.json build && deno task --config packages/cli/deno.json compile", - "compile:all": "deno task --config packages/app/deno.json build && deno task --config packages/cli/deno.json compile:linux && deno task --config packages/cli/deno.json compile:macos && deno task --config packages/cli/deno.json compile:windows", - "test": "deno test", - "lint": "deno lint", - "fmt": "deno fmt" + "compile:all": "deno task --config packages/app/deno.json build && deno task --config packages/cli/deno.json 'compile-*'", + "test": "deno run -A npm:vitest", + "lint": "deno fmt && deno check &&deno lint --fix" + }, + "imports": { + "vitest": "npm:vitest@^3.1.3" } } diff --git a/deno.lock b/deno.lock index f6ececb2..ba61a904 100644 --- a/deno.lock +++ b/deno.lock @@ -1,37 +1,53 @@ { "version": "5", "specifiers": { - "npm:@deno/vite-plugin@^1.0.4": "1.0.4_vite@6.3.5__picomatch@4.0.2", - "npm:@inquirer/prompts@^7.5.0": "7.5.0", + "npm:@deno/vite-plugin@^1.0.4": "1.0.4_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0", + "npm:@inquirer/prompts@^7.5.0": "7.5.0_@types+node@22.12.0", + "npm:@radix-ui/react-dialog@^1.1.13": "1.1.13_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-dropdown-menu@^2.1.14": "2.1.14_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-label@^2.1.6": "2.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-scroll-area@^1.2.8": "1.2.8_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-separator@^1.1.6": "1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-slider@^1.3.4": "1.3.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-slot@^1.2.2": "1.2.2_@types+react@19.1.3_react@19.1.0", + "npm:@radix-ui/react-toast@^1.2.13": "1.2.13_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:@radix-ui/react-tooltip@^1.2.6": "1.2.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", "npm:@radix-ui/themes@^3.2.1": "3.2.1_react@19.1.0_react-dom@19.1.0__react@19.1.0_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3", - "npm:@tailwindcss/vite@^4.1.5": "4.1.5_vite@6.3.5__picomatch@4.0.2", + "npm:@tailwindcss/vite@^4.1.5": "4.1.5_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0", "npm:@types/cytoscape-fcose@^2.2.4": "2.2.4", "npm:@types/express@^5.0.1": "5.0.1", + "npm:@types/node@*": "22.12.0", "npm:@types/react-dom@^19.1.3": "19.1.3_@types+react@19.1.3", "npm:@types/react-router@^5.1.20": "5.1.20", "npm:@types/react@^19.1.3": "19.1.3", "npm:@types/yargs@^17.0.33": "17.0.33", - "npm:@vitejs/plugin-react@^4.4.1": "4.4.1_vite@6.3.5__picomatch@4.0.2_@babel+core@7.27.1", - "npm:autoprefixer@^10.4.21": "10.4.21_postcss@8.5.3", + "npm:@vitejs/plugin-react@^4.4.1": "4.4.1_vite@6.3.5__picomatch@4.0.2_@babel+core@7.27.1_@types+node@22.12.0", + "npm:class-variance-authority@~0.7.1": "0.7.1", + "npm:clsx@^2.1.1": "2.1.1", "npm:cytoscape-fcose@^2.2.0": "2.2.0_cytoscape@3.31.1", "npm:cytoscape@3.31.1": "3.31.1", "npm:express@^5.1.0": "5.1.0", + "npm:find-unused-exports@*": "7.1.1", "npm:glob@^11.0.2": "11.0.2", "npm:http-proxy-middleware@^3.0.5": "3.0.5", + "npm:lucide-react@0.508": "0.508.0_react@19.1.0", "npm:react-dom@^19.1.0": "19.1.0_react@19.1.0", - "npm:react-icons@5.5.0": "5.5.0_react@19.1.0", - "npm:react-resizable-panels@2.1.8": "2.1.8_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "npm:react-resizable-panels@^3.0.1": "3.0.1_react@19.1.0_react-dom@19.1.0__react@19.1.0", "npm:react-router@^7.5.3": "7.5.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", - "npm:react-toastify@^11.0.5": "11.0.5_react@19.1.0_react-dom@19.1.0__react@19.1.0", "npm:react@^19.1.0": "19.1.0", + "npm:shadcn@latest": "2.5.0_@babel+core@7.27.1_@types+node@22.12.0", + "npm:tailwind-merge@^3.2.0": "3.2.0", "npm:tailwindcss@^4.1.5": "4.1.5", "npm:tree-sitter-c-sharp@~0.23.1": "0.23.1_tree-sitter@0.22.4", "npm:tree-sitter-python@~0.23.6": "0.23.6_tree-sitter@0.22.4", "npm:tree-sitter@~0.22.4": "0.22.4", + "npm:tw-animate-css@^1.2.9": "1.2.9", "npm:uuid@^11.1.0": "11.1.0", - "npm:vite@*": "6.3.5_picomatch@4.0.2", - "npm:vite@^6.3.5": "6.3.5_picomatch@4.0.2", - "npm:vitest@^3.1.3": "3.1.3_vite@6.3.5__picomatch@4.0.2", + "npm:vite@*": "6.3.5_picomatch@4.0.2_@types+node@22.12.0", + "npm:vite@^6.3.5": "6.3.5_picomatch@4.0.2_@types+node@22.12.0", + "npm:vitest@*": "3.1.3_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0", + "npm:vitest@3.1.3": "3.1.3_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0", + "npm:vitest@^3.1.3": "3.1.3_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0", "npm:yargs@^17.7.2": "17.7.2", "npm:zod@^3.24.4": "3.24.4" }, @@ -43,6 +59,10 @@ "@jridgewell/trace-mapping" ] }, + "@antfu/ni@23.3.1": { + "integrity": "sha512-C90iyzm/jLV7Lomv2UzwWUzRv9WZr1oRsFRKsX5HjQL4EXrbi9H/RtBkjCP+NF+ABZXUKpAa4F1dkoTaea4zHg==", + "bin": true + }, "@babel/code-frame@7.27.1": { "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dependencies": [ @@ -84,6 +104,12 @@ "jsesc" ] }, + "@babel/helper-annotate-as-pure@7.27.1": { + "integrity": "sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==", + "dependencies": [ + "@babel/types" + ] + }, "@babel/helper-compilation-targets@7.27.2": { "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "dependencies": [ @@ -94,6 +120,26 @@ "semver" ] }, + "@babel/helper-create-class-features-plugin@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "dependencies": [ + "@babel/core", + "@babel/helper-annotate-as-pure", + "@babel/helper-member-expression-to-functions", + "@babel/helper-optimise-call-expression", + "@babel/helper-replace-supers", + "@babel/helper-skip-transparent-expression-wrappers", + "@babel/traverse", + "semver" + ] + }, + "@babel/helper-member-expression-to-functions@7.27.1": { + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, "@babel/helper-module-imports@7.27.1": { "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "dependencies": [ @@ -110,9 +156,31 @@ "@babel/traverse" ] }, + "@babel/helper-optimise-call-expression@7.27.1": { + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dependencies": [ + "@babel/types" + ] + }, "@babel/helper-plugin-utils@7.27.1": { "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==" }, + "@babel/helper-replace-supers@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dependencies": [ + "@babel/core", + "@babel/helper-member-expression-to-functions", + "@babel/helper-optimise-call-expression", + "@babel/traverse" + ] + }, + "@babel/helper-skip-transparent-expression-wrappers@7.27.1": { + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, "@babel/helper-string-parser@7.27.1": { "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==" }, @@ -136,6 +204,13 @@ ], "bin": true }, + "@babel/plugin-syntax-typescript@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dependencies": [ + "@babel/core", + "@babel/helper-plugin-utils" + ] + }, "@babel/plugin-transform-react-jsx-self@7.27.1_@babel+core@7.27.1": { "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", "dependencies": [ @@ -150,6 +225,17 @@ "@babel/helper-plugin-utils" ] }, + "@babel/plugin-transform-typescript@7.27.1_@babel+core@7.27.1": { + "integrity": "sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==", + "dependencies": [ + "@babel/core", + "@babel/helper-annotate-as-pure", + "@babel/helper-create-class-features-plugin", + "@babel/helper-plugin-utils", + "@babel/helper-skip-transparent-expression-wrappers", + "@babel/plugin-syntax-typescript" + ] + }, "@babel/template@7.27.2": { "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dependencies": [ @@ -177,10 +263,35 @@ "@babel/helper-validator-identifier" ] }, + "@bundled-es-modules/cookie@2.0.1": { + "integrity": "sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==", + "dependencies": [ + "cookie@0.7.2" + ] + }, + "@bundled-es-modules/statuses@1.0.1": { + "integrity": "sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==", + "dependencies": [ + "statuses" + ] + }, + "@bundled-es-modules/tough-cookie@0.1.6": { + "integrity": "sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==", + "dependencies": [ + "@types/tough-cookie", + "tough-cookie" + ] + }, "@deno/vite-plugin@1.0.4_vite@6.3.5__picomatch@4.0.2": { "integrity": "sha512-xg8YT8Wn2sGXSnJgiGTpBGX1Dov0c6fd1rAp8VsfrCUtyBRRWzwVMAnd3fQ4yq8h7LSVvJUxEFN4U421k/DQLA==", "dependencies": [ - "vite" + "vite@6.3.5_picomatch@4.0.2" + ] + }, + "@deno/vite-plugin@1.0.4_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0": { + "integrity": "sha512-xg8YT8Wn2sGXSnJgiGTpBGX1Dov0c6fd1rAp8VsfrCUtyBRRWzwVMAnd3fQ4yq8h7LSVvJUxEFN4U421k/DQLA==", + "dependencies": [ + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0" ] }, "@emnapi/core@1.4.3": { @@ -351,50 +462,119 @@ "@floating-ui/utils@0.2.9": { "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==" }, + "@import-maps/resolve@2.0.0": { + "integrity": "sha512-RwzRTpmrrS6Q1ZhQExwuxJGK1Wqhv4stt+OF2JzS+uawewpwNyU7EJL1WpBex7aDiiGLs4FsXGkfUBdYuX7xiQ==" + }, "@inquirer/checkbox@4.1.5": { "integrity": "sha512-swPczVU+at65xa5uPfNP9u3qx/alNwiaykiI/ExpsmMSQW55trmZcwhYWzw/7fj+n6Q8z1eENvR7vFfq9oPSAQ==", "dependencies": [ - "@inquirer/core", + "@inquirer/core@10.1.10", "@inquirer/figures", - "@inquirer/type", + "@inquirer/type@3.0.6", "ansi-escapes", "yoctocolors-cjs" ] }, + "@inquirer/checkbox@4.1.5_@types+node@22.12.0": { + "integrity": "sha512-swPczVU+at65xa5uPfNP9u3qx/alNwiaykiI/ExpsmMSQW55trmZcwhYWzw/7fj+n6Q8z1eENvR7vFfq9oPSAQ==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/figures", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", + "ansi-escapes", + "yoctocolors-cjs" + ], + "optionalPeers": [ + "@types/node" + ] + }, "@inquirer/confirm@5.1.9": { "integrity": "sha512-NgQCnHqFTjF7Ys2fsqK2WtnA8X1kHyInyG+nMIuHowVTIgIuS10T4AznI/PvbqSpJqjCUqNBlKGh1v3bwLFL4w==", "dependencies": [ - "@inquirer/core", - "@inquirer/type" + "@inquirer/core@10.1.10", + "@inquirer/type@3.0.6" + ] + }, + "@inquirer/confirm@5.1.9_@types+node@22.12.0": { + "integrity": "sha512-NgQCnHqFTjF7Ys2fsqK2WtnA8X1kHyInyG+nMIuHowVTIgIuS10T4AznI/PvbqSpJqjCUqNBlKGh1v3bwLFL4w==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/core@10.1.10": { "integrity": "sha512-roDaKeY1PYY0aCqhRmXihrHjoSW2A00pV3Ke5fTpMCkzcGF64R8e0lw3dK+eLEHwS4vB5RnW1wuQmvzoRul8Mw==", "dependencies": [ "@inquirer/figures", - "@inquirer/type", + "@inquirer/type@3.0.6", + "ansi-escapes", + "cli-width", + "mute-stream", + "signal-exit@4.1.0", + "wrap-ansi@6.2.0", + "yoctocolors-cjs" + ] + }, + "@inquirer/core@10.1.10_@types+node@22.12.0": { + "integrity": "sha512-roDaKeY1PYY0aCqhRmXihrHjoSW2A00pV3Ke5fTpMCkzcGF64R8e0lw3dK+eLEHwS4vB5RnW1wuQmvzoRul8Mw==", + "dependencies": [ + "@inquirer/figures", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", "ansi-escapes", "cli-width", "mute-stream", - "signal-exit", + "signal-exit@4.1.0", "wrap-ansi@6.2.0", "yoctocolors-cjs" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/editor@4.2.10": { "integrity": "sha512-5GVWJ+qeI6BzR6TIInLP9SXhWCEcvgFQYmcRG6d6RIlhFjM5TyG18paTGBgRYyEouvCmzeco47x9zX9tQEofkw==", "dependencies": [ - "@inquirer/core", - "@inquirer/type", + "@inquirer/core@10.1.10", + "@inquirer/type@3.0.6", + "external-editor" + ] + }, + "@inquirer/editor@4.2.10_@types+node@22.12.0": { + "integrity": "sha512-5GVWJ+qeI6BzR6TIInLP9SXhWCEcvgFQYmcRG6d6RIlhFjM5TyG18paTGBgRYyEouvCmzeco47x9zX9tQEofkw==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", "external-editor" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/expand@4.0.12": { "integrity": "sha512-jV8QoZE1fC0vPe6TnsOfig+qwu7Iza1pkXoUJ3SroRagrt2hxiL+RbM432YAihNR7m7XnU0HWl/WQ35RIGmXHw==", "dependencies": [ - "@inquirer/core", - "@inquirer/type", + "@inquirer/core@10.1.10", + "@inquirer/type@3.0.6", + "yoctocolors-cjs" + ] + }, + "@inquirer/expand@4.0.12_@types+node@22.12.0": { + "integrity": "sha512-jV8QoZE1fC0vPe6TnsOfig+qwu7Iza1pkXoUJ3SroRagrt2hxiL+RbM432YAihNR7m7XnU0HWl/WQ35RIGmXHw==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", "yoctocolors-cjs" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/figures@1.0.11": { @@ -403,70 +583,171 @@ "@inquirer/input@4.1.9": { "integrity": "sha512-mshNG24Ij5KqsQtOZMgj5TwEjIf+F2HOESk6bjMwGWgcH5UBe8UoljwzNFHqdMbGYbgAf6v2wU/X9CAdKJzgOA==", "dependencies": [ - "@inquirer/core", - "@inquirer/type" + "@inquirer/core@10.1.10", + "@inquirer/type@3.0.6" + ] + }, + "@inquirer/input@4.1.9_@types+node@22.12.0": { + "integrity": "sha512-mshNG24Ij5KqsQtOZMgj5TwEjIf+F2HOESk6bjMwGWgcH5UBe8UoljwzNFHqdMbGYbgAf6v2wU/X9CAdKJzgOA==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/number@3.0.12": { "integrity": "sha512-7HRFHxbPCA4e4jMxTQglHJwP+v/kpFsCf2szzfBHy98Wlc3L08HL76UDiA87TOdX5fwj2HMOLWqRWv9Pnn+Z5Q==", "dependencies": [ - "@inquirer/core", - "@inquirer/type" + "@inquirer/core@10.1.10", + "@inquirer/type@3.0.6" + ] + }, + "@inquirer/number@3.0.12_@types+node@22.12.0": { + "integrity": "sha512-7HRFHxbPCA4e4jMxTQglHJwP+v/kpFsCf2szzfBHy98Wlc3L08HL76UDiA87TOdX5fwj2HMOLWqRWv9Pnn+Z5Q==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/password@4.0.12": { "integrity": "sha512-FlOB0zvuELPEbnBYiPaOdJIaDzb2PmJ7ghi/SVwIHDDSQ2K4opGBkF+5kXOg6ucrtSUQdLhVVY5tycH0j0l+0g==", "dependencies": [ - "@inquirer/core", - "@inquirer/type", + "@inquirer/core@10.1.10", + "@inquirer/type@3.0.6", "ansi-escapes" ] }, + "@inquirer/password@4.0.12_@types+node@22.12.0": { + "integrity": "sha512-FlOB0zvuELPEbnBYiPaOdJIaDzb2PmJ7ghi/SVwIHDDSQ2K4opGBkF+5kXOg6ucrtSUQdLhVVY5tycH0j0l+0g==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", + "ansi-escapes" + ], + "optionalPeers": [ + "@types/node" + ] + }, "@inquirer/prompts@7.5.0": { "integrity": "sha512-tk8Bx7l5AX/CR0sVfGj3Xg6v7cYlFBkEahH+EgBB+cZib6Fc83dwerTbzj7f2+qKckjIUGsviWRI1d7lx6nqQA==", "dependencies": [ - "@inquirer/checkbox", - "@inquirer/confirm", - "@inquirer/editor", - "@inquirer/expand", - "@inquirer/input", - "@inquirer/number", - "@inquirer/password", - "@inquirer/rawlist", - "@inquirer/search", - "@inquirer/select" + "@inquirer/checkbox@4.1.5", + "@inquirer/confirm@5.1.9", + "@inquirer/editor@4.2.10", + "@inquirer/expand@4.0.12", + "@inquirer/input@4.1.9", + "@inquirer/number@3.0.12", + "@inquirer/password@4.0.12", + "@inquirer/rawlist@4.1.0", + "@inquirer/search@3.0.12", + "@inquirer/select@4.2.0" + ] + }, + "@inquirer/prompts@7.5.0_@types+node@22.12.0": { + "integrity": "sha512-tk8Bx7l5AX/CR0sVfGj3Xg6v7cYlFBkEahH+EgBB+cZib6Fc83dwerTbzj7f2+qKckjIUGsviWRI1d7lx6nqQA==", + "dependencies": [ + "@inquirer/checkbox@4.1.5_@types+node@22.12.0", + "@inquirer/confirm@5.1.9_@types+node@22.12.0", + "@inquirer/editor@4.2.10_@types+node@22.12.0", + "@inquirer/expand@4.0.12_@types+node@22.12.0", + "@inquirer/input@4.1.9_@types+node@22.12.0", + "@inquirer/number@3.0.12_@types+node@22.12.0", + "@inquirer/password@4.0.12_@types+node@22.12.0", + "@inquirer/rawlist@4.1.0_@types+node@22.12.0", + "@inquirer/search@3.0.12_@types+node@22.12.0", + "@inquirer/select@4.2.0_@types+node@22.12.0", + "@types/node" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/rawlist@4.1.0": { "integrity": "sha512-6ob45Oh9pXmfprKqUiEeMz/tjtVTFQTgDDz1xAMKMrIvyrYjAmRbQZjMJfsictlL4phgjLhdLu27IkHNnNjB7g==", "dependencies": [ - "@inquirer/core", - "@inquirer/type", + "@inquirer/core@10.1.10", + "@inquirer/type@3.0.6", "yoctocolors-cjs" ] }, + "@inquirer/rawlist@4.1.0_@types+node@22.12.0": { + "integrity": "sha512-6ob45Oh9pXmfprKqUiEeMz/tjtVTFQTgDDz1xAMKMrIvyrYjAmRbQZjMJfsictlL4phgjLhdLu27IkHNnNjB7g==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", + "yoctocolors-cjs" + ], + "optionalPeers": [ + "@types/node" + ] + }, "@inquirer/search@3.0.12": { "integrity": "sha512-H/kDJA3kNlnNIjB8YsaXoQI0Qccgf0Na14K1h8ExWhNmUg2E941dyFPrZeugihEa9AZNW5NdsD/NcvUME83OPQ==", "dependencies": [ - "@inquirer/core", + "@inquirer/core@10.1.10", + "@inquirer/figures", + "@inquirer/type@3.0.6", + "yoctocolors-cjs" + ] + }, + "@inquirer/search@3.0.12_@types+node@22.12.0": { + "integrity": "sha512-H/kDJA3kNlnNIjB8YsaXoQI0Qccgf0Na14K1h8ExWhNmUg2E941dyFPrZeugihEa9AZNW5NdsD/NcvUME83OPQ==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", "@inquirer/figures", - "@inquirer/type", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", "yoctocolors-cjs" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/select@4.2.0": { "integrity": "sha512-KkXQ4aSySWimpV4V/TUJWdB3tdfENZUU765GjOIZ0uPwdbGIG6jrxD4dDf1w68uP+DVtfNhr1A92B+0mbTZ8FA==", "dependencies": [ - "@inquirer/core", + "@inquirer/core@10.1.10", + "@inquirer/figures", + "@inquirer/type@3.0.6", + "ansi-escapes", + "yoctocolors-cjs" + ] + }, + "@inquirer/select@4.2.0_@types+node@22.12.0": { + "integrity": "sha512-KkXQ4aSySWimpV4V/TUJWdB3tdfENZUU765GjOIZ0uPwdbGIG6jrxD4dDf1w68uP+DVtfNhr1A92B+0mbTZ8FA==", + "dependencies": [ + "@inquirer/core@10.1.10_@types+node@22.12.0", "@inquirer/figures", - "@inquirer/type", + "@inquirer/type@3.0.6_@types+node@22.12.0", + "@types/node", "ansi-escapes", "yoctocolors-cjs" + ], + "optionalPeers": [ + "@types/node" ] }, "@inquirer/type@3.0.6": { "integrity": "sha512-/mKVCtVpyBu3IDarv0G+59KC4stsD5mDsGpYh+GKs1NZT88Jh52+cuoA1AtLk2Q0r/quNl+1cSUyLRHBFeD0XA==" }, + "@inquirer/type@3.0.6_@types+node@22.12.0": { + "integrity": "sha512-/mKVCtVpyBu3IDarv0G+59KC4stsD5mDsGpYh+GKs1NZT88Jh52+cuoA1AtLk2Q0r/quNl+1cSUyLRHBFeD0XA==", + "dependencies": [ + "@types/node" + ], + "optionalPeers": [ + "@types/node" + ] + }, "@isaacs/cliui@8.0.2": { "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dependencies": [ @@ -502,6 +783,17 @@ "@jridgewell/sourcemap-codec" ] }, + "@mswjs/interceptors@0.37.6": { + "integrity": "sha512-wK+5pLK5XFmgtH3aQ2YVvA3HohS3xqV/OxuVOdNx9Wpnz7VE/fnC+e1A7ln6LFYeck7gOJ/dsZV6OLplOtAJ2w==", + "dependencies": [ + "@open-draft/deferred-promise", + "@open-draft/logger", + "@open-draft/until", + "is-node-process", + "outvariant", + "strict-event-emitter" + ] + }, "@napi-rs/wasm-runtime@0.2.9": { "integrity": "sha512-OKRBiajrrxB9ATokgEQoG87Z25c67pCpYcCwmXYX8PBftC9pBfN18gnm/fh1wurSLEKIAt+QRFLFCQISrb66Jg==", "dependencies": [ @@ -510,6 +802,36 @@ "@tybys/wasm-util" ] }, + "@nodelib/fs.scandir@2.1.5": { + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": [ + "@nodelib/fs.stat", + "run-parallel" + ] + }, + "@nodelib/fs.stat@2.0.5": { + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk@1.2.8": { + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": [ + "@nodelib/fs.scandir", + "fastq" + ] + }, + "@open-draft/deferred-promise@2.2.0": { + "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==" + }, + "@open-draft/logger@0.3.0": { + "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dependencies": [ + "is-node-process", + "outvariant" + ] + }, + "@open-draft/until@2.1.0": { + "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==" + }, "@radix-ui/colors@3.0.0": { "integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==" }, @@ -611,6 +933,20 @@ "@types/react-dom" ] }, + "@radix-ui/react-arrow@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-2JMfHJf/eVnwq+2dewT3C0acmCWD3XiVA1Da+jTDqo342UlU13WvXtqHhG+yJw5JeQmu4ue2eMy6gcEArLBlcw==", + "dependencies": [ + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-arrow@1.1.6_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-2JMfHJf/eVnwq+2dewT3C0acmCWD3XiVA1Da+jTDqo342UlU13WvXtqHhG+yJw5JeQmu4ue2eMy6gcEArLBlcw==", "dependencies": [ @@ -757,6 +1093,23 @@ "@types/react-dom" ] }, + "@radix-ui/react-collection@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-PbhRFK4lIEw9ADonj48tiYWzkllz81TM7KVYyyMMw2cwHO7D5h4XKEblL8NlaRisTK3QTe6tBEhDccFUryxHBQ==", + "dependencies": [ + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-slot@1.2.2_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-collection@1.1.6_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-PbhRFK4lIEw9ADonj48tiYWzkllz81TM7KVYyyMMw2cwHO7D5h4XKEblL8NlaRisTK3QTe6tBEhDccFUryxHBQ==", "dependencies": [ @@ -785,6 +1138,16 @@ "@types/react-dom" ] }, + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", + "dependencies": [ + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-compose-refs@1.1.2_react@19.1.0": { "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", "dependencies": [ @@ -833,6 +1196,16 @@ "@types/react-dom" ] }, + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", + "dependencies": [ + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-context@1.1.2_react@19.1.0": { "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", "dependencies": [ @@ -849,6 +1222,33 @@ "@types/react" ] }, + "@radix-ui/react-dialog@1.1.13_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-ARFmqUyhIVS3+riWzwGTe7JLjqwqgnODBUZdqpWar/z1WFs9z76fuOs/2BOWCR+YboRn4/WN9aoaGVwqNRr8VA==", + "dependencies": [ + "@radix-ui/primitive", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-dismissable-layer@1.1.9_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-focus-guards@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-focus-scope@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-id@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-portal@1.1.8_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-presence@1.1.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-slot@1.2.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "aria-hidden", + "react", + "react-dom", + "react-remove-scroll@2.6.3_@types+react@19.1.3_react@19.1.0" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-dialog@1.1.13_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-ARFmqUyhIVS3+riWzwGTe7JLjqwqgnODBUZdqpWar/z1WFs9z76fuOs/2BOWCR+YboRn4/WN9aoaGVwqNRr8VA==", "dependencies": [ @@ -897,6 +1297,16 @@ "@types/react-dom" ] }, + "@radix-ui/react-direction@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", + "dependencies": [ + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-direction@1.1.1_react@19.1.0": { "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", "dependencies": [ @@ -913,6 +1323,24 @@ "@types/react" ] }, + "@radix-ui/react-dismissable-layer@1.1.9_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ==", + "dependencies": [ + "@radix-ui/primitive", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-escape-keydown@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-dismissable-layer@1.1.9_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-way197PiTvNp+WBP7svMJasHl+vibhWGQDb6Mgf5mhEWJkgb85z7Lfl9TUdkqpWsf8GRNmoopx9ZxCyDzmgRMQ==", "dependencies": [ @@ -943,6 +1371,26 @@ "@types/react-dom" ] }, + "@radix-ui/react-dropdown-menu@2.1.14_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-lzuyNjoWOoaMFE/VC5FnAAYM16JmQA8ZmucOXtlhm2kKR5TSU95YLAueQ4JYuRmUJmBvSqXaVFGIfuukybwZJQ==", + "dependencies": [ + "@radix-ui/primitive", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-id@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-menu@2.1.14_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-dropdown-menu@2.1.14_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-lzuyNjoWOoaMFE/VC5FnAAYM16JmQA8ZmucOXtlhm2kKR5TSU95YLAueQ4JYuRmUJmBvSqXaVFGIfuukybwZJQ==", "dependencies": [ @@ -977,6 +1425,16 @@ "@types/react-dom" ] }, + "@radix-ui/react-focus-guards@1.1.2_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", + "dependencies": [ + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-focus-guards@1.1.2_react@19.1.0": { "integrity": "sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==", "dependencies": [ @@ -993,6 +1451,22 @@ "@types/react" ] }, + "@radix-ui/react-focus-scope@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw==", + "dependencies": [ + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-focus-scope@1.1.6_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-r9zpYNUQY+2jWHWZGyddQLL9YHkM/XvSFHVcWs7bdVuxMAnCwTAuy6Pf47Z4nw7dYcUou1vg/VgjjrrH03VeBw==", "dependencies": [ @@ -1089,6 +1563,17 @@ "@types/react-dom" ] }, + "@radix-ui/react-id@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", + "dependencies": [ + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-id@1.1.1_react@19.1.0": { "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", "dependencies": [ @@ -1107,6 +1592,20 @@ "@types/react" ] }, + "@radix-ui/react-label@2.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-S/hv1mTlgcPX2gCTJrWuTjSXf7ER3Zf7zWGtOprxhIIY93Qin3n5VgNA0Ez9AgrK/lEtlYgzLd4f5x6AVar4Yw==", + "dependencies": [ + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-label@2.1.6_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-S/hv1mTlgcPX2gCTJrWuTjSXf7ER3Zf7zWGtOprxhIIY93Qin3n5VgNA0Ez9AgrK/lEtlYgzLd4f5x6AVar4Yw==", "dependencies": [ @@ -1129,6 +1628,37 @@ "@types/react-dom" ] }, + "@radix-ui/react-menu@2.1.14_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-0zSiBAIFq9GSKoSH5PdEaQeRB3RnEGxC+H2P0egtnKoKKLNBH8VBHyVO6/jskhjAezhOIplyRUj7U2lds9A+Yg==", + "dependencies": [ + "@radix-ui/primitive", + "@radix-ui/react-collection@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-direction@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-dismissable-layer@1.1.9_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-focus-guards@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-focus-scope@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-id@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-popper@1.2.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-portal@1.1.8_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-presence@1.1.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-roving-focus@1.1.9_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-slot@1.2.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "aria-hidden", + "react", + "react-dom", + "react-remove-scroll@2.6.3_@types+react@19.1.3_react@19.1.0" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-menu@2.1.14_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-0zSiBAIFq9GSKoSH5PdEaQeRB3RnEGxC+H2P0egtnKoKKLNBH8VBHyVO6/jskhjAezhOIplyRUj7U2lds9A+Yg==", "dependencies": [ @@ -1403,6 +1933,29 @@ "@types/react-dom" ] }, + "@radix-ui/react-popper@1.2.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-7iqXaOWIjDBfIG7aq8CUEeCSsQMLFdn7VEE8TaFz704DtEzpPHR7w/uuzRflvKgltqSAImgcmxQ7fFX3X7wasg==", + "dependencies": [ + "@floating-ui/react-dom", + "@radix-ui/react-arrow@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-rect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-size@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/rect", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-popper@1.2.6_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-7iqXaOWIjDBfIG7aq8CUEeCSsQMLFdn7VEE8TaFz704DtEzpPHR7w/uuzRflvKgltqSAImgcmxQ7fFX3X7wasg==", "dependencies": [ @@ -1443,6 +1996,21 @@ "@types/react-dom" ] }, + "@radix-ui/react-portal@1.1.8_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-hQsTUIn7p7fxCPvao/q6wpbxmCwgLrlz+nOrJgC+RwfZqWY/WN+UMqkXzrtKbPrF82P43eCTl3ekeKuyAQbFeg==", + "dependencies": [ + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-portal@1.1.8_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-hQsTUIn7p7fxCPvao/q6wpbxmCwgLrlz+nOrJgC+RwfZqWY/WN+UMqkXzrtKbPrF82P43eCTl3ekeKuyAQbFeg==", "dependencies": [ @@ -1467,6 +2035,21 @@ "@types/react-dom" ] }, + "@radix-ui/react-presence@1.1.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", + "dependencies": [ + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-presence@1.1.4_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-ueDqRbdc4/bkaQT3GIpLQssRlFgWaL/U2z/S31qRwwLWoxHLgry3SIfCwhxeQNbirEUXFa+lq3RL3oBYXtcmIA==", "dependencies": [ @@ -1491,6 +2074,20 @@ "@types/react-dom" ] }, + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-uHa+l/lKfxuDD2zjN/0peM/RhhSmRjr5YWdk/37EnSv1nJ88uvG85DPexSm8HdFQROd2VdERJ6ynXbkCFi+APw==", + "dependencies": [ + "@radix-ui/react-slot@1.2.2_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-primitive@2.1.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-uHa+l/lKfxuDD2zjN/0peM/RhhSmRjr5YWdk/37EnSv1nJ88uvG85DPexSm8HdFQROd2VdERJ6ynXbkCFi+APw==", "dependencies": [ @@ -1577,6 +2174,28 @@ "@types/react-dom" ] }, + "@radix-ui/react-roving-focus@1.1.9_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-ZzrIFnMYHHCNqSNCsuN6l7wlewBEq0O0BCSBkabJMFXVO51LRUTq71gLP1UxFvmrXElqmPjA5VX7IqC9VpazAQ==", + "dependencies": [ + "@radix-ui/primitive", + "@radix-ui/react-collection@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-direction@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-id@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-roving-focus@1.1.9_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-ZzrIFnMYHHCNqSNCsuN6l7wlewBEq0O0BCSBkabJMFXVO51LRUTq71gLP1UxFvmrXElqmPjA5VX7IqC9VpazAQ==", "dependencies": [ @@ -1615,6 +2234,28 @@ "@types/react-dom" ] }, + "@radix-ui/react-scroll-area@1.2.8_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-K5h1RkYA6M0Sn61BV5LQs686zqBsSC0sGzL4/Gw4mNnjzrQcGSc6YXfC6CRFNaGydSdv5+M8cb0eNsOGo0OXtQ==", + "dependencies": [ + "@radix-ui/number", + "@radix-ui/primitive", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-direction@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-presence@1.1.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-scroll-area@1.2.8_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-K5h1RkYA6M0Sn61BV5LQs686zqBsSC0sGzL4/Gw4mNnjzrQcGSc6YXfC6CRFNaGydSdv5+M8cb0eNsOGo0OXtQ==", "dependencies": [ @@ -1715,6 +2356,20 @@ "@types/react-dom" ] }, + "@radix-ui/react-separator@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-Izof3lPpbCfTM7WDta+LRkz31jem890VjEvpVRoWQNKpDUMMVffuyq854XPGP1KYGWWmjmYvHvPFeocWhFCy1w==", + "dependencies": [ + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-separator@1.1.6_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-Izof3lPpbCfTM7WDta+LRkz31jem890VjEvpVRoWQNKpDUMMVffuyq854XPGP1KYGWWmjmYvHvPFeocWhFCy1w==", "dependencies": [ @@ -1737,6 +2392,30 @@ "@types/react-dom" ] }, + "@radix-ui/react-slider@1.3.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-Cp6hEmQtRJFci285vkdIJ+HCDLTRDk+25VhFwa1fcubywjMUE3PynBgtN5RLudOgSCYMlT4jizCXdmV+8J7Y2w==", + "dependencies": [ + "@radix-ui/number", + "@radix-ui/primitive", + "@radix-ui/react-collection@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-direction@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-previous@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-size@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-slider@1.3.4_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-Cp6hEmQtRJFci285vkdIJ+HCDLTRDk+25VhFwa1fcubywjMUE3PynBgtN5RLudOgSCYMlT4jizCXdmV+8J7Y2w==", "dependencies": [ @@ -1775,8 +2454,19 @@ "react-dom" ], "optionalPeers": [ - "@types/react", - "@types/react-dom" + "@types/react", + "@types/react-dom" + ] + }, + "@radix-ui/react-slot@1.2.2_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-y7TBO4xN4Y94FvcWIOIh18fM4R1A8S4q1jhoz4PNzOoHsFcN8pogcFmZrTYAm4F9VRUrWP/Mw7xSKybIeRI+CQ==", + "dependencies": [ + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" ] }, "@radix-ui/react-slot@1.2.2_react@19.1.0": { @@ -1867,6 +2557,31 @@ "@types/react-dom" ] }, + "@radix-ui/react-toast@1.2.13_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-e/e43mQAwgYs8BY4y9l99xTK6ig1bK2uXsFLOMn9IZ16lAgulSTsotcPHVT2ZlSb/ye6Sllq7IgyDB8dGhpeXQ==", + "dependencies": [ + "@radix-ui/primitive", + "@radix-ui/react-collection@1.1.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-dismissable-layer@1.1.9_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-portal@1.1.8_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-presence@1.1.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-visually-hidden@1.2.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-toast@1.2.13_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-e/e43mQAwgYs8BY4y9l99xTK6ig1bK2uXsFLOMn9IZ16lAgulSTsotcPHVT2ZlSb/ye6Sllq7IgyDB8dGhpeXQ==", "dependencies": [ @@ -2005,6 +2720,31 @@ "@types/react-dom" ] }, + "@radix-ui/react-tooltip@1.2.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-zYb+9dc9tkoN2JjBDIIPLQtk3gGyz8FMKoqYTb8EMVQ5a5hBcdHPECrsZVI4NpPAUOixhkoqg7Hj5ry5USowfA==", + "dependencies": [ + "@radix-ui/primitive", + "@radix-ui/react-compose-refs@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-context@1.1.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-dismissable-layer@1.1.9_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-id@1.1.1_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-popper@1.2.6_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-portal@1.1.8_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-presence@1.1.4_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@radix-ui/react-slot@1.2.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-visually-hidden@1.2.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-tooltip@1.2.6_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-zYb+9dc9tkoN2JjBDIIPLQtk3gGyz8FMKoqYTb8EMVQ5a5hBcdHPECrsZVI4NpPAUOixhkoqg7Hj5ry5USowfA==", "dependencies": [ @@ -2049,6 +2789,16 @@ "@types/react-dom" ] }, + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", + "dependencies": [ + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-callback-ref@1.1.1_react@19.1.0": { "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", "dependencies": [ @@ -2065,6 +2815,18 @@ "@types/react" ] }, + "@radix-ui/react-use-controllable-state@1.2.2_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", + "dependencies": [ + "@radix-ui/react-use-effect-event@0.0.2_@types+react@19.1.3_react@19.1.0", + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-controllable-state@1.2.2_react@19.1.0": { "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", "dependencies": [ @@ -2085,6 +2847,17 @@ "@types/react" ] }, + "@radix-ui/react-use-effect-event@0.0.2_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", + "dependencies": [ + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-effect-event@0.0.2_react@19.1.0": { "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", "dependencies": [ @@ -2103,6 +2876,17 @@ "@types/react" ] }, + "@radix-ui/react-use-escape-keydown@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", + "dependencies": [ + "@radix-ui/react-use-callback-ref@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-escape-keydown@1.1.1_react@19.1.0": { "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", "dependencies": [ @@ -2139,6 +2923,16 @@ "@types/react" ] }, + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", + "dependencies": [ + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-layout-effect@1.1.1_react@19.1.0": { "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", "dependencies": [ @@ -2155,6 +2949,16 @@ "@types/react" ] }, + "@radix-ui/react-use-previous@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", + "dependencies": [ + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-previous@1.1.1_react@19.1.0": { "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", "dependencies": [ @@ -2171,6 +2975,17 @@ "@types/react" ] }, + "@radix-ui/react-use-rect@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", + "dependencies": [ + "@radix-ui/rect", + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-rect@1.1.1_react@19.1.0": { "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", "dependencies": [ @@ -2189,6 +3004,17 @@ "@types/react" ] }, + "@radix-ui/react-use-size@1.1.1_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", + "dependencies": [ + "@radix-ui/react-use-layout-effect@1.1.1_@types+react@19.1.3_react@19.1.0", + "@types/react", + "react" + ], + "optionalPeers": [ + "@types/react" + ] + }, "@radix-ui/react-use-size@1.1.1_react@19.1.0": { "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", "dependencies": [ @@ -2207,6 +3033,20 @@ "@types/react" ] }, + "@radix-ui/react-visually-hidden@1.2.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-ORCmRUbNiZIv6uV5mhFrhsIKw4UX/N3syZtyqvry61tbGm4JlgQuSn0hk5TwCARsCjkcnuRkSdCE3xfb+ADHew==", + "dependencies": [ + "@radix-ui/react-primitive@2.1.2_@types+react@19.1.3_@types+react-dom@19.1.3__@types+react@19.1.3_react@19.1.0_react-dom@19.1.0__react@19.1.0", + "@types/react", + "@types/react-dom", + "react", + "react-dom" + ], + "optionalPeers": [ + "@types/react", + "@types/react-dom" + ] + }, "@radix-ui/react-visually-hidden@1.2.2_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-ORCmRUbNiZIv6uV5mhFrhsIKw4UX/N3syZtyqvry61tbGm4JlgQuSn0hk5TwCARsCjkcnuRkSdCE3xfb+ADHew==", "dependencies": [ @@ -2360,6 +3200,9 @@ "os": ["win32"], "cpu": ["x64"] }, + "@sindresorhus/merge-streams@2.3.0": { + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==" + }, "@tailwindcss/node@4.1.5": { "integrity": "sha512-CBhSWo0vLnWhXIvpD0qsPephiaUYfHUX3U9anwDaHZAeuGpTiB3XmsxPAN6qX7bFhipyGBqOa1QYQVVhkOUGxg==", "dependencies": [ @@ -2459,7 +3302,25 @@ "@tailwindcss/node", "@tailwindcss/oxide", "tailwindcss", - "vite" + "vite@6.3.5_picomatch@4.0.2" + ] + }, + "@tailwindcss/vite@4.1.5_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0": { + "integrity": "sha512-FE1stRoqdHSb7RxesMfCXE8icwI1W6zGE/512ae3ZDrpkQYTTYeSyUJPRCjZd8CwVAhpDUbi1YR8pcZioFJQ/w==", + "dependencies": [ + "@tailwindcss/node", + "@tailwindcss/oxide", + "tailwindcss", + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0" + ] + }, + "@ts-morph/common@0.19.0": { + "integrity": "sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==", + "dependencies": [ + "fast-glob", + "minimatch@7.4.6", + "mkdirp", + "path-browserify" ] }, "@tybys/wasm-util@0.9.0": { @@ -2510,6 +3371,9 @@ "@types/node" ] }, + "@types/cookie@0.6.0": { + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==" + }, "@types/cytoscape-fcose@2.2.4": { "integrity": "sha512-QwWtnT8HI9h+DHhG5krGc1ZY0Ex+cn85MvX96ZNAjSxuXiZDnjIZW/ypVkvvubTjIY4rSdkJY1D/Nsn8NDpmAw==", "dependencies": [ @@ -2600,6 +3464,12 @@ "@types/send" ] }, + "@types/statuses@2.0.5": { + "integrity": "sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==" + }, + "@types/tough-cookie@4.0.5": { + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==" + }, "@types/yargs-parser@21.0.3": { "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" }, @@ -2617,7 +3487,18 @@ "@babel/plugin-transform-react-jsx-source", "@types/babel__core", "react-refresh", - "vite" + "vite@6.3.5_picomatch@4.0.2" + ] + }, + "@vitejs/plugin-react@4.4.1_vite@6.3.5__picomatch@4.0.2_@babel+core@7.27.1_@types+node@22.12.0": { + "integrity": "sha512-IpEm5ZmeXAP/osiBXVVP5KjFMzbWOonMs0NaQQl+xYnUAcq4oHUBsF2+p4MgKWG4YMmFYJU8A6sxRPuowllm6w==", + "dependencies": [ + "@babel/core", + "@babel/plugin-transform-react-jsx-self", + "@babel/plugin-transform-react-jsx-source", + "@types/babel__core", + "react-refresh", + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0" ] }, "@vitest/expect@3.1.3": { @@ -2635,10 +3516,22 @@ "@vitest/spy", "estree-walker", "magic-string", - "vite" + "vite@6.3.5_picomatch@4.0.2" + ], + "optionalPeers": [ + "vite@6.3.5_picomatch@4.0.2" + ] + }, + "@vitest/mocker@3.1.3_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0": { + "integrity": "sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==", + "dependencies": [ + "@vitest/spy", + "estree-walker", + "magic-string", + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0" ], "optionalPeers": [ - "vite" + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0" ] }, "@vitest/pretty-format@3.1.3": { @@ -2683,10 +3576,13 @@ "negotiator" ] }, + "agent-base@7.1.3": { + "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==" + }, "ansi-escapes@4.3.2": { "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dependencies": [ - "type-fest" + "type-fest@0.21.3" ] }, "ansi-regex@5.0.1": { @@ -2704,6 +3600,12 @@ "ansi-styles@6.2.1": { "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" }, + "arg@5.0.2": { + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + }, + "argparse@2.0.1": { + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, "aria-hidden@1.2.4": { "integrity": "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==", "dependencies": [ @@ -2713,22 +3615,26 @@ "assertion-error@2.0.1": { "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==" }, - "autoprefixer@10.4.21_postcss@8.5.3": { - "integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==", + "ast-types@0.16.1": { + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", "dependencies": [ - "browserslist", - "caniuse-lite", - "fraction.js", - "normalize-range", - "picocolors", - "postcss", - "postcss-value-parser" - ], - "bin": true + "tslib" + ] }, "balanced-match@1.0.2": { "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, + "base64-js@1.5.1": { + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl@5.1.0": { + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "dependencies": [ + "buffer", + "inherits", + "readable-stream" + ] + }, "body-parser@2.2.0": { "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", "dependencies": [ @@ -2765,6 +3671,13 @@ ], "bin": true }, + "buffer@6.0.3": { + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dependencies": [ + "base64-js", + "ieee754" + ] + }, "bytes@3.1.2": { "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, @@ -2785,6 +3698,9 @@ "get-intrinsic" ] }, + "callsites@3.1.0": { + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, "caniuse-lite@1.0.30001717": { "integrity": "sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw==" }, @@ -2798,15 +3714,33 @@ "pathval" ] }, + "chalk@5.4.1": { + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==" + }, "chardet@0.7.0": { "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "check-error@2.1.1": { "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==" }, + "class-variance-authority@0.7.1": { + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "dependencies": [ + "clsx" + ] + }, "classnames@2.5.1": { "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" }, + "cli-cursor@4.0.0": { + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dependencies": [ + "restore-cursor" + ] + }, + "cli-spinners@2.9.2": { + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==" + }, "cli-width@4.1.0": { "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==" }, @@ -2818,9 +3752,15 @@ "wrap-ansi@7.0.0" ] }, + "clone@1.0.4": { + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==" + }, "clsx@2.1.1": { "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==" }, + "code-block-writer@12.0.0": { + "integrity": "sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==" + }, "color-convert@2.0.1": { "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dependencies": [ @@ -2830,6 +3770,9 @@ "color-name@1.1.4": { "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "commander@10.0.1": { + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" + }, "content-disposition@1.0.0": { "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", "dependencies": [ @@ -2857,10 +3800,19 @@ "layout-base" ] }, + "cosmiconfig@8.3.6": { + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dependencies": [ + "import-fresh", + "js-yaml", + "parse-json", + "path-type@4.0.0" + ] + }, "cross-spawn@7.0.6": { "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": [ - "path-key", + "path-key@3.1.1", "shebang-command", "which" ] @@ -2878,6 +3830,9 @@ "cytoscape@3.31.1": { "integrity": "sha512-Hx5Mtb1+hnmAKaZZ/7zL1Y5HTFYOjdDswZy/jD+1WINRU8KVi1B7+vlHdsTwY+VCFucTreoyu1RDzQJ9u0d2Hw==" }, + "data-uri-to-buffer@4.0.1": { + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==" + }, "debug@4.4.0": { "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", "dependencies": [ @@ -2887,6 +3842,15 @@ "deep-eql@5.0.2": { "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==" }, + "deepmerge@4.3.1": { + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + }, + "defaults@1.0.4": { + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dependencies": [ + "clone" + ] + }, "depd@2.0.0": { "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" }, @@ -2896,6 +3860,9 @@ "detect-node-es@1.1.0": { "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, + "diff@5.2.0": { + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==" + }, "dunder-proto@1.0.1": { "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dependencies": [ @@ -2929,6 +3896,12 @@ "tapable" ] }, + "error-ex@1.3.2": { + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dependencies": [ + "is-arrayish" + ] + }, "es-define-property@1.0.1": { "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" }, @@ -2982,6 +3955,10 @@ "escape-html@1.0.3": { "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, + "esprima@4.0.1": { + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": true + }, "estree-walker@3.0.3": { "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dependencies": [ @@ -2994,6 +3971,20 @@ "eventemitter3@4.0.7": { "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" }, + "execa@7.2.0": { + "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", + "dependencies": [ + "cross-spawn", + "get-stream", + "human-signals", + "is-stream", + "merge-stream", + "npm-run-path", + "onetime@6.0.0", + "signal-exit@3.0.7", + "strip-final-newline" + ] + }, "expect-type@1.2.1": { "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==" }, @@ -3037,6 +4028,22 @@ "tmp" ] }, + "fast-glob@3.3.3": { + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dependencies": [ + "@nodelib/fs.stat", + "@nodelib/fs.walk", + "glob-parent", + "merge2", + "micromatch" + ] + }, + "fastq@1.19.1": { + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dependencies": [ + "reusify" + ] + }, "fdir@6.4.4_picomatch@4.0.2": { "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", "dependencies": [ @@ -3046,6 +4053,13 @@ "picomatch@4.0.2" ] }, + "fetch-blob@3.2.0": { + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dependencies": [ + "node-domexception", + "web-streams-polyfill" + ] + }, "fill-range@7.1.1": { "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": [ @@ -3063,6 +4077,19 @@ "statuses" ] }, + "find-unused-exports@7.1.1": { + "integrity": "sha512-vr8llp+VmD3/+SvjPoGzo/SyzJGeYFBSjOaQex2hvAomfzB4ke9BEUXc6lR+CjG5xd+SSvWylFhhdCctGzeV0g==", + "dependencies": [ + "@babel/core", + "@import-maps/resolve", + "@types/babel__core", + "@types/node", + "arg", + "globby", + "kleur@4.1.5" + ], + "bin": true + }, "follow-redirects@1.15.9": { "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" }, @@ -3070,18 +4097,29 @@ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", "dependencies": [ "cross-spawn", - "signal-exit" + "signal-exit@4.1.0" + ] + }, + "formdata-polyfill@4.0.10": { + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dependencies": [ + "fetch-blob" ] }, "forwarded@0.2.0": { "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, - "fraction.js@4.3.7": { - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==" - }, "fresh@2.0.0": { "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==" }, + "fs-extra@11.3.0": { + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dependencies": [ + "graceful-fs", + "jsonfile", + "universalify@2.0.1" + ] + }, "fsevents@2.3.3": { "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "os": ["darwin"], @@ -3114,6 +4152,9 @@ "get-nonce@1.0.1": { "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" }, + "get-own-enumerable-keys@1.0.0": { + "integrity": "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==" + }, "get-proto@1.0.1": { "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dependencies": [ @@ -3121,12 +4162,21 @@ "es-object-atoms" ] }, + "get-stream@6.0.1": { + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + }, + "glob-parent@5.1.2": { + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": [ + "is-glob" + ] + }, "glob@11.0.2": { "integrity": "sha512-YT7U7Vye+t5fZ/QMkBFrTJ7ZQxInIUjwyAjVj84CYXqgBdv30MFUPGnBR6sQaVq6Is15wYJUsnzTuWaGRBhBAQ==", "dependencies": [ "foreground-child", "jackspeak", - "minimatch", + "minimatch@10.0.1", "minipass", "package-json-from-dist", "path-scurry" @@ -3136,12 +4186,26 @@ "globals@11.12.0": { "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, + "globby@14.1.0": { + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dependencies": [ + "@sindresorhus/merge-streams", + "fast-glob", + "ignore", + "path-type@6.0.0", + "slash", + "unicorn-magic" + ] + }, "gopd@1.2.0": { "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" }, "graceful-fs@4.2.11": { "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, + "graphql@16.11.0": { + "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==" + }, "has-symbols@1.1.0": { "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" }, @@ -3151,6 +4215,9 @@ "function-bind" ] }, + "headers-polyfill@4.0.3": { + "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==" + }, "http-errors@2.0.0": { "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dependencies": [ @@ -3180,6 +4247,16 @@ "requires-port" ] }, + "https-proxy-agent@6.2.1": { + "integrity": "sha512-ONsE3+yfZF2caH5+bJlcddtWqNI3Gvs5A38+ngvljxaBiRXRswym2c7yf8UAeFpRFKjFNHIFEHqR/OLAWJzyiA==", + "dependencies": [ + "agent-base", + "debug" + ] + }, + "human-signals@4.3.1": { + "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==" + }, "iconv-lite@0.4.24": { "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dependencies": [ @@ -3192,12 +4269,28 @@ "safer-buffer" ] }, + "ieee754@1.2.1": { + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore@7.0.4": { + "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==" + }, + "import-fresh@3.3.1": { + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dependencies": [ + "parent-module", + "resolve-from" + ] + }, "inherits@2.0.4": { "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ipaddr.js@1.9.1": { "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-arrayish@0.2.1": { + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + }, "is-extglob@2.1.1": { "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" }, @@ -3210,15 +4303,33 @@ "is-extglob" ] }, + "is-interactive@2.0.0": { + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==" + }, + "is-node-process@1.2.0": { + "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==" + }, "is-number@7.0.0": { "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-obj@3.0.0": { + "integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==" + }, "is-plain-object@5.0.0": { "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" }, "is-promise@4.0.0": { "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" }, + "is-regexp@3.1.0": { + "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==" + }, + "is-stream@3.0.0": { + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==" + }, + "is-unicode-supported@1.3.0": { + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==" + }, "isexe@2.0.0": { "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, @@ -3235,14 +4346,39 @@ "js-tokens@4.0.0": { "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "js-yaml@4.1.0": { + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": [ + "argparse" + ], + "bin": true + }, "jsesc@3.1.0": { "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "bin": true }, + "json-parse-even-better-errors@2.3.1": { + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "json5@2.2.3": { "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": true }, + "jsonfile@6.1.0": { + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": [ + "universalify@2.0.1" + ], + "optionalDependencies": [ + "graceful-fs" + ] + }, + "kleur@3.0.3": { + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" + }, + "kleur@4.1.5": { + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" + }, "layout-base@2.0.1": { "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" }, @@ -3314,6 +4450,16 @@ "lightningcss-win32-x64-msvc" ] }, + "lines-and-columns@1.2.4": { + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + }, + "log-symbols@5.1.0": { + "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", + "dependencies": [ + "chalk", + "is-unicode-supported" + ] + }, "loupe@3.1.3": { "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==" }, @@ -3326,6 +4472,12 @@ "yallist" ] }, + "lucide-react@0.508.0_react@19.1.0": { + "integrity": "sha512-gcP16PnexqtOFrTtv98kVsGzTfnbPekzZiQfByi2S89xfk7E/4uKE1USZqccIp58v42LqkO7MuwpCqshwSrJCg==", + "dependencies": [ + "react" + ] + }, "magic-string@0.30.17": { "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "dependencies": [ @@ -3341,6 +4493,12 @@ "merge-descriptors@2.0.0": { "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==" }, + "merge-stream@2.0.0": { + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "merge2@1.4.1": { + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, "micromatch@4.0.8": { "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": [ @@ -3357,18 +4515,87 @@ "mime-db" ] }, + "mimic-fn@2.1.0": { + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "mimic-fn@4.0.0": { + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==" + }, "minimatch@10.0.1": { "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", "dependencies": [ "brace-expansion" ] }, + "minimatch@7.4.6": { + "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "dependencies": [ + "brace-expansion" + ] + }, + "minimist@1.2.8": { + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, "minipass@7.1.2": { "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==" }, + "mkdirp@2.1.6": { + "integrity": "sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==", + "bin": true + }, "ms@2.1.3": { "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "msw@2.7.6": { + "integrity": "sha512-P+rwn43ktxN8ghcl8q+hSAUlEi0PbJpDhGmDkw4zeUnRj3hBCVynWD+dTu38yLYKCE9ZF1OYcvpy7CTBRcqkZA==", + "dependencies": [ + "@bundled-es-modules/cookie", + "@bundled-es-modules/statuses", + "@bundled-es-modules/tough-cookie", + "@inquirer/confirm@5.1.9", + "@mswjs/interceptors", + "@open-draft/deferred-promise", + "@open-draft/until", + "@types/cookie", + "@types/statuses", + "graphql", + "headers-polyfill", + "is-node-process", + "outvariant", + "path-to-regexp@6.3.0", + "picocolors", + "strict-event-emitter", + "type-fest@4.41.0", + "yargs" + ], + "scripts": true, + "bin": true + }, + "msw@2.7.6_@types+node@22.12.0": { + "integrity": "sha512-P+rwn43ktxN8ghcl8q+hSAUlEi0PbJpDhGmDkw4zeUnRj3hBCVynWD+dTu38yLYKCE9ZF1OYcvpy7CTBRcqkZA==", + "dependencies": [ + "@bundled-es-modules/cookie", + "@bundled-es-modules/statuses", + "@bundled-es-modules/tough-cookie", + "@inquirer/confirm@5.1.9_@types+node@22.12.0", + "@mswjs/interceptors", + "@open-draft/deferred-promise", + "@open-draft/until", + "@types/cookie", + "@types/statuses", + "graphql", + "headers-polyfill", + "is-node-process", + "outvariant", + "path-to-regexp@6.3.0", + "picocolors", + "strict-event-emitter", + "type-fest@4.41.0", + "yargs" + ], + "scripts": true, + "bin": true + }, "mute-stream@2.0.0": { "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==" }, @@ -3382,6 +4609,18 @@ "node-addon-api@8.3.1": { "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==" }, + "node-domexception@1.0.0": { + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": true + }, + "node-fetch@3.3.2": { + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dependencies": [ + "data-uri-to-buffer", + "fetch-blob", + "formdata-polyfill" + ] + }, "node-gyp-build@4.8.4": { "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "bin": true @@ -3389,8 +4628,11 @@ "node-releases@2.0.19": { "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==" }, - "normalize-range@0.1.2": { - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==" + "npm-run-path@5.3.0": { + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", + "dependencies": [ + "path-key@4.0.0" + ] }, "object-inspect@1.13.4": { "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==" @@ -3407,18 +4649,68 @@ "wrappy" ] }, + "onetime@5.1.2": { + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": [ + "mimic-fn@2.1.0" + ] + }, + "onetime@6.0.0": { + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dependencies": [ + "mimic-fn@4.0.0" + ] + }, + "ora@6.3.1": { + "integrity": "sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==", + "dependencies": [ + "chalk", + "cli-cursor", + "cli-spinners", + "is-interactive", + "is-unicode-supported", + "log-symbols", + "stdin-discarder", + "strip-ansi@7.1.0", + "wcwidth" + ] + }, "os-tmpdir@1.0.2": { "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" }, + "outvariant@1.4.3": { + "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==" + }, "package-json-from-dist@1.0.1": { "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==" }, + "parent-module@1.0.1": { + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dependencies": [ + "callsites" + ] + }, + "parse-json@5.2.0": { + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dependencies": [ + "@babel/code-frame", + "error-ex", + "json-parse-even-better-errors", + "lines-and-columns" + ] + }, "parseurl@1.3.3": { "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "path-browserify@1.0.1": { + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, "path-key@3.1.1": { "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, + "path-key@4.0.0": { + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==" + }, "path-scurry@2.0.0": { "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", "dependencies": [ @@ -3426,9 +4718,18 @@ "minipass" ] }, + "path-to-regexp@6.3.0": { + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==" + }, "path-to-regexp@8.2.0": { "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==" }, + "path-type@4.0.0": { + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "path-type@6.0.0": { + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==" + }, "pathe@2.0.3": { "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==" }, @@ -3444,9 +4745,6 @@ "picomatch@4.0.2": { "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==" }, - "postcss-value-parser@4.2.0": { - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" - }, "postcss@8.5.3": { "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "dependencies": [ @@ -3455,6 +4753,13 @@ "source-map-js" ] }, + "prompts@2.4.2": { + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dependencies": [ + "kleur@3.0.3", + "sisteransi" + ] + }, "proxy-addr@2.0.7": { "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dependencies": [ @@ -3462,12 +4767,27 @@ "ipaddr.js" ] }, + "psl@1.15.0": { + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dependencies": [ + "punycode" + ] + }, + "punycode@2.3.1": { + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + }, "qs@6.14.0": { "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "dependencies": [ "side-channel" ] }, + "querystringify@2.2.0": { + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, + "queue-microtask@1.2.3": { + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, "radix-ui@1.4.1_react@19.1.0_react-dom@19.1.0__react@19.1.0": { "integrity": "sha512-xG1aeAgvAiVglxHXMpHyk7RqLGnc8VnDUZvzpE8rZ8GAhuGeNm/+7YbIwCV+rKKRpsSgxdnvfUObQidK2EnTzw==", "dependencies": [ @@ -3617,15 +4937,21 @@ "scheduler" ] }, - "react-icons@5.5.0_react@19.1.0": { - "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==", - "dependencies": [ - "react" - ] - }, "react-refresh@0.17.0": { "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==" }, + "react-remove-scroll-bar@2.3.8_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", + "dependencies": [ + "@types/react", + "react", + "react-style-singleton@2.2.3_@types+react@19.1.3_react@19.1.0", + "tslib" + ], + "optionalPeers": [ + "@types/react" + ] + }, "react-remove-scroll-bar@2.3.8_react@19.1.0": { "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", "dependencies": [ @@ -3646,6 +4972,21 @@ "@types/react" ] }, + "react-remove-scroll@2.6.3_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", + "dependencies": [ + "@types/react", + "react", + "react-remove-scroll-bar@2.3.8_@types+react@19.1.3_react@19.1.0", + "react-style-singleton@2.2.3_@types+react@19.1.3_react@19.1.0", + "tslib", + "use-callback-ref@1.3.3_@types+react@19.1.3_react@19.1.0", + "use-sidecar@1.1.3_@types+react@19.1.3_react@19.1.0" + ], + "optionalPeers": [ + "@types/react" + ] + }, "react-remove-scroll@2.6.3_react@19.1.0": { "integrity": "sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==", "dependencies": [ @@ -3672,8 +5013,8 @@ "@types/react" ] }, - "react-resizable-panels@2.1.8_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-oDvD0sw34Ecx00cQFLiRJpAE2fCgNLBr8DMrBzkrsaUiLpAycIQoY3eAWfMblDql3pTIMZ60wJ/P89RO1htM2w==", + "react-resizable-panels@3.0.1_react@19.1.0_react-dom@19.1.0__react@19.1.0": { + "integrity": "sha512-6ruCEyw0iqXRcXEktPQn1HL553DNhrdLisCyEdSpzhkmo9bPqZxskJZ+aGeFqJ1qPvIWxuAiag82kvLSb2JZTQ==", "dependencies": [ "react", "react-dom" @@ -3692,6 +5033,18 @@ "react-dom" ] }, + "react-style-singleton@2.2.3_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", + "dependencies": [ + "@types/react", + "get-nonce", + "react", + "tslib" + ], + "optionalPeers": [ + "@types/react" + ] + }, "react-style-singleton@2.2.3_react@19.1.0": { "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", "dependencies": [ @@ -3712,16 +5065,26 @@ "@types/react" ] }, - "react-toastify@11.0.5_react@19.1.0_react-dom@19.1.0__react@19.1.0": { - "integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==", + "react@19.1.0": { + "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==" + }, + "readable-stream@3.6.2": { + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": [ - "clsx", - "react", - "react-dom" + "inherits", + "string_decoder", + "util-deprecate" ] }, - "react@19.1.0": { - "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==" + "recast@0.23.11": { + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dependencies": [ + "ast-types", + "esprima", + "source-map", + "tiny-invariant", + "tslib" + ] }, "require-directory@2.1.1": { "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" @@ -3729,6 +5092,19 @@ "requires-port@1.0.0": { "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "resolve-from@4.0.0": { + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "restore-cursor@4.0.0": { + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "dependencies": [ + "onetime@5.1.2", + "signal-exit@3.0.7" + ] + }, + "reusify@1.1.0": { + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==" + }, "rollup@4.40.2": { "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", "dependencies": [ @@ -3766,7 +5142,13 @@ "depd", "is-promise", "parseurl", - "path-to-regexp" + "path-to-regexp@8.2.0" + ] + }, + "run-parallel@1.2.0": { + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": [ + "queue-microtask" ] }, "safe-buffer@5.2.1": { @@ -3813,6 +5195,64 @@ "setprototypeof@1.2.0": { "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" }, + "shadcn@2.5.0_@babel+core@7.27.1": { + "integrity": "sha512-kqbTpDWIYE8spytMiJFoKyzOTHb+DzNLjMXzz+ifDFTBgTPv6gIydmirTZwwfFb23XvenrTSVHsZHUjGsllcHw==", + "dependencies": [ + "@antfu/ni", + "@babel/core", + "@babel/parser", + "@babel/plugin-transform-typescript", + "commander", + "cosmiconfig", + "deepmerge", + "diff", + "execa", + "fast-glob", + "fs-extra", + "https-proxy-agent", + "kleur@4.1.5", + "msw@2.7.6", + "node-fetch", + "ora", + "postcss", + "prompts", + "recast", + "stringify-object", + "ts-morph", + "tsconfig-paths", + "zod" + ], + "bin": true + }, + "shadcn@2.5.0_@babel+core@7.27.1_@types+node@22.12.0": { + "integrity": "sha512-kqbTpDWIYE8spytMiJFoKyzOTHb+DzNLjMXzz+ifDFTBgTPv6gIydmirTZwwfFb23XvenrTSVHsZHUjGsllcHw==", + "dependencies": [ + "@antfu/ni", + "@babel/core", + "@babel/parser", + "@babel/plugin-transform-typescript", + "commander", + "cosmiconfig", + "deepmerge", + "diff", + "execa", + "fast-glob", + "fs-extra", + "https-proxy-agent", + "kleur@4.1.5", + "msw@2.7.6_@types+node@22.12.0", + "node-fetch", + "ora", + "postcss", + "prompts", + "recast", + "stringify-object", + "ts-morph", + "tsconfig-paths", + "zod" + ], + "bin": true + }, "shebang-command@2.0.0": { "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dependencies": [ @@ -3861,12 +5301,24 @@ "siginfo@2.0.0": { "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==" }, + "signal-exit@3.0.7": { + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, "signal-exit@4.1.0": { "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" }, + "sisteransi@1.0.5": { + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + }, + "slash@5.1.0": { + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==" + }, "source-map-js@1.2.1": { "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" }, + "source-map@0.6.1": { + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, "stackback@0.0.2": { "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==" }, @@ -3876,6 +5328,15 @@ "std-env@3.9.0": { "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==" }, + "stdin-discarder@0.1.0": { + "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", + "dependencies": [ + "bl" + ] + }, + "strict-event-emitter@0.5.1": { + "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==" + }, "string-width@4.2.3": { "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dependencies": [ @@ -3892,6 +5353,20 @@ "strip-ansi@7.1.0" ] }, + "string_decoder@1.3.0": { + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": [ + "safe-buffer" + ] + }, + "stringify-object@5.0.0": { + "integrity": "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==", + "dependencies": [ + "get-own-enumerable-keys", + "is-obj", + "is-regexp" + ] + }, "strip-ansi@6.0.1": { "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": [ @@ -3904,12 +5379,24 @@ "ansi-regex@6.1.0" ] }, + "strip-bom@3.0.0": { + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + }, + "strip-final-newline@3.0.0": { + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==" + }, + "tailwind-merge@3.2.0": { + "integrity": "sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==" + }, "tailwindcss@4.1.5": { "integrity": "sha512-nYtSPfWGDiWgCkwQG/m+aX83XCwf62sBgg3bIlNiiOcggnS1x3uVRDAuyelBFL+vJdOPPCGElxv9DjHJjRHiVA==" }, "tapable@2.2.1": { "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, + "tiny-invariant@1.3.3": { + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==" + }, "tinybench@2.9.0": { "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==" }, @@ -3947,6 +5434,15 @@ "toidentifier@1.0.1": { "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "tough-cookie@4.1.4": { + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", + "dependencies": [ + "psl", + "punycode", + "universalify@0.2.0", + "url-parse" + ] + }, "tree-sitter-c-sharp@0.23.1_tree-sitter@0.22.4": { "integrity": "sha512-9zZ4FlcTRWWfRf6f4PgGhG8saPls6qOOt75tDfX7un9vQZJmARjPrAC6yBNCX2T/VKcCjIDbgq0evFaB3iGhQw==", "dependencies": [ @@ -3979,15 +5475,36 @@ ], "scripts": true }, + "ts-morph@18.0.0": { + "integrity": "sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==", + "dependencies": [ + "@ts-morph/common", + "code-block-writer" + ] + }, + "tsconfig-paths@4.2.0": { + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dependencies": [ + "json5", + "minimist", + "strip-bom" + ] + }, "tslib@2.8.1": { "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "turbo-stream@2.4.0": { "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" }, + "tw-animate-css@1.2.9": { + "integrity": "sha512-9O4k1at9pMQff9EAcCEuy1UNO43JmaPQvq+0lwza9Y0BQ6LB38NiMj+qHqjoQf40355MX+gs6wtlR6H9WsSXFg==" + }, "type-fest@0.21.3": { "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" }, + "type-fest@4.41.0": { + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==" + }, "type-is@2.0.1": { "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "dependencies": [ @@ -3999,6 +5516,15 @@ "undici-types@6.20.0": { "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" }, + "unicorn-magic@0.3.0": { + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==" + }, + "universalify@0.2.0": { + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==" + }, + "universalify@2.0.1": { + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + }, "unpipe@1.0.0": { "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, @@ -4011,6 +5537,24 @@ ], "bin": true }, + "url-parse@1.5.10": { + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": [ + "querystringify", + "requires-port" + ] + }, + "use-callback-ref@1.3.3_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", + "dependencies": [ + "@types/react", + "react", + "tslib" + ], + "optionalPeers": [ + "@types/react" + ] + }, "use-callback-ref@1.3.3_react@19.1.0": { "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", "dependencies": [ @@ -4029,6 +5573,18 @@ "@types/react" ] }, + "use-sidecar@1.1.3_@types+react@19.1.3_react@19.1.0": { + "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", + "dependencies": [ + "@types/react", + "detect-node-es", + "react", + "tslib" + ], + "optionalPeers": [ + "@types/react" + ] + }, "use-sidecar@1.1.3_react@19.1.0": { "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "dependencies": [ @@ -4055,6 +5611,9 @@ "react" ] }, + "util-deprecate@1.0.2": { + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, "uuid@11.1.0": { "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "bin": true @@ -4069,7 +5628,18 @@ "debug", "es-module-lexer", "pathe", - "vite" + "vite@6.3.5_picomatch@4.0.2" + ], + "bin": true + }, + "vite-node@3.1.3_@types+node@22.12.0": { + "integrity": "sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==", + "dependencies": [ + "cac", + "debug", + "es-module-lexer", + "pathe", + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0" ], "bin": true }, @@ -4088,11 +5658,58 @@ ], "bin": true }, + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0": { + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dependencies": [ + "@types/node", + "esbuild", + "fdir", + "picomatch@4.0.2", + "postcss", + "rollup", + "tinyglobby" + ], + "optionalDependencies": [ + "fsevents" + ], + "optionalPeers": [ + "@types/node" + ], + "bin": true + }, "vitest@3.1.3_vite@6.3.5__picomatch@4.0.2": { "integrity": "sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==", "dependencies": [ "@vitest/expect", - "@vitest/mocker", + "@vitest/mocker@3.1.3_vite@6.3.5__picomatch@4.0.2", + "@vitest/pretty-format", + "@vitest/runner", + "@vitest/snapshot", + "@vitest/spy", + "@vitest/utils", + "chai", + "debug", + "expect-type", + "magic-string", + "pathe", + "std-env", + "tinybench", + "tinyexec", + "tinyglobby", + "tinypool", + "tinyrainbow", + "vite@6.3.5_picomatch@4.0.2", + "vite-node@3.1.3", + "why-is-node-running" + ], + "bin": true + }, + "vitest@3.1.3_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0": { + "integrity": "sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==", + "dependencies": [ + "@types/node", + "@vitest/expect", + "@vitest/mocker@3.1.3_vite@6.3.5__picomatch@4.0.2_@types+node@22.12.0", "@vitest/pretty-format", "@vitest/runner", "@vitest/snapshot", @@ -4109,12 +5726,24 @@ "tinyglobby", "tinypool", "tinyrainbow", - "vite", - "vite-node", + "vite@6.3.5_picomatch@4.0.2_@types+node@22.12.0", + "vite-node@3.1.3_@types+node@22.12.0", "why-is-node-running" ], + "optionalPeers": [ + "@types/node" + ], "bin": true }, + "wcwidth@1.0.1": { + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dependencies": [ + "defaults" + ] + }, + "web-streams-polyfill@3.3.3": { + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==" + }, "which@2.0.2": { "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dependencies": [ @@ -4186,10 +5815,22 @@ } }, "workspace": { + "dependencies": [ + "npm:vitest@^3.1.3" + ], "members": { "packages/app": { "dependencies": [ "npm:@deno/vite-plugin@^1.0.4", + "npm:@radix-ui/react-dialog@^1.1.13", + "npm:@radix-ui/react-dropdown-menu@^2.1.14", + "npm:@radix-ui/react-label@^2.1.6", + "npm:@radix-ui/react-scroll-area@^1.2.8", + "npm:@radix-ui/react-separator@^1.1.6", + "npm:@radix-ui/react-slider@^1.3.4", + "npm:@radix-ui/react-slot@^1.2.2", + "npm:@radix-ui/react-toast@^1.2.13", + "npm:@radix-ui/react-tooltip@^1.2.6", "npm:@radix-ui/themes@^3.2.1", "npm:@tailwindcss/vite@^4.1.5", "npm:@types/cytoscape-fcose@^2.2.4", @@ -4197,16 +5838,18 @@ "npm:@types/react-router@^5.1.20", "npm:@types/react@^19.1.3", "npm:@vitejs/plugin-react@^4.4.1", - "npm:autoprefixer@^10.4.21", + "npm:class-variance-authority@~0.7.1", + "npm:clsx@^2.1.1", "npm:cytoscape-fcose@^2.2.0", "npm:cytoscape@3.31.1", + "npm:lucide-react@0.508", "npm:react-dom@^19.1.0", - "npm:react-icons@5.5.0", - "npm:react-resizable-panels@2.1.8", + "npm:react-resizable-panels@^3.0.1", "npm:react-router@^7.5.3", - "npm:react-toastify@^11.0.5", "npm:react@^19.1.0", + "npm:tailwind-merge@^3.2.0", "npm:tailwindcss@^4.1.5", + "npm:tw-animate-css@^1.2.9", "npm:vite@^6.3.5" ] }, @@ -4222,7 +5865,6 @@ "npm:tree-sitter-python@~0.23.6", "npm:tree-sitter@~0.22.4", "npm:uuid@^11.1.0", - "npm:vitest@^3.1.3", "npm:yargs@^17.7.2", "npm:zod@^3.24.4" ] diff --git a/packages/app/components.json b/packages/app/components.json new file mode 100644 index 00000000..285033d3 --- /dev/null +++ b/packages/app/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "", + "css": "src/styles/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} diff --git a/packages/app/deno.json b/packages/app/deno.json index 23d155d5..c964995b 100644 --- a/packages/app/deno.json +++ b/packages/app/deno.json @@ -5,6 +5,15 @@ "imports": { "@napi/shared": "../shared/src/index.ts", "@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.4", + "@radix-ui/react-dialog": "npm:@radix-ui/react-dialog@^1.1.13", + "@radix-ui/react-dropdown-menu": "npm:@radix-ui/react-dropdown-menu@^2.1.14", + "@radix-ui/react-label": "npm:@radix-ui/react-label@^2.1.6", + "@radix-ui/react-scroll-area": "npm:@radix-ui/react-scroll-area@^1.2.8", + "@radix-ui/react-separator": "npm:@radix-ui/react-separator@^1.1.6", + "@radix-ui/react-slider": "npm:@radix-ui/react-slider@^1.3.4", + "@radix-ui/react-slot": "npm:@radix-ui/react-slot@^1.2.2", + "@radix-ui/react-toast": "npm:@radix-ui/react-toast@^1.2.13", + "@radix-ui/react-tooltip": "npm:@radix-ui/react-tooltip@^1.2.6", "@radix-ui/themes": "npm:@radix-ui/themes@^3.2.1", "@tailwindcss/vite": "npm:@tailwindcss/vite@^4.1.5", "@types/cytoscape-fcose": "npm:@types/cytoscape-fcose@^2.2.4", @@ -12,16 +21,18 @@ "@types/react-dom": "npm:@types/react-dom@^19.1.3", "@types/react-router": "npm:@types/react-router@^5.1.20", "@vitejs/plugin-react": "npm:@vitejs/plugin-react@^4.4.1", - "autoprefixer": "npm:autoprefixer@^10.4.21", + "class-variance-authority": "npm:class-variance-authority@^0.7.1", + "clsx": "npm:clsx@^2.1.1", "cytoscape-fcose": "npm:cytoscape-fcose@^2.2.0", + "lucide-react": "npm:lucide-react@^0.508.0", "react": "npm:react@^19.1.0", "react-dom": "npm:react-dom@^19.1.0", - "react-icons": "npm:react-icons@5.5.0", "react-router": "npm:react-router@^7.5.3", - "react-toastify": "npm:react-toastify@^11.0.5", - "react-resizable-panels": "npm:react-resizable-panels@2.1.8", + "react-resizable-panels": "npm:react-resizable-panels@^3.0.1", "cytoscape": "npm:cytoscape@3.31.1", + "tailwind-merge": "npm:tailwind-merge@^3.2.0", "tailwindcss": "npm:tailwindcss@^4.1.5", + "tw-animate-css": "npm:tw-animate-css@^1.2.9", "vite": "npm:vite@^6.3.5" }, "tasks": { diff --git a/packages/app/index.html b/packages/app/index.html index be954c35..723f8983 100644 --- a/packages/app/index.html +++ b/packages/app/index.html @@ -3,6 +3,7 @@ + NanoAPI diff --git a/packages/app/src/components/Cytoscape/ControlExtensions/FiltersExtension.tsx b/packages/app/src/components/Cytoscape/ControlExtensions/FiltersExtension.tsx deleted file mode 100644 index 227cb303..00000000 --- a/packages/app/src/components/Cytoscape/ControlExtensions/FiltersExtension.tsx +++ /dev/null @@ -1,301 +0,0 @@ -import { type MouseEvent, useEffect, useRef, useState } from "react"; -import { useParams } from "react-router"; -import { Button, Checkbox, DropdownMenu } from "@radix-ui/themes"; -import { LuChevronUp } from "react-icons/lu"; -import type { Core } from "cytoscape"; -import { toast } from "react-toastify"; -import { MdFilterAlt } from "react-icons/md"; - -interface FiltersType { - showExternal: boolean; - showInternal: boolean; - showVariables: boolean; - showFunctions: boolean; - showClasses: boolean; -} - -export default function FiltersExtension(props: { - busy: boolean; - cy: Core; - onLayout: () => void; -}) { - const initialized = useRef(false); - const [filters, setFilters] = useState({ - showExternal: true, - showInternal: true, - showVariables: true, - showFunctions: true, - showClasses: true, - }); - const { file } = useParams(); - - function checkFiltersSet() { - if (!filters) return false; - - // For boolean filters, assuming they take the form "show X" - // then we need to return false if they are set to their default value - if (!filters.showExternal) { - return true; - } - - if (!filters.showInternal) { - return true; - } - - if (!filters.showVariables) { - return true; - } - - if (!filters.showFunctions) { - return true; - } - - if (!filters.showClasses) { - return true; - } - - return false; - } - - useEffect(() => { - if (!props.cy) return; - - const INITIAL_NODE_LIMIT = 50; - const nodeCount = props.cy.nodes().length; - - // Handle strict mode for dev - if (!initialized.current) { - initialized.current = true; - return; - } - - if (nodeCount > INITIAL_NODE_LIMIT) { - toast.info( - `There are more than ${INITIAL_NODE_LIMIT} elements on screen. We recommend using the filters in the control bar to get a better view of the graph.`, - ); - } - }, []); - - // Show and hide external nodes and edges - useEffect(() => { - if (!props.cy) return; - - // Grab only the external nodes - const nodes = props.cy.nodes().filter((node) => { - return node.data("customData").isExternal; - }); - - if (filters.showExternal) { - nodes.removeClass("hidden"); - } else { - nodes.addClass("hidden"); - } - }, [filters.showExternal]); - - // Show and hide internal nodes and edges - useEffect(() => { - if (!props.cy) return; - - // Grab only the internal nodes - const nodes = props.cy.nodes().filter((node) => { - return ( - !node.data("customData").isExternal && - node.data("customData").fileName !== file - ); - }); - if (filters.showInternal) { - nodes.removeClass("hidden"); - } else { - nodes.addClass("hidden"); - } - }, [filters.showInternal]); - - // Show and hide variables - useEffect(() => { - if (!props.cy) return; - - // Grab only the variable nodes - const nodes = props.cy.nodes().filter((node) => { - return ( - node.data("customData").symbolType === "variable" && - node.data("customData").fileName === file - ); - }); - if (filters.showVariables) { - nodes.removeClass("hidden"); - } else { - nodes.addClass("hidden"); - } - }, [filters.showVariables]); - - // Show and hide functions - useEffect(() => { - if (!props.cy) return; - - // Grab only the function nodes - const nodes = props.cy.nodes().filter((node) => { - return ( - node.data("customData").symbolType === "function" && - node.data("customData").fileName === file - ); - }); - if (filters.showFunctions) { - nodes.removeClass("hidden"); - } else { - nodes.addClass("hidden"); - } - }, [filters.showFunctions]); - - // Show and hide classes - useEffect(() => { - if (!props.cy) return; - - // Grab only the class nodes - const nodes = props.cy.nodes().filter((node) => { - return ( - node.data("customData").symbolType === "class" && - node.data("customData").fileName === file - ); - }); - - if (filters.showClasses) { - nodes.removeClass("hidden"); - } else { - nodes.addClass("hidden"); - } - }, [filters.showClasses]); - - return ( - - - - - - {/* Add filter options here */} - Supporting files - { - e.preventDefault(); - setFilters({ ...filters, showExternal: !filters.showExternal }); - }} - className="flex justify-between" - > - Show external - - setFilters({ ...filters, showExternal: Boolean(checked) })} - /> - - { - e.preventDefault(); - setFilters({ ...filters, showInternal: !filters.showInternal }); - }} - className="flex justify-between" - > - Show internal - - setFilters({ ...filters, showInternal: Boolean(checked) })} - /> - - - Main file - { - e.preventDefault(); - setFilters({ ...filters, showVariables: !filters.showVariables }); - }} - className="flex justify-between" - > - Show variables - - setFilters({ ...filters, showVariables: Boolean(checked) })} - /> - - { - e.preventDefault(); - setFilters({ ...filters, showFunctions: !filters.showFunctions }); - }} - className="flex justify-between" - > - Show functions - - setFilters({ ...filters, showFunctions: Boolean(checked) })} - /> - - { - e.preventDefault(); - setFilters({ ...filters, showClasses: !filters.showClasses }); - }} - className="flex justify-between" - > - Show classes - - setFilters({ ...filters, showClasses: Boolean(checked) })} - /> - - - - - - ); -} diff --git a/packages/app/src/components/Cytoscape/ControlExtensions/GraphDepthExtension.tsx b/packages/app/src/components/Cytoscape/ControlExtensions/GraphDepthExtension.tsx deleted file mode 100644 index 0abb5ce2..00000000 --- a/packages/app/src/components/Cytoscape/ControlExtensions/GraphDepthExtension.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import { useState } from "react"; -import type { Core } from "cytoscape"; -import { Button, DropdownMenu, Slider, TextField } from "@radix-ui/themes"; -import { MdTune } from "react-icons/md"; -import { LuChevronUp } from "react-icons/lu"; - -export default function GraphDepthExtension(props: { - busy: boolean; - cy: Core; - dependencyState: { - depth: number; - setDepth: (depth: number) => void; - }; - dependentState: { - depth: number; - setDepth: (depth: number) => void; - }; -}) { - const { dependencyState, dependentState } = props; - const [tempDependencyDepth, setTempDependencyDepth] = useState( - dependencyState.depth, - ); - const [tempDependentDepth, setTempDependentDepth] = useState( - dependentState.depth, - ); - - function checkFiltersSet() { - if (!props.cy) return false; - - if ( - tempDependencyDepth > 1 || - tempDependentDepth > 1 || - tempDependencyDepth < 1 || - tempDependentDepth < 1 - ) { - return true; - } - - return false; - } - - function applyChanges() { - if (tempDependencyDepth !== dependencyState.depth) { - dependencyState.setDepth(tempDependencyDepth); - } - if (tempDependentDepth !== dependentState.depth) { - dependentState.setDepth(tempDependentDepth); - } - } - - return ( - - - - - - Dependency depth -
- { - setTempDependencyDepth(value[0]); - }} - className="grow" - /> - { - const parsedValue = parseInt(e.target.value, 10); - if (!isNaN(parsedValue) && parsedValue >= 0) { - setTempDependencyDepth(parsedValue); - } - }} - onKeyUp={(e) => { - if (e.key === "Up" || e.key === "ArrowUp") { - setTempDependencyDepth(tempDependencyDepth + 1); - } else if (e.key === "Down" || e.key === "ArrowDown") { - setTempDependencyDepth( - tempDependencyDepth === 0 ? 0 : tempDependencyDepth - 1, - ); - } - }} - className="max-w-10" - /> -
- - Dependent depth -
- { - setTempDependentDepth(value[0]); - }} - className="grow" - /> - { - const parsedValue = parseInt(e.target.value, 10); - if (!isNaN(parsedValue) && parsedValue >= 0) { - setTempDependentDepth(parsedValue); - } - }} - onKeyUp={(e) => { - if (e.key === "Up" || e.key === "ArrowUp") { - setTempDependentDepth(tempDependentDepth + 1); - } else if (e.key === "Down" || e.key === "ArrowDown") { - setTempDependentDepth( - tempDependentDepth === 0 ? 0 : tempDependentDepth - 1, - ); - } - }} - className="max-w-10" - /> -
- - - -
-
- ); -} diff --git a/packages/app/src/components/Cytoscape/ControlExtensions/MetricsExtension.tsx b/packages/app/src/components/Cytoscape/ControlExtensions/MetricsExtension.tsx deleted file mode 100644 index 7debbe64..00000000 --- a/packages/app/src/components/Cytoscape/ControlExtensions/MetricsExtension.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { Button, DropdownMenu } from "@radix-ui/themes"; -import { LuChevronUp } from "react-icons/lu"; -import { - type Metric, - metricCharacterCount, - metricCodeCharacterCount, - metricCodeLineCount, - metricCyclomaticComplexity, - metricDependencyCount, - metricDependentCount, - metricLinesCount, -} from "@napi/shared"; - -// Extension for the controls in the project view -export default function MetricsExtension(props: { - busy: boolean; - metricState: { - metric: Metric | undefined; - setMetric: (metric: Metric | undefined) => void; - }; -}) { - const metric = props.metricState.metric; - - function getMetricLabel(metric: Metric | undefined) { - if (metric === metricLinesCount) { - return "Lines"; - } - if (metric === metricCodeLineCount) { - return "Code Lines"; - } - if (metric === metricCharacterCount) { - return "Chars"; - } - if (metric === metricCodeCharacterCount) { - return "Code Chars"; - } - if (metric === metricDependencyCount) { - return "Dependencies"; - } - if (metric === metricDependentCount) { - return "Dependents"; - } - if (metric === metricCyclomaticComplexity) { - return "Complexity"; - } else { - return "No Metric"; - } - } - - return ( - - - - - - props.metricState?.setMetric?.(undefined)} - disabled={props.busy} - > - No Metric - - {( - [ - { metric: metricLinesCount, label: "Total Lines" }, - { metric: metricCodeLineCount, label: "Code Lines" }, - { metric: metricCharacterCount, label: "Total Characters" }, - { metric: metricCodeCharacterCount, label: "Code Characters" }, - { metric: metricDependencyCount, label: "Dependencies Count" }, - { metric: metricDependentCount, label: "Dependents Count" }, - { - metric: metricCyclomaticComplexity, - label: "Cyclomatic Complexity", - }, - ] as { metric: Metric; label: string }[] - ).map(({ metric, label }) => ( - props.metricState?.setMetric?.(metric)} - > - {label} - - ))} - - - ); -} diff --git a/packages/app/src/components/Cytoscape/Controls.tsx b/packages/app/src/components/Cytoscape/Controls.tsx deleted file mode 100644 index 1cff5af1..00000000 --- a/packages/app/src/components/Cytoscape/Controls.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import type { ReactNode } from "react"; -import { Button, Tooltip } from "@radix-ui/themes"; -import type { Core } from "cytoscape"; -import { - MdFilterCenterFocus, - MdOutlineAccountTree, - MdOutlineZoomIn, - MdOutlineZoomOut, -} from "react-icons/md"; - -export default function Controls(props: { - busy: boolean; - cy: Core; - onLayout: () => void; - showFilters?: boolean; - children?: ReactNode; -}) { - function handleFit() { - const elements = props.cy.elements(); - const padding = 10; - props.cy.center(elements).fit(elements, padding); - } - - function handleZoom(zoom: number) { - const level = props.cy.zoom() * zoom; - const x = props.cy.width() / 2; - const y = props.cy.height() / 2; - const renderedPosition = { x, y }; - - props.cy.zoom({ - level, - renderedPosition, - }); - } - - return ( -
-
-
- - - - - - - - - - - - - {/* Used to pass extensions into the controls */} - {props.children} -
-
-
- ); -} diff --git a/packages/app/src/components/Cytoscape/Skeleton.tsx b/packages/app/src/components/Cytoscape/Skeleton.tsx deleted file mode 100644 index 11bdddd8..00000000 --- a/packages/app/src/components/Cytoscape/Skeleton.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { Skeleton } from "@radix-ui/themes"; - -export function CytoscapeSkeleton() { - return ( -
- -
- - -
-
- - - - -
-
- ); -} diff --git a/packages/app/src/components/Cytoscape/contextMenu/FileContextMenu.tsx b/packages/app/src/components/Cytoscape/contextMenu/FileContextMenu.tsx deleted file mode 100644 index b3c11f20..00000000 --- a/packages/app/src/components/Cytoscape/contextMenu/FileContextMenu.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { Link } from "react-router"; -import { DropdownMenu } from "@radix-ui/themes"; -import { - LuFolderSearch2, - LuGitGraph, - LuPanelRightOpen, - LuSearchCode, -} from "react-icons/lu"; -import type { FileDependencyManifest } from "@napi/shared"; - -export default function FileContextMenu(props: { - position: { x: number; y: number }; - fileDependencyManifest: FileDependencyManifest; - open: boolean; - showInSidebar: (filename: string) => void; - onOpenChange: (open: boolean) => void; - setDetailsPaneOpen: (open: boolean) => void; - setExtractionNodes: ( - filePath: string, - symbols: string[], - action: "add" | "remove", - ) => void; -}) { - function handleOnExtract() { - props.setExtractionNodes( - props.fileDependencyManifest.filePath, - Object.values(props.fileDependencyManifest.symbols).map( - (symbol) => symbol.id, - ), - "add", - ); - } - - return ( -
props.onOpenChange(false)} // Optional auto-close - > - - -
- - - - - {props.fileDependencyManifest.filePath.split("/").pop()} - - - props.setDetailsPaneOpen(true)} - > -
- Show details - -
-
- - - Inspect symbols - - - - - props.showInSidebar( - props.fileDependencyManifest.filePath.split("/").pop() || "", - )} - > -
- Show file - -
-
- - handleOnExtract()} - > -
- Extract all symbols - -
-
-
- -
- ); -} diff --git a/packages/app/src/components/Cytoscape/contextMenu/SymbolContextMenu.tsx b/packages/app/src/components/Cytoscape/contextMenu/SymbolContextMenu.tsx deleted file mode 100644 index d82fdbef..00000000 --- a/packages/app/src/components/Cytoscape/contextMenu/SymbolContextMenu.tsx +++ /dev/null @@ -1,98 +0,0 @@ -import { Link, useParams } from "react-router"; -import { DropdownMenu } from "@radix-ui/themes"; -import { LuGitGraph, LuPanelRightOpen, LuSearchCode } from "react-icons/lu"; -import type { FileDependencyManifest } from "@napi/shared"; - -export default function SymbolContextMenu(props: { - position: { x: number; y: number }; - fileDependencyManifest: FileDependencyManifest; - symbolId: string; - open: boolean; - onOpenChange: (open: boolean) => void; - setDetailsPaneOpen: (open: boolean) => void; - setExtractionNodes: ( - filePath: string, - symbols: string[], - action: "add" | "remove", - ) => void; -}) { - const { file, instance } = useParams(); - - const isSymbolLevelView = file && instance; - - function handleOnExtract() { - props.setExtractionNodes( - props.fileDependencyManifest.filePath, - [props.symbolId], - "add", - ); - } - - return ( -
props.onOpenChange(false)} // Optional auto-close - > - - -
- - - - -

- {props.fileDependencyManifest.symbols[props.symbolId].id} -

-
- {/* TODO: There is something wrong with the details pane on the symbol-level view */} - {/* Fix it, and then remove the following */} - {!isSymbolLevelView && ( - <> - - props.setDetailsPaneOpen(true)} - > -
- Details - -
-
- - - Inspect symbol - - - - - )} - - handleOnExtract()} - > -
- Extract symbol - -
-
-
- -
- ); -} diff --git a/packages/app/src/components/DisplayNameWithTootip.tsx b/packages/app/src/components/DisplayNameWithTootip.tsx new file mode 100644 index 00000000..d6e974e8 --- /dev/null +++ b/packages/app/src/components/DisplayNameWithTootip.tsx @@ -0,0 +1,32 @@ +import { Tooltip, TooltipContent, TooltipTrigger } from "./shadcn/Tooltip.tsx"; + +export default function DisplayNameWithTooltip(props: { + name: string; + maxChar?: number; + truncateBefore?: boolean; +}) { + const maxChar = props.maxChar || 30; + + if (props.name.length > maxChar) { + let displayedName: string; + + if (props.truncateBefore) { + displayedName = "..." + props.name.slice(0, maxChar); + } else { + displayedName = props.name.slice(0, maxChar) + "..."; + } + + return ( + + + {displayedName} + + +
{props.name}
+
+
+ ); + } else { + return {props.name}; + } +} diff --git a/packages/app/src/components/FileDetailsPane.tsx b/packages/app/src/components/FileDetailsPane.tsx deleted file mode 100644 index dab3ff54..00000000 --- a/packages/app/src/components/FileDetailsPane.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import { Link } from "react-router"; -import type { ReactNode } from "react"; -import { Button, Callout, ScrollArea, Separator, Text } from "@radix-ui/themes"; -import { - LuCircleX, - LuCode, - LuFileText, - LuSearchCode, - LuTriangle, - LuX, -} from "react-icons/lu"; -import { - type FileAuditManifest, - type FileDependencyManifest, - metricCharacterCount, - metricCodeCharacterCount, - metricCodeLineCount, - metricCyclomaticComplexity, - metricDependencyCount, - metricDependentCount, - metricLinesCount, -} from "@napi/shared"; - -// Subcomponent for section headings -function SectionHeading({ children }: { children: ReactNode }) { - return ( -
- {children} -
- ); -} - -// Metric item component for consistent display -function MetricItem({ - label, - value, - alert, -}: { - label: string; - value: number | string; - alert?: { message: { long: string } }; -}) { - return ( -
-
- - {label}: - -
- {value} - {alert && } -
-
- {alert && ( - - - - - {alert.message.long} - - )} -
- ); -} - -// Alert badge component -function AlertBadge({ count }: { count: number }) { - return ( -
- 0 ? "text-amber-500" : "text-gray-400"}`} - /> - 0 ? "text-amber-500" : "text-gray-400"}> - {count} - -
- ); -} - -// Symbol metrics and alerts component -function SymbolSection({ - symbol, - fileDependencyManifest, -}: { - symbol: { - id: string; - alerts: Record; - }; - fileDependencyManifest: FileDependencyManifest; -}) { - const symbolData = fileDependencyManifest.symbols[symbol.id]; - const alerts = Object.values(symbol.alerts); - const alertsByMetric = alerts.reduce( - (acc, alert) => { - if (alert.metric) { - acc[alert.metric] = alert; - } - return acc; - }, - {} as Record, - ); - - return ( -
-
- - {symbolData.type}: {symbol.id} - - -
- -
- {symbolData.metrics && - Object.entries(symbolData.metrics).map(([metricKey, value]) => ( - - ))} -
-
- ); -} - -export default function FileDetailsPane(props: { - fileDependencyManifest: FileDependencyManifest; - fileAuditManifest: FileAuditManifest; - open: boolean; - setOpen: (open: boolean) => void; -}) { - const { fileDependencyManifest, fileAuditManifest, open, setOpen } = props; - const fileName = fileDependencyManifest.filePath.split("/").pop() || ""; - const fileAlerts = Object.values(fileAuditManifest.alerts) as { - message: { long: string }; - metric: string; - }[]; - - // Organize alerts by their metric for file metrics - const alertsByMetric = fileAlerts.reduce( - (acc, alert) => { - if (alert.metric) { - acc[alert.metric] = alert; - } - return acc; - }, - {} as Record, - ); - - return ( -
- - {/* Header */} -
-

- {fileName} -

- -
- - - {/* File Metrics with Alerts */} - -
-
- -
File Metrics
-
- -
-
-
- - - - - - - -
- - {/* Symbols with their metrics and alerts */} - - Symbols - - - {/* Total symbols count */} -
- -
-
    - {Object.entries( - Object.values(fileDependencyManifest.symbols).reduce( - (acc, symbol) => { - acc[symbol.type] = (acc[symbol.type] || 0) + 1; - return acc; - }, - {} as Record, - ), - ).map(([type, count]) => ( -
  • - {type}: {count} -
  • - ))} -
-
-
- - {/* Individual symbols with their metrics and alerts */} -
- {Object.values(fileAuditManifest.symbols).map((symbol) => ( - - ))} -
- - {/* Action Buttons */} -
- - - -
-
-
- ); -} diff --git a/packages/app/src/components/FileExplorer/FileExplorer.tsx b/packages/app/src/components/FileExplorer/FileExplorer.tsx deleted file mode 100644 index 91f19162..00000000 --- a/packages/app/src/components/FileExplorer/FileExplorer.tsx +++ /dev/null @@ -1,832 +0,0 @@ -import { - Button, - Checkbox, - IconButton, - ScrollArea, - TextField, - Tooltip, -} from "@radix-ui/themes"; -import { useEffect, useRef, useState } from "react"; -import { Link } from "react-router"; -import { - type ImperativePanelHandle, - Panel, - PanelGroup, - PanelResizeHandle, -} from "react-resizable-panels"; -import type { ExtractionNode } from "@napi/shared"; -import { FileExplorerSkeleton } from "./Skeleton.tsx"; -import { LuSearchCode, LuSearchSlash, LuX } from "react-icons/lu"; -import languageIcon from "./languageIcons.tsx"; -import { - MdDragHandle, - MdOutlineKeyboardArrowDown, - MdOutlineKeyboardArrowLeft, - MdOutlineKeyboardArrowRight, - MdOutlineRemoveRedEye, - MdSearch, - MdSubdirectoryArrowRight, - MdVerticalAlignBottom, - MdVerticalAlignTop, -} from "react-icons/md"; -import { runExtraction } from "../../service/api/index.ts"; -import { toast } from "react-toastify"; - -interface TreeData { - id: string; - level: number; - name: string; - matchesSearch: boolean; - children?: TreeData[]; // Only for non leaf nodes - isSymbol?: boolean; // Only for leaf nodes -} - -export interface FileExplorerFile { - path: string; - symbols: string[]; -} - -export default function FileExplorer(props: { - busy: boolean; - files: FileExplorerFile[]; - isOpen: boolean; - setIsOpen: (open: boolean) => void; - search: string; - setIsSearch: (search: string) => void; - highlightedNodeId: string | null; - setHighlightedNodeId: (node: string | null) => void; - extractionState: { - extractionNodes: Record; - updateExtractionNodes: ( - filePath: string, - symbols: string[], - action: "add" | "remove", - ) => void; - }; -}) { - const [treeData, setTreeData] = useState([]); - const [extractionPanelSize, setExtractionPanelSize] = useState(0); - const extractionPanelRef = useRef(null); - - function nodeMatchesSearch(name: string, symbols: string[]): boolean { - return ( - !props.search || - name.toLowerCase().includes(props.search.toLowerCase()) || - symbols.some((symbol) => - symbol.toLowerCase().includes(props.search.toLowerCase()) - ) - ); - } - - function addFileToTree( - currentLevel: TreeData[], - segments: string[], - cumulativePath: string, - symbols: string[], - ): boolean { - const [segment, ...remainingSegments] = segments; - const nodeId = cumulativePath ? `${cumulativePath}/${segment}` : segment; - let existingNode = currentLevel.find((node) => node.name === segment); - - if (!existingNode) { - existingNode = { - id: nodeId, - level: 0, - name: segment, - matchesSearch: false, - children: [], - }; - currentLevel.push(existingNode); - } - - const matchesCurrentNode = nodeMatchesSearch(segment, symbols); - - if (remainingSegments.length > 0) { - const childMatches = addFileToTree( - existingNode.children as TreeData[], - remainingSegments, - nodeId, - symbols, - ); - existingNode.matchesSearch = existingNode.matchesSearch || childMatches; - } else { - existingNode.matchesSearch = existingNode.matchesSearch || - matchesCurrentNode; - - // ADD SYMBOLS AS CHILDREN HERE - if (symbols.length > 0) { - existingNode.children = symbols.map((symbol) => ({ - id: `${nodeId}#${symbol}`, - level: existingNode.level + 1, - name: symbol, - matchesSearch: !props.search || - symbol.toLowerCase().includes(props.search.toLowerCase()), - isSymbol: true, - })); - - // Update matchesSearch if symbol matches - existingNode.matchesSearch = existingNode.matchesSearch || - existingNode.children.some((child) => child.matchesSearch); - } - } - - return existingNode.matchesSearch; - } - - function buildTreeData(files: FileExplorerFile[]): TreeData[] { - let rootNodes: TreeData[] = []; - - files.forEach((file) => { - // Filter out elements that don't match the search - // on either the filename or the symbols - if (!nodeMatchesSearch(file.path, file.symbols)) { - return; - } - - const segments = file.path.split("/"); - - // Add the file to the tree structure - addFileToTree(rootNodes, segments, "", file.symbols); - }); - - rootNodes = rootNodes.map(flattenNode); - rootNodes = setLevels(rootNodes); - - return rootNodes; - } - - // Recursive helper that flattens a single node - function flattenNode(node: TreeData): TreeData { - // Recursively flatten all children - if (node.children) { - node.children = node.children.map(flattenNode); - } - - // As long as the node has exactly one child, merge them - while ( - node.children && - node.children.length === 1 && - !node.children[0].isSymbol - ) { - const [child] = node.children; - - // Merge child's name into parent - node.name = `${node.name}/${child.name}`; - // Update the parent's id to child's id (which is already the full path) - node.id = child.id; - // Optionally inherit the child's level if needed - node.level = child.level; - // Replace parent's children with child's children - node.children = child.children; - - // Continue merging in case the new "flattened" node also has exactly one child - } - - return node; - } - - function setLevels(nodes: TreeData[], currentLevel = 0): TreeData[] { - return nodes.map((node) => { - // Assign the current level - node.level = currentLevel; - - // Recursively set levels for children - if (node.children && node.children.length > 0) { - node.children = setLevels(node.children, currentLevel + 1); - } - - return node; - }); - } - - function handleResize(size: number) { - setExtractionPanelSize(size); - } - - function handleExpandAndCollapse() { - if (extractionPanelRef.current) { - if (extractionPanelSize > 0) { - extractionPanelRef.current.resize(0); - setExtractionPanelSize(0); - } else { - extractionPanelRef.current.resize(50); - setExtractionPanelSize(50); - } - } - } - - useEffect(() => { - // Use setTimeout to ensure the panel is resized after the DOM has updated - // IF WE DON'T DO THIS, the panel will not resize correctly when forcing - // the sidebar to open if it was closed. - // This is a side effect of the way we do the sidebar and state management - setTimeout(() => { - if (extractionPanelRef.current) { - extractionPanelRef.current.resize(50); - } - }, 50); - }, [props.extractionState.extractionNodes]); - - useEffect(() => { - setTreeData(buildTreeData(props.files)); - }, [props.files, props.search]); - - return ( - - -
-
- {props.isOpen && ( - - logo - NanoAPI - - )} - -
- -
- {props.busy ? : ( - <> - props.setIsSearch(e.target.value)} - className={`min-h-8 transition-all duration-300 overflow-hidden ${ - !props.isOpen && "w-0" - }`} - > - - - - {props.search.length > 0 && ( - - props.setIsSearch("")} - > - - - - )} - - - - - - )} -
-
-
- {props.isOpen && ( - <> -
- {extractionPanelSize > 0 - ? ( - handleExpandAndCollapse()} - className="text-xl text-gray-light dark:text-gray-dark" - /> - ) - : ( - handleExpandAndCollapse()} - className="text-xl text-gray-light dark:text-gray-dark" - /> - )} - - Symbol Extraction - - -
- - - - - )} -
- ); -} - -function ListElement(props: { - nodes: TreeData[]; - search: string; - hlNodeId: string | null; - setHLNodeId: (node: string | null) => void; -}) { - return ( -
    - {props.nodes.map((node) => { - return ( - - ); - })} -
- ); -} - -function NodeElement(props: { - node: TreeData; - search: string; - hlNodeId: string | null; - setHLNodeId: (node: string | null) => void; -}) { - const [isOpen, setIsOpen] = useState(false); - - const shouldAutoExpand = props.search.length > 0 && props.node.matchesSearch; - const isHighlighted = props.hlNodeId === props.node.id; - - function toggleHighlight(id: string) { - if (isHighlighted) { - props.setHLNodeId(null); - } else { - props.setHLNodeId(id); - } - } - - useEffect(() => { - setIsOpen(shouldAutoExpand); - }, [shouldAutoExpand]); - - function handleToggle() { - setIsOpen((value) => !value); - } - - return ( -
  • -
    - {props.node.children && - props.node.children.length > 0 && - !props.node.children[0].isSymbol - ? ( - - ) - : ( - <> - {!props.node.isSymbol - ? ( -
    -
    - -
    -
    - - - - - - - - -
    -
    - ) - : ( -
    -
    - - -
    -
    - -
    -
    - )} - - )} -
    - {isOpen && props.node.children && ( - - )} -
  • - ); -} - -function DisplayedPath({ - node, - search = "", -}: { - node: TreeData; - search: string; -}) { - const maxPathLength = Math.max(25 - 2 * node.level, 5); - let foundInSearch = false; - if (search.length > 2) { - foundInSearch = node.name.toLowerCase().includes(search.toLowerCase()); - } - - if (node.name.length > maxPathLength) { - return ( - -
    - {`...${node.name.slice(-maxPathLength)}`} -
    -
    - ); - } - - return ( -
    - {node.name} -
    - ); -} - -enum EditMode { - NONE = "none", // Nothing has been edited - EDITING = "editing", // The user is currently editing - CANCELLED = "cancelled", // The user has cancelled the edit - COMPLETED = "completed", // The user has completed the edit -} - -function ExtractionPanel(props: { - extractionNodes: Record; - updateExtractionNodes: ( - filePath: string, - symbols: string[], - action: "add" | "remove", - ) => void; -}) { - const [editMode, setEditMode] = useState(EditMode.NONE); - const [extractionLoading, setExtractionLoading] = useState(false); - - async function runExtractionViaAPI() { - setExtractionLoading(true); - - const extractionNodes = Object.values(props.extractionNodes); - const response = await runExtraction(extractionNodes); - - if (response && response.success) { - toast.success( - "Extraction completed successfully. You'll find the extracted files in the output directory.", - ); - } else { - toast.error("Extraction failed. Please check the logs for more details."); - } - - setExtractionLoading(false); - } - - return ( -
    - - {Object.keys(props.extractionNodes).map((key) => { - const node = props.extractionNodes[key]; - return ( - - ); - })} - -
    - {editMode !== EditMode.EDITING && ( - <> - - - - - - - - )} - {editMode === EditMode.EDITING && ( - <> - - - - )} -
    -
    - ); -} - -function ExtractionElement(props: { - node: ExtractionNode; - updateExtractionNodes: ( - filePath: string, - symbols: string[], - action: "add" | "remove", - ) => void; - editMode?: EditMode; -}) { - type CheckedState = boolean | "indeterminate"; - - const symbolMap = new Map(); - props.node.symbols.forEach((symbol) => { - symbolMap.set(symbol, true); - }); - - const [fileChecked, setFileChecked] = useState(true); - const [checkedSymbols, setCheckedSymbols] = useState(symbolMap); - const maxPathLength = 20; - - function getDisplayedPath(name: string) { - if (name.length > maxPathLength) { - return ( - -
    - {`...${ - name.slice( - -maxPathLength, - ) - }`} -
    -
    - ); - } - return
    {name}
    ; - } - - function resolveFileCheckedState(symbolMap: Map) { - const allChecked = props.node.symbols.every((symbol) => { - return symbolMap.get(symbol) === true; - }); - const allUnchecked = props.node.symbols.every((symbol) => { - return symbolMap.get(symbol) === false; - }); - if (allChecked) { - return true; - } - if (allUnchecked) { - return false; - } - return "indeterminate"; - } - - function handleSymbolCheck(symbol: string, checked: boolean) { - setCheckedSymbols((prev) => { - const newMap = new Map(prev); - newMap.set(symbol, checked); - setFileChecked(resolveFileCheckedState(newMap)); - return newMap; - }); - } - - useEffect(() => { - if (props.editMode === EditMode.COMPLETED) { - // Check if any of the symbols are unchecked, and remove them from the extraction - const uncheckedSymbols = Array.from(checkedSymbols.entries()) - .filter(([, checked]) => !checked) - .map(([symbol]) => symbol); - if (uncheckedSymbols.length > 0) { - props.updateExtractionNodes( - props.node.filePath, - uncheckedSymbols, - "remove", - ); - } - - // If a file is unchecked, remove all symbols from the extraction - if (fileChecked === false) { - props.updateExtractionNodes( - props.node.filePath, - props.node.symbols, - "remove", - ); - } - - //Finally, update the checkedSymbols to remove the unchecked symbols - setCheckedSymbols((prev) => { - const newMap = new Map(); - props.node.symbols.forEach((symbol) => { - if (prev.get(symbol) !== false) { - newMap.set(symbol, true); - } - }); - return newMap; - }); - setFileChecked(true); - } - - if (props.editMode === EditMode.CANCELLED) { - // Reset the checked state to the original state - // by setting everything to true - setFileChecked(true); - setCheckedSymbols(() => { - const newMap = new Map(); - props.node.symbols.forEach((symbol) => { - newMap.set(symbol, true); - }); - return newMap; - }); - } - }, [props.editMode]); - - return ( -
    -
    -
    - {languageIcon(props.node.filePath.split(".").pop() || "txt")} - {getDisplayedPath(props.node.filePath)} -
    - {props.editMode === EditMode.EDITING && ( - -
    - { - setFileChecked(Boolean(checked)); - for (const symbol of props.node.symbols) { - if (checked) { - checkedSymbols.set(symbol, true); - } else { - checkedSymbols.set(symbol, false); - } - } - }} - > - -
    -
    - )} -
    - {props.node.symbols.map((symbol) => ( -
    -
    - - {getDisplayedPath(symbol)} -
    - {props.editMode === EditMode.EDITING && ( - -
    - { - handleSymbolCheck(symbol, Boolean(checked)); - }} - > - -
    -
    - )} -
    - ))} -
    - ); -} diff --git a/packages/app/src/components/FileExplorer/Skeleton.tsx b/packages/app/src/components/FileExplorer/Skeleton.tsx deleted file mode 100644 index ecaba2d5..00000000 --- a/packages/app/src/components/FileExplorer/Skeleton.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Skeleton } from "@radix-ui/themes"; - -export function FileExplorerSkeleton() { - return ( -
    - - - - - - - -
    - ); -} diff --git a/packages/app/src/components/FileExplorer/languageIcons.tsx b/packages/app/src/components/FileExplorer/languageIcons.tsx deleted file mode 100644 index 16e531d8..00000000 --- a/packages/app/src/components/FileExplorer/languageIcons.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { LuFileCode } from "react-icons/lu"; -import { DiPython } from "react-icons/di"; -import { TbBrandCSharp } from "react-icons/tb"; -import type { JSX } from "react"; - -const languageIconMap: Record = { - py: ( - - ), - cs: ( - - ), - fallback: ( - - ), -}; - -export default function languageIcon(fileExtension: string) { - const icon = languageIconMap[fileExtension] || languageIconMap.fallback; - return icon; -} diff --git a/packages/app/src/components/SymbolDetailsPane.tsx b/packages/app/src/components/SymbolDetailsPane.tsx deleted file mode 100644 index ddccbc93..00000000 --- a/packages/app/src/components/SymbolDetailsPane.tsx +++ /dev/null @@ -1,251 +0,0 @@ -import type { ReactNode } from "react"; -import { Link } from "react-router"; -import { Button, Callout, ScrollArea, Separator, Text } from "@radix-ui/themes"; -import { - LuCircleX, - LuCode, - LuFileText, - LuSearchCode, - LuTriangle, - LuX, -} from "react-icons/lu"; -import { - type FileAuditManifest, - type FileDependencyManifest, - metricCharacterCount, - metricCodeCharacterCount, - metricCodeLineCount, - metricCyclomaticComplexity, - metricDependencyCount, - metricDependentCount, - metricLinesCount, -} from "@napi/shared"; - -// Subcomponent for section headings -function SectionHeading({ children }: { children: ReactNode }) { - return ( -
    - {children} -
    - ); -} - -// Metric item component for consistent display -function MetricItem({ - label, - value, - alert, -}: { - label: string; - value: number | string; - alert?: { message: { long: string } }; -}) { - return ( -
    -
    - - {label}: - -
    - {value} - {alert && } -
    -
    - {alert && ( - - - - - {alert.message.long} - - )} -
    - ); -} - -// Alert badge component -function AlertBadge({ count }: { count: number }) { - return ( -
    - 0 ? "text-amber-500" : "text-gray-400"}`} - /> - 0 ? "text-amber-500" : "text-gray-400"}> - {count} - -
    - ); -} - -export default function SymbolDetailsPane(props: { - fileDependencyManifest: FileDependencyManifest; - fileAuditManifest: FileAuditManifest; - symbolId: string; - open: boolean; - setOpen: (open: boolean) => void; -}) { - const { fileDependencyManifest, fileAuditManifest, symbolId, open, setOpen } = - props; - const fileName = fileDependencyManifest.filePath.split("/").pop() || ""; - const symbolData = fileDependencyManifest.symbols[symbolId]; - const symbolName = symbolData?.id || symbolId; - const symbolType = symbolData?.type || ""; - - // Get alerts related to the current symbol only - const symbolAlertsObj = fileAuditManifest.symbols[symbolId]?.alerts || {}; - const symbolAlerts = Object.values(symbolAlertsObj) as { - message: { long: string }; - metric: string; - }[]; - - // Organize alerts by their metric for symbol metrics - const symbolAlertsByMetric = symbolAlerts.reduce( - (acc, alert) => { - if (alert.metric) { - acc[alert.metric] = alert; - } - return acc; - }, - {} as Record, - ); - - const fileAlerts = Object.values(fileAuditManifest.alerts) as { - message: { long: string }; - metric: string; - }[]; - - // Organize alerts by their metric for file metrics - const alertsByMetric = fileAlerts.reduce( - (acc, alert) => { - if (alert.metric) { - acc[alert.metric] = alert; - } - return acc; - }, - {} as Record, - ); - - return ( -
    - - {/* Header */} -
    -

    - {fileName} -

    - -
    - - - - {/* File Metrics with Alerts */} - -
    -
    - -
    File Metrics
    -
    - -
    -
    -
    - - - - - - - -
    - - {/* Current Symbol with its metrics and alerts */} - - Symbol - - - {symbolData && fileAuditManifest.symbols[symbolId] && ( -
    -
    - - {symbolType}: {symbolName} - - -
    - -
    - {symbolData.metrics && - Object.entries(symbolData.metrics).map(([metricKey, value]) => ( - - ))} -
    -
    - )} - - {/* Action Buttons */} -
    - - - -
    -
    -
    - ); -} diff --git a/packages/app/src/components/contextMenu/FileContextMenu.tsx b/packages/app/src/components/contextMenu/FileContextMenu.tsx new file mode 100644 index 00000000..a9c013fa --- /dev/null +++ b/packages/app/src/components/contextMenu/FileContextMenu.tsx @@ -0,0 +1,74 @@ +import { Link } from "react-router"; +import type { FileDependencyManifest } from "@napi/shared"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "../shadcn/Dropdownmenu.tsx"; +import { PanelRight, SearchCode } from "lucide-react"; +import DisplayNameWithTooltip from "../DisplayNameWithTootip.tsx"; + +export default function FileContextMenu(props: { + context: { + position: { x: number; y: number }; + fileDependencyManifest: FileDependencyManifest; + } | undefined; + onClose: () => void; + onOpenDetails: (filePath: string) => void; +}) { + return ( +
    + props.onClose()} + > + + + + + + + + + props.context?.fileDependencyManifest && + props.onOpenDetails( + props.context?.fileDependencyManifest.filePath, + )} + > +
    + +
    Show details
    +
    +
    + + +
    + +
    Inspect symbols
    +
    + +
    +
    +
    +
    + ); +} diff --git a/packages/app/src/components/contextMenu/SymbolContextMenu.tsx b/packages/app/src/components/contextMenu/SymbolContextMenu.tsx new file mode 100644 index 00000000..e3277ddb --- /dev/null +++ b/packages/app/src/components/contextMenu/SymbolContextMenu.tsx @@ -0,0 +1,84 @@ +import { Link } from "react-router"; +import type { + FileDependencyManifest, + SymbolDependencyManifest, +} from "@napi/shared"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "../shadcn/Dropdownmenu.tsx"; +import { PanelRight, SearchCode } from "lucide-react"; +import DisplayNameWithTooltip from "../DisplayNameWithTootip.tsx"; + +export default function SymbolContextMenu(props: { + context: { + position: { x: number; y: number }; + fileDependencyManifest: FileDependencyManifest; + symbolDependencyManifest: SymbolDependencyManifest; + } | undefined; + onClose: () => void; + onOpenDetails: (filePath: string, symbolId: string) => void; +}) { + return ( +
    + props.onClose()} + > + + + + + + + + + props.context?.fileDependencyManifest && + props.onOpenDetails( + props.context?.fileDependencyManifest.filePath, + props.context?.symbolDependencyManifest.id, + )} + > +
    + +
    Show details
    +
    +
    + + +
    + +
    Inspect symbol
    +
    + +
    +
    +
    +
    + ); +} diff --git a/packages/app/src/components/controls/ControlExtensions/FiltersExtension.tsx b/packages/app/src/components/controls/ControlExtensions/FiltersExtension.tsx new file mode 100644 index 00000000..f68f9cce --- /dev/null +++ b/packages/app/src/components/controls/ControlExtensions/FiltersExtension.tsx @@ -0,0 +1,150 @@ +import { type MouseEvent, useEffect, useState } from "react"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "../../shadcn/Tooltip.tsx"; +import { + DropdownMenu, + DropdownMenuCheckboxItem, + DropdownMenuContent, + DropdownMenuLabel, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "../../shadcn/Dropdownmenu.tsx"; +import { Button } from "../../shadcn/Button.tsx"; +import { Funnel } from "lucide-react"; + +export default function FiltersExtension(props: { + busy: boolean; + currentFileName?: string; + onFilterChange: ( + showExternal: boolean, + showVariables: boolean, + showFunctions: boolean, + showClasses: boolean, + showStructs: boolean, + showEnums: boolean, + showInterfaces: boolean, + showRecords: boolean, + showDelegates: boolean, + ) => void; +}) { + const [showExternal, setShowExternal] = useState(true); + const [showVariables, setShowVariables] = useState(true); + const [showFunctions, setShowFunctions] = useState(true); + const [showClasses, setShowClasses] = useState(true); + const [showStructs, setShowStructs] = useState(true); + const [showEnums, setShowEnums] = useState(true); + const [showInterfaces, setShowInterfaces] = useState(true); + const [showRecords, setShowRecords] = useState(true); + const [showDelegates, setShowDelegates] = useState(true); + + useEffect(() => { + props.onFilterChange( + showExternal, + showVariables, + showFunctions, + showClasses, + showStructs, + showEnums, + showInterfaces, + showRecords, + showDelegates, + ); + }, [ + showExternal, + showVariables, + showFunctions, + showClasses, + showStructs, + showEnums, + showInterfaces, + showRecords, + showDelegates, + ]); + + function handleFilterClick( + e: MouseEvent, + set: React.Dispatch>, + ) { + e.preventDefault(); + set((prev) => !prev); + } + + return ( + + + + + + + + + Filters + + + {[ + { + label: "Show external", + checked: showExternal, + set: setShowExternal, + }, + { + label: "Show variables", + checked: showVariables, + set: setShowVariables, + }, + { + label: "Show functions", + checked: showFunctions, + set: setShowFunctions, + }, + { + label: "Show classes", + checked: showClasses, + set: setShowClasses, + }, + { + label: "Show structs", + checked: showStructs, + set: setShowStructs, + }, + { label: "Show enums", checked: showEnums, set: setShowEnums }, + { + label: "Show interfaces", + checked: showInterfaces, + set: setShowInterfaces, + }, + { + label: "Show records", + checked: showRecords, + set: setShowRecords, + }, + { + label: "Show delegates", + checked: showDelegates, + set: setShowDelegates, + }, + ].map(({ label, checked, set }) => ( + handleFilterClick(e, set)} + > + {label} + + ))} + + + + Hide or show specific elements in the graph. + + + ); +} diff --git a/packages/app/src/components/controls/ControlExtensions/GraphDepthExtension.tsx b/packages/app/src/components/controls/ControlExtensions/GraphDepthExtension.tsx new file mode 100644 index 00000000..19a71bd5 --- /dev/null +++ b/packages/app/src/components/controls/ControlExtensions/GraphDepthExtension.tsx @@ -0,0 +1,128 @@ +import { useState } from "react"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "../../shadcn/Tooltip.tsx"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuTrigger, +} from "../../shadcn/Dropdownmenu.tsx"; +import { Button } from "../../shadcn/Button.tsx"; +import { Settings2 } from "lucide-react"; +import { Slider } from "../../shadcn/Slider.tsx"; +import { Input } from "../../shadcn/Input.tsx"; +import { Label } from "../../shadcn/Label.tsx"; + +export default function GraphDepthExtension(props: { + busy: boolean; + dependencyState: { + depth: number; + setDepth: (depth: number) => void; + }; + dependentState: { + depth: number; + setDepth: (depth: number) => void; + }; +}) { + const { dependencyState, dependentState } = props; + const [tempDependencyDepth, setTempDependencyDepth] = useState( + dependencyState.depth, + ); + const [tempDependentDepth, setTempDependentDepth] = useState( + dependentState.depth, + ); + + function handleSubmit(e: React.FormEvent) { + e.preventDefault(); + if (tempDependencyDepth !== dependencyState.depth) { + dependencyState.setDepth(tempDependencyDepth); + } + if (tempDependentDepth !== dependentState.depth) { + dependentState.setDepth(tempDependentDepth); + } + } + + return ( + + + + + + + + +
    + +
    + { + setTempDependencyDepth(value[0]); + }} + /> + { + setTempDependencyDepth(parseInt(e.target.value, 10)); + }} + className="w-20" + /> +
    + +
    + { + setTempDependentDepth(value[0]); + }} + /> + { + setTempDependentDepth(parseInt(e.target.value, 10)); + }} + disabled={props.busy} + className="w-20" + /> +
    + +
    +
    +
    + + Set the depth of the dependencies shown on the graph. + +
    + ); +} diff --git a/packages/app/src/components/controls/ControlExtensions/MetricsExtension.tsx b/packages/app/src/components/controls/ControlExtensions/MetricsExtension.tsx new file mode 100644 index 00000000..5fa2d339 --- /dev/null +++ b/packages/app/src/components/controls/ControlExtensions/MetricsExtension.tsx @@ -0,0 +1,98 @@ +import { + type Metric, + metricCharacterCount, + metricCodeCharacterCount, + metricCodeLineCount, + metricCyclomaticComplexity, + metricDependencyCount, + metricDependentCount, + metricLinesCount, +} from "@napi/shared"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "../../shadcn/Tooltip.tsx"; +import { Button } from "../../shadcn/Button.tsx"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "../../shadcn/Dropdownmenu.tsx"; + +// Extension for the controls in the project view +export default function MetricsExtension(props: { + busy: boolean; + metricState: { + metric: Metric | undefined; + setMetric: (metric: Metric | undefined) => void; + }; +}) { + const metric = props.metricState.metric; + + function getMetricLabel(metric: Metric | undefined) { + if (metric === metricLinesCount) { + return "Lines"; + } + if (metric === metricCodeLineCount) { + return "Code Lines"; + } + if (metric === metricCharacterCount) { + return "Chars"; + } + if (metric === metricCodeCharacterCount) { + return "Code Chars"; + } + if (metric === metricDependencyCount) { + return "Dependencies"; + } + if (metric === metricDependentCount) { + return "Dependents"; + } + if (metric === metricCyclomaticComplexity) { + return "Complexity"; + } else { + return "None"; + } + } + + return ( + + + + + + + + + {([ + { metric: undefined, label: "No Metric" }, + { metric: metricLinesCount, label: "Lines" }, + { metric: metricCodeLineCount, label: "Code Lines" }, + { metric: metricCharacterCount, label: "Total Characters" }, + { metric: metricCodeCharacterCount, label: "Code Characters" }, + { metric: metricDependencyCount, label: "Dependencies" }, + { metric: metricDependentCount, label: "Dependents" }, + { metric: metricCyclomaticComplexity, label: "Complexity" }, + ] as { metric: Metric | undefined; label: string }[]).map((val) => ( + props.metricState?.setMetric?.(val.metric)} + > + {val.label} + + ))} + + + + Select a metric to display on the graph + + + ); +} diff --git a/packages/app/src/components/controls/Controls.tsx b/packages/app/src/components/controls/Controls.tsx new file mode 100644 index 00000000..ffdbbea0 --- /dev/null +++ b/packages/app/src/components/controls/Controls.tsx @@ -0,0 +1,102 @@ +import type { ReactNode } from "react"; +import { Button } from "../shadcn/Button.tsx"; +import { Tooltip, TooltipContent, TooltipTrigger } from "../shadcn/Tooltip.tsx"; +import type { Core } from "cytoscape"; +import { Focus, Network, ZoomIn, ZoomOut } from "lucide-react"; + +export default function Controls(props: { + busy: boolean; + cy: Core | undefined; + onLayout: () => void; + showFilters?: boolean; + children?: ReactNode; +}) { + function handleFit() { + if (!props.cy) return; + + const elements = props.cy.elements(); + const padding = 10; + props.cy.center(elements).fit(elements, padding); + } + + function handleZoom(zoom: number) { + if (!props.cy) return; + + const level = props.cy.zoom() * zoom; + const x = props.cy.width() / 2; + const y = props.cy.height() / 2; + const renderedPosition = { x, y }; + + props.cy.zoom({ + level, + renderedPosition, + }); + } + + return ( +
    + + + + + + Fit to screen + + + + + + + + Reset layout + + + + + + + + Zoom out + + + + + + + + Zoom in + + + {/* Used to pass extensions into the controls */} + {props.children} +
    + ); +} diff --git a/packages/app/src/components/detailsPanes/FileDetailsPane.tsx b/packages/app/src/components/detailsPanes/FileDetailsPane.tsx new file mode 100644 index 00000000..9fa24ec2 --- /dev/null +++ b/packages/app/src/components/detailsPanes/FileDetailsPane.tsx @@ -0,0 +1,199 @@ +import type { FileAuditManifest, FileDependencyManifest } from "@napi/shared"; +import { + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "../shadcn/Sheet.tsx"; +import { Card, CardContent, CardHeader, CardTitle } from "../shadcn/Card.tsx"; +import { Code, File, Pickaxe, SearchCode } from "lucide-react"; +import { ScrollArea } from "../shadcn/Scrollarea.tsx"; +import { Button } from "../shadcn/Button.tsx"; +import { Link } from "react-router"; +import DisplayNameWithTooltip from "../DisplayNameWithTootip.tsx"; +import Metrics from "./metrics.tsx"; +import AlertBadge from "./alertBadge.tsx"; + +export default function FileDetailsPane(props: { + context: { + fileDependencyManifest: FileDependencyManifest; + fileAuditManifest: FileAuditManifest; + } | undefined; + onClose: () => void; + onAddSymbolsForExtraction: (filePath: string, symbolIds: string[]) => void; +}) { + function markAllSymbolsForExtraction() { + if (!props.context?.fileDependencyManifest) { + return; + } + + props.onAddSymbolsForExtraction( + props.context?.fileDependencyManifest.filePath, + Object.keys(props.context.fileDependencyManifest.symbols), + ); + } + + function markSymbolForExtraction(symbolId: string) { + if (!props.context?.fileDependencyManifest) { + return; + } + + props.onAddSymbolsForExtraction( + props.context.fileDependencyManifest.filePath, + [symbolId], + ); + } + + return ( +
    + props.onClose()} + > + + + + +
    + + +
    +
    + + +
    + +
    + + + +
    + +
    File Metrics
    +
    + +
    +
    + + + + + +
    + +
    + Symbols ({Object.keys( + props.context?.fileDependencyManifest.symbols || {}, + ).length || 0}) +
    +
    +
    +
    + +
    + {Object.entries( + Object.values( + props.context?.fileDependencyManifest.symbols || [], + ).reduce((acc, symbol) => { + acc[symbol.type] = (acc[symbol.type] || 0) + 1; + return acc; + }, {} as Record), + ).map(([type, count]) => ( +
    +
    {type}
    +
    {count}
    +
    + ))} +
    +
    +
    + {Object.values( + props.context?.fileDependencyManifest.symbols || {}, + ).map((symbol) => ( + + + +
    + + +
    +
    + + +
    + + + +
    + ))} +
    +
    +
    +
    +
    + ); +} diff --git a/packages/app/src/components/detailsPanes/SymbolDetailsPane.tsx b/packages/app/src/components/detailsPanes/SymbolDetailsPane.tsx new file mode 100644 index 00000000..235156d9 --- /dev/null +++ b/packages/app/src/components/detailsPanes/SymbolDetailsPane.tsx @@ -0,0 +1,171 @@ +import type { + FileAuditManifest, + FileDependencyManifest, + SymbolAuditManifest, + SymbolDependencyManifest, +} from "@napi/shared"; +import { + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + SheetTrigger, +} from "../shadcn/Sheet.tsx"; +import { Card, CardContent, CardHeader, CardTitle } from "../shadcn/Card.tsx"; +import { Code, File, Pickaxe, SearchCode } from "lucide-react"; +import { ScrollArea } from "../shadcn/Scrollarea.tsx"; +import { Button } from "../shadcn/Button.tsx"; +import { Link } from "react-router"; +import DisplayNameWithTooltip from "../DisplayNameWithTootip.tsx"; +import Metrics from "./metrics.tsx"; +import AlertBadge from "./alertBadge.tsx"; + +export default function SymbolDetailsPane(props: { + context: { + fileDependencyManifest: FileDependencyManifest; + symbolDependencyManifest: SymbolDependencyManifest; + fileAuditManifest: FileAuditManifest; + symbolAuditManifest: SymbolAuditManifest; + } | undefined; + onClose: () => void; + onAddSymbolsForExtraction: (filePath: string, symbolIds: string[]) => void; +}) { + function markSymbolForExtraction(symbolId: string) { + if (!props.context?.fileDependencyManifest) { + return; + } + + props.onAddSymbolsForExtraction( + props.context.fileDependencyManifest.filePath, + [symbolId], + ); + } + + return ( +
    + props.onClose()} + > + + + + +
    + + +
    +
    + + +
    +
    + + + +
    + +
    + + + +
    + +
    Symbol Metrics
    +
    + +
    +
    + + + +
    + + + +
    + +
    File Metrics
    +
    + +
    +
    + + + +
    +
    +
    +
    +
    +
    + ); +} diff --git a/packages/app/src/components/detailsPanes/alertBadge.tsx b/packages/app/src/components/detailsPanes/alertBadge.tsx new file mode 100644 index 00000000..fcab2042 --- /dev/null +++ b/packages/app/src/components/detailsPanes/alertBadge.tsx @@ -0,0 +1,16 @@ +import { Check, TriangleAlert } from "lucide-react"; + +export default function AlertBadge(props: { count: number }) { + return ( +
    + {props.count > 0 + ? ( + <> + + {props.count} + + ) + : } +
    + ); +} diff --git a/packages/app/src/components/detailsPanes/metrics.tsx b/packages/app/src/components/detailsPanes/metrics.tsx new file mode 100644 index 00000000..e1a44e35 --- /dev/null +++ b/packages/app/src/components/detailsPanes/metrics.tsx @@ -0,0 +1,69 @@ +import { + type FileAuditManifest, + type FileDependencyManifest, + metricCharacterCount, + metricCodeCharacterCount, + metricCodeLineCount, + metricCyclomaticComplexity, + metricDependencyCount, + metricDependentCount, + metricLinesCount, + type SymbolAuditManifest, + type SymbolDependencyManifest, +} from "@napi/shared"; +import { Alert, AlertDescription } from "../shadcn/Alert.tsx"; + +export default function Metrics(props: { + dependencyManifest: + | FileDependencyManifest + | SymbolDependencyManifest + | undefined; + auditManifest: FileAuditManifest | SymbolAuditManifest | undefined; +}) { + function metricToHumanString(metric: string) { + switch (metric) { + case metricLinesCount: + return "Lines"; + case metricCodeLineCount: + return "Code Lines"; + case metricCharacterCount: + return "Characters"; + case metricCodeCharacterCount: + return "Code Characters"; + case metricDependencyCount: + return "Dependencies"; + case metricDependentCount: + return "Dependents"; + case metricCyclomaticComplexity: + return "Cyclomatic Complexity"; + default: + return metric; + } + } + + return ( +
    + {Object.entries(props.dependencyManifest?.metrics || {}).map(( + [key, value], + ) => ( +
    +
    +
    + {metricToHumanString(key)} +
    +
    + {value} +
    +
    + {(props.auditManifest?.alerts || {})?.[key] && ( + + + {props.auditManifest?.alerts?.[key]?.message?.long} + + + )} +
    + ))} +
    + ); +} diff --git a/packages/app/src/components/shadcn/Alert.tsx b/packages/app/src/components/shadcn/Alert.tsx new file mode 100644 index 00000000..f80fec6d --- /dev/null +++ b/packages/app/src/components/shadcn/Alert.tsx @@ -0,0 +1,59 @@ +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "../../lib/utils.ts"; + +const alertVariants = cva( + "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7", + { + variants: { + variant: { + default: "bg-background text-foreground", + destructive: + "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive", + }, + }, + defaultVariants: { + variant: "default", + }, + }, +); + +const Alert = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes & VariantProps +>(({ className, variant, ...props }, ref) => ( +
    +)); +Alert.displayName = "Alert"; + +const AlertTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
    +)); +AlertTitle.displayName = "AlertTitle"; + +const AlertDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
    +)); +AlertDescription.displayName = "AlertDescription"; + +export { Alert, AlertDescription, AlertTitle }; diff --git a/packages/app/src/components/shadcn/Breadcrumb.tsx b/packages/app/src/components/shadcn/Breadcrumb.tsx new file mode 100644 index 00000000..05f4a7f6 --- /dev/null +++ b/packages/app/src/components/shadcn/Breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from "react"; +import { Slot } from "@radix-ui/react-slot"; +import { ChevronRight, MoreHorizontal } from "lucide-react"; + +import { cn } from "../../lib/utils.ts"; + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode; + } +>(({ ...props }, ref) =>