From 773b15a645a1052070d43d654a9d2a1062d9dfe3 Mon Sep 17 00:00:00 2001 From: Boris Date: Wed, 11 Jun 2025 20:29:26 +0200 Subject: [PATCH] feat: websockets for pipeline update streaming (#851) ## Description ## DCO Affirmation I affirm that all code in every commit of this pull request conforms to the terms of the Topoteretes Developer Certificate of Origin. --------- Co-authored-by: hajdul88 <52442977+hajdul88@users.noreply.github.com> Co-authored-by: lxobr <122801072+lxobr@users.noreply.github.com> Co-authored-by: Igor Ilic <30923996+dexters1@users.noreply.github.com> Co-authored-by: Hande <159312713+hande-k@users.noreply.github.com> Co-authored-by: Vasilije <8619304+Vasilije1990@users.noreply.github.com> --- cognee-frontend/.prettierrc | 7 + cognee-frontend/package-lock.json | 1138 +++++++++++--- cognee-frontend/package.json | 10 +- cognee-frontend/postcss.config.mjs | 5 + .../src/app/(graph)/CogneeAddWidget.tsx | 89 ++ .../src/app/(graph)/CrewAITrigger.tsx | 26 + .../src/app/(graph)/GraphControls.tsx | 184 +++ cognee-frontend/src/app/(graph)/GraphView.tsx | 276 ++++ .../src/app/(graph)/example_data.json | 1376 +++++++++++++++++ .../src/app/auth/AuthPage.module.css | 16 - cognee-frontend/src/app/auth/AuthPage.tsx | 37 +- cognee-frontend/src/app/globals.css | 13 +- cognee-frontend/src/app/page copy.tsx | 130 ++ cognee-frontend/src/app/page.tsx | 131 +- .../src/modules/datasets/cognifyDataset.ts | 34 +- .../src/modules/datasets/getDatasetGraph.ts | 6 + .../ingestion/DatasetsView/DatasetsView.tsx | 2 +- .../ingestion/DatasetsView/StatusIcon.tsx | 15 - .../src/modules/ingestion/useDatasets.ts | 6 +- .../LoadingIndicator.module.css | 6 +- cognee-frontend/src/ui/Icons/DeleteIcon.tsx | 7 + cognee-frontend/src/ui/Icons/GitHubIcon.tsx | 2 +- cognee-frontend/src/ui/Icons/index.ts | 1 + .../src/ui/Partials/FeedbackForm.tsx | 66 + .../src/ui/Partials/Footer/Footer.module.css | 16 - .../src/ui/Partials/Footer/Footer.tsx | 40 +- .../src/ui/Partials/SignInForm/SignInForm.tsx | 75 +- cognee-frontend/src/ui/Partials/index.ts | 11 +- cognee-frontend/src/ui/elements/CTAButton.tsx | 8 + cognee-frontend/src/ui/elements/Input.tsx | 8 + .../src/ui/elements/NeutralButton.tsx | 8 + cognee-frontend/src/ui/elements/Select.tsx | 10 + .../src/ui/elements/StatusIndicator.tsx | 22 + cognee-frontend/src/ui/elements/TextArea.tsx | 7 + cognee-frontend/src/ui/elements/index.ts | 6 + cognee-frontend/src/utils/index.ts | 5 +- cognee-frontend/src/utils/useBoolean.ts | 14 + cognee/api/client.py | 15 +- cognee/api/v1/add/add.py | 9 +- cognee/api/v1/add/routers/get_add_router.py | 7 +- cognee/api/v1/cognify/cognify.py | 90 +- .../v1/cognify/routers/get_cognify_router.py | 120 +- .../datasets/routers/get_datasets_router.py | 49 +- .../corpus_builder/corpus_builder_executor.py | 5 +- .../databases/graph/kuzu/adapter.py | 1 + .../operations/get_pipeline_run_metrics.py | 57 +- .../pipelines/models/PipelineRunInfo.py | 33 + cognee/modules/pipelines/models/__init__.py | 7 + .../operations/log_pipeline_run_initiated.py | 5 +- .../operations/log_pipeline_run_start.py | 4 +- .../modules/pipelines/operations/pipeline.py | 30 +- .../modules/pipelines/operations/run_tasks.py | 48 +- .../queues/pipeline_run_info_queues.py | 37 + cognee/modules/pipelines/utils/__init__.py | 2 + .../pipelines/utils/generate_pipeline_id.py | 5 + .../utils/generate_pipeline_run_id.py | 5 + .../retrieval/exceptions/exceptions.py | 10 + .../retrieval/graph_completion_retriever.py | 4 + .../utils/brute_force_triplet_search.py | 2 + cognee/tests/test_cognee_server_start.py | 2 +- poetry.lock | 34 +- pyproject.toml | 1 + uv.lock | 2 + 63 files changed, 3736 insertions(+), 661 deletions(-) create mode 100644 cognee-frontend/.prettierrc create mode 100644 cognee-frontend/postcss.config.mjs create mode 100644 cognee-frontend/src/app/(graph)/CogneeAddWidget.tsx create mode 100644 cognee-frontend/src/app/(graph)/CrewAITrigger.tsx create mode 100644 cognee-frontend/src/app/(graph)/GraphControls.tsx create mode 100644 cognee-frontend/src/app/(graph)/GraphView.tsx create mode 100644 cognee-frontend/src/app/(graph)/example_data.json delete mode 100644 cognee-frontend/src/app/auth/AuthPage.module.css create mode 100644 cognee-frontend/src/app/page copy.tsx create mode 100644 cognee-frontend/src/modules/datasets/getDatasetGraph.ts delete mode 100644 cognee-frontend/src/modules/ingestion/DatasetsView/StatusIcon.tsx create mode 100644 cognee-frontend/src/ui/Icons/DeleteIcon.tsx create mode 100644 cognee-frontend/src/ui/Partials/FeedbackForm.tsx delete mode 100644 cognee-frontend/src/ui/Partials/Footer/Footer.module.css create mode 100644 cognee-frontend/src/ui/elements/CTAButton.tsx create mode 100644 cognee-frontend/src/ui/elements/Input.tsx create mode 100644 cognee-frontend/src/ui/elements/NeutralButton.tsx create mode 100644 cognee-frontend/src/ui/elements/Select.tsx create mode 100644 cognee-frontend/src/ui/elements/StatusIndicator.tsx create mode 100644 cognee-frontend/src/ui/elements/TextArea.tsx create mode 100644 cognee-frontend/src/ui/elements/index.ts create mode 100644 cognee-frontend/src/utils/useBoolean.ts create mode 100644 cognee/modules/pipelines/models/PipelineRunInfo.py create mode 100644 cognee/modules/pipelines/queues/pipeline_run_info_queues.py create mode 100644 cognee/modules/pipelines/utils/__init__.py create mode 100644 cognee/modules/pipelines/utils/generate_pipeline_id.py create mode 100644 cognee/modules/pipelines/utils/generate_pipeline_run_id.py diff --git a/cognee-frontend/.prettierrc b/cognee-frontend/.prettierrc new file mode 100644 index 000000000..b5c691802 --- /dev/null +++ b/cognee-frontend/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "es5", + "tabWidth": 2, + "semi": true, + "singleQuote": false, + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/cognee-frontend/package-lock.json b/cognee-frontend/package-lock.json index 7ed113b5a..4cc799733 100644 --- a/cognee-frontend/package-lock.json +++ b/cognee-frontend/package-lock.json @@ -1,21 +1,25 @@ { "name": "cognee-frontend", - "version": "0.1.0", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cognee-frontend", - "version": "0.1.0", + "version": "1.0.0", "dependencies": { "classnames": "^2.5.1", - "next": "^14.2.26", + "d3-force-3d": "^3.0.6", + "next": "15.3.2", "ohmy-ui": "^0.0.6", "react": "^18", "react-dom": "^18", + "react-force-graph-2d": "^1.27.1", + "tailwindcss": "^4.1.7", "uuid": "^9.0.1" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.7", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", @@ -25,52 +29,36 @@ "typescript": "^5" } }, - "../Guerrilla/ohmy-ui": { - "version": "0.0.3", - "extraneous": true, - "license": "MIT", + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, "dependencies": { - "classnames": "^2.3.2" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, - "devDependencies": { - "@rollup/plugin-commonjs": "^25.0.7", - "@rollup/plugin-node-resolve": "^15.2.3", - "@rollup/plugin-terser": "^0.4.4", - "@rollup/plugin-typescript": "^11.1.6", - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "eslint": "^8", - "eslint-config-next": "14.0.4", - "next": "14.0.4", - "postcss": "^8.4.32", - "postcss-custom-media": "^10.0.2", - "postcss-import": "^15.1.0", - "postcss-preset-env": "^9.3.0", - "rollup": "^4.17.2", - "rollup-plugin-dts": "^6.1.0", - "rollup-plugin-peer-deps-external": "^2.2.4", - "rollup-plugin-postcss": "^4.0.2", - "typescript": "^5" - }, - "peerDependencies": { - "@types/react": "^18", - "react": "^18", - "react-dom": "^18" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } + "engines": { + "node": ">=6.0.0" } }, "node_modules/@babel/runtime": { - "version": "7.24.5", + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz", + "integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==", "dev": true, - "license": "MIT", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, "engines": { "node": ">=6.9.0" } @@ -157,6 +145,42 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.2.tgz", + "integrity": "sha512-OfXHZPppddivUJnqyKoi5YVeHRkkNE2zUFT2gbpKxp/JZCFYEYubnMg+gOp6lWfasPrTS+KPosKqdI+ELYVDtg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.1.0" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -198,11 +222,70 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, "node_modules/@next/env": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.26.tgz", - "integrity": "sha512-vO//GJ/YBco+H7xdQhzJxF7ub3SUwft76jwaeOyVVQFHCi5DCnkP16WHB+JBylo4vOKPoZBlR94Z8xBxNBdNJA==", - "license": "MIT" + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.3.2.tgz", + "integrity": "sha512-xURk++7P7qR9JG1jJtLzPzf0qEvqCN0A/T3DXf8IPMKo9/6FfjxtEffRJIIew/bIL4T3C2jLLqBor8B/zVlx6g==" }, "node_modules/@next/eslint-plugin-next": { "version": "14.2.3", @@ -213,9 +296,10 @@ } }, "node_modules/@next/eslint-plugin-next/node_modules/brace-expansion": { - "version": "2.0.1", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -242,9 +326,10 @@ } }, "node_modules/@next/eslint-plugin-next/node_modules/minimatch": { - "version": "9.0.4", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -256,13 +341,12 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.26.tgz", - "integrity": "sha512-zDJY8gsKEseGAxG+C2hTMT0w9Nk9N1Sk1qV7vXYz9MEiyRoF5ogQX2+vplyUMIfygnjn9/A04I6yrUTRTuRiyQ==", + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.3.2.tgz", + "integrity": "sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g==", "cpu": [ "arm64" ], - "license": "MIT", "optional": true, "os": [ "darwin" @@ -271,134 +355,6 @@ "node": ">= 10" } }, - "node_modules/@next/swc-darwin-x64": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.26.tgz", - "integrity": "sha512-U0adH5ryLfmTDkahLwG9sUQG2L0a9rYux8crQeC92rPhi3jGQEY47nByQHrVrt3prZigadwj/2HZ1LUUimuSbg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.26.tgz", - "integrity": "sha512-SINMl1I7UhfHGM7SoRiw0AbwnLEMUnJ/3XXVmhyptzriHbWvPPbbm0OEVG24uUKhuS1t0nvN/DBvm5kz6ZIqpg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.26.tgz", - "integrity": "sha512-s6JaezoyJK2DxrwHWxLWtJKlqKqTdi/zaYigDXUJ/gmx/72CrzdVZfMvUc6VqnZ7YEvRijvYo+0o4Z9DencduA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.26.tgz", - "integrity": "sha512-FEXeUQi8/pLr/XI0hKbe0tgbLmHFRhgXOUiPScz2hk0hSmbGiU8aUqVslj/6C6KA38RzXnWoJXo4FMo6aBxjzg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.26.tgz", - "integrity": "sha512-BUsomaO4d2DuXhXhgQCVt2jjX4B4/Thts8nDoIruEJkhE5ifeQFtvW5c9JkdOtYvE5p2G0hcwQ0UbRaQmQwaVg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.26.tgz", - "integrity": "sha512-5auwsMVzT7wbB2CZXQxDctpWbdEnEW/e66DyXO1DcgHxIyhP06awu+rHKshZE+lPLIGiwtjo7bsyeuubewwxMw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-ia32-msvc": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.26.tgz", - "integrity": "sha512-GQWg/Vbz9zUGi9X80lOeGsz1rMH/MtFO/XqigDznhhhTfDlDoynCM6982mPCbSlxJ/aveZcKtTlwfAjwhyxDpg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.26.tgz", - "integrity": "sha512-2rdB3T1/Gp7bv1eQTTm9d1Y1sv9UuJ2LAwOE0Pe2prHKe32UNscj7YS13fRB37d0GAiGNR+Y7ZcW8YjDI8Ns0w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -450,13 +406,117 @@ "license": "Apache-2.0" }, "node_modules/@swc/helpers": { - "version": "0.5.5", + "version": "0.5.15", "license": "Apache-2.0", "dependencies": { - "@swc/counter": "^0.1.3", - "tslib": "^2.4.0" + "tslib": "^2.8.0" } }, + "node_modules/@tailwindcss/node": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.8.tgz", + "integrity": "sha512-OWwBsbC9BFAJelmnNcrKuf+bka2ZxCE2A4Ft53Tkg4uoiE67r/PMEYwCsourC26E+kmxfwE0hVzMdxqeW+xu7Q==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.3.0", + "enhanced-resolve": "^5.18.1", + "jiti": "^2.4.2", + "lightningcss": "1.30.1", + "magic-string": "^0.30.17", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.8" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.8.tgz", + "integrity": "sha512-d7qvv9PsM5N3VNKhwVUhpK6r4h9wtLkJ6lz9ZY9aeZgrUWk1Z8VPyqyDT9MZlem7GTGseRQHkeB1j3tC7W1P+A==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "detect-libc": "^2.0.4", + "tar": "^7.4.3" + }, + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.8", + "@tailwindcss/oxide-darwin-arm64": "4.1.8", + "@tailwindcss/oxide-darwin-x64": "4.1.8", + "@tailwindcss/oxide-freebsd-x64": "4.1.8", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.8", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.8", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.8", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.8", + "@tailwindcss/oxide-linux-x64-musl": "4.1.8", + "@tailwindcss/oxide-wasm32-wasi": "4.1.8", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.8", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.8" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.8.tgz", + "integrity": "sha512-RdRvedGsT0vwVVDztvyXhKpsU2ark/BjgG0huo4+2BluxdXo8NDgzl77qh0T1nUxmM11eXwR8jA39ibvSTbi7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.8.tgz", + "integrity": "sha512-vB/vlf7rIky+w94aWMw34bWW1ka6g6C3xIOdICKX2GC0VcLtL6fhlLiafF0DVIwa9V6EHz8kbWMkS2s2QvvNlw==", + "dev": true, + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.1.8", + "@tailwindcss/oxide": "4.1.8", + "postcss": "^8.4.41", + "tailwindcss": "4.1.8" + } + }, + "node_modules/@tailwindcss/postcss/node_modules/postcss": { + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz", + "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/@tweenjs/tween.js": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-25.0.0.tgz", + "integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==" + }, "node_modules/@types/json5": { "version": "0.0.29", "dev": true, @@ -580,9 +640,10 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -622,6 +683,14 @@ "dev": true, "license": "ISC" }, + "node_modules/accessor-fn": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/accessor-fn/-/accessor-fn-1.5.3.tgz", + "integrity": "sha512-rkAofCwe/FvYFUlMB0v0gWmhqtfAtV1IUkdPbfhTUyYniu5LrC0A0UJkTH0Jv3S8SvwkmfuAlY+mQIJATdocMA==", + "engines": { + "node": ">=12" + } + }, "node_modules/acorn": { "version": "8.11.3", "dev": true, @@ -889,6 +958,15 @@ "dev": true, "license": "MIT" }, + "node_modules/bezier-js": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-6.1.4.tgz", + "integrity": "sha512-PA0FW9ZpcHbojUCMu28z9Vg/fNkwTj5YhusSAjHHDfHDGLxJ6YUKrAN2vk1fP2MMOxVw4Oko16FMlRGVBGqLKg==", + "funding": { + "type": "individual", + "url": "https://github.com/Pomax/bezierjs/blob/master/FUNDING.md" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -899,11 +977,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, - "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -962,6 +1041,17 @@ ], "license": "CC-BY-4.0" }, + "node_modules/canvas-color-tracker": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/canvas-color-tracker/-/canvas-color-tracker-1.3.2.tgz", + "integrity": "sha512-ryQkDX26yJ3CXzb3hxUVNlg1NKE4REc5crLBq661Nxzr8TNd236SaEf2ffYLXyI5tSABSeguHLqcVq4vf9L3Zg==", + "dependencies": { + "tinycolor2": "^1.6.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/chalk": { "version": "4.1.2", "dev": true, @@ -977,6 +1067,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/classnames": { "version": "2.5.1", "license": "MIT" @@ -985,9 +1084,22 @@ "version": "0.0.1", "license": "MIT" }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "optional": true, + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -998,18 +1110,29 @@ }, "node_modules/color-name": { "version": "1.1.4", - "dev": true, + "devOptional": true, "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "optional": true, + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/concat-map": { "version": "0.0.1", "dev": true, "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1024,6 +1147,203 @@ "devOptional": true, "license": "MIT" }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-binarytree": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d3-binarytree/-/d3-binarytree-1.0.2.tgz", + "integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==" + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force-3d": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/d3-force-3d/-/d3-force-3d-3.0.6.tgz", + "integrity": "sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA==", + "dependencies": { + "d3-binarytree": "1", + "d3-dispatch": "1 - 3", + "d3-octree": "1", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-octree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-octree/-/d3-octree-1.1.0.tgz", + "integrity": "sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==" + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "dev": true, @@ -1138,6 +1458,15 @@ "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "devOptional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "dev": true, @@ -1171,9 +1500,10 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.16.1", + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", "dev": true, - "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -1792,9 +2122,10 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1835,6 +2166,19 @@ "dev": true, "license": "ISC" }, + "node_modules/float-tooltip": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/float-tooltip/-/float-tooltip-1.7.5.tgz", + "integrity": "sha512-/kXzuDnnBqyyWyhDMH7+PfP8J/oXiAavGzcRxASOMRHFuReDtofizLLJsf7nnDLAfEaMW4pVWaXrAjtnglpEkg==", + "dependencies": { + "d3-selection": "2 - 3", + "kapsule": "^1.16", + "preact": "10" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/for-each": { "version": "0.3.3", "dev": true, @@ -1843,6 +2187,31 @@ "is-callable": "^1.1.3" } }, + "node_modules/force-graph": { + "version": "1.49.6", + "resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.49.6.tgz", + "integrity": "sha512-o3uZ22YMvRwcS4RZ5lMQE5mCsQ5w1AzR4bPlQ1cThqgAxRrzOO4mGOaeNGTAkGGQwL6f7RIBCaxPNtvkbgAykw==", + "dependencies": { + "@tweenjs/tween.js": "18 - 25", + "accessor-fn": "1", + "bezier-js": "3 - 6", + "canvas-color-tracker": "^1.3", + "d3-array": "1 - 3", + "d3-drag": "2 - 3", + "d3-force-3d": "2 - 3", + "d3-scale": "1 - 4", + "d3-scale-chromatic": "1 - 3", + "d3-selection": "2 - 3", + "d3-zoom": "2 - 3", + "float-tooltip": "^1.7", + "index-array-by": "1", + "kapsule": "^1.16", + "lodash-es": "4" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/foreground-child": { "version": "3.1.1", "dev": true, @@ -2032,6 +2401,7 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", + "dev": true, "license": "ISC" }, "node_modules/graphemer": { @@ -2144,6 +2514,14 @@ "node": ">=0.8.19" } }, + "node_modules/index-array-by": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/index-array-by/-/index-array-by-1.4.2.tgz", + "integrity": "sha512-SP23P27OUKzXWEC/TOyWlwLviofQkCSCKONnc62eItjp69yCZZPqDQtr3Pw5gJDnPeUMqExmKydNZaJO0FU9pw==", + "engines": { + "node": ">=12" + } + }, "node_modules/inflight": { "version": "1.0.6", "dev": true, @@ -2171,6 +2549,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/is-array-buffer": { "version": "3.0.4", "dev": true, @@ -2186,6 +2572,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "optional": true + }, "node_modules/is-async-function": { "version": "2.0.0", "dev": true, @@ -2352,8 +2744,9 @@ }, "node_modules/is-number": { "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -2538,6 +2931,23 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jerrypick": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/jerrypick/-/jerrypick-1.1.2.tgz", + "integrity": "sha512-YKnxXEekXKzhpf7CLYA0A+oDP8V0OhICNCr5lv96FvSsDEmrb0GKM776JgQvHTMjr7DTTPEVv/1Ciaw0uEWzBA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "license": "MIT" @@ -2593,6 +3003,17 @@ "node": ">=4.0" } }, + "node_modules/kapsule": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/kapsule/-/kapsule-1.16.3.tgz", + "integrity": "sha512-4+5mNNf4vZDSwPhKprKwz3330iisPrb08JyMgbsdFrimBCKNHecua/WBwvVg3n7vwx0C1ARjfhwIpbrbd9n5wg==", + "dependencies": { + "lodash-es": "4" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/keyv": { "version": "4.5.4", "dev": true, @@ -2629,6 +3050,54 @@ "node": ">= 0.8.0" } }, + "node_modules/lightningcss": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", + "dev": true, + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/locate-path": { "version": "6.0.0", "dev": true, @@ -2643,6 +3112,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "dev": true, @@ -2666,6 +3140,15 @@ "node": "14 || >=16.14" } }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, "node_modules/merge2": { "version": "1.4.1", "dev": true, @@ -2675,11 +3158,12 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, - "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -2706,27 +3190,56 @@ } }, "node_modules/minipass": { - "version": "7.1.1", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ms": { "version": "2.1.2", "dev": true, "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.7", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -2740,41 +3253,41 @@ "license": "MIT" }, "node_modules/next": { - "version": "14.2.26", - "resolved": "https://registry.npmjs.org/next/-/next-14.2.26.tgz", - "integrity": "sha512-b81XSLihMwCfwiUVRRja3LphLo4uBBMZEzBBWMaISbKTwOmq3wPknIETy/8000tr7Gq4WmbuFYPS7jOYIf+ZJw==", - "license": "MIT", + "version": "15.3.2", + "resolved": "https://registry.npmjs.org/next/-/next-15.3.2.tgz", + "integrity": "sha512-CA3BatMyHkxZ48sgOCLdVHjFU36N7TF1HhqAHLFOkV6buwZnvMI84Cug8xD56B9mCuKrqXnLn94417GrZ/jjCQ==", "dependencies": { - "@next/env": "14.2.26", - "@swc/helpers": "0.5.5", + "@next/env": "15.3.2", + "@swc/counter": "0.1.3", + "@swc/helpers": "0.5.15", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", - "graceful-fs": "^4.2.11", "postcss": "8.4.31", - "styled-jsx": "5.1.1" + "styled-jsx": "5.1.6" }, "bin": { "next": "dist/bin/next" }, "engines": { - "node": ">=18.17.0" + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "14.2.26", - "@next/swc-darwin-x64": "14.2.26", - "@next/swc-linux-arm64-gnu": "14.2.26", - "@next/swc-linux-arm64-musl": "14.2.26", - "@next/swc-linux-x64-gnu": "14.2.26", - "@next/swc-linux-x64-musl": "14.2.26", - "@next/swc-win32-arm64-msvc": "14.2.26", - "@next/swc-win32-ia32-msvc": "14.2.26", - "@next/swc-win32-x64-msvc": "14.2.26" + "@next/swc-darwin-arm64": "15.3.2", + "@next/swc-darwin-x64": "15.3.2", + "@next/swc-linux-arm64-gnu": "15.3.2", + "@next/swc-linux-arm64-musl": "15.3.2", + "@next/swc-linux-x64-gnu": "15.3.2", + "@next/swc-linux-x64-musl": "15.3.2", + "@next/swc-win32-arm64-msvc": "15.3.2", + "@next/swc-win32-x64-msvc": "15.3.2", + "sharp": "^0.34.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.41.2", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "peerDependenciesMeta": { @@ -2784,6 +3297,9 @@ "@playwright/test": { "optional": true }, + "babel-plugin-react-compiler": { + "optional": true + }, "sass": { "optional": true } @@ -2791,7 +3307,6 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -2907,8 +3422,7 @@ }, "node_modules/ohmy-ui": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/ohmy-ui/-/ohmy-ui-0.0.6.tgz", - "integrity": "sha512-3IRbspxHyTufWJ7G2ErmnKzwEK3SkkXX5Y0m5Er7PIDeU3vE/HfrwV9tAe/lgf2xmVKBiVLuPz58O7Wj5qPxSA==", + "license": "MIT", "dependencies": { "classnames": "^2.3.2" }, @@ -3039,8 +3553,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", - "license": "ISC" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" }, "node_modules/picomatch": { "version": "2.3.1", @@ -3087,6 +3602,15 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/preact": { + "version": "10.26.8", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.8.tgz", + "integrity": "sha512-1nMfdFjucm5hKvq0IClqZwK4FJkGXhRrQstOQ3P4vp8HxKrJEMFcY6RdBRVTdfQS/UlnX6gfbPuTvaqx/bDoeQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -3097,7 +3621,6 @@ }, "node_modules/prop-types": { "version": "15.8.1", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -3134,7 +3657,8 @@ }, "node_modules/react": { "version": "18.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -3144,7 +3668,8 @@ }, "node_modules/react-dom": { "version": "18.3.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -3153,11 +3678,40 @@ "react": "^18.3.1" } }, + "node_modules/react-force-graph-2d": { + "version": "1.27.1", + "resolved": "https://registry.npmjs.org/react-force-graph-2d/-/react-force-graph-2d-1.27.1.tgz", + "integrity": "sha512-/b1k+HbW9QCzGILJibyzN2PVZdDWTFuEylqcJGkUTBs0uLcK0h2LgOUuVU+GpRGpuXmj9sBAt43zz+PTETFHGg==", + "dependencies": { + "force-graph": "^1.49", + "prop-types": "15", + "react-kapsule": "^2.5" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", - "dev": true, "license": "MIT" }, + "node_modules/react-kapsule": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/react-kapsule/-/react-kapsule-2.5.7.tgz", + "integrity": "sha512-kifAF4ZPD77qZKc4CKLmozq6GY1sBzPEJTIJb0wWFK6HsePJatK3jXplZn2eeAt3x67CDozgi7/rO8fNQ/AL7A==", + "dependencies": { + "jerrypick": "^1.1.1" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", "dev": true, @@ -3178,11 +3732,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "dev": true, - "license": "MIT" - }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "dev": true, @@ -3312,14 +3861,15 @@ }, "node_modules/scheduler": { "version": "0.23.2", - "license": "MIT", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/semver": { - "version": "7.6.2", - "dev": true, + "version": "7.7.2", + "devOptional": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -3358,6 +3908,47 @@ "node": ">= 0.4" } }, + "node_modules/sharp": { + "version": "0.34.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.2.tgz", + "integrity": "sha512-lszvBmB9QURERtyKT2bNmsgxXK0ShJrL/fvqlonCo7e6xBF8nT8xU6pW+PMIbLsz0RxQk3rgH9kd8UmvOzlMJg==", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.4", + "semver": "^7.7.2" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.2", + "@img/sharp-darwin-x64": "0.34.2", + "@img/sharp-libvips-darwin-arm64": "1.1.0", + "@img/sharp-libvips-darwin-x64": "1.1.0", + "@img/sharp-libvips-linux-arm": "1.1.0", + "@img/sharp-libvips-linux-arm64": "1.1.0", + "@img/sharp-libvips-linux-ppc64": "1.1.0", + "@img/sharp-libvips-linux-s390x": "1.1.0", + "@img/sharp-libvips-linux-x64": "1.1.0", + "@img/sharp-libvips-linuxmusl-arm64": "1.1.0", + "@img/sharp-libvips-linuxmusl-x64": "1.1.0", + "@img/sharp-linux-arm": "0.34.2", + "@img/sharp-linux-arm64": "0.34.2", + "@img/sharp-linux-s390x": "0.34.2", + "@img/sharp-linux-x64": "0.34.2", + "@img/sharp-linuxmusl-arm64": "0.34.2", + "@img/sharp-linuxmusl-x64": "0.34.2", + "@img/sharp-wasm32": "0.34.2", + "@img/sharp-win32-arm64": "0.34.2", + "@img/sharp-win32-ia32": "0.34.2", + "@img/sharp-win32-x64": "0.34.2" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "dev": true, @@ -3405,6 +3996,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "optional": true, + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, "node_modules/slash": { "version": "3.0.0", "dev": true, @@ -3414,8 +4014,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "license": "BSD-3-Clause", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -3600,7 +4201,7 @@ } }, "node_modules/styled-jsx": { - "version": "5.1.1", + "version": "5.1.6", "license": "MIT", "dependencies": { "client-only": "0.0.1" @@ -3609,7 +4210,7 @@ "node": ">= 12.0.0" }, "peerDependencies": { - "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" }, "peerDependenciesMeta": { "@babel/core": { @@ -3642,6 +4243,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwindcss": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz", + "integrity": "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==" + }, "node_modules/tapable": { "version": "2.2.1", "dev": true, @@ -3650,15 +4256,38 @@ "node": ">=6" } }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/text-table": { "version": "0.2.0", "dev": true, "license": "MIT" }, + "node_modules/tinycolor2": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.6.0.tgz", + "integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==" + }, "node_modules/to-regex-range": { "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, - "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -3689,7 +4318,7 @@ } }, "node_modules/tslib": { - "version": "2.6.2", + "version": "2.8.1", "license": "0BSD" }, "node_modules/type-check": { @@ -4022,6 +4651,15 @@ "dev": true, "license": "ISC" }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "engines": { + "node": ">=18" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "dev": true, diff --git a/cognee-frontend/package.json b/cognee-frontend/package.json index d74bb7207..a9bf808b2 100644 --- a/cognee-frontend/package.json +++ b/cognee-frontend/package.json @@ -1,6 +1,6 @@ { "name": "cognee-frontend", - "version": "0.1.0", + "version": "1.0.0", "private": true, "scripts": { "dev": "next dev", @@ -10,13 +10,17 @@ }, "dependencies": { "classnames": "^2.5.1", + "d3-force-3d": "^3.0.6", + "next": "15.3.2", "ohmy-ui": "^0.0.6", "react": "^18", "react-dom": "^18", - "uuid": "^9.0.1", - "next": "^14.2.26" + "react-force-graph-2d": "^1.27.1", + "tailwindcss": "^4.1.7", + "uuid": "^9.0.1" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.7", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", diff --git a/cognee-frontend/postcss.config.mjs b/cognee-frontend/postcss.config.mjs new file mode 100644 index 000000000..7e0ba624f --- /dev/null +++ b/cognee-frontend/postcss.config.mjs @@ -0,0 +1,5 @@ +export default { + plugins: { + "@tailwindcss/postcss": {}, + } +} diff --git a/cognee-frontend/src/app/(graph)/CogneeAddWidget.tsx b/cognee-frontend/src/app/(graph)/CogneeAddWidget.tsx new file mode 100644 index 000000000..9d87895dd --- /dev/null +++ b/cognee-frontend/src/app/(graph)/CogneeAddWidget.tsx @@ -0,0 +1,89 @@ +"use client"; + +import { ChangeEvent, useEffect } from "react"; +import { CTAButton, StatusIndicator } from "@/ui/elements"; + +import addData from "@/modules/ingestion/addData"; +import cognifyDataset from "@/modules/datasets/cognifyDataset"; +import useDatasets from "@/modules/ingestion/useDatasets"; +import getDatasetGraph from '@/modules/datasets/getDatasetGraph'; + +export interface NodesAndEdges { + nodes: { id: string; label: string }[]; + links: { source: string; target: string; label: string }[]; +} + +interface CogneeAddWidgetProps { + onData: (data: NodesAndEdges) => void; +} + +export default function CogneeAddWidget({ onData }: CogneeAddWidgetProps) { + const { + datasets, + addDataset, + removeDataset, + refreshDatasets, + } = useDatasets(); + + useEffect(() => { + refreshDatasets() + .then((datasets) => { + const dataset = datasets?.[0]; + + if (dataset) { + getDatasetGraph(dataset) + .then((graph) => onData({ + nodes: graph.nodes, + links: graph.edges, + })); + } + }); + }, [refreshDatasets]); + + const handleAddFiles = (dataset: { id?: string, name?: string }, event: ChangeEvent) => { + event.stopPropagation(); + + if (!event.currentTarget.files) { + throw new Error("Error: No files added to the uploader input."); + } + + const files: File[] = Array.from(event.currentTarget.files); + + return addData(dataset, files) + .then(() => { + console.log("Data added successfully."); + + const onUpdate = (data: any) => { + onData({ + nodes: data.payload.nodes, + links: data.payload.edges, + }); + }; + + return cognifyDataset(dataset, onUpdate) + .then((data) => console.log(data)); + }); + }; + + return ( +
+ {datasets.length ? datasets.map((dataset) => ( +
+
+ + {dataset.name} +
+ + + + Add Data + +
+ )) : ( + + + + Add Data + + )} +
+ ); +} diff --git a/cognee-frontend/src/app/(graph)/CrewAITrigger.tsx b/cognee-frontend/src/app/(graph)/CrewAITrigger.tsx new file mode 100644 index 000000000..b3f9b0171 --- /dev/null +++ b/cognee-frontend/src/app/(graph)/CrewAITrigger.tsx @@ -0,0 +1,26 @@ +import { fetch } from "@/utils"; +import { CTAButton, Input } from "@/ui/elements"; + +interface CrewAIFormPayload extends HTMLFormElement { + username1: HTMLInputElement; + username2: HTMLInputElement; +} + +export default function CrewAITrigger() { + const handleRunCrewAI = (event: React.FormEvent) => { + fetch("/v1/crew-ai/run", { + method: "POST", + body: new FormData(event.currentTarget), + }) + .then(response => response.json()) + .then((data) => console.log(data)); + }; + + return ( +
+ + + Run CrewAI +
+ ); +} diff --git a/cognee-frontend/src/app/(graph)/GraphControls.tsx b/cognee-frontend/src/app/(graph)/GraphControls.tsx new file mode 100644 index 000000000..3e2d6c5ac --- /dev/null +++ b/cognee-frontend/src/app/(graph)/GraphControls.tsx @@ -0,0 +1,184 @@ +"use client"; + +import { v4 as uuid4 } from "uuid"; +import classNames from "classnames"; +import { NodeObject } from "react-force-graph-2d"; +import { ChangeEvent, useImperativeHandle, useState } from "react"; + +import { DeleteIcon } from "@/ui/Icons"; +import { FeedbackForm } from "@/ui/Partials"; +import { CTAButton, Input, NeutralButton, Select } from "@/ui/elements"; + +interface GraphControlsProps { + isAddNodeFormOpen: boolean; + ref: React.RefObject; + onFitIntoView: () => void; + onGraphShapeChange: (shape: string) => void; +} + +export interface GraphControlsAPI { + setSelectedNode: (node: NodeObject | null) => void; + getSelectedNode: () => NodeObject | null; +} + +type ActivityLog = { + id: string; + timestamp: number; + activity: string; +}[]; + +type NodeProperties = { + id: string; + name: string; + value: string; +}[]; + +export default function GraphControls({ isAddNodeFormOpen, onGraphShapeChange, onFitIntoView, ref }: GraphControlsProps) { + const [selectedNode, setSelectedNode] = useState(null); + const [activityLog, setActivityLog] = useState([]); + const [nodeProperties, setNodeProperties] = useState([]); + const [newProperty, setNewProperty] = useState({ + id: uuid4(), + name: "", + value: "", + }); + + const handlePropertyChange = (property: NodeProperties[0], property_key: string, event: ChangeEvent) => { + const value = event.target.value; + + setNodeProperties(nodeProperties.map((nodeProperty) => (nodeProperty.id === property.id ? {...nodeProperty, [property_key]: value } : nodeProperty))); + }; + + const handlePropertyAdd = () => { + if (newProperty.name && newProperty.value) { + setNodeProperties([...nodeProperties, newProperty]); + setNewProperty({ id: uuid4(), name: "", value: "" }); + } else { + alert("Please fill in both name and value fields for the new property."); + } + }; + + const handlePropertyDelete = (property: NodeProperties[0]) => { + setNodeProperties(nodeProperties.filter((nodeProperty) => nodeProperty.id !== property.id)); + }; + + const handleNewPropertyChange = (property: NodeProperties[0], property_key: string, event: ChangeEvent) => { + const value = event.target.value; + + setNewProperty({...property, [property_key]: value }); + }; + + useImperativeHandle(ref, () => ({ + setSelectedNode, + getSelectedNode: () => selectedNode, + })); + + const [selectedTab, setSelectedTab] = useState("nodeDetails"); + + const handleGraphShapeControl = (event: ChangeEvent) => { + onGraphShapeChange(event.target.value); + }; + + return ( + <> +
+ + + +
+ +
+ {selectedTab === "nodeDetails" && ( + <> +
+ + +
+ + Fit Graph into View + + {isAddNodeFormOpen ? ( +
{}}> +
+ Source Node ID: + +
+
+ {nodeProperties.map((property) => ( +
+ + + +
+ ))} +
+ + + Add +
+
+ Add Node +
+ ) : ( + selectedNode ? ( +
+
+
+ ID: + {selectedNode.id} +
+ + {Object.entries(selectedNode.properties).map(([key, value]) => ( +
+ {key}: + {typeof value === "object" ? JSON.stringify(value) : value as string} +
+ ))} +
+ + {}}>Edit Node +
+ ) : ( + No node selected. + ) + )} + + )} + + {selectedTab === "activityLog" && ( +
+ {activityLog.map((activity) => ( +
+ {activity.timestamp} + {activity.activity} +
+ ))} + {!activityLog.length && No activity logged.} +
+ )} + + {selectedTab === "feedback" && ( +
+ {}} /> +
+ )} +
+ + ); +} diff --git a/cognee-frontend/src/app/(graph)/GraphView.tsx b/cognee-frontend/src/app/(graph)/GraphView.tsx new file mode 100644 index 000000000..b74260723 --- /dev/null +++ b/cognee-frontend/src/app/(graph)/GraphView.tsx @@ -0,0 +1,276 @@ +"use client"; + +import { forceCollide, forceManyBody } from "d3-force-3d"; +import { useEffect, useRef, useState } from "react"; +import ForceGraph, { ForceGraphMethods, LinkObject, NodeObject } from "react-force-graph-2d"; + +import { TextLogo } from "@/ui/App"; +import { Divider } from "@/ui/Layout"; +import { Footer } from "@/ui/Partials"; +import CrewAITrigger from "./CrewAITrigger"; +import CogneeAddWidget, { NodesAndEdges } from "./CogneeAddWidget"; +import GraphControls, { GraphControlsAPI } from "./GraphControls"; + +import { useBoolean } from "@/utils"; + +// import exampleData from "./example_data.json"; + +interface GraphNode { + id: string | number; + label: string; + properties?: {}; +} + +interface GraphData { + nodes: GraphNode[]; + links: { source: string | number; target: string | number; label: string }[]; +} + +export default function GraphView() { + const { + value: isAddNodeFormOpen, + setTrue: enableAddNodeForm, + setFalse: disableAddNodeForm, + } = useBoolean(false); + + const [data, updateData] = useState(null); + + const onDataChange = (newData: NodesAndEdges) => { + if (data === null) { + updateData({ + nodes: newData.nodes, + links: newData.links, + }); + } else { + updateData({ + nodes: [...data.nodes, ...newData.nodes], + links: [...data.links, ...newData.links], + }); + } + }; + + const graphRef = useRef(); + + const graphControls = useRef(null); + + const handleNodeClick = (node: NodeObject) => { + graphControls.current?.setSelectedNode(node); + graphRef.current?.d3ReheatSimulation(); + }; + + const textSize = 6; + const nodeSize = 15; + const addNodeDistanceFromSourceNode = 15; + + const handleBackgroundClick = (event: MouseEvent) => { + const graphBoundingBox = document.getElementById("graph-container")?.querySelector("canvas")?.getBoundingClientRect(); + const x = event.clientX - graphBoundingBox!.x; + const y = event.clientY - graphBoundingBox!.y; + + const graphClickCoords = graphRef.current!.screen2GraphCoords(x, y); + + const selectedNode = graphControls.current?.getSelectedNode(); + + if (!selectedNode) { + return; + } + + const distanceFromAddNode = Math.sqrt( + Math.pow(graphClickCoords.x - (selectedNode!.x! + addNodeDistanceFromSourceNode), 2) + + Math.pow(graphClickCoords.y - (selectedNode!.y! + addNodeDistanceFromSourceNode), 2) + ); + + if (distanceFromAddNode <= 10) { + enableAddNodeForm(); + } else { + disableAddNodeForm(); + graphControls.current?.setSelectedNode(null); + } + }; + + function renderNode(node: NodeObject, ctx: CanvasRenderingContext2D, globalScale: number) { + const selectedNode = graphControls.current?.getSelectedNode(); + + ctx.save(); + + if (node.id === selectedNode?.id) { + ctx.fillStyle = "gray"; + + ctx.beginPath(); + ctx.arc(node.x! + addNodeDistanceFromSourceNode, node.y! + addNodeDistanceFromSourceNode, 10, 0, 2 * Math.PI); + ctx.fill(); + + ctx.beginPath(); + ctx.moveTo(node.x! + addNodeDistanceFromSourceNode - 5, node.y! + addNodeDistanceFromSourceNode) + ctx.lineTo(node.x! + addNodeDistanceFromSourceNode - 5 + 10, node.y! + addNodeDistanceFromSourceNode); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(node.x! + addNodeDistanceFromSourceNode, node.y! + addNodeDistanceFromSourceNode - 5) + ctx.lineTo(node.x! + addNodeDistanceFromSourceNode, node.y! + addNodeDistanceFromSourceNode - 5 + 10); + ctx.stroke(); + } + + // ctx.beginPath(); + // ctx.arc(node.x, node.y, nodeSize, 0, 2 * Math.PI); + // ctx.fill(); + + // draw text label (with background rect) + const textPos = { + x: node.x!, + y: node.y!, + }; + + ctx.translate(textPos.x, textPos.y); + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillStyle = "#333333"; + ctx.font = `${textSize}px Sans-Serif`; + ctx.fillText(node.label, 0, 0); + + ctx.restore(); + } + + function renderLink(link: LinkObject, ctx: CanvasRenderingContext2D) { + const MAX_FONT_SIZE = 4; + const LABEL_NODE_MARGIN = nodeSize * 1.5; + + const start = link.source; + const end = link.target; + + // ignore unbound links + if (typeof start !== "object" || typeof end !== "object") return; + + const textPos = { + x: start.x! + (end.x! - start.x!) / 2, + y: start.y! + (end.y! - start.y!) / 2, + }; + + const relLink = { x: end.x! - start.x!, y: end.y! - start.y! }; + + const maxTextLength = Math.sqrt(Math.pow(relLink.x, 2) + Math.pow(relLink.y, 2)) - LABEL_NODE_MARGIN * 2; + + let textAngle = Math.atan2(relLink.y, relLink.x); + // maintain label vertical orientation for legibility + if (textAngle > Math.PI / 2) textAngle = -(Math.PI - textAngle); + if (textAngle < -Math.PI / 2) textAngle = -(-Math.PI - textAngle); + + const label = link.label + + // estimate fontSize to fit in link length + ctx.font = "1px Sans-Serif"; + const fontSize = Math.min(MAX_FONT_SIZE, maxTextLength / ctx.measureText(label).width); + ctx.font = `${fontSize}px Sans-Serif`; + const textWidth = ctx.measureText(label).width; + const bckgDimensions = [textWidth, fontSize].map(n => n + fontSize * 0.2); // some padding + + // draw text label (with background rect) + ctx.save(); + ctx.translate(textPos.x, textPos.y); + ctx.rotate(textAngle); + + ctx.fillStyle = "rgba(255, 255, 255, 0.8)"; + ctx.fillRect(- bckgDimensions[0] / 2, - bckgDimensions[1] / 2, bckgDimensions[0], bckgDimensions[1]); + + ctx.textAlign = "center"; + ctx.textBaseline = "middle"; + ctx.fillStyle = "darkgrey"; + ctx.fillText(label, 0, 0); + ctx.restore(); + } + + function handleDagError(loopNodeIds: (string | number)[]) { + console.log(loopNodeIds); + } + + useEffect(() => { + // add collision force + graphRef.current!.d3Force("collision", forceCollide(nodeSize * 1.5)); + graphRef.current!.d3Force("charge", forceManyBody().strength(-1500).distanceMin(300).distanceMax(900)); + }, [data]); + + const [graphShape, setGraphShape] = useState(undefined); + + return ( +
+
+ +
+ +
+
+ {data ? ( + "after"} + nodeAutoColorBy="group" + + linkLabel="label" + linkCanvasObject={renderLink} + linkCanvasObjectMode={() => "after"} + linkDirectionalArrowLength={3.5} + linkDirectionalArrowRelPos={1} + + onNodeClick={handleNodeClick} + onBackgroundClick={handleBackgroundClick} + d3VelocityDecay={0.3} + /> + ) : ( + "after"} + nodeAutoColorBy="group" + + linkLabel="label" + linkCanvasObject={renderLink} + linkCanvasObjectMode={() => "after"} + linkDirectionalArrowLength={3.5} + linkDirectionalArrowRelPos={1} + /> + )} +
+ +
+ + +
+ +
+ graphRef.current?.zoomToFit(1000, 50)} + onGraphShapeChange={setGraphShape} + /> +
+
+ +
+
+
+ Nodes: {data?.nodes.length} + Edges: {data?.links.length} +
+
+
+
+ ); +} diff --git a/cognee-frontend/src/app/(graph)/example_data.json b/cognee-frontend/src/app/(graph)/example_data.json new file mode 100644 index 000000000..74095afd6 --- /dev/null +++ b/cognee-frontend/src/app/(graph)/example_data.json @@ -0,0 +1,1376 @@ +{ + "nodes": [ + { + "id": 1, + "label": "Tom Hanks", + "properties": { + "name": "Tom Hanks", + "born": "1956", + "type": "Actor" + } + }, + { + "id": 2, + "label": "Leonardo DiCaprio", + "properties": { + "name": "Leonardo DiCaprio", + "born": "1974", + "type": "Actor" + } + }, + { + "id": 3, + "label": "Steven Spielberg", + "properties": { + "name": "Steven Spielberg", + "born": "1946", + "type": "Director" + } + }, + { + "id": 4, + "label": "Christopher Nolan", + "properties": { + "name": "Christopher Nolan", + "born": "1970", + "type": "Director" + } + }, + { + "id": 5, + "label": "Saving Private Ryan", + "properties": { + "title": "Saving Private Ryan", + "year": "1998", + "type": "Film" + } + }, + { + "id": 6, + "label": "Forrest Gump", + "properties": { + "title": "Forrest Gump", + "year": "1994", + "type": "Film" + } + }, + { + "id": 7, + "label": "Inception", + "properties": { + "title": "Inception", + "year": "2010", + "type": "Film" + } + }, + { + "id": 8, + "label": "The Revenant", + "properties": { + "title": "The Revenant", + "year": "2015", + "type": "Film" + } + }, + { + "id": 9, + "label": "Meryl Streep", + "properties": { + "name": "Meryl Streep", + "born": "1949", + "type": "Actor" + } + }, + { + "id": 10, + "label": "The Devil Wears Prada", + "properties": { + "title": "The Devil Wears Prada", + "year": "2006", + "type": "Film" + } + }, + { + "id": 11, + "label": "Anne Hathaway", + "properties": { + "name": "Anne Hathaway", + "born": "1982", + "type": "Actor" + } + }, + { + "id": 12, + "label": "The Dark Knight Rises", + "properties": { + "title": "The Dark Knight Rises", + "year": "2012", + "type": "Film" + } + }, + { + "id": 13, + "label": "Interstellar", + "properties": { + "title": "Interstellar", + "year": "2014", + "type": "Film" + } + }, + { + "id": 14, + "label": "Matthew McConaughey", + "properties": { + "name": "Matthew McConaughey", + "born": "1969", + "type": "Actor" + } + }, + { + "id": 15, + "label": "Christian Bale", + "properties": { + "name": "Christian Bale", + "born": "1974", + "type": "Actor" + } + }, + { + "id": 16, + "label": "The Dark Knight", + "properties": { + "title": "The Dark Knight", + "year": "2008", + "type": "Film" + } + }, + { + "id": 17, + "label": "Heath Ledger", + "properties": { + "name": "Heath Ledger", + "born": "1979", + "died": "2008", + "type": "Actor" + } + }, + { + "id": 18, + "label": "Joseph Gordon-Levitt", + "properties": { + "name": "Joseph Gordon-Levitt", + "born": "1981", + "type": "Actor" + } + }, + { + "id": 19, + "label": "Warner Bros", + "properties": { + "name": "Warner Bros", + "founded": "1923", + "type": "Studio" + } + }, + { + "id": 20, + "label": "Paramount", + "properties": { + "name": "Paramount", + "founded": "1912", + "type": "Studio" + } + }, + { + "id": 21, + "label": "Universal", + "properties": { + "name": "Universal", + "founded": "1912", + "type": "Studio" + } + }, + { + "id": 22, + "label": "The Wolf of Wall Street", + "properties": { + "title": "The Wolf of Wall Street", + "year": "2013", + "type": "Film" + } + }, + { + "id": 23, + "label": "Martin Scorsese", + "properties": { + "name": "Martin Scorsese", + "born": "1942", + "type": "Director" + } + }, + { + "id": 24, + "label": "Goodfellas", + "properties": { + "title": "Goodfellas", + "year": "1990", + "type": "Film" + } + }, + { + "id": 25, + "label": "Robert De Niro", + "properties": { + "name": "Robert De Niro", + "born": "1943", + "type": "Actor" + } + }, + { + "id": 26, + "label": "Catch Me If You Can", + "properties": { + "title": "Catch Me If You Can", + "year": "2002", + "type": "Film" + } + }, + { + "id": 27, + "label": "Dunkirk", + "properties": { + "title": "Dunkirk", + "year": "2017", + "type": "Film" + } + }, + { + "id": 28, + "label": "Titanic", + "properties": { + "title": "Titanic", + "year": "1997", + "type": "Film" + } + }, + { + "id": 29, + "label": "James Cameron", + "properties": { + "name": "James Cameron", + "born": "1954", + "type": "Director" + } + }, + { + "id": 30, + "label": "Kate Winslet", + "properties": { + "name": "Kate Winslet", + "born": "1975", + "type": "Actor" + } + }, + { + "id": 31, + "label": "Academy Award", + "properties": { + "name": "Academy Award", + "type": "Award" + } + }, + { + "id": 32, + "label": "Golden Globe", + "properties": { + "name": "Golden Globe", + "type": "Award" + } + }, + { + "id": 33, + "label": "Drama", + "properties": { + "name": "Drama", + "type": "Genre" + } + }, + { + "id": 34, + "label": "Sci-Fi", + "properties": { + "name": "Sci-Fi", + "type": "Genre" + } + }, + { + "id": 35, + "label": "Action", + "properties": { + "name": "Action", + "type": "Genre" + } + }, + { + "id": 36, + "label": "Comedy", + "properties": { + "name": "Comedy", + "type": "Genre" + } + }, + { + "id": 37, + "label": "Crime", + "properties": { + "name": "Crime", + "type": "Genre" + } + }, + { + "id": 38, + "label": "Avatar", + "properties": { + "title": "Avatar", + "year": "2009", + "type": "Film" + } + }, + { + "id": 39, + "label": "Sam Worthington", + "properties": { + "name": "Sam Worthington", + "born": "1976", + "type": "Actor" + } + }, + { + "id": 40, + "label": "The Terminal", + "properties": { + "title": "The Terminal", + "year": "2004", + "type": "Film" + } + }, + { + "id": 41, + "label": "Quentin Tarantino", + "properties": { + "name": "Quentin Tarantino", + "born": "1963", + "type": "Director" + } + }, + { + "id": 42, + "label": "Pulp Fiction", + "properties": { + "title": "Pulp Fiction", + "year": "1994", + "type": "Film" + } + }, + { + "id": 43, + "label": "Samuel L. Jackson", + "properties": { + "name": "Samuel L. Jackson", + "born": "1948", + "type": "Actor" + } + }, + { + "id": 44, + "label": "Uma Thurman", + "properties": { + "name": "Uma Thurman", + "born": "1970", + "type": "Actor" + } + }, + { + "id": 45, + "label": "John Travolta", + "properties": { + "name": "John Travolta", + "born": "1954", + "type": "Actor" + } + }, + { + "id": 46, + "label": "Django Unchained", + "properties": { + "title": "Django Unchained", + "year": "2012", + "type": "Film" + } + }, + { + "id": 47, + "label": "Jamie Foxx", + "properties": { + "name": "Jamie Foxx", + "born": "1967", + "type": "Actor" + } + }, + { + "id": 48, + "label": "Christoph Waltz", + "properties": { + "name": "Christoph Waltz", + "born": "1956", + "type": "Actor" + } + }, + { + "id": 49, + "label": "20th Century Fox", + "properties": { + "name": "20th Century Fox", + "founded": "1935", + "type": "Studio" + } + }, + { + "id": 50, + "label": "Python", + "properties": { + "name": "Python", + "created": "1991", + "creator": "Guido van Rossum", + "type": "Technology" + } + }, + { + "id": 51, + "label": "TensorFlow", + "properties": { + "name": "TensorFlow", + "created": "2015", + "organization": "Google", + "type": "Technology" + } + }, + { + "id": 52, + "label": "Data Science", + "properties": { + "name": "Data Science", + "description": "Interdisciplinary field", + "popularity": "High", + "type": "Technology" + } + } + ], + "edges": [ + { + "source": 1, + "target": 5, + "label": "ACTED_IN", + "properties": { + "role": "Captain Miller" + } + }, + { + "source": 1, + "target": 6, + "label": "ACTED_IN", + "properties": { + "role": "Forrest Gump" + } + }, + { + "source": 1, + "target": 40, + "label": "ACTED_IN", + "properties": { + "role": "Viktor Navorski" + } + }, + { + "source": 1, + "target": 26, + "label": "ACTED_IN", + "properties": { + "role": "Carl Hanratty" + } + }, + { + "source": 2, + "target": 7, + "label": "ACTED_IN", + "properties": { + "role": "Cobb" + } + }, + { + "source": 2, + "target": 8, + "label": "ACTED_IN", + "properties": { + "role": "Hugh Glass" + } + }, + { + "source": 2, + "target": 22, + "label": "ACTED_IN", + "properties": { + "role": "Jordan Belfort" + } + }, + { + "source": 2, + "target": 26, + "label": "ACTED_IN", + "properties": { + "role": "Frank Abagnale Jr." + } + }, + { + "source": 2, + "target": 28, + "label": "ACTED_IN", + "properties": { + "role": "Jack Dawson" + } + }, + { + "source": 3, + "target": 5, + "label": "DIRECTED", + "properties": { + "year": "1998" + } + }, + { + "source": 3, + "target": 26, + "label": "DIRECTED", + "properties": { + "year": "2002" + } + }, + { + "source": 3, + "target": 40, + "label": "DIRECTED", + "properties": { + "year": "2004" + } + }, + { + "source": 4, + "target": 7, + "label": "DIRECTED", + "properties": { + "year": "2010" + } + }, + { + "source": 4, + "target": 12, + "label": "DIRECTED", + "properties": { + "year": "2012" + } + }, + { + "source": 4, + "target": 13, + "label": "DIRECTED", + "properties": { + "year": "2014" + } + }, + { + "source": 4, + "target": 16, + "label": "DIRECTED", + "properties": { + "year": "2008" + } + }, + { + "source": 4, + "target": 27, + "label": "DIRECTED", + "properties": { + "year": "2017" + } + }, + { + "source": 9, + "target": 10, + "label": "ACTED_IN", + "properties": { + "role": "Miranda Priestly" + } + }, + { + "source": 11, + "target": 10, + "label": "ACTED_IN", + "properties": { + "role": "Andy Sachs" + } + }, + { + "source": 11, + "target": 12, + "label": "ACTED_IN", + "properties": { + "role": "Selina Kyle" + } + }, + { + "source": 11, + "target": 13, + "label": "ACTED_IN", + "properties": { + "role": "Amelia Brand" + } + }, + { + "source": 14, + "target": 13, + "label": "ACTED_IN", + "properties": { + "role": "Cooper" + } + }, + { + "source": 15, + "target": 12, + "label": "ACTED_IN", + "properties": { + "role": "Bruce Wayne" + } + }, + { + "source": 15, + "target": 16, + "label": "ACTED_IN", + "properties": { + "role": "Bruce Wayne" + } + }, + { + "source": 17, + "target": 16, + "label": "ACTED_IN", + "properties": { + "role": "Joker" + } + }, + { + "source": 18, + "target": 7, + "label": "ACTED_IN", + "properties": { + "role": "Arthur" + } + }, + { + "source": 18, + "target": 12, + "label": "ACTED_IN", + "properties": { + "role": "John Blake" + } + }, + { + "source": 19, + "target": 7, + "label": "PRODUCED", + "properties": { + "budget": "$160 million" + } + }, + { + "source": 19, + "target": 12, + "label": "PRODUCED", + "properties": { + "budget": "$250 million" + } + }, + { + "source": 19, + "target": 13, + "label": "PRODUCED", + "properties": { + "budget": "$165 million" + } + }, + { + "source": 19, + "target": 16, + "label": "PRODUCED", + "properties": { + "budget": "$185 million" + } + }, + { + "source": 19, + "target": 27, + "label": "PRODUCED", + "properties": { + "budget": "$100 million" + } + }, + { + "source": 20, + "target": 13, + "label": "PRODUCED", + "properties": { + "co-production": "true" + } + }, + { + "source": 20, + "target": 28, + "label": "PRODUCED", + "properties": { + "budget": "$200 million" + } + }, + { + "source": 20, + "target": 6, + "label": "PRODUCED", + "properties": { + "budget": "$55 million" + } + }, + { + "source": 20, + "target": 22, + "label": "PRODUCED", + "properties": { + "budget": "$100 million" + } + }, + { + "source": 21, + "target": 26, + "label": "PRODUCED", + "properties": { + "budget": "$52 million" + } + }, + { + "source": 21, + "target": 40, + "label": "PRODUCED", + "properties": { + "budget": "$75 million" + } + }, + { + "source": 21, + "target": 5, + "label": "PRODUCED", + "properties": { + "budget": "$70 million" + } + }, + { + "source": 23, + "target": 22, + "label": "DIRECTED", + "properties": { + "year": "2013" + } + }, + { + "source": 23, + "target": 24, + "label": "DIRECTED", + "properties": { + "year": "1990" + } + }, + { + "source": 25, + "target": 24, + "label": "ACTED_IN", + "properties": { + "role": "Jimmy Conway" + } + }, + { + "source": 29, + "target": 28, + "label": "DIRECTED", + "properties": { + "year": "1997" + } + }, + { + "source": 29, + "target": 38, + "label": "DIRECTED", + "properties": { + "year": "2009" + } + }, + { + "source": 30, + "target": 28, + "label": "ACTED_IN", + "properties": { + "role": "Rose DeWitt Bukater" + } + }, + { + "source": 39, + "target": 38, + "label": "ACTED_IN", + "properties": { + "role": "Jake Sully" + } + }, + { + "source": 41, + "target": 42, + "label": "DIRECTED", + "properties": { + "year": "1994" + } + }, + { + "source": 41, + "target": 46, + "label": "DIRECTED", + "properties": { + "year": "2012" + } + }, + { + "source": 43, + "target": 42, + "label": "ACTED_IN", + "properties": { + "role": "Jules Winnfield" + } + }, + { + "source": 44, + "target": 42, + "label": "ACTED_IN", + "properties": { + "role": "Mia Wallace" + } + }, + { + "source": 45, + "target": 42, + "label": "ACTED_IN", + "properties": { + "role": "Vincent Vega" + } + }, + { + "source": 47, + "target": 46, + "label": "ACTED_IN", + "properties": { + "role": "Django" + } + }, + { + "source": 48, + "target": 46, + "label": "ACTED_IN", + "properties": { + "role": "Dr. King Schultz" + } + }, + { + "source": 2, + "target": 46, + "label": "ACTED_IN", + "properties": { + "role": "Calvin Candie" + } + }, + { + "source": 43, + "target": 46, + "label": "ACTED_IN", + "properties": { + "role": "Stephen" + } + }, + { + "source": 49, + "target": 28, + "label": "PRODUCED", + "properties": { + "co-production": "true" + } + }, + { + "source": 49, + "target": 38, + "label": "PRODUCED", + "properties": { + "budget": "$237 million" + } + }, + { + "source": 5, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 5, + "target": 35, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 6, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 6, + "target": 36, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 7, + "target": 34, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 7, + "target": 35, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 8, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 10, + "target": 36, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 10, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 12, + "target": 35, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 12, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 13, + "target": 34, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 13, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 16, + "target": 35, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 16, + "target": 37, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 22, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 22, + "target": 36, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 24, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 24, + "target": 37, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 26, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 27, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 27, + "target": 35, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 28, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 38, + "target": 34, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 38, + "target": 35, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 40, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 40, + "target": 36, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 42, + "target": 37, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 42, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 46, + "target": 33, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 46, + "target": 35, + "label": "BELONGS_TO", + "properties": {} + }, + { + "source": 6, + "target": 31, + "label": "WON", + "properties": { + "year": "1995", + "category": "Best Picture" + } + }, + { + "source": 1, + "target": 31, + "label": "WON", + "properties": { + "year": "1995", + "category": "Best Actor" + } + }, + { + "source": 8, + "target": 31, + "label": "NOMINATED_FOR", + "properties": { + "year": "2016", + "category": "Best Picture" + } + }, + { + "source": 2, + "target": 31, + "label": "WON", + "properties": { + "year": "2016", + "category": "Best Actor" + } + }, + { + "source": 17, + "target": 31, + "label": "WON", + "properties": { + "year": "2009", + "category": "Best Supporting Actor" + } + }, + { + "source": 9, + "target": 31, + "label": "WON", + "properties": { + "year": "2012", + "category": "Best Actress" + } + }, + { + "source": 29, + "target": 31, + "label": "WON", + "properties": { + "year": "1998", + "category": "Best Director" + } + }, + { + "source": 28, + "target": 31, + "label": "WON", + "properties": { + "year": "1998", + "category": "Best Picture" + } + }, + { + "source": 42, + "target": 31, + "label": "NOMINATED_FOR", + "properties": { + "year": "1995", + "category": "Best Picture" + } + }, + { + "source": 48, + "target": 31, + "label": "WON", + "properties": { + "year": "2013", + "category": "Best Supporting Actor" + } + }, + { + "source": 1, + "target": 32, + "label": "WON", + "properties": { + "year": "1995", + "category": "Best Actor" + } + }, + { + "source": 2, + "target": 32, + "label": "WON", + "properties": { + "year": "2016", + "category": "Best Actor" + } + }, + { + "source": 9, + "target": 32, + "label": "WON", + "properties": { + "year": "2012", + "category": "Best Actress" + } + }, + { + "source": 28, + "target": 32, + "label": "WON", + "properties": { + "year": "1998", + "category": "Best Picture" + } + }, + { + "source": 2, + "target": 23, + "label": "FREQUENT_COLLABORATOR", + "properties": { + "films": "5" + } + }, + { + "source": 4, + "target": 15, + "label": "FREQUENT_COLLABORATOR", + "properties": { + "films": "3" + } + }, + { + "source": 4, + "target": 18, + "label": "FREQUENT_COLLABORATOR", + "properties": { + "films": "2" + } + }, + { + "source": 3, + "target": 1, + "label": "FREQUENT_COLLABORATOR", + "properties": { + "films": "5" + } + }, + { + "source": 41, + "target": 43, + "label": "FREQUENT_COLLABORATOR", + "properties": { + "films": "6" + } + }, + { + "source": 41, + "target": 44, + "label": "FREQUENT_COLLABORATOR", + "properties": { + "films": "3" + } + }, + { + "source": 1, + "target": 30, + "label": "WORKED_WITH", + "properties": { + "films": "1" + } + }, + { + "source": 2, + "target": 18, + "label": "WORKED_WITH", + "properties": { + "films": "1" + } + }, + { + "source": 18, + "target": 2, + "label": "WORKED_WITH", + "properties": { + "films": "1" + } + }, + { + "source": 2, + "target": 48, + "label": "WORKED_WITH", + "properties": { + "films": "2" + } + }, + { + "source": 30, + "target": 2, + "label": "WORKED_WITH", + "properties": { + "films": "1" + } + }, + { + "source": 2, + "target": 30, + "label": "WORKED_WITH", + "properties": { + "films": "1" + } + }, + { + "source": 50, + "target": 51, + "label": "POWERS", + "properties": { + "since": "2015" + } + }, + { + "source": 51, + "target": 52, + "label": "ENABLES", + "properties": { + "impact": "High" + } + }, + { + "source": 52, + "target": 50, + "label": "USES", + "properties": { + "popularity": "Very High" + } + } + ], + "colors": { + "Actor": "#4285F4", + "Director": "#EA4335", + "Film": "#FBBC05", + "Studio": "#34A853", + "Award": "#CDDC39", + "Genre": "#009688", + "Technology": "#9C27B0" + }, + "configuration": { + "logo": { + "url": "https://repository-images.githubusercontent.com/679343504/477b34f0-e864-4b05-b0d6-58bf8249f38c", + "position": "bottomRight", + "size": 100, + "padding": 20 + } + } +} \ No newline at end of file diff --git a/cognee-frontend/src/app/auth/AuthPage.module.css b/cognee-frontend/src/app/auth/AuthPage.module.css deleted file mode 100644 index fb9ed118a..000000000 --- a/cognee-frontend/src/app/auth/AuthPage.module.css +++ /dev/null @@ -1,16 +0,0 @@ -.main { - display: flex; - flex-direction: row; - flex-direction: column; - padding: 0; - min-height: 100vh; -} - -.authContainer { - flex: 1; - display: flex; - padding: 24px 0; - margin: 0 auto; - max-width: 440px; - width: 100%; -} diff --git a/cognee-frontend/src/app/auth/AuthPage.tsx b/cognee-frontend/src/app/auth/AuthPage.tsx index 9cfb5e89f..9ec563028 100644 --- a/cognee-frontend/src/app/auth/AuthPage.tsx +++ b/cognee-frontend/src/app/auth/AuthPage.tsx @@ -1,29 +1,24 @@ -import { Spacer, Stack, Text } from 'ohmy-ui'; -import { TextLogo } from '@/ui/App'; -import Footer from '@/ui/Partials/Footer/Footer'; - -import styles from './AuthPage.module.css'; -import { Divider } from '@/ui/Layout'; -import SignInForm from '@/ui/Partials/SignInForm/SignInForm'; +import { TextLogo } from "@/ui/App"; +import { Divider } from "@/ui/Layout"; +import Footer from "@/ui/Partials/Footer/Footer"; +import SignInForm from "@/ui/Partials/SignInForm/SignInForm"; export default function AuthPage() { return ( -
- - - - - - -
- -

Sign in

- -
+
+
+
- + +
+
+

Sign in

+ +
+
+
- +
) } diff --git a/cognee-frontend/src/app/globals.css b/cognee-frontend/src/app/globals.css index 118237db8..1007b2fb7 100644 --- a/cognee-frontend/src/app/globals.css +++ b/cognee-frontend/src/app/globals.css @@ -15,23 +15,16 @@ --textarea-default-color: #0D051C !important; } -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - html, body { + height: 100%; max-width: 100vw; overflow-x: hidden; } -body { - background: var(--global-background-default); -} - a { color: inherit; text-decoration: none; } + +@import "tailwindcss"; diff --git a/cognee-frontend/src/app/page copy.tsx b/cognee-frontend/src/app/page copy.tsx new file mode 100644 index 000000000..21847fd75 --- /dev/null +++ b/cognee-frontend/src/app/page copy.tsx @@ -0,0 +1,130 @@ +'use client'; + +import { useCallback, useEffect, useState } from 'react'; +import styles from "./page.module.css"; +import { GhostButton, Notification, NotificationContainer, Spacer, Stack, Text, useBoolean, useNotifications } from 'ohmy-ui'; +import useDatasets from '@/modules/ingestion/useDatasets'; +import DataView, { Data } from '@/modules/ingestion/DataView'; +import DatasetsView from '@/modules/ingestion/DatasetsView'; +import classNames from 'classnames'; +import addData from '@/modules/ingestion/addData'; +import cognifyDataset from '@/modules/datasets/cognifyDataset'; +import getDatasetData from '@/modules/datasets/getDatasetData'; +import { Footer, SettingsModal } from '@/ui/Partials'; +import { TextLogo } from '@/ui/App'; +import { SettingsIcon } from '@/ui/Icons'; + +export default function Home() { + const { + datasets, + refreshDatasets, + } = useDatasets(); + + const [datasetData, setDatasetData] = useState([]); + const [selectedDataset, setSelectedDataset] = useState(null); + + useEffect(() => { + refreshDatasets(); + }, [refreshDatasets]); + + const openDatasetData = (dataset: { id: string }) => { + getDatasetData(dataset) + .then(setDatasetData) + .then(() => setSelectedDataset(dataset.id)); + }; + + const closeDatasetData = () => { + setDatasetData([]); + setSelectedDataset(null); + }; + + const { notifications, showNotification } = useNotifications(); + + const onDataAdd = useCallback((dataset: { id: string }, files: File[]) => { + return addData(dataset, files) + .then(() => { + showNotification("Data added successfully. Please run \"Cognify\" when ready.", 5000); + openDatasetData(dataset); + }); + }, [showNotification]) + + const onDatasetCognify = useCallback((dataset: { id: string, name: string }) => { + showNotification(`Cognification started for dataset "${dataset.name}".`, 5000); + + return cognifyDataset(dataset) + .then(() => { + showNotification(`Dataset "${dataset.name}" cognified.`, 5000); + }) + .catch(() => { + showNotification(`Dataset "${dataset.name}" cognification failed. Please try again.`, 5000); + }); + }, [showNotification]); + + const onCognify = useCallback(() => { + const dataset = datasets.find((dataset) => dataset.id === selectedDataset); + return onDatasetCognify({ + id: dataset!.id, + name: dataset!.name, + }); + }, [datasets, onDatasetCognify, selectedDataset]); + + const { + value: isSettingsModalOpen, + setTrue: openSettingsModal, + setFalse: closeSettingsModal, + } = useBoolean(false); + + return ( +
+ + + + + + + + + + +
+
0, + })}> + +
+ {datasetData.length > 0 && selectedDataset && ( +
+ +
+ )} +
+
+ +
+ + + {notifications.map((notification, index: number) => ( + + {notification.message} + + ))} + +
+ ); +} diff --git a/cognee-frontend/src/app/page.tsx b/cognee-frontend/src/app/page.tsx index 21847fd75..b6bae761a 100644 --- a/cognee-frontend/src/app/page.tsx +++ b/cognee-frontend/src/app/page.tsx @@ -1,130 +1 @@ -'use client'; - -import { useCallback, useEffect, useState } from 'react'; -import styles from "./page.module.css"; -import { GhostButton, Notification, NotificationContainer, Spacer, Stack, Text, useBoolean, useNotifications } from 'ohmy-ui'; -import useDatasets from '@/modules/ingestion/useDatasets'; -import DataView, { Data } from '@/modules/ingestion/DataView'; -import DatasetsView from '@/modules/ingestion/DatasetsView'; -import classNames from 'classnames'; -import addData from '@/modules/ingestion/addData'; -import cognifyDataset from '@/modules/datasets/cognifyDataset'; -import getDatasetData from '@/modules/datasets/getDatasetData'; -import { Footer, SettingsModal } from '@/ui/Partials'; -import { TextLogo } from '@/ui/App'; -import { SettingsIcon } from '@/ui/Icons'; - -export default function Home() { - const { - datasets, - refreshDatasets, - } = useDatasets(); - - const [datasetData, setDatasetData] = useState([]); - const [selectedDataset, setSelectedDataset] = useState(null); - - useEffect(() => { - refreshDatasets(); - }, [refreshDatasets]); - - const openDatasetData = (dataset: { id: string }) => { - getDatasetData(dataset) - .then(setDatasetData) - .then(() => setSelectedDataset(dataset.id)); - }; - - const closeDatasetData = () => { - setDatasetData([]); - setSelectedDataset(null); - }; - - const { notifications, showNotification } = useNotifications(); - - const onDataAdd = useCallback((dataset: { id: string }, files: File[]) => { - return addData(dataset, files) - .then(() => { - showNotification("Data added successfully. Please run \"Cognify\" when ready.", 5000); - openDatasetData(dataset); - }); - }, [showNotification]) - - const onDatasetCognify = useCallback((dataset: { id: string, name: string }) => { - showNotification(`Cognification started for dataset "${dataset.name}".`, 5000); - - return cognifyDataset(dataset) - .then(() => { - showNotification(`Dataset "${dataset.name}" cognified.`, 5000); - }) - .catch(() => { - showNotification(`Dataset "${dataset.name}" cognification failed. Please try again.`, 5000); - }); - }, [showNotification]); - - const onCognify = useCallback(() => { - const dataset = datasets.find((dataset) => dataset.id === selectedDataset); - return onDatasetCognify({ - id: dataset!.id, - name: dataset!.name, - }); - }, [datasets, onDatasetCognify, selectedDataset]); - - const { - value: isSettingsModalOpen, - setTrue: openSettingsModal, - setFalse: closeSettingsModal, - } = useBoolean(false); - - return ( -
- - - - - - - - - - -
-
0, - })}> - -
- {datasetData.length > 0 && selectedDataset && ( -
- -
- )} -
-
- -
- - - {notifications.map((notification, index: number) => ( - - {notification.message} - - ))} - -
- ); -} +export { default } from "./(graph)/GraphView"; diff --git a/cognee-frontend/src/modules/datasets/cognifyDataset.ts b/cognee-frontend/src/modules/datasets/cognifyDataset.ts index a723c712b..09d9b85dc 100644 --- a/cognee-frontend/src/modules/datasets/cognifyDataset.ts +++ b/cognee-frontend/src/modules/datasets/cognifyDataset.ts @@ -1,6 +1,6 @@ import { fetch } from '@/utils'; -export default function cognifyDataset(dataset: { id?: string, name?: string }) { +export default function cognifyDataset(dataset: { id?: string, name?: string }, onUpdate = (data: []) => {}) { return fetch('/v1/cognify', { method: 'POST', headers: { @@ -9,5 +9,35 @@ export default function cognifyDataset(dataset: { id?: string, name?: string }) body: JSON.stringify({ datasets: [dataset.id || dataset.name], }), - }).then((response) => response.json()); + }) + .then((response) => response.json()) + .then((data) => { + const websocket = new WebSocket(`ws://localhost:8000/api/v1/cognify/subscribe/${data.pipeline_run_id}`); + + websocket.onopen = () => { + websocket.send(JSON.stringify({ + "Authorization": `Bearer ${localStorage.getItem("access_token")}`, + })); + }; + + let isCognifyDone = false; + + websocket.onmessage = (event) => { + const data = JSON.parse(event.data); + onUpdate(data); + + if (data.status === "PipelineRunCompleted") { + isCognifyDone = true; + websocket.close(); + } + }; + + return new Promise(async (resolve) => { + while (!isCognifyDone) { + await new Promise(resolve => setTimeout(resolve, 1000)); + } + + resolve(true); + }); + }); } diff --git a/cognee-frontend/src/modules/datasets/getDatasetGraph.ts b/cognee-frontend/src/modules/datasets/getDatasetGraph.ts new file mode 100644 index 000000000..f4a2dac26 --- /dev/null +++ b/cognee-frontend/src/modules/datasets/getDatasetGraph.ts @@ -0,0 +1,6 @@ +import { fetch } from '@/utils'; + +export default function getDatasetGraph(dataset: { id: string }) { + return fetch(`/v1/datasets/${dataset.id}/graph`) + .then((response) => response.json()); +} diff --git a/cognee-frontend/src/modules/ingestion/DatasetsView/DatasetsView.tsx b/cognee-frontend/src/modules/ingestion/DatasetsView/DatasetsView.tsx index 68a0d606c..7cfb43876 100644 --- a/cognee-frontend/src/modules/ingestion/DatasetsView/DatasetsView.tsx +++ b/cognee-frontend/src/modules/ingestion/DatasetsView/DatasetsView.tsx @@ -1,7 +1,7 @@ import { useState } from 'react'; import Link from 'next/link'; import { Explorer } from '@/ui/Partials'; -import StatusIcon from './StatusIcon'; +import StatusIcon from '@/ui/elements/StatusIndicator'; import { LoadingIndicator } from '@/ui/App'; import { DropdownMenu, GhostButton, Stack, Text, CTAButton, useBoolean, Modal, Spacer } from "ohmy-ui"; import styles from "./DatasetsView.module.css"; diff --git a/cognee-frontend/src/modules/ingestion/DatasetsView/StatusIcon.tsx b/cognee-frontend/src/modules/ingestion/DatasetsView/StatusIcon.tsx deleted file mode 100644 index c69bb7259..000000000 --- a/cognee-frontend/src/modules/ingestion/DatasetsView/StatusIcon.tsx +++ /dev/null @@ -1,15 +0,0 @@ -export default function StatusIcon({ status }: { status: 'DATASET_PROCESSING_COMPLETED' | string }) { - const isSuccess = status === 'DATASET_PROCESSING_COMPLETED'; - - return ( -
- ); -} \ No newline at end of file diff --git a/cognee-frontend/src/modules/ingestion/useDatasets.ts b/cognee-frontend/src/modules/ingestion/useDatasets.ts index 90652273b..441e3a0e3 100644 --- a/cognee-frontend/src/modules/ingestion/useDatasets.ts +++ b/cognee-frontend/src/modules/ingestion/useDatasets.ts @@ -73,7 +73,7 @@ function useDatasets() { }, []); const fetchDatasets = useCallback(() => { - fetch('/v1/datasets', { + return fetch('/v1/datasets', { headers: { Authorization: `Bearer ${localStorage.getItem('access_token')}`, }, @@ -84,9 +84,9 @@ function useDatasets() { if (datasets.length > 0) { checkDatasetStatuses(datasets); - } else { - window.location.href = '/wizard'; } + + return datasets; }) .catch((error) => { console.error('Error fetching datasets:', error); diff --git a/cognee-frontend/src/ui/App/Loading/DefaultLoadingIndicator/LoadingIndicator.module.css b/cognee-frontend/src/ui/App/Loading/DefaultLoadingIndicator/LoadingIndicator.module.css index adaf0e1bc..472081d57 100644 --- a/cognee-frontend/src/ui/App/Loading/DefaultLoadingIndicator/LoadingIndicator.module.css +++ b/cognee-frontend/src/ui/App/Loading/DefaultLoadingIndicator/LoadingIndicator.module.css @@ -1,9 +1,9 @@ .loadingIndicator { - width: 16px; - height: 16px; + width: 1rem; + height: 1rem; border-radius: 50%; - border: 2px solid var(--global-color-primary); + border: 0.18rem solid white; border-top-color: transparent; border-bottom-color: transparent; animation: spin 2s linear infinite; diff --git a/cognee-frontend/src/ui/Icons/DeleteIcon.tsx b/cognee-frontend/src/ui/Icons/DeleteIcon.tsx new file mode 100644 index 000000000..298e3c07b --- /dev/null +++ b/cognee-frontend/src/ui/Icons/DeleteIcon.tsx @@ -0,0 +1,7 @@ +export default function DeleteIcon({ width = 12, height = 14, color = 'currentColor' }) { + return ( + + + + ); +} diff --git a/cognee-frontend/src/ui/Icons/GitHubIcon.tsx b/cognee-frontend/src/ui/Icons/GitHubIcon.tsx index 9526adfd7..590b2c217 100644 --- a/cognee-frontend/src/ui/Icons/GitHubIcon.tsx +++ b/cognee-frontend/src/ui/Icons/GitHubIcon.tsx @@ -3,7 +3,7 @@ export default function GitHubIcon({ width = 24, height = 24, color = 'currentCo - + ); diff --git a/cognee-frontend/src/ui/Icons/index.ts b/cognee-frontend/src/ui/Icons/index.ts index b9f517211..71d6307c2 100644 --- a/cognee-frontend/src/ui/Icons/index.ts +++ b/cognee-frontend/src/ui/Icons/index.ts @@ -1,3 +1,4 @@ +export { default as DeleteIcon } from './DeleteIcon'; export { default as GithubIcon } from './GitHubIcon'; export { default as DiscordIcon } from './DiscordIcon'; export { default as SettingsIcon } from './SettingsIcon'; diff --git a/cognee-frontend/src/ui/Partials/FeedbackForm.tsx b/cognee-frontend/src/ui/Partials/FeedbackForm.tsx new file mode 100644 index 000000000..76ecebf43 --- /dev/null +++ b/cognee-frontend/src/ui/Partials/FeedbackForm.tsx @@ -0,0 +1,66 @@ +"use client"; + +import { useState } from "react"; +import { LoadingIndicator } from "@/ui/App"; +import { fetch, useBoolean } from "@/utils"; +import { CTAButton, TextArea } from "@/ui/elements"; + +interface SignInFormPayload extends HTMLFormElement { + feedback: HTMLTextAreaElement; +} + +interface FeedbackFormProps { + onSuccess: () => void; +} + +export default function FeedbackForm({ onSuccess }: FeedbackFormProps) { + const { + value: isSubmittingFeedback, + setTrue: disableFeedbackSubmit, + setFalse: enableFeedbackSubmit, + } = useBoolean(false); + + const [feedbackError, setFeedbackError] = useState(null); + + const signIn = (event: React.FormEvent) => { + event.preventDefault(); + const formElements = event.currentTarget; + + const authCredentials = new FormData(); + authCredentials.append("feedback", formElements.feedback.value); + + setFeedbackError(null); + disableFeedbackSubmit(); + + fetch("/v1/feedback/reasoning", { + method: "POST", + body: authCredentials, + }) + .then(response => response.json()) + .then(() => { + onSuccess(); + }) + .catch(error => setFeedbackError(error.detail)) + .finally(() => enableFeedbackSubmit()); + }; + + return ( +
+
+
+ +