You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ma...@apache.org on 2023/10/17 22:21:20 UTC

[camel-karavan] branch main updated (9347c357 -> d897c6ca)

This is an automated email from the ASF dual-hosted git repository.

marat pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git


    from 9347c357 Fix selected style for selected element in Designer
     new 9c953210 Topology in Designer for #939
     new d897c6ca Fix #939

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 karavan-core/package-lock.json                     |   28 +-
 karavan-core/package.json                          |    6 +-
 karavan-designer/package-lock.json                 |  152 +-
 karavan-designer/package.json                      |   20 +-
 .../src}/topology/CustomEdge.tsx                   |    4 +-
 .../src}/topology/CustomGroup.tsx                  |    1 -
 .../src}/topology/CustomNode.tsx                   |    4 +-
 .../src}/topology/TopologyApi.tsx                  |    6 +-
 .../src}/topology/TopologyPropertiesPanel.tsx      |   19 +-
 .../src}/topology/TopologyStore.ts                 |   14 +-
 .../src}/topology/TopologyTab.tsx                  |   26 +-
 .../src}/topology/TopologyToolbar.tsx              |   12 +-
 .../src}/topology/topology.css                     |    0
 karavan-space/package-lock.json                    | 1612 +++++++++++++++-----
 karavan-space/package.json                         |   22 +-
 karavan-space/src/designer/route/DslElement.tsx    |    4 +-
 .../src}/topology/CustomEdge.tsx                   |    4 +-
 .../src}/topology/CustomGroup.tsx                  |    1 -
 .../src}/topology/CustomNode.tsx                   |    4 +-
 .../src}/topology/TopologyApi.tsx                  |    6 +-
 .../src}/topology/TopologyPropertiesPanel.tsx      |   19 +-
 .../src}/topology/TopologyStore.ts                 |   14 +-
 .../src}/topology/TopologyTab.tsx                  |   26 +-
 .../src}/topology/TopologyToolbar.tsx              |   12 +-
 .../src}/topology/topology.css                     |    0
 karavan-vscode/package-lock.json                   |  996 +++++++++++-
 karavan-vscode/package.json                        |   36 +-
 karavan-vscode/src/designerView.ts                 |    2 -
 karavan-vscode/src/extension.ts                    |   13 +-
 karavan-vscode/src/helpView.ts                     |    2 +-
 .../src/{helpView.ts => topologyView.ts}           |  100 +-
 karavan-vscode/src/utils.ts                        |   15 +
 karavan-vscode/webview/App.tsx                     |   86 +-
 karavan-vscode/webview/index.css                   |    5 +
 .../webview}/topology/CustomEdge.tsx               |    4 +-
 .../webview}/topology/CustomGroup.tsx              |    1 -
 .../webview}/topology/CustomNode.tsx               |    4 +-
 .../webview}/topology/TopologyApi.tsx              |   14 +-
 .../webview}/topology/TopologyPropertiesPanel.tsx  |   19 +-
 .../webview}/topology/TopologyStore.ts             |   14 +-
 .../webview}/topology/TopologyTab.tsx              |   26 +-
 .../webview}/topology/TopologyToolbar.tsx          |   12 +-
 .../webview}/topology/topology.css                 |    0
 .../karavan-app/src/main/webui/package-lock.json   |  152 +-
 .../karavan-app/src/main/webui/package.json        |   29 +-
 .../main/webui/src/designer/route/DslElement.tsx   |    4 +-
 .../src/main/webui/src/project/ProjectPanel.tsx    |    9 +-
 ...{TopologyToolbar.tsx => ProjectTopologyTab.tsx} |   47 +-
 .../src/{project => }/topology/CustomEdge.tsx      |    4 +-
 .../src/{project => }/topology/CustomGroup.tsx     |    1 -
 .../src/{project => }/topology/CustomNode.tsx      |    4 +-
 .../src/{project => }/topology/TopologyApi.tsx     |    6 +-
 .../topology/TopologyPropertiesPanel.tsx           |   19 +-
 .../src/{project => }/topology/TopologyStore.ts    |   14 +-
 .../src/{project => }/topology/TopologyTab.tsx     |   26 +-
 .../src/{project => }/topology/TopologyToolbar.tsx |   12 +-
 .../webui/src/{project => }/topology/topology.css  |    0
 57 files changed, 2709 insertions(+), 983 deletions(-)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/CustomEdge.tsx (87%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/CustomGroup.tsx (94%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/CustomNode.tsx (92%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/TopologyApi.tsx (97%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/TopologyPropertiesPanel.tsx (81%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/TopologyStore.ts (86%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/TopologyTab.tsx (87%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/TopologyToolbar.tsx (78%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-designer/src}/topology/topology.css (100%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/CustomEdge.tsx (87%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/CustomGroup.tsx (94%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/CustomNode.tsx (92%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/TopologyApi.tsx (97%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/TopologyPropertiesPanel.tsx (81%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/TopologyStore.ts (86%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/TopologyTab.tsx (87%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/TopologyToolbar.tsx (78%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-space/src}/topology/topology.css (100%)
 copy karavan-vscode/src/{helpView.ts => topologyView.ts} (50%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/CustomEdge.tsx (87%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/CustomGroup.tsx (94%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/CustomNode.tsx (92%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/TopologyApi.tsx (95%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/TopologyPropertiesPanel.tsx (81%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/TopologyStore.ts (86%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/TopologyTab.tsx (87%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/TopologyToolbar.tsx (78%)
 copy {karavan-web/karavan-app/src/main/webui/src/project => karavan-vscode/webview}/topology/topology.css (100%)
 copy karavan-web/karavan-app/src/main/webui/src/project/topology/{TopologyToolbar.tsx => ProjectTopologyTab.tsx} (52%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/CustomEdge.tsx (87%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/CustomGroup.tsx (94%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/CustomNode.tsx (92%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/TopologyApi.tsx (97%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/TopologyPropertiesPanel.tsx (81%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/TopologyStore.ts (86%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/TopologyTab.tsx (87%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/TopologyToolbar.tsx (78%)
 rename karavan-web/karavan-app/src/main/webui/src/{project => }/topology/topology.css (100%)


[camel-karavan] 02/02: Fix #939

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit d897c6cafa70cd74755dbc857eb2e625e144c558
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Oct 17 18:21:11 2023 -0400

    Fix #939
---
 karavan-core/package-lock.json                     |  28 +-
 karavan-core/package.json                          |   6 +-
 karavan-designer/src/topology/TopologyStore.ts     |   4 +-
 karavan-designer/src/topology/TopologyTab.tsx      |   3 +-
 karavan-space/src/topology/TopologyStore.ts        |   4 +-
 karavan-space/src/topology/TopologyTab.tsx         |   3 +-
 karavan-vscode/package-lock.json                   | 996 +++++++++++++++++++--
 karavan-vscode/package.json                        |  36 +-
 karavan-vscode/src/designerView.ts                 |   2 -
 karavan-vscode/src/extension.ts                    |  13 +-
 karavan-vscode/src/helpView.ts                     |   2 +-
 .../src/{helpView.ts => topologyView.ts}           | 100 +--
 karavan-vscode/src/utils.ts                        |  15 +
 karavan-vscode/webview/App.tsx                     |  86 +-
 karavan-vscode/webview/index.css                   |   5 +
 karavan-vscode/webview/topology/CustomEdge.tsx     |  30 +
 karavan-vscode/webview/topology/CustomGroup.tsx    |  31 +
 karavan-vscode/webview/topology/CustomNode.tsx     |  56 ++
 karavan-vscode/webview/topology/TopologyApi.tsx    | 265 ++++++
 .../webview/topology/TopologyPropertiesPanel.tsx   |  68 ++
 .../webview}/topology/TopologyStore.ts             |   4 +-
 .../webview}/topology/TopologyTab.tsx              |   3 +-
 .../webview/topology/TopologyToolbar.tsx           |  44 +
 karavan-vscode/webview/topology/topology.css       |  62 ++
 .../src/project/topology/ProjectTopologyTab.tsx    |   3 +-
 .../src/main/webui/src/topology/TopologyStore.ts   |   4 +-
 .../src/main/webui/src/topology/TopologyTab.tsx    |   3 +-
 27 files changed, 1666 insertions(+), 210 deletions(-)

diff --git a/karavan-core/package-lock.json b/karavan-core/package-lock.json
index 7023f324..798e7224 100644
--- a/karavan-core/package-lock.json
+++ b/karavan-core/package-lock.json
@@ -9,11 +9,11 @@
       "version": "4.0.1",
       "license": "Apache-2.0",
       "dependencies": {
-        "@types/js-yaml": "^4.0.5",
-        "@types/uuid": "^8.3.4",
+        "@types/js-yaml": "^4.0.7",
+        "@types/uuid": "^9.0.5",
         "tsconfig-paths": "^4.2.0",
         "typescript": "^5.1",
-        "uuid": "8.3.2"
+        "uuid": "9.0.1"
       },
       "devDependencies": {
         "@types/chai": "^4.3.0",
@@ -137,9 +137,9 @@
       "dev": true
     },
     "node_modules/@types/js-yaml": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.6.tgz",
-      "integrity": "sha512-ACTuifTSIIbyksx2HTon3aFtCKWcID7/h3XEmRpDYdMCXxPbl+m9GteOJeaAkiAta/NJaSFuA7ahZ0NkwajDSw=="
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.7.tgz",
+      "integrity": "sha512-RJZP9WAMMr1514KbdSXkLRrKvYQacjr1+HWnY8pui/uBTBoSgD9ZGR17u/d4nb9NpERp0FkdLBe7hq8NIPBgkg=="
     },
     "node_modules/@types/mocha": {
       "version": "9.1.1",
@@ -154,9 +154,9 @@
       "dev": true
     },
     "node_modules/@types/uuid": {
-      "version": "8.3.4",
-      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
-      "integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw=="
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.5.tgz",
+      "integrity": "sha512-xfHdwa1FMJ082prjSJpoEI57GZITiQz10r3vEJCHa2khEFQjKy91aWKz6+zybzssCvXUwE1LQWgWVwZ4nYUvHQ=="
     },
     "node_modules/acorn": {
       "version": "8.10.0",
@@ -1493,9 +1493,13 @@
       }
     },
     "node_modules/uuid": {
-      "version": "8.3.2",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
-      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
       "bin": {
         "uuid": "dist/bin/uuid"
       }
diff --git a/karavan-core/package.json b/karavan-core/package.json
index e5d85fef..5658ba10 100644
--- a/karavan-core/package.json
+++ b/karavan-core/package.json
@@ -36,11 +36,11 @@
   },
   "homepage": "https://github.com/apache/camel-karavan#readme",
   "dependencies": {
-    "@types/js-yaml": "^4.0.5",
-    "@types/uuid": "^8.3.4",
+    "@types/js-yaml": "^4.0.7",
+    "@types/uuid": "^9.0.5",
     "tsconfig-paths": "^4.2.0",
     "typescript": "^5.1",
-    "uuid": "8.3.2"
+    "uuid": "9.0.1"
   },
   "devDependencies": {
     "@types/chai": "^4.3.0",
diff --git a/karavan-designer/src/topology/TopologyStore.ts b/karavan-designer/src/topology/TopologyStore.ts
index 5bbdf124..3cf5067b 100644
--- a/karavan-designer/src/topology/TopologyStore.ts
+++ b/karavan-designer/src/topology/TopologyStore.ts
@@ -39,9 +39,7 @@ export const useTopologyStore = createWithEqualityFn<TopologyState>((set) => ({
     selectedIds: [],
     setSelectedIds: (selectedIds: string[]) => {
         set((state: TopologyState) => {
-            state.selectedIds.length = 0;
-            state.selectedIds.push(...selectedIds);
-            return {selectedIds: state.selectedIds};
+            return {selectedIds: selectedIds};
         });
     },
     setFileName: (fileName?: string) => {
diff --git a/karavan-designer/src/topology/TopologyTab.tsx b/karavan-designer/src/topology/TopologyTab.tsx
index df48e0c0..520bf8d2 100644
--- a/karavan-designer/src/topology/TopologyTab.tsx
+++ b/karavan-designer/src/topology/TopologyTab.tsx
@@ -41,6 +41,7 @@ interface Props {
     files: IntegrationFile[],
     onClickCreateButton: () => void
     onSetFile: (fileName: string) => void
+    hideToolbar: boolean
 }
 
 export function TopologyTab (props: Props) {
@@ -93,7 +94,7 @@ export function TopologyTab (props: Props) {
     return (
         <TopologyView
             className="topology-panel"
-            contextToolbar={<TopologyToolbar onClickCreateButton={props.onClickCreateButton}/>}
+            contextToolbar={!props.hideToolbar? <TopologyToolbar onClickCreateButton={props.onClickCreateButton}/> : undefined}
             sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
                 <TopologyControlBar
diff --git a/karavan-space/src/topology/TopologyStore.ts b/karavan-space/src/topology/TopologyStore.ts
index 5bbdf124..3cf5067b 100644
--- a/karavan-space/src/topology/TopologyStore.ts
+++ b/karavan-space/src/topology/TopologyStore.ts
@@ -39,9 +39,7 @@ export const useTopologyStore = createWithEqualityFn<TopologyState>((set) => ({
     selectedIds: [],
     setSelectedIds: (selectedIds: string[]) => {
         set((state: TopologyState) => {
-            state.selectedIds.length = 0;
-            state.selectedIds.push(...selectedIds);
-            return {selectedIds: state.selectedIds};
+            return {selectedIds: selectedIds};
         });
     },
     setFileName: (fileName?: string) => {
diff --git a/karavan-space/src/topology/TopologyTab.tsx b/karavan-space/src/topology/TopologyTab.tsx
index df48e0c0..520bf8d2 100644
--- a/karavan-space/src/topology/TopologyTab.tsx
+++ b/karavan-space/src/topology/TopologyTab.tsx
@@ -41,6 +41,7 @@ interface Props {
     files: IntegrationFile[],
     onClickCreateButton: () => void
     onSetFile: (fileName: string) => void
+    hideToolbar: boolean
 }
 
 export function TopologyTab (props: Props) {
@@ -93,7 +94,7 @@ export function TopologyTab (props: Props) {
     return (
         <TopologyView
             className="topology-panel"
-            contextToolbar={<TopologyToolbar onClickCreateButton={props.onClickCreateButton}/>}
+            contextToolbar={!props.hideToolbar? <TopologyToolbar onClickCreateButton={props.onClickCreateButton}/> : undefined}
             sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
                 <TopologyControlBar
diff --git a/karavan-vscode/package-lock.json b/karavan-vscode/package-lock.json
index fce14e68..05431c48 100644
--- a/karavan-vscode/package-lock.json
+++ b/karavan-vscode/package-lock.json
@@ -9,21 +9,22 @@
       "version": "4.0.1",
       "license": "Apache-2.0",
       "dependencies": {
-        "@monaco-editor/react": "4.5.1",
-        "@patternfly/patternfly": "^5.0.2",
-        "@patternfly/react-core": "^5.0.0",
-        "@patternfly/react-table": "^5.0.0",
-        "@types/js-yaml": "4.0.5",
-        "@types/uuid": "9.0.1",
+        "@monaco-editor/react": "^4.6.0",
+        "@patternfly/patternfly": "^5.1.0",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-table": "^5.1.1",
+        "@patternfly/react-topology": "^5.1.0",
+        "@types/js-yaml": "4.0.7",
+        "@types/uuid": "9.0.5",
         "html-to-image": "1.11.11",
         "js-yaml": "^4.1.0",
         "path-browserify": "^1.0.1",
         "react": "18.2.0",
         "react-dom": "18.2.0",
-        "rxjs": "7.8.0",
+        "rxjs": "7.8.1",
         "shelljs": "^0.8.5",
-        "uuid": "9.0.0",
-        "zustand": "^4.4.1"
+        "uuid": "9.0.1",
+        "zustand": "4.4.3"
       },
       "devDependencies": {
         "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
@@ -1853,7 +1854,6 @@
       "version": "7.23.1",
       "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz",
       "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==",
-      "dev": true,
       "dependencies": {
         "regenerator-runtime": "^0.14.0"
       },
@@ -1876,9 +1876,9 @@
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz",
-      "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==",
+      "version": "7.23.2",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+      "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.22.13",
@@ -2064,9 +2064,9 @@
       }
     },
     "node_modules/@monaco-editor/loader": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz",
-      "integrity": "sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz",
+      "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
       "dependencies": {
         "state-local": "^1.0.6"
       },
@@ -2075,11 +2075,11 @@
       }
     },
     "node_modules/@monaco-editor/react": {
-      "version": "4.5.1",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.5.1.tgz",
-      "integrity": "sha512-NNDFdP+2HojtNhCkRfE6/D6ro6pBNihaOzMbGK84lNWzRu+CfBjwzGt4jmnqimLuqp5yE5viHS2vi+QOAnD5FQ==",
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz",
+      "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==",
       "dependencies": {
-        "@monaco-editor/loader": "^1.3.3"
+        "@monaco-editor/loader": "^1.4.0"
       },
       "peerDependencies": {
         "monaco-editor": ">= 0.25.0 < 1",
@@ -2123,19 +2123,19 @@
       }
     },
     "node_modules/@patternfly/patternfly": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz",
-      "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA=="
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.1.0.tgz",
+      "integrity": "sha512-wzVgL/0xPsmuRKWc6lMNEo5gDcTUtyU231eJSBTapOKXiwBOv2flvLEHPYLO6oDYXO+hwUrVgbcZFWMd1UlLwA=="
     },
     "node_modules/@patternfly/react-core": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.1.tgz",
-      "integrity": "sha512-Eevd+8ACLFV733J+cpo4FRgNtRBObIgmUcrqLjf9H99jZ1hFpBgacFyHiALFi2cuoNVGmdEzskFl+4c7Uo0n+w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.1.1.tgz",
+      "integrity": "sha512-9DbgQMXYmF8A4aCNLKXwIN1H07SIPoPaVLvx+yiDuJfDx4Qi0T+H7j5cx0VfDfxuCpqea3POJWqBQn1HnwS4wQ==",
       "dependencies": {
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
-        "focus-trap": "7.4.3",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
+        "focus-trap": "7.5.2",
         "react-dropzone": "^14.2.3",
         "tslib": "^2.5.0"
       },
@@ -2145,28 +2145,28 @@
       }
     },
     "node_modules/@patternfly/react-icons": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.1.tgz",
-      "integrity": "sha512-MduetDRzve3eRlKAioM/UxmVuPyFccdeBWAKhbN4SBn7RaZWS7kO7/xZzNkpeT5pqQIeAACvz3uiV2/3uAf38w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.1.1.tgz",
+      "integrity": "sha512-9gCxkWz2xcdi0rtXu2F0L68w4tLIlsgGTACo1ggr4aVng9jRX++o1PlCOqscOd9o0NiFnFD7BLlZUGvJWaYEZg==",
       "peerDependencies": {
         "react": "^17 || ^18",
         "react-dom": "^17 || ^18"
       }
     },
     "node_modules/@patternfly/react-styles": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz",
-      "integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.1.1.tgz",
+      "integrity": "sha512-swO9X+WixYYDsMVsEJp1V8QUfhEQY91QfFm4phfYP4jc2TQ2opIFYdUIHkc+yrZwBhrgb/pPUUfemyqAoSbZcA=="
     },
     "node_modules/@patternfly/react-table": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.0.1.tgz",
-      "integrity": "sha512-2YbM6XvgG9ubJE4caPQKPMFBkcf7zYzLUFbHnkyfInpWeVNBs/+ZDAP2wnIHce7uaPLnJ1t0FVzGwaD/UuPwkg==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.1.1.tgz",
+      "integrity": "sha512-9tAtHj16hemJ6YRBWIm2O+QRNoFWYQt8ZLQ1G0KBwpg2t2G2CbGsS2RG+BamO4IVE6IPo3Yoo39p4UCNRiGVpA==",
       "dependencies": {
-        "@patternfly/react-core": "^5.0.1",
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
         "lodash": "^4.17.19",
         "tslib": "^2.5.0"
       },
@@ -2176,9 +2176,37 @@
       }
     },
     "node_modules/@patternfly/react-tokens": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz",
-      "integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.1.1.tgz",
+      "integrity": "sha512-cHuNkzNA9IY9aDwfjSEkitQoVEvRhOJRKhH0yIRlRByEkbdoV9jJZ9xj20hNShE+bxmNuom+MCTQSkpkN1bV8A=="
+    },
+    "node_modules/@patternfly/react-topology": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.1.0.tgz",
+      "integrity": "sha512-Qzu7GMxqCsRvQj4RF2AHOGSp0nPpVuDE2xpdAaj/yCKz0cqHhvrwpC4+qyVL3mlqIs5qb+Fxm2d81Do7YIx3ig==",
+      "dependencies": {
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@types/d3": "^7.4.0",
+        "@types/d3-force": "^1.2.1",
+        "@types/dagre": "0.7.42",
+        "@types/react-measure": "^2.0.6",
+        "d3": "^7.8.0",
+        "dagre": "0.8.2",
+        "lodash": "^4.17.19",
+        "mobx": "^6.9.0",
+        "mobx-react": "^7.6.0",
+        "point-in-svg-path": "^1.0.1",
+        "popper.js": "^1.16.1",
+        "react-measure": "^2.3.0",
+        "tslib": "^2.0.0",
+        "webcola": "3.4.0"
+      },
+      "peerDependencies": {
+        "react": "^17 || ^18",
+        "react-dom": "^17 || ^18"
+      }
     },
     "node_modules/@svgr/babel-plugin-add-jsx-attribute": {
       "version": "7.0.0",
@@ -2457,6 +2485,233 @@
       "integrity": "sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw==",
       "dev": true
     },
+    "node_modules/@types/d3": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.1.tgz",
+      "integrity": "sha512-lBpYmbHTCtFKO1DB1R7E9dXp9/g1F3JXSGOF7iKPZ+wRmYg/Q6tCRHODGOc5Qk25fJRe2PI60EDRf2HLPUncMA==",
+      "dependencies": {
+        "@types/d3-array": "*",
+        "@types/d3-axis": "*",
+        "@types/d3-brush": "*",
+        "@types/d3-chord": "*",
+        "@types/d3-color": "*",
+        "@types/d3-contour": "*",
+        "@types/d3-delaunay": "*",
+        "@types/d3-dispatch": "*",
+        "@types/d3-drag": "*",
+        "@types/d3-dsv": "*",
+        "@types/d3-ease": "*",
+        "@types/d3-fetch": "*",
+        "@types/d3-force": "*",
+        "@types/d3-format": "*",
+        "@types/d3-geo": "*",
+        "@types/d3-hierarchy": "*",
+        "@types/d3-interpolate": "*",
+        "@types/d3-path": "*",
+        "@types/d3-polygon": "*",
+        "@types/d3-quadtree": "*",
+        "@types/d3-random": "*",
+        "@types/d3-scale": "*",
+        "@types/d3-scale-chromatic": "*",
+        "@types/d3-selection": "*",
+        "@types/d3-shape": "*",
+        "@types/d3-time": "*",
+        "@types/d3-time-format": "*",
+        "@types/d3-timer": "*",
+        "@types/d3-transition": "*",
+        "@types/d3-zoom": "*"
+      }
+    },
+    "node_modules/@types/d3-array": {
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.8.tgz",
+      "integrity": "sha512-2xAVyAUgaXHX9fubjcCbGAUOqYfRJN1em1EKR2HfzWBpObZhwfnZKvofTN4TplMqJdFQao61I+NVSai/vnBvDQ=="
+    },
+    "node_modules/@types/d3-axis": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.4.tgz",
+      "integrity": "sha512-ySnjI/7qm+J602VjcejXcqs1hEuu5UBbGaJGp+Cn/yKVc1iS3JueLVpToGdQsS2sqta7tqA/kG4ore/+LH90UA==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-brush": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.4.tgz",
+      "integrity": "sha512-Kg5uIsdJNMCs5lTqeZFsTKqj9lBvpiFRDkYN3j2CDlPhonNDg9/gXVpv1E/MKh3tEqArryIj9o6RBGE/MQe+6Q==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-chord": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.4.tgz",
+      "integrity": "sha512-p4PvN1N+7GL3Y/NI9Ug1TKwowUV6h664kmxL79ctp1HRYCk1mhP0+SXhjRsoWXCdnJfbLLLmpV99rt8dMrHrzg=="
+    },
+    "node_modules/@types/d3-color": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.1.tgz",
+      "integrity": "sha512-CSAVrHAtM9wfuLJ2tpvvwCU/F22sm7rMHNN+yh9D6O6hyAms3+O0cgMpC1pm6UEUMOntuZC8bMt74PteiDUdCg=="
+    },
+    "node_modules/@types/d3-contour": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.4.tgz",
+      "integrity": "sha512-B0aeX8Xg3MNUglULxqDvlgY1SVXuN2xtEleYSAY0iMhl/SMVT7snzgAveejjwM3KaWuNXIoXEJ7dmXE8oPq/jA==",
+      "dependencies": {
+        "@types/d3-array": "*",
+        "@types/geojson": "*"
+      }
+    },
+    "node_modules/@types/d3-delaunay": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.2.tgz",
+      "integrity": "sha512-WplUJ/OHU7eITneDqNnzK+2pgR+WDzUHG6XAUVo+oWHPQq74VcgUdw8a4ODweaZzF56OVYK+x9GxCyuq6hSu1A=="
+    },
+    "node_modules/@types/d3-dispatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.4.tgz",
+      "integrity": "sha512-NApHpGHRNxUy7e2Lfzl/cwOucmn4Xdx6FdmXzAoomo8T81LyGmlBjjko/vP0TVzawlvEFLDq8OCRLulW6DDzKw=="
+    },
+    "node_modules/@types/d3-drag": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.4.tgz",
+      "integrity": "sha512-/t53K1erTuUbP7WIX9SE0hlmytpTYRbIthlhbGkBHzCV5vPO++7yrk8OlisWPyIJO5TGowTmqCtGH2tokY5T/g==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-dsv": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.4.tgz",
+      "integrity": "sha512-YxfUVJ55HxR8oq88136w09mBMPNhgH7PZjteq72onWXWOohGif/cLQnQv8V4A5lEGjXF04LhwSTpmzpY9wyVyA=="
+    },
+    "node_modules/@types/d3-ease": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz",
+      "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA=="
+    },
+    "node_modules/@types/d3-fetch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.4.tgz",
+      "integrity": "sha512-RleYajubALkGjrvatxWhlygfvB1KNF0Uzz9guRUeeA+M/2B7l8rxObYdktaX9zU1st04lMCHjZWe4vbl+msH2Q==",
+      "dependencies": {
+        "@types/d3-dsv": "*"
+      }
+    },
+    "node_modules/@types/d3-force": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-1.2.5.tgz",
+      "integrity": "sha512-1TB2IqtkPXsr7zUgPORayl2xsl28X4WMwlpaw2BLKTQpJ5ePO1t6TkM4spbTwoqc6dWipVTwg0gdOVrbzGQPNQ=="
+    },
+    "node_modules/@types/d3-format": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.2.tgz",
+      "integrity": "sha512-9oQWvKk2qVBo49FQq8yD/et8Lx0W5Ac2FdGSOUecqOFKqh0wkpyHqf9Qc7A06ftTR+Lz13Pi3jHIQis0aCueOA=="
+    },
+    "node_modules/@types/d3-geo": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.5.tgz",
+      "integrity": "sha512-ysEEU93Wv9p2UZBxTK3kUP7veHgyhTA0qYtI7bxK5EMXb3JxGv0D4IH54PxprAF26n+uHci24McVmzwIdLgvgQ==",
+      "dependencies": {
+        "@types/geojson": "*"
+      }
+    },
+    "node_modules/@types/d3-hierarchy": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.4.tgz",
+      "integrity": "sha512-wrvjpRFdmEu6yAqgjGy8MSud9ggxJj+I9XLuztLeSf/E0j0j6RQYtxH2J8U0Cfbgiw9ZDHyhpmaVuWhxscYaAQ=="
+    },
+    "node_modules/@types/d3-interpolate": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.2.tgz",
+      "integrity": "sha512-zAbCj9lTqW9J9PlF4FwnvEjXZUy75NQqPm7DMHZXuxCFTpuTrdK2NMYGQekf4hlasL78fCYOLu4EE3/tXElwow==",
+      "dependencies": {
+        "@types/d3-color": "*"
+      }
+    },
+    "node_modules/@types/d3-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz",
+      "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg=="
+    },
+    "node_modules/@types/d3-polygon": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz",
+      "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw=="
+    },
+    "node_modules/@types/d3-quadtree": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.3.tgz",
+      "integrity": "sha512-GDWaR+rGEk4ToLQSGugYnoh9AYYblsg/8kmdpa1KAJMwcdZ0v8rwgnldURxI5UrzxPlCPzF7by/Tjmv+Jn21Dg=="
+    },
+    "node_modules/@types/d3-random": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz",
+      "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ=="
+    },
+    "node_modules/@types/d3-scale": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.5.tgz",
+      "integrity": "sha512-w/C++3W394MHzcLKO2kdsIn5KKNTOqeQVzyPSGPLzQbkPw/jpeaGtSRlakcKevGgGsjJxGsbqS0fPrVFDbHrDA==",
+      "dependencies": {
+        "@types/d3-time": "*"
+      }
+    },
+    "node_modules/@types/d3-scale-chromatic": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+      "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw=="
+    },
+    "node_modules/@types/d3-selection": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.7.tgz",
+      "integrity": "sha512-qoj2O7KjfqCobmtFOth8FMvjwMVPUAAmn6xiUbLl1ld7vQCPgffvyV5BBcEFfqWdilAUm+3zciU/3P3vZrUMlg=="
+    },
+    "node_modules/@types/d3-shape": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.3.tgz",
+      "integrity": "sha512-cHMdIq+rhF5IVwAV7t61pcEXfEHsEsrbBUPkFGBwTXuxtTAkBBrnrNA8++6OWm3jwVsXoZYQM8NEekg6CPJ3zw==",
+      "dependencies": {
+        "@types/d3-path": "*"
+      }
+    },
+    "node_modules/@types/d3-time": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.1.tgz",
+      "integrity": "sha512-5j/AnefKAhCw4HpITmLDTPlf4vhi8o/dES+zbegfPb7LaGfNyqkLxBR6E+4yvTAgnJLmhe80EXFMzUs38fw4oA=="
+    },
+    "node_modules/@types/d3-time-format": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.1.tgz",
+      "integrity": "sha512-Br6EFeu9B1Zrem7KaYbr800xCmEDyq8uE60kEU8rWhC/XpFYX6ocGMZuRJDQfFCq6SyakQxNHFqIfJbFLf4x6Q=="
+    },
+    "node_modules/@types/d3-timer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz",
+      "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g=="
+    },
+    "node_modules/@types/d3-transition": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.5.tgz",
+      "integrity": "sha512-dcfjP6prFxj3ziFOJrnt4W2P0oXNj/sGxsJXH8286sHtVZ4qWGbjuZj+RRCYx4YZ4C0izpeE8OqXVCtoWEtzYg==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-zoom": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.5.tgz",
+      "integrity": "sha512-mIefdTLtxuWUWTbBupCUXPAXVPmi8/Uwrq41gQpRh0rD25GMU1ku+oTELqNY2NuuiI0F3wXC5e1liBQi7YS7XQ==",
+      "dependencies": {
+        "@types/d3-interpolate": "*",
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/dagre": {
+      "version": "0.7.42",
+      "resolved": "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.42.tgz",
+      "integrity": "sha512-knVdi1Ul8xYgJ0wdhQ+/2YGJFKJFa/5srcPII9zvOs4KhsHfpnFrSTQXATYmjslglxRMif3Lg+wEZ0beag+94A=="
+    },
     "node_modules/@types/eslint": {
       "version": "8.44.3",
       "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.3.tgz",
@@ -2483,6 +2738,11 @@
       "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==",
       "dev": true
     },
+    "node_modules/@types/geojson": {
+      "version": "7946.0.11",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.11.tgz",
+      "integrity": "sha512-L7A0AINMXQpVwxHJ4jxD6/XjZ4NDufaRlUJHjNIFKYUFBH1SvOW+neaqb0VTRSLW5suSrSu19ObFEFnfNcr+qg=="
+    },
     "node_modules/@types/glob": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz",
@@ -2494,9 +2754,9 @@
       }
     },
     "node_modules/@types/js-yaml": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz",
-      "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA=="
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.7.tgz",
+      "integrity": "sha512-RJZP9WAMMr1514KbdSXkLRrKvYQacjr1+HWnY8pui/uBTBoSgD9ZGR17u/d4nb9NpERp0FkdLBe7hq8NIPBgkg=="
     },
     "node_modules/@types/json-schema": {
       "version": "7.0.13",
@@ -2525,14 +2785,12 @@
     "node_modules/@types/prop-types": {
       "version": "15.7.7",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz",
-      "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==",
-      "devOptional": true
+      "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog=="
     },
     "node_modules/@types/react": {
       "version": "18.2.0",
       "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.0.tgz",
       "integrity": "sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==",
-      "devOptional": true,
       "dependencies": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -2548,11 +2806,18 @@
         "@types/react": "*"
       }
     },
+    "node_modules/@types/react-measure": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.9.tgz",
+      "integrity": "sha512-8h9n24GK9Ckg1IxDjZLIjUu7/LDNVx2NbQd6KoD9R0JRy8B4ipA5OGCpsYhB6VULc4KlhsINKYUjd8+Urecq1A==",
+      "dependencies": {
+        "@types/react": "*"
+      }
+    },
     "node_modules/@types/scheduler": {
       "version": "0.16.4",
       "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz",
-      "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==",
-      "devOptional": true
+      "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ=="
     },
     "node_modules/@types/shelljs": {
       "version": "0.8.13",
@@ -2565,9 +2830,9 @@
       }
     },
     "node_modules/@types/uuid": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
-      "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA=="
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.5.tgz",
+      "integrity": "sha512-xfHdwa1FMJ082prjSJpoEI57GZITiQz10r3vEJCHa2khEFQjKy91aWKz6+zybzssCvXUwE1LQWgWVwZ4nYUvHQ=="
     },
     "node_modules/@types/vscode": {
       "version": "1.82.0",
@@ -3738,7 +4003,6 @@
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
       "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
-      "dev": true,
       "engines": {
         "node": ">= 10"
       }
@@ -4034,8 +4298,386 @@
     "node_modules/csstype": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
-      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
-      "devOptional": true
+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+    },
+    "node_modules/d3": {
+      "version": "7.8.5",
+      "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
+      "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
+      "dependencies": {
+        "d3-array": "3",
+        "d3-axis": "3",
+        "d3-brush": "3",
+        "d3-chord": "3",
+        "d3-color": "3",
+        "d3-contour": "4",
+        "d3-delaunay": "6",
+        "d3-dispatch": "3",
+        "d3-drag": "3",
+        "d3-dsv": "3",
+        "d3-ease": "3",
+        "d3-fetch": "3",
+        "d3-force": "3",
+        "d3-format": "3",
+        "d3-geo": "3",
+        "d3-hierarchy": "3",
+        "d3-interpolate": "3",
+        "d3-path": "3",
+        "d3-polygon": "3",
+        "d3-quadtree": "3",
+        "d3-random": "3",
+        "d3-scale": "4",
+        "d3-scale-chromatic": "3",
+        "d3-selection": "3",
+        "d3-shape": "3",
+        "d3-time": "3",
+        "d3-time-format": "4",
+        "d3-timer": "3",
+        "d3-transition": "3",
+        "d3-zoom": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "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-axis": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
+      "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-brush": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+      "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "3",
+        "d3-transition": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-chord": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
+      "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
+      "dependencies": {
+        "d3-path": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "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-contour": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",
+      "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
+      "dependencies": {
+        "d3-array": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-delaunay": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
+      "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
+      "dependencies": {
+        "delaunator": "5"
+      },
+      "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-dsv": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
+      "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+      "dependencies": {
+        "commander": "7",
+        "iconv-lite": "0.6",
+        "rw": "1"
+      },
+      "bin": {
+        "csv2json": "bin/dsv2json.js",
+        "csv2tsv": "bin/dsv2dsv.js",
+        "dsv2dsv": "bin/dsv2dsv.js",
+        "dsv2json": "bin/dsv2json.js",
+        "json2csv": "bin/json2dsv.js",
+        "json2dsv": "bin/json2dsv.js",
+        "json2tsv": "bin/json2dsv.js",
+        "tsv2csv": "bin/dsv2dsv.js",
+        "tsv2json": "bin/dsv2json.js"
+      },
+      "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-fetch": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
+      "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
+      "dependencies": {
+        "d3-dsv": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-force": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
+      "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "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-geo": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz",
+      "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==",
+      "dependencies": {
+        "d3-array": "2.5.0 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-hierarchy": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+      "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+      "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-path": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-polygon": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
+      "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "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-random": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+      "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+      "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.0.0",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+      "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+      "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-shape": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+      "dependencies": {
+        "d3-path": "^3.1.0"
+      },
+      "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/dagre": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.2.tgz",
+      "integrity": "sha512-TEOOGZOkCOgCG7AoUIq64sJ3d21SMv8tyoqteLpX+UsUsS9Qw8iap4hhogXY4oB3r0bbZuAjO0atAilgCmsE0Q==",
+      "dependencies": {
+        "graphlib": "^2.1.5",
+        "lodash": "^4.17.4"
+      }
     },
     "node_modules/debug": {
       "version": "4.3.4",
@@ -4124,6 +4766,14 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/delaunator": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
+      "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
+      "dependencies": {
+        "robust-predicates": "^3.0.0"
+      }
+    },
     "node_modules/diff": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
@@ -5133,11 +5783,11 @@
       "dev": true
     },
     "node_modules/focus-trap": {
-      "version": "7.4.3",
-      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
-      "integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
+      "version": "7.5.2",
+      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz",
+      "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==",
       "dependencies": {
-        "tabbable": "^6.1.2"
+        "tabbable": "^6.2.0"
       }
     },
     "node_modules/for-each": {
@@ -5275,6 +5925,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/get-node-dimensions": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz",
+      "integrity": "sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ=="
+    },
     "node_modules/get-symbol-description": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
@@ -5390,6 +6045,14 @@
       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
       "dev": true
     },
+    "node_modules/graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
+      "dependencies": {
+        "lodash": "^4.17.15"
+      }
+    },
     "node_modules/has": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
@@ -5511,6 +6174,17 @@
         "node": ">= 6"
       }
     },
+    "node_modules/iconv-lite": {
+      "version": "0.6.3",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+      "dependencies": {
+        "safer-buffer": ">= 2.1.2 < 3.0.0"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/icss-utils": {
       "version": "5.1.0",
       "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
@@ -5610,6 +6284,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/interpret": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz",
@@ -6512,6 +7194,60 @@
         "mkdirp": "bin/cmd.js"
       }
     },
+    "node_modules/mobx": {
+      "version": "6.10.2",
+      "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.10.2.tgz",
+      "integrity": "sha512-B1UGC3ieK3boCjnMEcZSwxqRDMdzX65H/8zOHbuTY8ZhvrIjTUoLRR2TP2bPqIgYRfb3+dUigu8yMZufNjn0LQ==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      }
+    },
+    "node_modules/mobx-react": {
+      "version": "7.6.0",
+      "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-7.6.0.tgz",
+      "integrity": "sha512-+HQUNuh7AoQ9ZnU6c4rvbiVVl+wEkb9WqYsVDzGLng+Dqj1XntHu79PvEWKtSMoMj67vFp/ZPXcElosuJO8ckA==",
+      "dependencies": {
+        "mobx-react-lite": "^3.4.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      },
+      "peerDependencies": {
+        "mobx": "^6.1.0",
+        "react": "^16.8.0 || ^17 || ^18"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/mobx-react-lite": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-3.4.3.tgz",
+      "integrity": "sha512-NkJREyFTSUXR772Qaai51BnE1voWx56LOL80xG7qkZr6vo8vEaLF3sz1JNUVh+rxmUzxYaqOhfuxTfqUh0FXUg==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      },
+      "peerDependencies": {
+        "mobx": "^6.1.0",
+        "react": "^16.8.0 || ^17 || ^18"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/mocha": {
       "version": "10.2.0",
       "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
@@ -6634,9 +7370,9 @@
       }
     },
     "node_modules/monaco-editor": {
-      "version": "0.43.0",
-      "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.43.0.tgz",
-      "integrity": "sha512-cnoqwQi/9fml2Szamv1XbSJieGJ1Dc8tENVMD26Kcfl7xGQWp7OBKMjlwKVGYFJ3/AXJjSOGvcqK7Ry/j9BM1Q==",
+      "version": "0.44.0",
+      "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.44.0.tgz",
+      "integrity": "sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==",
       "peer": true
     },
     "node_modules/ms": {
@@ -7037,6 +7773,24 @@
         "node": ">=8"
       }
     },
+    "node_modules/point-in-svg-path": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/point-in-svg-path/-/point-in-svg-path-1.0.2.tgz",
+      "integrity": "sha512-+Smsf7B9e7eRFHIwpN+4rE8inF2APbFWeywPfUgbeh02xdJSkbTz6Pqdt7A36wVCR+CnLbaNkRnBjgOpF5RMVQ==",
+      "engines": {
+        "node": ">=8.x.x"
+      }
+    },
+    "node_modules/popper.js": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+      "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
+      "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
     "node_modules/postcss": {
       "version": "8.4.31",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -7307,6 +8061,21 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
     },
+    "node_modules/react-measure": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.5.2.tgz",
+      "integrity": "sha512-M+rpbTLWJ3FD6FXvYV6YEGvQ5tMayQ3fGrZhRPHrE9bVlBYfDCLuDcgNttYfk8IqfOI03jz6cbpqMRTUclQnaA==",
+      "dependencies": {
+        "@babel/runtime": "^7.2.0",
+        "get-node-dimensions": "^1.2.1",
+        "prop-types": "^15.6.2",
+        "resize-observer-polyfill": "^1.5.0"
+      },
+      "peerDependencies": {
+        "react": ">0.13.0",
+        "react-dom": ">0.13.0"
+      }
+    },
     "node_modules/readable-stream": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
@@ -7386,8 +8155,7 @@
     "node_modules/regenerator-runtime": {
       "version": "0.14.0",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
-      "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==",
-      "dev": true
+      "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
     },
     "node_modules/regenerator-transform": {
       "version": "0.15.2",
@@ -7483,6 +8251,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
     "node_modules/resolve": {
       "version": "1.22.6",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
@@ -7554,6 +8327,11 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/robust-predicates": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
+      "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="
+    },
     "node_modules/run-parallel": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -7587,10 +8365,15 @@
         "run-script-os": "index.js"
       }
     },
+    "node_modules/rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
+    },
     "node_modules/rxjs": {
-      "version": "7.8.0",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.0.tgz",
-      "integrity": "sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg==",
+      "version": "7.8.1",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
       "dependencies": {
         "tslib": "^2.1.0"
       }
@@ -7639,6 +8422,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
     "node_modules/scheduler": {
       "version": "0.23.0",
       "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
@@ -8716,9 +9504,13 @@
       "dev": true
     },
     "node_modules/uuid": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
-      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
       "bin": {
         "uuid": "dist/bin/uuid"
       }
@@ -8758,6 +9550,54 @@
         "node": ">=10.13.0"
       }
     },
+    "node_modules/webcola": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/webcola/-/webcola-3.4.0.tgz",
+      "integrity": "sha512-4BiLXjXw3SJHo3Xd+rF+7fyClT6n7I+AR6TkBqyQ4kTsePSAMDLRCXY1f3B/kXJeP9tYn4G1TblxTO+jAt0gaw==",
+      "dependencies": {
+        "d3-dispatch": "^1.0.3",
+        "d3-drag": "^1.0.4",
+        "d3-shape": "^1.3.5",
+        "d3-timer": "^1.0.5"
+      }
+    },
+    "node_modules/webcola/node_modules/d3-dispatch": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
+      "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
+    },
+    "node_modules/webcola/node_modules/d3-drag": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz",
+      "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==",
+      "dependencies": {
+        "d3-dispatch": "1",
+        "d3-selection": "1"
+      }
+    },
+    "node_modules/webcola/node_modules/d3-path": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+      "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
+    },
+    "node_modules/webcola/node_modules/d3-selection": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz",
+      "integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg=="
+    },
+    "node_modules/webcola/node_modules/d3-shape": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+      "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+      "dependencies": {
+        "d3-path": "1"
+      }
+    },
+    "node_modules/webcola/node_modules/d3-timer": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz",
+      "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
+    },
     "node_modules/webpack": {
       "version": "5.81.0",
       "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.81.0.tgz",
@@ -9207,9 +10047,9 @@
       }
     },
     "node_modules/zustand": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.1.tgz",
-      "integrity": "sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==",
+      "version": "4.4.3",
+      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.3.tgz",
+      "integrity": "sha512-oRy+X3ZazZvLfmv6viIaQmtLOMeij1noakIsK/Y47PWYhT8glfXzQ4j0YcP5i0P0qI1A4rIB//SGROGyZhx91A==",
       "dependencies": {
         "use-sync-external-store": "1.2.0"
       },
diff --git a/karavan-vscode/package.json b/karavan-vscode/package.json
index a9d8cfa8..1671fc79 100644
--- a/karavan-vscode/package.json
+++ b/karavan-vscode/package.json
@@ -457,6 +457,11 @@
       }
     },
     "commands": [
+      {
+        "command": "karavan.topology",
+        "title": "Karavan: Show Topology",
+        "icon": "$(type-hierarchy)"
+      },
       {
         "command": "karavan.create-yaml",
         "title": "Karavan: Create Integration",
@@ -531,6 +536,11 @@
           "when": "explorerResourceIsFolder || explorerResourceIsRoot",
           "group": "karavan@2"
         },
+        {
+          "command": "karavan.topology",
+          "when": "explorerResourceIsFolder || explorerResourceIsRoot || resourceFilename =~ /.camel.yaml$/",
+          "group": "karavan@1"
+        },
         {
           "command": "karavan.create-application",
           "when": "explorerResourceIsFolder || explorerResourceIsRoot",
@@ -590,6 +600,11 @@
         }
       ],
       "view/title": [
+        {
+          "command": "karavan.topology",
+          "when": "view == integrations",
+          "group": "navigation@0"
+        },
         {
           "command": "karavan.create-yaml",
           "when": "view == integrations",
@@ -681,7 +696,7 @@
   },
   "scripts": {
     "copy-core": "cp -r ../karavan-core/src/core webview",
-    "copy-designer": "cp -r ../karavan-designer/src/designer webview && cp -r ../karavan-designer/src/knowledgebase webview",
+    "copy-designer": "cp -r ../karavan-designer/src/designer webview && cp -r ../karavan-designer/src/knowledgebase webview && cp -r ../karavan-designer/src/topology webview",
     "replace-import": "run-script-os",
     "replace-import:darwin": "find webview -type f -name '*.ts*' -exec sed -i '' 's!karavan-core/lib!core!g' {} +",
     "replace-import:linux": "find webview -type f -name '*.ts*' -exec sed -i 's!karavan-core/lib!core!g' {} +",
@@ -700,21 +715,22 @@
     "open-in-browser": "vscode-test-web --extensionDevelopmentPath=. ../karavan-demo/hello-world/"
   },
   "dependencies": {
-    "@monaco-editor/react": "4.5.1",
-    "@patternfly/patternfly": "^5.0.2",
-    "@patternfly/react-core": "^5.0.0",
-    "@patternfly/react-table": "^5.0.0",
-    "@types/js-yaml": "4.0.5",
-    "@types/uuid": "9.0.1",
+    "@monaco-editor/react": "^4.6.0",
+    "@patternfly/patternfly": "^5.1.0",
+    "@patternfly/react-core": "^5.1.1",
+    "@patternfly/react-table": "^5.1.1",
+    "@patternfly/react-topology": "^5.1.0",
+    "@types/js-yaml": "4.0.7",
+    "@types/uuid": "9.0.5",
     "html-to-image": "1.11.11",
     "js-yaml": "^4.1.0",
     "path-browserify": "^1.0.1",
     "react": "18.2.0",
     "react-dom": "18.2.0",
-    "rxjs": "7.8.0",
+    "rxjs": "7.8.1",
     "shelljs": "^0.8.5",
-    "uuid": "9.0.0",
-    "zustand": "^4.4.1"
+    "uuid": "9.0.1",
+    "zustand": "4.4.3"
   },
   "devDependencies": {
     "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
diff --git a/karavan-vscode/src/designerView.ts b/karavan-vscode/src/designerView.ts
index 5caa9beb..944b5d9e 100644
--- a/karavan-vscode/src/designerView.ts
+++ b/karavan-vscode/src/designerView.ts
@@ -17,7 +17,6 @@
 import {Uri, window, commands, WebviewPanel, ExtensionContext, ViewColumn, WebviewPanelOnDidChangeViewStateEvent } from "vscode";
 import * as path from "path";
 import * as utils from "./utils";
-import * as jbang from "./jbang";
 import { CamelDefinitionYaml } from "core/api/CamelDefinitionYaml";
 import { Integration } from "core/model/IntegrationDefinition";
 import { getWebviewContent } from "./webviewContent";
@@ -116,7 +115,6 @@ export class DesignerView {
                             utils.save(message.relativePath, message.code);
                             break;
                         case 'saveCode':
-                            console.log("saveCode")
                             utils.saveCode(message.name, message.yamlFullPath, message.yamFileName, message.code);
                             break;
                         case 'getData':
diff --git a/karavan-vscode/src/extension.ts b/karavan-vscode/src/extension.ts
index 17eea70a..ae52d15f 100644
--- a/karavan-vscode/src/extension.ts
+++ b/karavan-vscode/src/extension.ts
@@ -23,6 +23,7 @@ import * as path from "path";
 import * as jbang from "./jbang";
 import * as utils from "./utils";
 import * as exec from "./exec";
+import { TopologyView } from './topologyView';
 
 const KARAVAN_LOADED = "karavan:loaded";
 
@@ -46,16 +47,20 @@ export function activate(context: ExtensionContext) {
     window.registerTreeDataProvider('help', helpView);
     commands.registerCommand('karavan.openKnowledgebase', () => helpView.openKaravanWebView("knowledgebase"));
 
+    const topologyView = new TopologyView(context);
+    const topologyCommand = commands.registerCommand("karavan.topology", (...args: any[]) => {
+        topologyView.openKaravanWebView(args[0]?.fsPath);
+    });
+    context.subscriptions.push(topologyCommand);
+
     // Create new Integration YAML command
     const createYaml = commands.registerCommand("karavan.create-yaml", (...args: any[]) => {
-        console.log("args", args)
         designer.createIntegration("plain", args[0]?.fsPath)
     });
     context.subscriptions.push(createYaml);
 
     // Open integration in designer command
     const open = commands.registerCommand("karavan.open", (...args: any[]) => {
-        console.log("args", args)
         designer.karavanOpen(args[0].fsPath, args[0].tab);
     });
     context.subscriptions.push(open);
@@ -195,6 +200,4 @@ export async function exportAndRunProject(rootPath?: string, run?: boolean) {
 
 export function deactivate() {
     commands.executeCommand("setContext", KARAVAN_LOADED, false);
-}
-
-
+}
\ No newline at end of file
diff --git a/karavan-vscode/src/helpView.ts b/karavan-vscode/src/helpView.ts
index def223b9..c1d11236 100644
--- a/karavan-vscode/src/helpView.ts
+++ b/karavan-vscode/src/helpView.ts
@@ -48,7 +48,7 @@ export class HelpView implements vscode.TreeDataProvider<HelpItem> {
 			// Karavan webview
 			const panel = vscode.window.createWebviewPanel(
 				"karavan",
-				page.toUpperCase(),
+				utils.capitalize(page),
 				vscode.ViewColumn.One,
 				{
 					enableScripts: true,
diff --git a/karavan-vscode/src/helpView.ts b/karavan-vscode/src/topologyView.ts
similarity index 50%
copy from karavan-vscode/src/helpView.ts
copy to karavan-vscode/src/topologyView.ts
index def223b9..55cfee6a 100644
--- a/karavan-vscode/src/helpView.ts
+++ b/karavan-vscode/src/topologyView.ts
@@ -16,39 +16,26 @@
  */
 import * as vscode from "vscode";
 import * as utils from "./utils";
-import { ThemeIcon } from "vscode";
+import * as path from "path";
 import { getWebviewContent } from "./webviewContent";
+import { WebviewPanelOnDidChangeViewStateEvent } from "vscode";
+
+const page = 'topology';
 
 const KARAVAN_PANELS: Map<string, vscode.WebviewPanel> = new Map<string, vscode.WebviewPanel>();
 
-export class HelpView implements vscode.TreeDataProvider<HelpItem> {
+export class TopologyView {
 
 	constructor(private context: vscode.ExtensionContext) {
 
 	}
-	private _onDidChangeTreeData: vscode.EventEmitter<HelpItem | undefined | void> = new vscode.EventEmitter<HelpItem | undefined | void>();
-	readonly onDidChangeTreeData: vscode.Event<HelpItem | undefined | void> = this._onDidChangeTreeData.event;
-
-	getTreeItem(element: HelpItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
-		return element;
-	}
-	getChildren(element?: HelpItem): vscode.ProviderResult<HelpItem[]> {
-		const helpItems: HelpItem[] = [];
-		helpItems.push(new HelpItem("Knowledgebase", "Knowledgebase", "knowledgebase", 'combine', { command: 'karavan.openKnowledgebase', title: '' }));
-		helpItems.push(new HelpItem("Report issue", "Report Issue", "issue", 'comment', { command: 'karavan.reportIssue', title: '' }));
-		return Promise.resolve(helpItems);
-	}
-
-	refresh(): void {
-		this._onDidChangeTreeData.fire();
-	}
 
-	openKaravanWebView(page: string) {
+	openKaravanWebView(fsPath: string | undefined) {
 		if (!KARAVAN_PANELS.has(page)) {
 			// Karavan webview
 			const panel = vscode.window.createWebviewPanel(
 				"karavan",
-				page.toUpperCase(),
+				"Topology",
 				vscode.ViewColumn.One,
 				{
 					enableScripts: true,
@@ -69,7 +56,10 @@ export class HelpView implements vscode.TreeDataProvider<HelpItem> {
 				message => {
 					switch (message.command) {
 						case 'getData':
-							this.sendData(panel, page);
+							this.sendData(panel, fsPath);
+							break;
+						case 'openFile':
+							this.openFile(fsPath, message.fileName);
 							break;
 					}
 				},
@@ -82,11 +72,13 @@ export class HelpView implements vscode.TreeDataProvider<HelpItem> {
 			}, null, this.context.subscriptions);
 
 			// Handle reopen
-			panel.onDidChangeViewState((e: vscode.WebviewPanelOnDidChangeViewStateEvent) => {
-				if (e.webviewPanel.active) {
-					e.webviewPanel.webview.postMessage({ command: 'reread' })
-				}
-			});
+            panel.onDidChangeViewState((e: WebviewPanelOnDidChangeViewStateEvent) => {
+                if (e.webviewPanel.active) {
+                    e.webviewPanel.webview.postMessage({ command: 'activate'});
+                } else {
+                    e.webviewPanel.webview.postMessage({ command: 'deactivate' });
+                }
+            });
 
 			KARAVAN_PANELS.set(page, panel);
 		} else {
@@ -94,36 +86,36 @@ export class HelpView implements vscode.TreeDataProvider<HelpItem> {
 		}
 	}
 
-	 sendData(panel: vscode.WebviewPanel, page: string) {
-		// Read and send Kamelets
-		utils.readKamelets(this.context).then(kamelets => {
-			panel.webview.postMessage({ command: 'kamelets', kamelets: kamelets });
-		}).finally(() => {
-			utils.readComponents(this.context).then(components => {
-				// Read and send Components
-				panel.webview.postMessage({ command: 'components', components: components });
+	sendData(panel: vscode.WebviewPanel, fsPath: string | undefined) {
+		if (fsPath) {
+			// Read and send Kamelets
+			utils.readKamelets(this.context).then(kamelets => {
+				panel.webview.postMessage({ command: 'kamelets', kamelets: kamelets });
 			}).finally(() => {
-				// Send integration
-				panel.webview.postMessage({ command: 'open', page: page });
+				utils.readComponents(this.context).then(components => {
+					// Read and send Components
+					panel.webview.postMessage({ command: 'components', components: components });
+				}).finally(() => {
+					// Read and send Integrations
+					let fullPath = fsPath;
+					if (fsPath.endsWith(".camel.yaml")) {
+						const parts = fsPath.split(path.sep);
+						parts.pop();
+						fullPath = parts.join(path.sep);
+					}
+					utils.readCamelYamlFiles(fullPath).then((files) => {
+						panel.webview.postMessage({ command: 'files', files: files });
+					}).finally(() => {
+						// Open
+						panel.webview.postMessage({ command: 'open', page: page });
+					})
+				})
 			})
-		})
+		}
 	}
-}
-
-export class HelpItem extends vscode.TreeItem {
 
-	constructor(
-		public readonly title: string,
-		public readonly tooltip: string,
-		public readonly page: string,
-		public readonly icon: string,
-		public readonly command?: vscode.Command
-	) {
-		super(title, vscode.TreeItemCollapsibleState.None);
-		this.tooltip = this.tooltip;
+	openFile(fsPath: string | undefined, fileName: string) {
+		const fullPath = fsPath + path.sep + fileName;
+		vscode.commands.executeCommand("karavan.open", { fsPath: fullPath })
 	}
-
-	iconPath = new ThemeIcon(this.icon);
-
-	contextValue = 'help';
-}
\ No newline at end of file
+}
diff --git a/karavan-vscode/src/utils.ts b/karavan-vscode/src/utils.ts
index 8f84c721..c31b25a6 100644
--- a/karavan-vscode/src/utils.ts
+++ b/karavan-vscode/src/utils.ts
@@ -189,6 +189,21 @@ export async function getCamelYamlFiles(baseDir: string) {
     return result;
 }
 
+export async function readCamelYamlFiles(dir: string) {
+    const result: any = {};
+    const files = await getCamelYamlFiles(dir);
+    for (let x in files){
+        const filename = files[x];
+        const readData = await readFile(path.resolve(filename));
+        const yaml = Buffer.from(readData).toString('utf8');
+        if (CamelDefinitionYaml.yamlIsIntegration(yaml)){
+            const basename = path.basename(filename);  
+            result[basename] = yaml;
+        }
+    }
+    return result;
+}
+
 export async function hasApplicationProperties(baseDir: string) {
     return (await getPropertyFiles(baseDir)).includes(baseDir + path.sep + 'application.properties');
 }
diff --git a/karavan-vscode/webview/App.tsx b/karavan-vscode/webview/App.tsx
index 090126a1..0b28d69c 100644
--- a/karavan-vscode/webview/App.tsx
+++ b/karavan-vscode/webview/App.tsx
@@ -23,8 +23,10 @@ import vscode from "./vscode";
 import { KameletApi } from "core/api/KameletApi";
 import { ComponentApi } from "core/api/ComponentApi";
 import { TemplateApi } from "./core/api/TemplateApi";
-import {EventBus} from "./designer/utils/EventBus";
+import { EventBus } from "./designer/utils/EventBus";
 import { KnowledgebasePage } from "./knowledgebase/KnowledgebasePage";
+import { TopologyTab } from "./topology/TopologyTab";
+import { IntegrationFile } from "./topology/TopologyStore";
 
 interface Props {
   dark: boolean
@@ -41,10 +43,10 @@ interface State {
   interval?: NodeJS.Timeout
   scheduledYaml: string
   hasChanges: boolean
-  page: "designer" | "knowledgebase"
+  page: "designer" | "knowledgebase" | 'topology'
   active: boolean
   tab?: string
-  files: string
+  files: IntegrationFile[]
 }
 
 class App extends React.Component<Props, State> {
@@ -61,7 +63,7 @@ class App extends React.Component<Props, State> {
     hasChanges: false,
     page: "designer",
     active: false,
-    files: '',
+    files: [],
   };
 
   saveScheduledChanges = () => {
@@ -75,6 +77,13 @@ class App extends React.Component<Props, State> {
     window.addEventListener('message', this.onMessage, false);
     vscode.postMessage({ command: 'getData' });
     this.setState({ interval: setInterval(this.saveScheduledChanges, 2000) });
+    if (this.props.dark) {
+      const box = document.getElementsByTagName('html');
+      if (box != null && box.length > 0) {
+        box[0].classList.add('pf-v5-theme-dark');
+        // box.classList.remove('bg-yellow');
+      }
+    }
   }
 
   componentWillUnmount() {
@@ -89,41 +98,48 @@ class App extends React.Component<Props, State> {
       case 'kamelets':
         KameletApi.saveKamelets(message.kamelets, true);
         this.setState((prevState: State) => {
-          prevState.loadingMessages.push("Kamelets loaded"); 
-          return {loadingMessages: prevState.loadingMessages}
+          prevState.loadingMessages.push("Kamelets loaded");
+          return { loadingMessages: prevState.loadingMessages }
         });
         break;
       case 'components':
         ComponentApi.saveComponents(message.components, true);
         this.setState((prevState: State) => {
-          prevState.loadingMessages.push("Components loaded"); 
-          return {loadingMessages: prevState.loadingMessages}
+          prevState.loadingMessages.push("Components loaded");
+          return { loadingMessages: prevState.loadingMessages }
         });
         break;
       case 'supportedComponents':
         ComponentApi.saveSupportedComponents(message.components);
         this.setState((prevState: State) => {
-          prevState.loadingMessages.push("Supported Components loaded"); 
-          return {loadingMessages: prevState.loadingMessages}
+          prevState.loadingMessages.push("Supported Components loaded");
+          return { loadingMessages: prevState.loadingMessages }
         });
-        break; 
+        break;
       case 'supportedOnly':
         ComponentApi.setSupportedOnly(true);
-        break;    
+        break;
+      case 'files':
+        this.saveIntegrationFiles(message.files);
+        this.setState((prevState: State) => {
+          prevState.loadingMessages.push("Integrations loaded");
+          return { loadingMessages: prevState.loadingMessages }
+        });
+        break;
       case 'templates':
         const templates = message.templates;
-        const map = new Map( Object.keys(templates).map(key => [key, templates[key]]));
+        const map = new Map(Object.keys(templates).map(key => [key, templates[key]]));
         TemplateApi.saveTemplates(map, true);
         this.setState((prevState: State) => {
-          prevState.loadingMessages.push("Templates loaded"); 
-          return {loadingMessages: prevState.loadingMessages}
+          prevState.loadingMessages.push("Templates loaded");
+          return { loadingMessages: prevState.loadingMessages }
         });
-        break;  
+        break;
       case 'javaCode':
         const javaCode = message.javaCode;
-        const javaCodeMap = new Map( Object.keys(javaCode).map(key => [key, javaCode[key]]));
+        const javaCodeMap = new Map(Object.keys(javaCode).map(key => [key, javaCode[key]]));
         TemplateApi.saveJavaCodes(javaCodeMap, true);
-        break;  
+        break;
       case 'open':
         if (this.state.filename === '' && this.state.key === '') {
           if (message.page !== "designer" && this.state.interval) clearInterval(this.state.interval);
@@ -170,36 +186,50 @@ class App extends React.Component<Props, State> {
     vscode.postMessage({ command: 'saveCode', name: name, yamlFullPath: this.state.fullPath, yamFileName: this.state.filename, code: code });
   }
 
+  saveIntegrationFiles(files: any) {
+    const f = Object.keys(files).map(key => new IntegrationFile(key, files[key]));
+    this.setState({ files: f });
+
+  }
+
   public render() {
-    const {loadingMessages, filename, key, yaml, page, loaded, tab} = this.state;
-    const {dark} = this.props;
+    const { loadingMessages, filename, key, yaml, page, loaded, tab } = this.state;
+    const { dark } = this.props;
     return (
       <Page className="karavan">
         {!loaded &&
           <PageSection variant={dark ? "dark" : "light"} className="loading-page">
-            <Spinner className="progress-stepper"  diameter="80px" aria-label="Loading..." />
+            <Spinner className="progress-stepper" diameter="80px" aria-label="Loading..." />
             {/* {loadingMessages.map(message => <Text component={TextVariants.h5}>{message}</Text>)} */}
             <Text component={TextVariants.h5}>Loading...</Text>
           </PageSection>
         }
         {loaded && page === "designer" &&
-          <KaravanDesigner 
-          showCodeTab={false}
+          <KaravanDesigner
+            showCodeTab={false}
             key={key}
             filename={filename}
             yaml={yaml}
             onSave={(filename, yaml, propertyOnly) => this.save(filename, yaml, propertyOnly)}
             tab={tab}
-            dark={dark} 
+            dark={dark}
             onSaveCustomCode={(name, code) => this.saveJavCode(name, code)}
             onGetCustomCode={(name, javaType) => {
-                let code = TemplateApi.getJavaCode(name);
-                if (code === undefined || code.length === 0) code = TemplateApi.generateCode(javaType, name);
-                return new Promise<string | undefined>(resolve => resolve(code))
+              let code = TemplateApi.getJavaCode(name);
+              if (code === undefined || code.length === 0) code = TemplateApi.generateCode(javaType, name);
+              return new Promise<string | undefined>(resolve => resolve(code))
             }}
-            />
+          />
         }
         {loaded && page === "knowledgebase" && <KnowledgebasePage dark={dark} />}
+        {loaded && page === "topology" &&
+          <TopologyTab
+            hideToolbar={true}
+            files={this.state.files}
+            onClickCreateButton={() => vscode.postMessage({ command: 'createIntegration' })}
+            onSetFile={(fileName) => vscode.postMessage({ command: 'openFile', fileName: fileName })}
+          />
+        }
       </Page>
     )
   }
diff --git a/karavan-vscode/webview/index.css b/karavan-vscode/webview/index.css
index 2074a097..163b2573 100644
--- a/karavan-vscode/webview/index.css
+++ b/karavan-vscode/webview/index.css
@@ -36,6 +36,7 @@ body, :root, #root, .karavan {
 
   --step-border-color: var(--pf-v5-global--active-color--200);
   --step-border-color-selected:var(--vscode-focusBorder);
+  padding: 0;
 }
 .karavan .properties .pf-v5-c-form-control > :is(input, select, textarea):focus {
   outline-color: var(--vscode-focusBorder);
@@ -467,4 +468,8 @@ color: var(--vscode-editor-foreground);
 
 #root .karavan .dsl-page .dsl-page-columns {
   padding-bottom: 0;
+}
+
+.vscode-dark .karavan .topology-panel .pf-topology__node .pf-topology__node__background {
+  fill: var(--pf-v5-global--palette--black-400); 
 }
\ No newline at end of file
diff --git a/karavan-vscode/webview/topology/CustomEdge.tsx b/karavan-vscode/webview/topology/CustomEdge.tsx
new file mode 100644
index 00000000..bd4fa92e
--- /dev/null
+++ b/karavan-vscode/webview/topology/CustomEdge.tsx
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as React from 'react';
+
+import './topology.css';
+import {DefaultEdge, observer} from '@patternfly/react-topology';
+
+
+const CustomEdge: React.FC<any> = observer(({ element, ...rest }) => {
+    return (
+        <DefaultEdge element={element} {...rest}>
+        </DefaultEdge>
+    )
+})
+export default CustomEdge;
\ No newline at end of file
diff --git a/karavan-vscode/webview/topology/CustomGroup.tsx b/karavan-vscode/webview/topology/CustomGroup.tsx
new file mode 100644
index 00000000..9e366c7c
--- /dev/null
+++ b/karavan-vscode/webview/topology/CustomGroup.tsx
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as React from 'react';
+
+import './topology.css';
+import { DefaultGroup, observer} from '@patternfly/react-topology';
+
+
+const CustomGroup: React.FC<any> = observer(({ element, ...rest }) => {
+
+    return (
+        <DefaultGroup element={element} {...rest}>
+        </DefaultGroup>
+    )
+})
+export default CustomGroup;
\ No newline at end of file
diff --git a/karavan-vscode/webview/topology/CustomNode.tsx b/karavan-vscode/webview/topology/CustomNode.tsx
new file mode 100644
index 00000000..2d87457d
--- /dev/null
+++ b/karavan-vscode/webview/topology/CustomNode.tsx
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as React from 'react';
+import {RegionsIcon} from '@patternfly/react-icons';
+
+import {DefaultNode, observer} from '@patternfly/react-topology';
+import {getDesignerIcon} from "../designer/utils/KaravanIcons";
+import {CamelUi} from "../designer/utils/CamelUi";
+import './topology.css';
+
+function getIcon(data: any) {
+    if (['route', 'rest'].includes(data.icon)) {
+        return (
+            <g transform={`translate(14, 14)`}>
+                {getDesignerIcon(data.icon)}
+            </g>
+        )
+    } else if (data.icon === 'element') {
+        return (
+            <g transform={`translate(14, 14)`}>
+                {CamelUi.getConnectionIcon(data.step)}
+            </g>
+        )
+    }
+    return <RegionsIcon/>;
+}
+
+const CustomNode: React.FC<any> = observer(({ element, ...rest }) => {
+
+    const data = element.getData();
+
+    return (
+        <DefaultNode
+            className="common-node"
+            element={element} {...rest}
+        >
+            {getIcon(data)}
+        </DefaultNode>
+    )
+})
+export default CustomNode;
\ No newline at end of file
diff --git a/karavan-vscode/webview/topology/TopologyApi.tsx b/karavan-vscode/webview/topology/TopologyApi.tsx
new file mode 100644
index 00000000..9655968d
--- /dev/null
+++ b/karavan-vscode/webview/topology/TopologyApi.tsx
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+    ComponentFactory,
+    EdgeAnimationSpeed,
+    EdgeModel,
+    EdgeStyle,
+    GraphComponent,
+    Model,
+    ModelKind,
+    NodeModel,
+    NodeShape,
+    NodeStatus,
+    withPanZoom, withSelection
+} from '@patternfly/react-topology';
+import CustomNode from "./CustomNode";
+import {Integration} from "core/model/IntegrationDefinition";
+import {CamelDefinitionYaml} from "core/api/CamelDefinitionYaml";
+import {TopologyUtils} from "core/api/TopologyUtils";
+import {
+    TopologyIncomingNode,
+    TopologyOutgoingNode,
+    TopologyRestNode,
+    TopologyRouteNode
+} from "core/model/TopologyDefinition";
+import CustomGroup from "./CustomGroup";
+import CustomEdge from "./CustomEdge";
+import {IntegrationFile} from "./TopologyStore";
+
+const NODE_DIAMETER = 60;
+
+export function getIntegrations(files: IntegrationFile[]): Integration[] {
+    return files.filter((file) => file.name.endsWith(".camel.yaml")).map((file) => {
+        return CamelDefinitionYaml.yamlToIntegration(file.name, file.code);
+    })
+}
+
+export function getIncomingNodes(tins: TopologyIncomingNode[]): NodeModel[] {
+    return tins.filter(tin => tin.type === 'external').map(tin => {
+        return {
+            id: tin.id,
+            type: 'node',
+            label: tin.title,
+            width: NODE_DIAMETER,
+            height: NODE_DIAMETER,
+            shape: NodeShape.ellipse,
+            status: NodeStatus.default,
+            data: {
+                isAlternate: false,
+                badge: tin.type,
+                icon: 'element',
+                type: 'step',
+                step: tin.from,
+                fileName: tin.fileName
+            }
+        }
+    });
+}
+
+export function getRoutes(tins: TopologyRouteNode[]): NodeModel[] {
+    return tins.map(tin => {
+        const node: NodeModel = {
+            id: tin.id,
+            type: 'node',
+            label: tin.title,
+            width: NODE_DIAMETER,
+            height: NODE_DIAMETER,
+            shape: NodeShape.rect,
+            status: NodeStatus.default,
+            data: {
+                isAlternate: false,
+                type: 'route',
+                icon: 'route',
+                step: tin.route,
+                routeId: tin.routeId,
+                fileName: tin.fileName,
+            }
+        }
+        return node;
+    });
+}
+
+export function getOutgoingNodes(tons: TopologyOutgoingNode[]): NodeModel[] {
+    return tons.filter(tin => tin.type === 'external').map(tin => {
+        const node: NodeModel = {
+            id: tin.id,
+            type: 'node',
+            label: tin.title,
+            width: NODE_DIAMETER,
+            height: NODE_DIAMETER,
+            shape: NodeShape.ellipse,
+            status: NodeStatus.default,
+            data: {
+                isAlternate: false,
+                icon: 'element',
+                type: 'step',
+                step: tin.step,
+                badge: tin.type,
+                fileName: tin.fileName
+            }
+        }
+        return node;
+    });
+}
+
+export function getIncomingEdges(tins: TopologyIncomingNode[]): EdgeModel[] {
+    return tins.filter(tin => tin.type === 'external').map(tin => {
+        const node: EdgeModel = {
+            id: 'edge-incoming-' + tin.routeId,
+            type: 'edge',
+            source: tin.id,
+            target: 'route-' + tin.routeId,
+            edgeStyle: tin.type === 'external' ? EdgeStyle.dashedMd : EdgeStyle.solid,
+            animationSpeed: tin.type === 'external' ? EdgeAnimationSpeed.medium : EdgeAnimationSpeed.none
+        }
+        return node;
+    });
+}
+
+export function getOutgoingEdges(tons: TopologyOutgoingNode[]): EdgeModel[] {
+    return tons.filter(tin => tin.type === 'external').map(tin => {
+        const node: EdgeModel = {
+            id: 'edge-outgoing-' + tin.routeId + '-' + (tin.step as any).id,
+            type: 'edge',
+            source: 'route-' + tin.routeId,
+            target: tin.id,
+            edgeStyle: tin.type === 'external' ? EdgeStyle.dashedMd : EdgeStyle.solid,
+            animationSpeed: tin.type === 'external' ? EdgeAnimationSpeed.medium : EdgeAnimationSpeed.none
+        }
+        return node;
+    });
+}
+
+export function getRestNodes(tins: TopologyRestNode[]): NodeModel[] {
+    return tins.map(tin => {
+        return {
+            id: tin.id,
+            type: 'node',
+            label: tin.title,
+            width: NODE_DIAMETER,
+            height: NODE_DIAMETER,
+            shape: NodeShape.hexagon,
+            status: NodeStatus.default,
+            data: {
+                isAlternate: false,
+                icon: 'rest',
+                type: 'rest',
+                step: tin.rest,
+                fileName: tin.fileName
+            }
+        }
+    });
+}
+
+export function getRestEdges(rest: TopologyRestNode[], tins: TopologyIncomingNode[]): EdgeModel[] {
+    const result: EdgeModel[] = [];
+    rest.forEach(tin => {
+        tin.uris.forEach((uri, index) => {
+            const target = TopologyUtils.getRouteIdByUri(tins, uri);
+            const node: EdgeModel = {
+                id: 'incoming-' + tin.id + '-' + index,
+                type: 'edge',
+                source: tin.id,
+                target: target,
+                edgeStyle: EdgeStyle.solid,
+                animationSpeed: EdgeAnimationSpeed.medium
+            }
+            if (target) result.push(node);
+        })
+    });
+    return result;
+}
+
+export function getInternalEdges(tons: TopologyOutgoingNode[], tins: TopologyIncomingNode[]): EdgeModel[] {
+    const result: EdgeModel[] = [];
+    tons.filter(ton => ton.type === 'internal').forEach((ton, index) => {
+        const uri: string = (ton.step as any).uri;
+        if (uri.startsWith("direct") || uri.startsWith("seda")) {
+            const name = (ton.step as any).parameters.name;
+            const target = TopologyUtils.getRouteIdByUriAndName(tins, uri, name);
+                const node: EdgeModel = {
+                id: 'internal-' + ton.id + '-' + index,
+                type: 'edge',
+                source: 'route-' + ton.routeId,
+                target: target,
+                edgeStyle: EdgeStyle.solid,
+                animationSpeed: EdgeAnimationSpeed.medium
+            }
+            if (target) result.push(node);
+        }
+    });
+    return result;
+}
+
+export function getModel(files: IntegrationFile[]): Model {
+    const integrations = getIntegrations(files);
+    const tins = TopologyUtils.findTopologyIncomingNodes(integrations);
+    const troutes = TopologyUtils.findTopologyRouteNodes(integrations);
+    const tons = TopologyUtils.findTopologyOutgoingNodes(integrations);
+    const trestns = TopologyUtils.findTopologyRestNodes(integrations);
+
+    const nodes: NodeModel[] = [];
+    const groups: NodeModel[] = troutes.map(r => {
+        const children = [r.id]
+        children.push(... tins.filter(i => i.routeId === r.routeId && i.type === 'external').map(i => i.id));
+        children.push(... tons.filter(i => i.routeId === r.routeId && i.type === 'external').map(i => i.id));
+        return   {
+            id: 'group-' + r.routeId,
+            children: children,
+            type: 'group',
+            group: true,
+            label: r.title,
+            style: {
+                padding: 40
+            }
+        }
+    })
+
+    nodes.push(...getRestNodes(trestns))
+    nodes.push(...getIncomingNodes(tins))
+    nodes.push(...getRoutes(troutes))
+    nodes.push(...getOutgoingNodes(tons))
+    // nodes.push(...groups)
+
+    const edges: EdgeModel[] = [];
+    edges.push(...getIncomingEdges(tins));
+    edges.push(...getOutgoingEdges(tons));
+    edges.push(...getRestEdges(trestns, tins));
+    edges.push(...getInternalEdges(tons, tins));
+
+    return {nodes: nodes, edges: edges, graph: {id: 'g1', type: 'graph', layout: 'Dagre'}};
+}
+
+export const customComponentFactory: ComponentFactory = (kind: ModelKind, type: string) => {
+    switch (type) {
+        case 'group':
+            return withSelection()(CustomGroup);
+        default:
+            switch (kind) {
+                case ModelKind.graph:
+                    return withPanZoom()(GraphComponent);
+                case ModelKind.node:
+                    return (withSelection()(CustomNode));
+                case ModelKind.edge:
+                    return (withSelection()(CustomEdge));
+                default:
+                    return undefined;
+            }
+    }
+}
\ No newline at end of file
diff --git a/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
new file mode 100644
index 00000000..24deca24
--- /dev/null
+++ b/karavan-vscode/webview/topology/TopologyPropertiesPanel.tsx
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React from 'react';
+import '../designer/karavan.css';
+import {shallow} from "zustand/shallow";
+import {TopologySideBar} from "@patternfly/react-topology";
+import {useTopologyStore} from "./TopologyStore";
+import {DslProperties} from "../designer/route/DslProperties";
+import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
+import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
+
+interface Props {
+    onSetFile: (fileName: string) => void
+}
+
+export function TopologyPropertiesPanel (props: Props) {
+
+    const [selectedIds, setSelectedIds, fileName] = useTopologyStore((s) =>
+        [s.selectedIds, s.setSelectedIds, s.fileName], shallow);
+
+    function getHeader() {
+        return (
+            <Flex className="properties-header" direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
+                <FlexItem spacer={{ default: 'spacerNone' }}>
+                    <Text>Filename:</Text>
+                </FlexItem>
+                <FlexItem>
+                    <Button variant="link" onClick={event => {
+                        if (fileName) {
+                            props.onSetFile(fileName);
+                        }
+                    }}
+                    >{fileName}
+                    </Button>
+                </FlexItem>
+                <FlexItem align={{ default: 'alignRight' }}>
+                    <Tooltip content={"Close"} position={TooltipPosition.top}>
+                        <Button variant="link" icon={<CloseIcon/>} onClick={event => setSelectedIds([])}/>
+                    </Tooltip>
+                </FlexItem>
+            </Flex>
+        )
+    }
+
+    return (
+        <TopologySideBar
+        className="topology-sidebar"
+        show={selectedIds.length > 0}
+        header={getHeader()}
+    >
+        <DslProperties isRouteDesigner={false}/>
+    </TopologySideBar>
+    )
+}
diff --git a/karavan-space/src/topology/TopologyStore.ts b/karavan-vscode/webview/topology/TopologyStore.ts
similarity index 91%
copy from karavan-space/src/topology/TopologyStore.ts
copy to karavan-vscode/webview/topology/TopologyStore.ts
index 5bbdf124..3cf5067b 100644
--- a/karavan-space/src/topology/TopologyStore.ts
+++ b/karavan-vscode/webview/topology/TopologyStore.ts
@@ -39,9 +39,7 @@ export const useTopologyStore = createWithEqualityFn<TopologyState>((set) => ({
     selectedIds: [],
     setSelectedIds: (selectedIds: string[]) => {
         set((state: TopologyState) => {
-            state.selectedIds.length = 0;
-            state.selectedIds.push(...selectedIds);
-            return {selectedIds: state.selectedIds};
+            return {selectedIds: selectedIds};
         });
     },
     setFileName: (fileName?: string) => {
diff --git a/karavan-space/src/topology/TopologyTab.tsx b/karavan-vscode/webview/topology/TopologyTab.tsx
similarity index 96%
copy from karavan-space/src/topology/TopologyTab.tsx
copy to karavan-vscode/webview/topology/TopologyTab.tsx
index df48e0c0..520bf8d2 100644
--- a/karavan-space/src/topology/TopologyTab.tsx
+++ b/karavan-vscode/webview/topology/TopologyTab.tsx
@@ -41,6 +41,7 @@ interface Props {
     files: IntegrationFile[],
     onClickCreateButton: () => void
     onSetFile: (fileName: string) => void
+    hideToolbar: boolean
 }
 
 export function TopologyTab (props: Props) {
@@ -93,7 +94,7 @@ export function TopologyTab (props: Props) {
     return (
         <TopologyView
             className="topology-panel"
-            contextToolbar={<TopologyToolbar onClickCreateButton={props.onClickCreateButton}/>}
+            contextToolbar={!props.hideToolbar? <TopologyToolbar onClickCreateButton={props.onClickCreateButton}/> : undefined}
             sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
                 <TopologyControlBar
diff --git a/karavan-vscode/webview/topology/TopologyToolbar.tsx b/karavan-vscode/webview/topology/TopologyToolbar.tsx
new file mode 100644
index 00000000..2d9fc55c
--- /dev/null
+++ b/karavan-vscode/webview/topology/TopologyToolbar.tsx
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import * as React from 'react';
+import {
+    Button,
+    ToolbarItem, Tooltip
+} from '@patternfly/react-core';
+import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
+
+interface Props {
+    onClickCreateButton: () => void
+}
+
+export function TopologyToolbar (props: Props) {
+
+    return (
+        <ToolbarItem align={{default: "alignRight"}}>
+            <Tooltip content={"Add new integration"}>
+                <Button size="sm"
+                        variant={"primary"}
+                        icon={<PlusIcon/>}
+                        onClick={e => props.onClickCreateButton()}
+                >
+                    Create
+                </Button>
+            </Tooltip>
+        </ToolbarItem>
+    )
+}
\ No newline at end of file
diff --git a/karavan-vscode/webview/topology/topology.css b/karavan-vscode/webview/topology/topology.css
new file mode 100644
index 00000000..bfd345b7
--- /dev/null
+++ b/karavan-vscode/webview/topology/topology.css
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.karavan .topology-panel .pf-v5-c-toolbar {
+    padding-bottom: 0;
+}
+
+.karavan .topology-panel .pf-v5-c-toolbar .pf-v5-c-toolbar__group{
+    width: 100%
+}
+
+.karavan .topology-panel .properties {
+    padding: 16px;
+    overflow: auto;
+}
+
+.karavan .topology-panel .properties-header {
+    padding: 10px;
+}
+
+.karavan .topology-panel .common-node .icon {
+    height: 32px;
+    width: 32px;
+}
+
+.karavan .topology-sidebar .pf-topology-side-bar__header {
+    margin-right: 0;
+}
+
+.karavan .topology-toolbar {
+    padding: 0;
+}
+
+.karavan .topology-sidebar {
+}
+
+.karavan .topology-sidebar .pf-topology-side-bar__dismiss {
+    display: none;
+}
+
+.karavan .pf-topology-side-bar > .pf-topology-side-bar__header + * {
+    margin-top: 0;
+}
+
+.karavan .topology-sidebar .properties .pf-v5-c-form {
+    pointer-events: none;
+    opacity: 0.7;
+}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/ProjectTopologyTab.tsx b/karavan-web/karavan-app/src/main/webui/src/project/topology/ProjectTopologyTab.tsx
index 9df98a40..935a91e8 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/ProjectTopologyTab.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/topology/ProjectTopologyTab.tsx
@@ -44,6 +44,7 @@ export const ProjectTopologyTab: React.FC = () => {
     return (
         <>
             <TopologyTab
+                hideToolbar={false}
                 files={files.map(f => new IntegrationFile(f.name, f.code))}
                 onClickCreateButton={() => setFile('create')}
                 onSetFile={(fileName) => selectFile(fileName)}
@@ -51,4 +52,4 @@ export const ProjectTopologyTab: React.FC = () => {
             <CreateFileModal types={['INTEGRATION']}/>
         </>
     );
-};
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/topology/TopologyStore.ts b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyStore.ts
index 5bbdf124..3cf5067b 100644
--- a/karavan-web/karavan-app/src/main/webui/src/topology/TopologyStore.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyStore.ts
@@ -39,9 +39,7 @@ export const useTopologyStore = createWithEqualityFn<TopologyState>((set) => ({
     selectedIds: [],
     setSelectedIds: (selectedIds: string[]) => {
         set((state: TopologyState) => {
-            state.selectedIds.length = 0;
-            state.selectedIds.push(...selectedIds);
-            return {selectedIds: state.selectedIds};
+            return {selectedIds: selectedIds};
         });
     },
     setFileName: (fileName?: string) => {
diff --git a/karavan-web/karavan-app/src/main/webui/src/topology/TopologyTab.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
index df48e0c0..520bf8d2 100644
--- a/karavan-web/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
@@ -41,6 +41,7 @@ interface Props {
     files: IntegrationFile[],
     onClickCreateButton: () => void
     onSetFile: (fileName: string) => void
+    hideToolbar: boolean
 }
 
 export function TopologyTab (props: Props) {
@@ -93,7 +94,7 @@ export function TopologyTab (props: Props) {
     return (
         <TopologyView
             className="topology-panel"
-            contextToolbar={<TopologyToolbar onClickCreateButton={props.onClickCreateButton}/>}
+            contextToolbar={!props.hideToolbar? <TopologyToolbar onClickCreateButton={props.onClickCreateButton}/> : undefined}
             sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
                 <TopologyControlBar


[camel-karavan] 01/02: Topology in Designer for #939

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

marat pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-karavan.git

commit 9c953210d84453e8f2d5d06b6086745f2f16dd1f
Author: Marat Gubaidullin <ma...@talismancloud.io>
AuthorDate: Tue Oct 17 08:47:47 2023 -0400

    Topology in Designer for #939
---
 karavan-designer/package-lock.json                 |  152 +-
 karavan-designer/package.json                      |   20 +-
 .../src}/topology/CustomEdge.tsx                   |    4 +-
 .../src}/topology/CustomGroup.tsx                  |    1 -
 .../src}/topology/CustomNode.tsx                   |    4 +-
 .../src}/topology/TopologyApi.tsx                  |    6 +-
 .../src}/topology/TopologyPropertiesPanel.tsx      |   19 +-
 .../src}/topology/TopologyStore.ts                 |   10 +
 .../src}/topology/TopologyTab.tsx                  |   25 +-
 .../src}/topology/TopologyToolbar.tsx              |   12 +-
 .../src}/topology/topology.css                     |    0
 karavan-space/package-lock.json                    | 1612 +++++++++++++++-----
 karavan-space/package.json                         |   22 +-
 karavan-space/src/designer/route/DslElement.tsx    |    4 +-
 .../src}/topology/CustomEdge.tsx                   |    4 +-
 .../src}/topology/CustomGroup.tsx                  |    1 -
 .../src}/topology/CustomNode.tsx                   |    4 +-
 .../src}/topology/TopologyApi.tsx                  |    6 +-
 .../src}/topology/TopologyPropertiesPanel.tsx      |   19 +-
 .../src}/topology/TopologyStore.ts                 |   10 +
 .../src}/topology/TopologyTab.tsx                  |   25 +-
 .../src}/topology/TopologyToolbar.tsx              |   12 +-
 .../src}/topology/topology.css                     |    0
 .../karavan-app/src/main/webui/package-lock.json   |  152 +-
 .../karavan-app/src/main/webui/package.json        |   29 +-
 .../main/webui/src/designer/route/DslElement.tsx   |    4 +-
 .../src/main/webui/src/project/ProjectPanel.tsx    |    9 +-
 ...{TopologyToolbar.tsx => ProjectTopologyTab.tsx} |   48 +-
 .../src/{project => }/topology/CustomEdge.tsx      |    4 +-
 .../src/{project => }/topology/CustomGroup.tsx     |    1 -
 .../src/{project => }/topology/CustomNode.tsx      |    4 +-
 .../src/{project => }/topology/TopologyApi.tsx     |    6 +-
 .../topology/TopologyPropertiesPanel.tsx           |   19 +-
 .../src/{project => }/topology/TopologyStore.ts    |   10 +
 .../src/{project => }/topology/TopologyTab.tsx     |   25 +-
 .../src/{project => }/topology/TopologyToolbar.tsx |   12 +-
 .../webui/src/{project => }/topology/topology.css  |    0
 37 files changed, 1557 insertions(+), 738 deletions(-)

diff --git a/karavan-designer/package-lock.json b/karavan-designer/package-lock.json
index 6e8dc28d..29280923 100644
--- a/karavan-designer/package-lock.json
+++ b/karavan-designer/package-lock.json
@@ -9,23 +9,23 @@
       "version": "4.0.1",
       "license": "Apache-2.0",
       "dependencies": {
-        "@monaco-editor/react": "^4.5.2",
-        "@patternfly/patternfly": "^5.0.2",
-        "@patternfly/react-core": "^5.0.0",
-        "@patternfly/react-table": "^5.0.0",
-        "@patternfly/react-topology": "^5.0.0",
-        "@types/js-yaml": "4.0.5",
+        "@monaco-editor/react": "^4.6.0",
+        "@patternfly/patternfly": "^5.1.0",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-table": "^5.1.1",
+        "@patternfly/react-topology": "^5.1.0",
+        "@types/js-yaml": "4.0.7",
         "@types/node": "18.16.3",
-        "@types/uuid": "9.0.1",
-        "axios": "1.4.0",
+        "@types/uuid": "9.0.5",
+        "axios": "1.5.1",
         "dagre": "0.8.5",
         "html-to-image": "1.11.11",
         "karavan-core": "file:../karavan-core",
         "react": "18.2.0",
         "react-dom": "18.2.0",
         "rxjs": "7.8.1",
-        "uuid": "9.0.0",
-        "zustand": "^4.4.1"
+        "uuid": "9.0.1",
+        "zustand": "^4.4.3"
       },
       "devDependencies": {
         "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
@@ -2097,9 +2097,9 @@
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz",
-      "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==",
+      "version": "7.23.2",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+      "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.22.13",
@@ -3356,9 +3356,9 @@
       "dev": true
     },
     "node_modules/@monaco-editor/loader": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz",
-      "integrity": "sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz",
+      "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
       "dependencies": {
         "state-local": "^1.0.6"
       },
@@ -3367,11 +3367,11 @@
       }
     },
     "node_modules/@monaco-editor/react": {
-      "version": "4.5.2",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.5.2.tgz",
-      "integrity": "sha512-emcWu6vg1OpXPiYll4aPOaXe8bwYB4UaaNTwtArFLgMoNGBzRZb2Xn0Bra2HMIFM7QLgs7fCGunHO5LkfT2LBA==",
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz",
+      "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==",
       "dependencies": {
-        "@monaco-editor/loader": "^1.3.3"
+        "@monaco-editor/loader": "^1.4.0"
       },
       "peerDependencies": {
         "monaco-editor": ">= 0.25.0 < 1",
@@ -3424,19 +3424,19 @@
       }
     },
     "node_modules/@patternfly/patternfly": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz",
-      "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA=="
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.1.0.tgz",
+      "integrity": "sha512-wzVgL/0xPsmuRKWc6lMNEo5gDcTUtyU231eJSBTapOKXiwBOv2flvLEHPYLO6oDYXO+hwUrVgbcZFWMd1UlLwA=="
     },
     "node_modules/@patternfly/react-core": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.1.tgz",
-      "integrity": "sha512-Eevd+8ACLFV733J+cpo4FRgNtRBObIgmUcrqLjf9H99jZ1hFpBgacFyHiALFi2cuoNVGmdEzskFl+4c7Uo0n+w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.1.1.tgz",
+      "integrity": "sha512-9DbgQMXYmF8A4aCNLKXwIN1H07SIPoPaVLvx+yiDuJfDx4Qi0T+H7j5cx0VfDfxuCpqea3POJWqBQn1HnwS4wQ==",
       "dependencies": {
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
-        "focus-trap": "7.4.3",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
+        "focus-trap": "7.5.2",
         "react-dropzone": "^14.2.3",
         "tslib": "^2.5.0"
       },
@@ -3446,28 +3446,28 @@
       }
     },
     "node_modules/@patternfly/react-icons": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.1.tgz",
-      "integrity": "sha512-MduetDRzve3eRlKAioM/UxmVuPyFccdeBWAKhbN4SBn7RaZWS7kO7/xZzNkpeT5pqQIeAACvz3uiV2/3uAf38w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.1.1.tgz",
+      "integrity": "sha512-9gCxkWz2xcdi0rtXu2F0L68w4tLIlsgGTACo1ggr4aVng9jRX++o1PlCOqscOd9o0NiFnFD7BLlZUGvJWaYEZg==",
       "peerDependencies": {
         "react": "^17 || ^18",
         "react-dom": "^17 || ^18"
       }
     },
     "node_modules/@patternfly/react-styles": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz",
-      "integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.1.1.tgz",
+      "integrity": "sha512-swO9X+WixYYDsMVsEJp1V8QUfhEQY91QfFm4phfYP4jc2TQ2opIFYdUIHkc+yrZwBhrgb/pPUUfemyqAoSbZcA=="
     },
     "node_modules/@patternfly/react-table": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.0.1.tgz",
-      "integrity": "sha512-2YbM6XvgG9ubJE4caPQKPMFBkcf7zYzLUFbHnkyfInpWeVNBs/+ZDAP2wnIHce7uaPLnJ1t0FVzGwaD/UuPwkg==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.1.1.tgz",
+      "integrity": "sha512-9tAtHj16hemJ6YRBWIm2O+QRNoFWYQt8ZLQ1G0KBwpg2t2G2CbGsS2RG+BamO4IVE6IPo3Yoo39p4UCNRiGVpA==",
       "dependencies": {
-        "@patternfly/react-core": "^5.0.1",
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
         "lodash": "^4.17.19",
         "tslib": "^2.5.0"
       },
@@ -3477,18 +3477,18 @@
       }
     },
     "node_modules/@patternfly/react-tokens": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz",
-      "integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.1.1.tgz",
+      "integrity": "sha512-cHuNkzNA9IY9aDwfjSEkitQoVEvRhOJRKhH0yIRlRByEkbdoV9jJZ9xj20hNShE+bxmNuom+MCTQSkpkN1bV8A=="
     },
     "node_modules/@patternfly/react-topology": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.0.0.tgz",
-      "integrity": "sha512-DW1dXXff5X+5K3ZW8rn1eqSggGfq5My/BMMcyhO6ankgAxAA4uK96/DbWaUMmSxkeHDSF6tD5jTd/SiglQzR1A==",
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.1.0.tgz",
+      "integrity": "sha512-Qzu7GMxqCsRvQj4RF2AHOGSp0nPpVuDE2xpdAaj/yCKz0cqHhvrwpC4+qyVL3mlqIs5qb+Fxm2d81Do7YIx3ig==",
       "dependencies": {
-        "@patternfly/react-core": "^5.0.0",
-        "@patternfly/react-icons": "^5.0.0",
-        "@patternfly/react-styles": "^5.0.0",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
         "@types/d3": "^7.4.0",
         "@types/d3-force": "^1.2.1",
         "@types/dagre": "0.7.42",
@@ -4382,9 +4382,9 @@
       }
     },
     "node_modules/@types/js-yaml": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz",
-      "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA=="
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.7.tgz",
+      "integrity": "sha512-RJZP9WAMMr1514KbdSXkLRrKvYQacjr1+HWnY8pui/uBTBoSgD9ZGR17u/d4nb9NpERp0FkdLBe7hq8NIPBgkg=="
     },
     "node_modules/@types/json-schema": {
       "version": "7.0.13",
@@ -4543,9 +4543,9 @@
       "dev": true
     },
     "node_modules/@types/uuid": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
-      "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA=="
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.5.tgz",
+      "integrity": "sha512-xfHdwa1FMJ082prjSJpoEI57GZITiQz10r3vEJCHa2khEFQjKy91aWKz6+zybzssCvXUwE1LQWgWVwZ4nYUvHQ=="
     },
     "node_modules/@types/ws": {
       "version": "8.5.6",
@@ -5545,9 +5545,9 @@
       }
     },
     "node_modules/axios": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
-      "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz",
+      "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==",
       "dependencies": {
         "follow-redirects": "^1.15.0",
         "form-data": "^4.0.0",
@@ -9211,11 +9211,11 @@
       "dev": true
     },
     "node_modules/focus-trap": {
-      "version": "7.4.3",
-      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
-      "integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
+      "version": "7.5.2",
+      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz",
+      "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==",
       "dependencies": {
-        "tabbable": "^6.1.2"
+        "tabbable": "^6.2.0"
       }
     },
     "node_modules/follow-redirects": {
@@ -14556,9 +14556,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.30",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz",
-      "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
       "dev": true,
       "funding": [
         {
@@ -18674,9 +18674,13 @@
       }
     },
     "node_modules/uuid": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
-      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
       "bin": {
         "uuid": "dist/bin/uuid"
       }
@@ -19780,9 +19784,9 @@
       }
     },
     "node_modules/zustand": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.1.tgz",
-      "integrity": "sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==",
+      "version": "4.4.3",
+      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.3.tgz",
+      "integrity": "sha512-oRy+X3ZazZvLfmv6viIaQmtLOMeij1noakIsK/Y47PWYhT8glfXzQ4j0YcP5i0P0qI1A4rIB//SGROGyZhx91A==",
       "dependencies": {
         "use-sync-external-store": "1.2.0"
       },
diff --git a/karavan-designer/package.json b/karavan-designer/package.json
index 4f9dd64f..337c4f14 100644
--- a/karavan-designer/package.json
+++ b/karavan-designer/package.json
@@ -26,23 +26,23 @@
     ]
   },
   "dependencies": {
-    "@monaco-editor/react": "^4.5.2",
-    "@patternfly/patternfly": "^5.0.2",
-    "@patternfly/react-core": "^5.0.0",
-    "@patternfly/react-table": "^5.0.0",
-    "@patternfly/react-topology": "^5.0.0",
-    "@types/js-yaml": "4.0.5",
+    "@monaco-editor/react": "^4.6.0",
+    "@patternfly/patternfly": "^5.1.0",
+    "@patternfly/react-core": "^5.1.1",
+    "@patternfly/react-table": "^5.1.1",
+    "@patternfly/react-topology": "^5.1.0",
+    "@types/js-yaml": "4.0.7",
     "@types/node": "18.16.3",
-    "@types/uuid": "9.0.1",
-    "axios": "1.4.0",
+    "@types/uuid": "9.0.5",
+    "axios": "1.5.1",
     "dagre": "0.8.5",
     "html-to-image": "1.11.11",
     "karavan-core": "file:../karavan-core",
     "react": "18.2.0",
     "react-dom": "18.2.0",
     "rxjs": "7.8.1",
-    "uuid": "9.0.0",
-    "zustand": "^4.4.1"
+    "uuid": "9.0.1",
+    "zustand": "^4.4.3"
   },
   "devDependencies": {
     "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx b/karavan-designer/src/topology/CustomEdge.tsx
similarity index 87%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx
copy to karavan-designer/src/topology/CustomEdge.tsx
index 0eb8e0eb..bd4fa92e 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx
+++ b/karavan-designer/src/topology/CustomEdge.tsx
@@ -18,12 +18,10 @@
 import * as React from 'react';
 
 import './topology.css';
-import {DefaultEdge, DefaultGroup, observer} from '@patternfly/react-topology';
+import {DefaultEdge, observer} from '@patternfly/react-topology';
 
 
 const CustomEdge: React.FC<any> = observer(({ element, ...rest }) => {
-    const data = element.getData();
-
     return (
         <DefaultEdge element={element} {...rest}>
         </DefaultEdge>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx b/karavan-designer/src/topology/CustomGroup.tsx
similarity index 94%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx
copy to karavan-designer/src/topology/CustomGroup.tsx
index 7df861ce..9e366c7c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx
+++ b/karavan-designer/src/topology/CustomGroup.tsx
@@ -22,7 +22,6 @@ import { DefaultGroup, observer} from '@patternfly/react-topology';
 
 
 const CustomGroup: React.FC<any> = observer(({ element, ...rest }) => {
-    const data = element.getData();
 
     return (
         <DefaultGroup element={element} {...rest}>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx b/karavan-designer/src/topology/CustomNode.tsx
similarity index 92%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx
copy to karavan-designer/src/topology/CustomNode.tsx
index 12492fdf..2d87457d 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx
+++ b/karavan-designer/src/topology/CustomNode.tsx
@@ -19,8 +19,8 @@ import * as React from 'react';
 import {RegionsIcon} from '@patternfly/react-icons';
 
 import {DefaultNode, observer} from '@patternfly/react-topology';
-import {getDesignerIcon} from "../../designer/utils/KaravanIcons";
-import {CamelUi} from "../../designer/utils/CamelUi";
+import {getDesignerIcon} from "../designer/utils/KaravanIcons";
+import {CamelUi} from "../designer/utils/CamelUi";
 import './topology.css';
 
 function getIcon(data: any) {
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx b/karavan-designer/src/topology/TopologyApi.tsx
similarity index 97%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx
copy to karavan-designer/src/topology/TopologyApi.tsx
index d9ec3ba9..44ff57a2 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx
+++ b/karavan-designer/src/topology/TopologyApi.tsx
@@ -29,7 +29,6 @@ import {
     withPanZoom, withSelection
 } from '@patternfly/react-topology';
 import CustomNode from "./CustomNode";
-import {ProjectFile} from "../../api/ProjectModels";
 import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
 import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
@@ -41,10 +40,11 @@ import {
 } from "karavan-core/lib/model/TopologyDefinition";
 import CustomGroup from "./CustomGroup";
 import CustomEdge from "./CustomEdge";
+import {IntegrationFile} from "./TopologyStore";
 
 const NODE_DIAMETER = 60;
 
-export function getIntegrations(files: ProjectFile[]): Integration[] {
+export function getIntegrations(files: IntegrationFile[]): Integration[] {
     return files.filter((file) => file.name.endsWith(".camel.yaml")).map((file) => {
         return CamelDefinitionYaml.yamlToIntegration(file.name, file.code);
     })
@@ -207,7 +207,7 @@ export function getInternalEdges(tons: TopologyOutgoingNode[], tins: TopologyInc
     return result;
 }
 
-export function getModel(files: ProjectFile[]): Model {
+export function getModel(files: IntegrationFile[]): Model {
     const integrations = getIntegrations(files);
     const tins = TopologyUtils.findTopologyIncomingNodes(integrations);
     const troutes = TopologyUtils.findTopologyRouteNodes(integrations);
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx b/karavan-designer/src/topology/TopologyPropertiesPanel.tsx
similarity index 81%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx
copy to karavan-designer/src/topology/TopologyPropertiesPanel.tsx
index 48aabcd7..24deca24 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-designer/src/topology/TopologyPropertiesPanel.tsx
@@ -15,23 +15,23 @@
  * limitations under the License.
  */
 import React from 'react';
-import '../../designer/karavan.css';
+import '../designer/karavan.css';
 import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
-import {DslProperties} from "../../designer/route/DslProperties";
+import {DslProperties} from "../designer/route/DslProperties";
 import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
-import {useFilesStore, useFileStore} from "../../api/ProjectStore";
 
-export function TopologyPropertiesPanel () {
+interface Props {
+    onSetFile: (fileName: string) => void
+}
+
+export function TopologyPropertiesPanel (props: Props) {
 
-    const [setFile] = useFileStore((s) => [s.setFile], shallow);
-    const [files] = useFilesStore((s) => [s.files], shallow);
     const [selectedIds, setSelectedIds, fileName] = useTopologyStore((s) =>
         [s.selectedIds, s.setSelectedIds, s.fileName], shallow);
 
-
     function getHeader() {
         return (
             <Flex className="properties-header" direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
@@ -41,10 +41,7 @@ export function TopologyPropertiesPanel () {
                 <FlexItem>
                     <Button variant="link" onClick={event => {
                         if (fileName) {
-                            const file = files.filter(f => f.name === fileName)?.at(0);
-                            if (file) {
-                                setFile('select', file);
-                            }
+                            props.onSetFile(fileName);
                         }
                     }}
                     >{fileName}
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts b/karavan-designer/src/topology/TopologyStore.ts
similarity index 89%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts
copy to karavan-designer/src/topology/TopologyStore.ts
index 750d1e16..5bbdf124 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts
+++ b/karavan-designer/src/topology/TopologyStore.ts
@@ -18,6 +18,16 @@
 import {createWithEqualityFn} from "zustand/traditional";
 import {shallow} from "zustand/shallow";
 
+export class IntegrationFile {
+    name: string = '';
+    code: string = '';
+
+    constructor(name: string, code: string) {
+        this.name = name;
+        this.code = code;
+    }
+}
+
 interface TopologyState {
     selectedIds: string []
     fileName?: string
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx b/karavan-designer/src/topology/TopologyTab.tsx
similarity index 88%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx
copy to karavan-designer/src/topology/TopologyTab.tsx
index 22e9dbc4..df48e0c0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx
+++ b/karavan-designer/src/topology/TopologyTab.tsx
@@ -30,16 +30,21 @@ import {
     SELECTION_EVENT, Model,
 } from '@patternfly/react-topology';
 import {customComponentFactory, getModel} from "./TopologyApi";
-import {useFilesStore} from "../../api/ProjectStore";
 import {shallow} from "zustand/shallow";
-import {useTopologyStore} from "./TopologyStore";
+import {IntegrationFile, useTopologyStore} from "./TopologyStore";
 import {TopologyPropertiesPanel} from "./TopologyPropertiesPanel";
 import {TopologyToolbar} from "./TopologyToolbar";
-import {useDesignerStore} from "../../designer/DesignerStore";
+import {useDesignerStore} from "../designer/DesignerStore";
 
-export const TopologyTab: React.FC = () => {
 
-    const [files] = useFilesStore((s) => [s.files], shallow);
+interface Props {
+    files: IntegrationFile[],
+    onClickCreateButton: () => void
+    onSetFile: (fileName: string) => void
+}
+
+export function TopologyTab (props: Props) {
+
     const [selectedIds, setSelectedIds, setFileName] = useTopologyStore((s) =>
         [s.selectedIds, s.setSelectedIds, s.setFileName], shallow);
     const [setSelectedStep] = useDesignerStore((s) => [s.setSelectedStep], shallow)
@@ -62,7 +67,7 @@ export const TopologyTab: React.FC = () => {
     }
 
     const controller = React.useMemo(() => {
-        const model = getModel(files);
+        const model = getModel(props.files);
         const newController = new Visualization();
         newController.registerLayoutFactory((_, graph) => new DagreLayout(graph));
         newController.registerComponentFactory(customComponentFactory);
@@ -81,15 +86,15 @@ export const TopologyTab: React.FC = () => {
 
     React.useEffect(() => {
         setSelectedIds([])
-        const model = getModel(files);
+        const model = getModel(props.files);
         controller.fromModel(model, false);
     }, []);
 
     return (
         <TopologyView
             className="topology-panel"
-            contextToolbar={<TopologyToolbar/>}
-            sideBar={<TopologyPropertiesPanel/>}
+            contextToolbar={<TopologyToolbar onClickCreateButton={props.onClickCreateButton}/>}
+            sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
                 <TopologyControlBar
                     controlButtons={createTopologyControlButtons({
@@ -117,4 +122,4 @@ export const TopologyTab: React.FC = () => {
             </VisualizationProvider>
         </TopologyView>
     );
-};
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx b/karavan-designer/src/topology/TopologyToolbar.tsx
similarity index 78%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
copy to karavan-designer/src/topology/TopologyToolbar.tsx
index f77abafe..2d9fc55c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
+++ b/karavan-designer/src/topology/TopologyToolbar.tsx
@@ -20,14 +20,13 @@ import {
     Button,
     ToolbarItem, Tooltip
 } from '@patternfly/react-core';
-import { useFileStore} from "../../api/ProjectStore";
-import {shallow} from "zustand/shallow";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {CreateFileModal} from "../files/CreateFileModal";
 
-export const TopologyToolbar: React.FC = () => {
+interface Props {
+    onClickCreateButton: () => void
+}
 
-    const [setFile] = useFileStore((s) => [s.setFile], shallow);
+export function TopologyToolbar (props: Props) {
 
     return (
         <ToolbarItem align={{default: "alignRight"}}>
@@ -35,12 +34,11 @@ export const TopologyToolbar: React.FC = () => {
                 <Button size="sm"
                         variant={"primary"}
                         icon={<PlusIcon/>}
-                        onClick={e => setFile("create")}
+                        onClick={e => props.onClickCreateButton()}
                 >
                     Create
                 </Button>
             </Tooltip>
-            <CreateFileModal types={['INTEGRATION']}/>
         </ToolbarItem>
     )
 }
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/topology.css b/karavan-designer/src/topology/topology.css
similarity index 100%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/topology.css
copy to karavan-designer/src/topology/topology.css
diff --git a/karavan-space/package-lock.json b/karavan-space/package-lock.json
index d496d57c..8c70eb79 100644
--- a/karavan-space/package-lock.json
+++ b/karavan-space/package-lock.json
@@ -9,25 +9,26 @@
       "version": "4.0.1",
       "license": "Apache-2.0",
       "dependencies": {
-        "@monaco-editor/react": "4.5.0",
-        "@patternfly/patternfly": "^5.0.2",
-        "@patternfly/react-core": "^5.0.0",
-        "@patternfly/react-table": "^5.0.0",
+        "@monaco-editor/react": "4.6.0",
+        "@patternfly/patternfly": "^5.1.0",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-table": "^5.1.1",
+        "@patternfly/react-topology": "^5.1.0",
         "@types/js-yaml": "4.0.5",
         "@types/node": "18.15.3",
-        "@types/uuid": "9.0.1",
-        "axios": "1.4.0",
+        "@types/uuid": "9.0.5",
+        "axios": "1.5.1",
         "dagre": "0.8.5",
         "html-to-image": "1.11.11",
         "karavan-core": "file:../karavan-core",
         "netlify-auth-providers": "^1.0.0-alpha5",
-        "octokit": "^2.0.10",
+        "octokit": "^3.1.1",
         "react": "18.2.0",
         "react-dom": "18.2.0",
         "react-scripts": "5.0.1",
         "rxjs": "7.8.1",
-        "uuid": "9.0.0",
-        "zustand": "^4.4.1"
+        "uuid": "9.0.1",
+        "zustand": "^4.4.3"
       },
       "devDependencies": {
         "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
@@ -1970,9 +1971,9 @@
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.23.0",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.0.tgz",
-      "integrity": "sha512-t/QaEvyIoIkwzpiZ7aoSKK8kObQYeF7T2v+dazAYCb8SXtp58zEVkWW7zAnju8FNKNdr4ScAOEDmMItbyOmEYw==",
+      "version": "7.23.2",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+      "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
       "dependencies": {
         "@babel/code-frame": "^7.22.13",
         "@babel/generator": "^7.23.0",
@@ -3138,9 +3139,9 @@
       "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A=="
     },
     "node_modules/@monaco-editor/loader": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz",
-      "integrity": "sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz",
+      "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
       "dependencies": {
         "state-local": "^1.0.6"
       },
@@ -3149,11 +3150,11 @@
       }
     },
     "node_modules/@monaco-editor/react": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.5.0.tgz",
-      "integrity": "sha512-VJMkp5Fe1+w8pLEq8tZPHZKu8zDXQIA1FtiDTSNccg1D3wg1YIZaH2es2Qpvop1k62g3c/YySRb3bnGXu2XwYQ==",
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz",
+      "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==",
       "dependencies": {
-        "@monaco-editor/loader": "^1.3.3"
+        "@monaco-editor/loader": "^1.4.0"
       },
       "peerDependencies": {
         "monaco-editor": ">= 0.25.0 < 1",
@@ -3202,356 +3203,365 @@
       }
     },
     "node_modules/@octokit/app": {
-      "version": "13.1.8",
-      "resolved": "https://registry.npmjs.org/@octokit/app/-/app-13.1.8.tgz",
-      "integrity": "sha512-bCncePMguVyFpdBbnceFKfmPOuUD94T189GuQ0l00ZcQ+mX4hyPqnaWJlsXE2HSdA71eV7p8GPDZ+ErplTkzow==",
+      "version": "14.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/app/-/app-14.0.1.tgz",
+      "integrity": "sha512-4opdXcWBVhzd6FOxlaxDKXXqi9Vz2hsDSWQGNo49HbYFAX11UqMpksMjEdfvHy0x19Pse8Nvn+R6inNb/V398w==",
       "dependencies": {
-        "@octokit/auth-app": "^4.0.13",
-        "@octokit/auth-unauthenticated": "^3.0.0",
-        "@octokit/core": "^4.0.0",
-        "@octokit/oauth-app": "^4.0.7",
-        "@octokit/plugin-paginate-rest": "^6.0.0",
-        "@octokit/types": "^9.0.0",
-        "@octokit/webhooks": "^10.0.0"
+        "@octokit/auth-app": "^6.0.0",
+        "@octokit/auth-unauthenticated": "^5.0.0",
+        "@octokit/core": "^5.0.0",
+        "@octokit/oauth-app": "^6.0.0",
+        "@octokit/plugin-paginate-rest": "^9.0.0",
+        "@octokit/types": "^12.0.0",
+        "@octokit/webhooks": "^12.0.1"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/auth-app": {
-      "version": "4.0.13",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.13.tgz",
-      "integrity": "sha512-NBQkmR/Zsc+8fWcVIFrwDgNXS7f4XDrkd9LHdi9DPQw1NdGHLviLzRO2ZBwTtepnwHXW5VTrVU9eFGijMUqllg==",
-      "dependencies": {
-        "@octokit/auth-oauth-app": "^5.0.0",
-        "@octokit/auth-oauth-user": "^2.0.0",
-        "@octokit/request": "^6.0.0",
-        "@octokit/request-error": "^3.0.0",
-        "@octokit/types": "^9.0.0",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-6.0.1.tgz",
+      "integrity": "sha512-tjCD4nzQNZgmLH62+PSnTF6eGerisFgV4v6euhqJik6yWV96e1ZiiGj+NXIqbgnpjLmtnBqVUrNyGKu3DoGEGA==",
+      "dependencies": {
+        "@octokit/auth-oauth-app": "^7.0.0",
+        "@octokit/auth-oauth-user": "^4.0.0",
+        "@octokit/request": "^8.0.2",
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/types": "^12.0.0",
         "deprecation": "^2.3.1",
-        "lru-cache": "^9.0.0",
+        "lru-cache": "^10.0.0",
         "universal-github-app-jwt": "^1.1.1",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/auth-app/node_modules/lru-cache": {
-      "version": "9.1.2",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz",
-      "integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==",
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.1.tgz",
+      "integrity": "sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g==",
       "engines": {
         "node": "14 || >=16.14"
       }
     },
     "node_modules/@octokit/auth-oauth-app": {
-      "version": "5.0.6",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.6.tgz",
-      "integrity": "sha512-SxyfIBfeFcWd9Z/m1xa4LENTQ3l1y6Nrg31k2Dcb1jS5ov7pmwMJZ6OGX8q3K9slRgVpeAjNA1ipOAMHkieqyw==",
-      "dependencies": {
-        "@octokit/auth-oauth-device": "^4.0.0",
-        "@octokit/auth-oauth-user": "^2.0.0",
-        "@octokit/request": "^6.0.0",
-        "@octokit/types": "^9.0.0",
+      "version": "7.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-7.0.1.tgz",
+      "integrity": "sha512-RE0KK0DCjCHXHlQBoubwlLijXEKfhMhKm9gO56xYvFmP1QTMb+vvwRPmQLLx0V+5AvV9N9I3lr1WyTzwL3rMDg==",
+      "dependencies": {
+        "@octokit/auth-oauth-device": "^6.0.0",
+        "@octokit/auth-oauth-user": "^4.0.0",
+        "@octokit/request": "^8.0.2",
+        "@octokit/types": "^12.0.0",
         "@types/btoa-lite": "^1.0.0",
         "btoa-lite": "^1.0.0",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/auth-oauth-device": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-4.0.5.tgz",
-      "integrity": "sha512-XyhoWRTzf2ZX0aZ52a6Ew5S5VBAfwwx1QnC2Np6Et3MWQpZjlREIcbcvVZtkNuXp6Z9EeiSLSDUqm3C+aMEHzQ==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-device/-/auth-oauth-device-6.0.1.tgz",
+      "integrity": "sha512-yxU0rkL65QkjbqQedgVx3gmW7YM5fF+r5uaSj9tM/cQGVqloXcqP2xK90eTyYvl29arFVCW8Vz4H/t47mL0ELw==",
       "dependencies": {
-        "@octokit/oauth-methods": "^2.0.0",
-        "@octokit/request": "^6.0.0",
-        "@octokit/types": "^9.0.0",
+        "@octokit/oauth-methods": "^4.0.0",
+        "@octokit/request": "^8.0.0",
+        "@octokit/types": "^12.0.0",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/auth-oauth-user": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.1.2.tgz",
-      "integrity": "sha512-kkRqNmFe7s5GQcojE3nSlF+AzYPpPv7kvP/xYEnE57584pixaFBH8Vovt+w5Y3E4zWUEOxjdLItmBTFAWECPAg==",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-4.0.1.tgz",
+      "integrity": "sha512-N94wWW09d0hleCnrO5wt5MxekatqEJ4zf+1vSe8MKMrhZ7gAXKFOKrDEZW2INltvBWJCyDUELgGRv8gfErH1Iw==",
       "dependencies": {
-        "@octokit/auth-oauth-device": "^4.0.0",
-        "@octokit/oauth-methods": "^2.0.0",
-        "@octokit/request": "^6.0.0",
-        "@octokit/types": "^9.0.0",
+        "@octokit/auth-oauth-device": "^6.0.0",
+        "@octokit/oauth-methods": "^4.0.0",
+        "@octokit/request": "^8.0.2",
+        "@octokit/types": "^12.0.0",
         "btoa-lite": "^1.0.0",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/auth-token": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz",
-      "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
+      "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/auth-unauthenticated": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-3.0.5.tgz",
-      "integrity": "sha512-yH2GPFcjrTvDWPwJWWCh0tPPtTL5SMgivgKPA+6v/XmYN6hGQkAto8JtZibSKOpf8ipmeYhLNWQ2UgW0GYILCw==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/auth-unauthenticated/-/auth-unauthenticated-5.0.1.tgz",
+      "integrity": "sha512-oxeWzmBFxWd+XolxKTc4zr+h3mt+yofn4r7OfoIkR/Cj/o70eEGmPsFbueyJE2iBAGpjgTnEOKM3pnuEGVmiqg==",
       "dependencies": {
-        "@octokit/request-error": "^3.0.0",
-        "@octokit/types": "^9.0.0"
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/types": "^12.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/core": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz",
-      "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==",
-      "dependencies": {
-        "@octokit/auth-token": "^3.0.0",
-        "@octokit/graphql": "^5.0.0",
-        "@octokit/request": "^6.0.0",
-        "@octokit/request-error": "^3.0.0",
-        "@octokit/types": "^9.0.0",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz",
+      "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==",
+      "dependencies": {
+        "@octokit/auth-token": "^4.0.0",
+        "@octokit/graphql": "^7.0.0",
+        "@octokit/request": "^8.0.2",
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/types": "^12.0.0",
         "before-after-hook": "^2.2.0",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/endpoint": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz",
-      "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==",
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz",
+      "integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==",
       "dependencies": {
-        "@octokit/types": "^9.0.0",
+        "@octokit/types": "^12.0.0",
         "is-plain-object": "^5.0.0",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/graphql": {
-      "version": "5.0.6",
-      "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz",
-      "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==",
+      "version": "7.0.2",
+      "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz",
+      "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==",
       "dependencies": {
-        "@octokit/request": "^6.0.0",
-        "@octokit/types": "^9.0.0",
+        "@octokit/request": "^8.0.1",
+        "@octokit/types": "^12.0.0",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/oauth-app": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-4.2.4.tgz",
-      "integrity": "sha512-iuOVFrmm5ZKNavRtYu5bZTtmlKLc5uVgpqTfMEqYYf2OkieV6VdxKZAb5qLVdEPL8LU2lMWcGpavPBV835cgoA==",
-      "dependencies": {
-        "@octokit/auth-oauth-app": "^5.0.0",
-        "@octokit/auth-oauth-user": "^2.0.0",
-        "@octokit/auth-unauthenticated": "^3.0.0",
-        "@octokit/core": "^4.0.0",
-        "@octokit/oauth-authorization-url": "^5.0.0",
-        "@octokit/oauth-methods": "^2.0.0",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-app/-/oauth-app-6.0.0.tgz",
+      "integrity": "sha512-bNMkS+vJ6oz2hCyraT9ZfTpAQ8dZNqJJQVNaKjPLx4ue5RZiFdU1YWXguOPR8AaSHS+lKe+lR3abn2siGd+zow==",
+      "dependencies": {
+        "@octokit/auth-oauth-app": "^7.0.0",
+        "@octokit/auth-oauth-user": "^4.0.0",
+        "@octokit/auth-unauthenticated": "^5.0.0",
+        "@octokit/core": "^5.0.0",
+        "@octokit/oauth-authorization-url": "^6.0.2",
+        "@octokit/oauth-methods": "^4.0.0",
         "@types/aws-lambda": "^8.10.83",
-        "fromentries": "^1.3.1",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/oauth-authorization-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-5.0.0.tgz",
-      "integrity": "sha512-y1WhN+ERDZTh0qZ4SR+zotgsQUE1ysKnvBt1hvDRB2WRzYtVKQjn97HEPzoehh66Fj9LwNdlZh+p6TJatT0zzg==",
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-authorization-url/-/oauth-authorization-url-6.0.2.tgz",
+      "integrity": "sha512-CdoJukjXXxqLNK4y/VOiVzQVjibqoj/xHgInekviUJV73y/BSIcwvJ/4aNHPBPKcPWFnd4/lO9uqRV65jXhcLA==",
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/oauth-methods": {
-      "version": "2.0.6",
-      "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-2.0.6.tgz",
-      "integrity": "sha512-l9Uml2iGN2aTWLZcm8hV+neBiFXAQ9+3sKiQe/sgumHlL6HDg0AQ8/l16xX/5jJvfxueqTW5CWbzd0MjnlfHZw==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/oauth-methods/-/oauth-methods-4.0.0.tgz",
+      "integrity": "sha512-dqy7BZLfLbi3/8X8xPKUKZclMEK9vN3fK5WF3ortRvtplQTszFvdAGbTo71gGLO+4ZxspNiLjnqdd64Chklf7w==",
       "dependencies": {
-        "@octokit/oauth-authorization-url": "^5.0.0",
-        "@octokit/request": "^6.2.3",
-        "@octokit/request-error": "^3.0.3",
-        "@octokit/types": "^9.0.0",
+        "@octokit/oauth-authorization-url": "^6.0.2",
+        "@octokit/request": "^8.0.2",
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/types": "^11.0.0",
         "btoa-lite": "^1.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
-    "node_modules/@octokit/openapi-types": {
+    "node_modules/@octokit/oauth-methods/node_modules/@octokit/openapi-types": {
       "version": "18.1.1",
       "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz",
       "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw=="
     },
-    "node_modules/@octokit/plugin-paginate-rest": {
-      "version": "6.1.2",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz",
-      "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==",
+    "node_modules/@octokit/oauth-methods/node_modules/@octokit/types": {
+      "version": "11.1.0",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz",
+      "integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==",
       "dependencies": {
-        "@octokit/tsconfig": "^1.0.2",
-        "@octokit/types": "^9.2.3"
-      },
+        "@octokit/openapi-types": "^18.0.0"
+      }
+    },
+    "node_modules/@octokit/openapi-types": {
+      "version": "19.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz",
+      "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw=="
+    },
+    "node_modules/@octokit/plugin-paginate-graphql": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-graphql/-/plugin-paginate-graphql-4.0.0.tgz",
+      "integrity": "sha512-7HcYW5tP7/Z6AETAPU14gp5H5KmCPT3hmJrS/5tO7HIgbwenYmgw4OY9Ma54FDySuxMwD+wsJlxtuGWwuZuItA==",
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       },
       "peerDependencies": {
-        "@octokit/core": ">=4"
+        "@octokit/core": ">=5"
       }
     },
-    "node_modules/@octokit/plugin-rest-endpoint-methods": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz",
-      "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==",
+    "node_modules/@octokit/plugin-paginate-rest": {
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz",
+      "integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==",
       "dependencies": {
-        "@octokit/types": "^10.0.0"
+        "@octokit/types": "^12.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       },
       "peerDependencies": {
-        "@octokit/core": ">=3"
+        "@octokit/core": ">=5"
       }
     },
-    "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": {
-      "version": "10.0.0",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz",
-      "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==",
+    "node_modules/@octokit/plugin-rest-endpoint-methods": {
+      "version": "10.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.1.tgz",
+      "integrity": "sha512-fgS6HPkPvJiz8CCliewLyym9qAx0RZ/LKh3sATaPfM41y/O2wQ4Z9MrdYeGPVh04wYmHFmWiGlKPC7jWVtZXQA==",
       "dependencies": {
-        "@octokit/openapi-types": "^18.0.0"
+        "@octokit/types": "^12.0.0"
+      },
+      "engines": {
+        "node": ">= 18"
+      },
+      "peerDependencies": {
+        "@octokit/core": ">=5"
       }
     },
     "node_modules/@octokit/plugin-retry": {
-      "version": "4.1.6",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-4.1.6.tgz",
-      "integrity": "sha512-obkYzIgEC75r8+9Pnfiiqy3y/x1bc3QLE5B7qvv9wi9Kj0R5tGQFC6QMBg1154WQ9lAVypuQDGyp3hNpp15gQQ==",
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz",
+      "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==",
       "dependencies": {
-        "@octokit/types": "^9.0.0",
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/types": "^12.0.0",
         "bottleneck": "^2.15.3"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       },
       "peerDependencies": {
-        "@octokit/core": ">=3"
+        "@octokit/core": ">=5"
       }
     },
     "node_modules/@octokit/plugin-throttling": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-5.2.3.tgz",
-      "integrity": "sha512-C9CFg9mrf6cugneKiaI841iG8DOv6P5XXkjmiNNut+swePxQ7RWEdAZRp5rJoE1hjsIqiYcKa/ZkOQ+ujPI39Q==",
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.0.0.tgz",
+      "integrity": "sha512-OkMbHYUidj81q92YRkPzWmwXkEtsI3KOcSkNm763aqUOh9IEplyX05XjKAdZFANAvaYH0Q4JBZwu4h2VnPVXZA==",
       "dependencies": {
-        "@octokit/types": "^9.0.0",
+        "@octokit/types": "^12.0.0",
         "bottleneck": "^2.15.3"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       },
       "peerDependencies": {
-        "@octokit/core": "^4.0.0"
+        "@octokit/core": "^5.0.0"
       }
     },
     "node_modules/@octokit/request": {
-      "version": "6.2.8",
-      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz",
-      "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==",
+      "version": "8.1.4",
+      "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.4.tgz",
+      "integrity": "sha512-M0aaFfpGPEKrg7XoA/gwgRvc9MSXHRO2Ioki1qrPDbl1e9YhjIwVoHE7HIKmv/m3idzldj//xBujcFNqGX6ENA==",
       "dependencies": {
-        "@octokit/endpoint": "^7.0.0",
-        "@octokit/request-error": "^3.0.0",
-        "@octokit/types": "^9.0.0",
+        "@octokit/endpoint": "^9.0.0",
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/types": "^12.0.0",
         "is-plain-object": "^5.0.0",
-        "node-fetch": "^2.6.7",
         "universal-user-agent": "^6.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/request-error": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz",
-      "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==",
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz",
+      "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==",
       "dependencies": {
-        "@octokit/types": "^9.0.0",
+        "@octokit/types": "^12.0.0",
         "deprecation": "^2.0.0",
         "once": "^1.4.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
-    "node_modules/@octokit/tsconfig": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz",
-      "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA=="
-    },
     "node_modules/@octokit/types": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz",
-      "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==",
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz",
+      "integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==",
       "dependencies": {
-        "@octokit/openapi-types": "^18.0.0"
+        "@octokit/openapi-types": "^19.0.0"
       }
     },
     "node_modules/@octokit/webhooks": {
-      "version": "10.9.1",
-      "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-10.9.1.tgz",
-      "integrity": "sha512-5NXU4VfsNOo2VSU/SrLrpPH2Z1ZVDOWFcET4EpnEBX1uh/v8Uz65UVuHIRx5TZiXhnWyRE9AO1PXHa+M/iWwZA==",
+      "version": "12.0.3",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-12.0.3.tgz",
+      "integrity": "sha512-8iG+/yza7hwz1RrQ7i7uGpK2/tuItZxZq1aTmeg2TNp2xTUB8F8lZF/FcZvyyAxT8tpDMF74TjFGCDACkf1kAQ==",
       "dependencies": {
-        "@octokit/request-error": "^3.0.0",
-        "@octokit/webhooks-methods": "^3.0.0",
-        "@octokit/webhooks-types": "6.11.0",
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/webhooks-methods": "^4.0.0",
+        "@octokit/webhooks-types": "7.1.0",
         "aggregate-error": "^3.1.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/webhooks-methods": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-3.0.3.tgz",
-      "integrity": "sha512-2vM+DCNTJ5vL62O5LagMru6XnYhV4fJslK+5YUkTa6rWlW2S+Tqs1lF9Wr9OGqHfVwpBj3TeztWfVON/eUoW1Q==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-4.0.0.tgz",
+      "integrity": "sha512-M8mwmTXp+VeolOS/kfRvsDdW+IO0qJ8kYodM/sAysk093q6ApgmBXwK1ZlUvAwXVrp/YVHp6aArj4auAxUAOFw==",
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/@octokit/webhooks-types": {
-      "version": "6.11.0",
-      "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-6.11.0.tgz",
-      "integrity": "sha512-AanzbulOHljrku1NGfafxdpTCfw2ENaWzH01N2vqQM+cUFbk868Cgh0xylz0JIM9BoKbfI++bdD6EYX0Q/UTEw=="
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-7.1.0.tgz",
+      "integrity": "sha512-y92CpG4kFFtBBjni8LHoV12IegJ+KFxLgKRengrVjKmGE5XMeCuGvlfRe75lTRrgXaG6XIWJlFpIDTlkoJsU8w=="
     },
     "node_modules/@patternfly/patternfly": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz",
-      "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA=="
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.1.0.tgz",
+      "integrity": "sha512-wzVgL/0xPsmuRKWc6lMNEo5gDcTUtyU231eJSBTapOKXiwBOv2flvLEHPYLO6oDYXO+hwUrVgbcZFWMd1UlLwA=="
     },
     "node_modules/@patternfly/react-core": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.1.tgz",
-      "integrity": "sha512-Eevd+8ACLFV733J+cpo4FRgNtRBObIgmUcrqLjf9H99jZ1hFpBgacFyHiALFi2cuoNVGmdEzskFl+4c7Uo0n+w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.1.1.tgz",
+      "integrity": "sha512-9DbgQMXYmF8A4aCNLKXwIN1H07SIPoPaVLvx+yiDuJfDx4Qi0T+H7j5cx0VfDfxuCpqea3POJWqBQn1HnwS4wQ==",
       "dependencies": {
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
-        "focus-trap": "7.4.3",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
+        "focus-trap": "7.5.2",
         "react-dropzone": "^14.2.3",
         "tslib": "^2.5.0"
       },
@@ -3561,28 +3571,28 @@
       }
     },
     "node_modules/@patternfly/react-icons": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.1.tgz",
-      "integrity": "sha512-MduetDRzve3eRlKAioM/UxmVuPyFccdeBWAKhbN4SBn7RaZWS7kO7/xZzNkpeT5pqQIeAACvz3uiV2/3uAf38w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.1.1.tgz",
+      "integrity": "sha512-9gCxkWz2xcdi0rtXu2F0L68w4tLIlsgGTACo1ggr4aVng9jRX++o1PlCOqscOd9o0NiFnFD7BLlZUGvJWaYEZg==",
       "peerDependencies": {
         "react": "^17 || ^18",
         "react-dom": "^17 || ^18"
       }
     },
     "node_modules/@patternfly/react-styles": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz",
-      "integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.1.1.tgz",
+      "integrity": "sha512-swO9X+WixYYDsMVsEJp1V8QUfhEQY91QfFm4phfYP4jc2TQ2opIFYdUIHkc+yrZwBhrgb/pPUUfemyqAoSbZcA=="
     },
     "node_modules/@patternfly/react-table": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.0.1.tgz",
-      "integrity": "sha512-2YbM6XvgG9ubJE4caPQKPMFBkcf7zYzLUFbHnkyfInpWeVNBs/+ZDAP2wnIHce7uaPLnJ1t0FVzGwaD/UuPwkg==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.1.1.tgz",
+      "integrity": "sha512-9tAtHj16hemJ6YRBWIm2O+QRNoFWYQt8ZLQ1G0KBwpg2t2G2CbGsS2RG+BamO4IVE6IPo3Yoo39p4UCNRiGVpA==",
       "dependencies": {
-        "@patternfly/react-core": "^5.0.1",
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
         "lodash": "^4.17.19",
         "tslib": "^2.5.0"
       },
@@ -3592,9 +3602,51 @@
       }
     },
     "node_modules/@patternfly/react-tokens": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz",
-      "integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.1.1.tgz",
+      "integrity": "sha512-cHuNkzNA9IY9aDwfjSEkitQoVEvRhOJRKhH0yIRlRByEkbdoV9jJZ9xj20hNShE+bxmNuom+MCTQSkpkN1bV8A=="
+    },
+    "node_modules/@patternfly/react-topology": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.1.0.tgz",
+      "integrity": "sha512-Qzu7GMxqCsRvQj4RF2AHOGSp0nPpVuDE2xpdAaj/yCKz0cqHhvrwpC4+qyVL3mlqIs5qb+Fxm2d81Do7YIx3ig==",
+      "dependencies": {
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@types/d3": "^7.4.0",
+        "@types/d3-force": "^1.2.1",
+        "@types/dagre": "0.7.42",
+        "@types/react-measure": "^2.0.6",
+        "d3": "^7.8.0",
+        "dagre": "0.8.2",
+        "lodash": "^4.17.19",
+        "mobx": "^6.9.0",
+        "mobx-react": "^7.6.0",
+        "point-in-svg-path": "^1.0.1",
+        "popper.js": "^1.16.1",
+        "react-measure": "^2.3.0",
+        "tslib": "^2.0.0",
+        "webcola": "3.4.0"
+      },
+      "peerDependencies": {
+        "react": "^17 || ^18",
+        "react-dom": "^17 || ^18"
+      }
+    },
+    "node_modules/@patternfly/react-topology/node_modules/@types/dagre": {
+      "version": "0.7.42",
+      "resolved": "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.42.tgz",
+      "integrity": "sha512-knVdi1Ul8xYgJ0wdhQ+/2YGJFKJFa/5srcPII9zvOs4KhsHfpnFrSTQXATYmjslglxRMif3Lg+wEZ0beag+94A=="
+    },
+    "node_modules/@patternfly/react-topology/node_modules/dagre": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.2.tgz",
+      "integrity": "sha512-TEOOGZOkCOgCG7AoUIq64sJ3d21SMv8tyoqteLpX+UsUsS9Qw8iap4hhogXY4oB3r0bbZuAjO0atAilgCmsE0Q==",
+      "dependencies": {
+        "graphlib": "^2.1.5",
+        "lodash": "^4.17.4"
+      }
     },
     "node_modules/@pmmmwh/react-refresh-webpack-plugin": {
       "version": "0.5.11",
@@ -4012,9 +4064,9 @@
       }
     },
     "node_modules/@types/aws-lambda": {
-      "version": "8.10.122",
-      "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.122.tgz",
-      "integrity": "sha512-vBkIh9AY22kVOCEKo5CJlyCgmSWvasC+SWUxL/x/vOwRobMpI/HG1xp/Ae3AqmSiZeLUbOhW0FCD3ZjqqUxmXw=="
+      "version": "8.10.124",
+      "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.124.tgz",
+      "integrity": "sha512-PHqK0SuAkFS3tZjceqRXecxxrWIN3VqTicuialtK2wZmvBy7H9WGc3u3+wOgaZB7N8SpSXDpWk9qa7eorpTStg=="
     },
     "node_modules/@types/babel__core": {
       "version": "7.20.2",
@@ -4092,6 +4144,228 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/d3": {
+      "version": "7.4.1",
+      "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.1.tgz",
+      "integrity": "sha512-lBpYmbHTCtFKO1DB1R7E9dXp9/g1F3JXSGOF7iKPZ+wRmYg/Q6tCRHODGOc5Qk25fJRe2PI60EDRf2HLPUncMA==",
+      "dependencies": {
+        "@types/d3-array": "*",
+        "@types/d3-axis": "*",
+        "@types/d3-brush": "*",
+        "@types/d3-chord": "*",
+        "@types/d3-color": "*",
+        "@types/d3-contour": "*",
+        "@types/d3-delaunay": "*",
+        "@types/d3-dispatch": "*",
+        "@types/d3-drag": "*",
+        "@types/d3-dsv": "*",
+        "@types/d3-ease": "*",
+        "@types/d3-fetch": "*",
+        "@types/d3-force": "*",
+        "@types/d3-format": "*",
+        "@types/d3-geo": "*",
+        "@types/d3-hierarchy": "*",
+        "@types/d3-interpolate": "*",
+        "@types/d3-path": "*",
+        "@types/d3-polygon": "*",
+        "@types/d3-quadtree": "*",
+        "@types/d3-random": "*",
+        "@types/d3-scale": "*",
+        "@types/d3-scale-chromatic": "*",
+        "@types/d3-selection": "*",
+        "@types/d3-shape": "*",
+        "@types/d3-time": "*",
+        "@types/d3-time-format": "*",
+        "@types/d3-timer": "*",
+        "@types/d3-transition": "*",
+        "@types/d3-zoom": "*"
+      }
+    },
+    "node_modules/@types/d3-array": {
+      "version": "3.0.8",
+      "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.0.8.tgz",
+      "integrity": "sha512-2xAVyAUgaXHX9fubjcCbGAUOqYfRJN1em1EKR2HfzWBpObZhwfnZKvofTN4TplMqJdFQao61I+NVSai/vnBvDQ=="
+    },
+    "node_modules/@types/d3-axis": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.4.tgz",
+      "integrity": "sha512-ySnjI/7qm+J602VjcejXcqs1hEuu5UBbGaJGp+Cn/yKVc1iS3JueLVpToGdQsS2sqta7tqA/kG4ore/+LH90UA==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-brush": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.4.tgz",
+      "integrity": "sha512-Kg5uIsdJNMCs5lTqeZFsTKqj9lBvpiFRDkYN3j2CDlPhonNDg9/gXVpv1E/MKh3tEqArryIj9o6RBGE/MQe+6Q==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-chord": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.4.tgz",
+      "integrity": "sha512-p4PvN1N+7GL3Y/NI9Ug1TKwowUV6h664kmxL79ctp1HRYCk1mhP0+SXhjRsoWXCdnJfbLLLmpV99rt8dMrHrzg=="
+    },
+    "node_modules/@types/d3-color": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.1.tgz",
+      "integrity": "sha512-CSAVrHAtM9wfuLJ2tpvvwCU/F22sm7rMHNN+yh9D6O6hyAms3+O0cgMpC1pm6UEUMOntuZC8bMt74PteiDUdCg=="
+    },
+    "node_modules/@types/d3-contour": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.4.tgz",
+      "integrity": "sha512-B0aeX8Xg3MNUglULxqDvlgY1SVXuN2xtEleYSAY0iMhl/SMVT7snzgAveejjwM3KaWuNXIoXEJ7dmXE8oPq/jA==",
+      "dependencies": {
+        "@types/d3-array": "*",
+        "@types/geojson": "*"
+      }
+    },
+    "node_modules/@types/d3-delaunay": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.2.tgz",
+      "integrity": "sha512-WplUJ/OHU7eITneDqNnzK+2pgR+WDzUHG6XAUVo+oWHPQq74VcgUdw8a4ODweaZzF56OVYK+x9GxCyuq6hSu1A=="
+    },
+    "node_modules/@types/d3-dispatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.4.tgz",
+      "integrity": "sha512-NApHpGHRNxUy7e2Lfzl/cwOucmn4Xdx6FdmXzAoomo8T81LyGmlBjjko/vP0TVzawlvEFLDq8OCRLulW6DDzKw=="
+    },
+    "node_modules/@types/d3-drag": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.4.tgz",
+      "integrity": "sha512-/t53K1erTuUbP7WIX9SE0hlmytpTYRbIthlhbGkBHzCV5vPO++7yrk8OlisWPyIJO5TGowTmqCtGH2tokY5T/g==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-dsv": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.4.tgz",
+      "integrity": "sha512-YxfUVJ55HxR8oq88136w09mBMPNhgH7PZjteq72onWXWOohGif/cLQnQv8V4A5lEGjXF04LhwSTpmzpY9wyVyA=="
+    },
+    "node_modules/@types/d3-ease": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.0.tgz",
+      "integrity": "sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA=="
+    },
+    "node_modules/@types/d3-fetch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.4.tgz",
+      "integrity": "sha512-RleYajubALkGjrvatxWhlygfvB1KNF0Uzz9guRUeeA+M/2B7l8rxObYdktaX9zU1st04lMCHjZWe4vbl+msH2Q==",
+      "dependencies": {
+        "@types/d3-dsv": "*"
+      }
+    },
+    "node_modules/@types/d3-force": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-1.2.5.tgz",
+      "integrity": "sha512-1TB2IqtkPXsr7zUgPORayl2xsl28X4WMwlpaw2BLKTQpJ5ePO1t6TkM4spbTwoqc6dWipVTwg0gdOVrbzGQPNQ=="
+    },
+    "node_modules/@types/d3-format": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.2.tgz",
+      "integrity": "sha512-9oQWvKk2qVBo49FQq8yD/et8Lx0W5Ac2FdGSOUecqOFKqh0wkpyHqf9Qc7A06ftTR+Lz13Pi3jHIQis0aCueOA=="
+    },
+    "node_modules/@types/d3-geo": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.0.5.tgz",
+      "integrity": "sha512-ysEEU93Wv9p2UZBxTK3kUP7veHgyhTA0qYtI7bxK5EMXb3JxGv0D4IH54PxprAF26n+uHci24McVmzwIdLgvgQ==",
+      "dependencies": {
+        "@types/geojson": "*"
+      }
+    },
+    "node_modules/@types/d3-hierarchy": {
+      "version": "3.1.4",
+      "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.4.tgz",
+      "integrity": "sha512-wrvjpRFdmEu6yAqgjGy8MSud9ggxJj+I9XLuztLeSf/E0j0j6RQYtxH2J8U0Cfbgiw9ZDHyhpmaVuWhxscYaAQ=="
+    },
+    "node_modules/@types/d3-interpolate": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.2.tgz",
+      "integrity": "sha512-zAbCj9lTqW9J9PlF4FwnvEjXZUy75NQqPm7DMHZXuxCFTpuTrdK2NMYGQekf4hlasL78fCYOLu4EE3/tXElwow==",
+      "dependencies": {
+        "@types/d3-color": "*"
+      }
+    },
+    "node_modules/@types/d3-path": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.0.tgz",
+      "integrity": "sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg=="
+    },
+    "node_modules/@types/d3-polygon": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.0.tgz",
+      "integrity": "sha512-D49z4DyzTKXM0sGKVqiTDTYr+DHg/uxsiWDAkNrwXYuiZVd9o9wXZIo+YsHkifOiyBkmSWlEngHCQme54/hnHw=="
+    },
+    "node_modules/@types/d3-quadtree": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.3.tgz",
+      "integrity": "sha512-GDWaR+rGEk4ToLQSGugYnoh9AYYblsg/8kmdpa1KAJMwcdZ0v8rwgnldURxI5UrzxPlCPzF7by/Tjmv+Jn21Dg=="
+    },
+    "node_modules/@types/d3-random": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.1.tgz",
+      "integrity": "sha512-IIE6YTekGczpLYo/HehAy3JGF1ty7+usI97LqraNa8IiDur+L44d0VOjAvFQWJVdZOJHukUJw+ZdZBlgeUsHOQ=="
+    },
+    "node_modules/@types/d3-scale": {
+      "version": "4.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.5.tgz",
+      "integrity": "sha512-w/C++3W394MHzcLKO2kdsIn5KKNTOqeQVzyPSGPLzQbkPw/jpeaGtSRlakcKevGgGsjJxGsbqS0fPrVFDbHrDA==",
+      "dependencies": {
+        "@types/d3-time": "*"
+      }
+    },
+    "node_modules/@types/d3-scale-chromatic": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+      "integrity": "sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw=="
+    },
+    "node_modules/@types/d3-selection": {
+      "version": "3.0.7",
+      "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.7.tgz",
+      "integrity": "sha512-qoj2O7KjfqCobmtFOth8FMvjwMVPUAAmn6xiUbLl1ld7vQCPgffvyV5BBcEFfqWdilAUm+3zciU/3P3vZrUMlg=="
+    },
+    "node_modules/@types/d3-shape": {
+      "version": "3.1.3",
+      "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.3.tgz",
+      "integrity": "sha512-cHMdIq+rhF5IVwAV7t61pcEXfEHsEsrbBUPkFGBwTXuxtTAkBBrnrNA8++6OWm3jwVsXoZYQM8NEekg6CPJ3zw==",
+      "dependencies": {
+        "@types/d3-path": "*"
+      }
+    },
+    "node_modules/@types/d3-time": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.1.tgz",
+      "integrity": "sha512-5j/AnefKAhCw4HpITmLDTPlf4vhi8o/dES+zbegfPb7LaGfNyqkLxBR6E+4yvTAgnJLmhe80EXFMzUs38fw4oA=="
+    },
+    "node_modules/@types/d3-time-format": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.1.tgz",
+      "integrity": "sha512-Br6EFeu9B1Zrem7KaYbr800xCmEDyq8uE60kEU8rWhC/XpFYX6ocGMZuRJDQfFCq6SyakQxNHFqIfJbFLf4x6Q=="
+    },
+    "node_modules/@types/d3-timer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.0.tgz",
+      "integrity": "sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g=="
+    },
+    "node_modules/@types/d3-transition": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.5.tgz",
+      "integrity": "sha512-dcfjP6prFxj3ziFOJrnt4W2P0oXNj/sGxsJXH8286sHtVZ4qWGbjuZj+RRCYx4YZ4C0izpeE8OqXVCtoWEtzYg==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-zoom": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.5.tgz",
+      "integrity": "sha512-mIefdTLtxuWUWTbBupCUXPAXVPmi8/Uwrq41gQpRh0rD25GMU1ku+oTELqNY2NuuiI0F3wXC5e1liBQi7YS7XQ==",
+      "dependencies": {
+        "@types/d3-interpolate": "*",
+        "@types/d3-selection": "*"
+      }
+    },
     "node_modules/@types/dagre": {
       "version": "0.7.50",
       "resolved": "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.50.tgz",
@@ -4143,6 +4417,11 @@
         "@types/send": "*"
       }
     },
+    "node_modules/@types/geojson": {
+      "version": "7946.0.11",
+      "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.11.tgz",
+      "integrity": "sha512-L7A0AINMXQpVwxHJ4jxD6/XjZ4NDufaRlUJHjNIFKYUFBH1SvOW+neaqb0VTRSLW5suSrSu19ObFEFnfNcr+qg=="
+    },
     "node_modules/@types/graceful-fs": {
       "version": "4.1.7",
       "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.7.tgz",
@@ -4242,8 +4521,7 @@
     "node_modules/@types/prop-types": {
       "version": "15.7.7",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.7.tgz",
-      "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog==",
-      "devOptional": true
+      "integrity": "sha512-FbtmBWCcSa2J4zL781Zf1p5YUBXQomPEcep9QZCfRfQgTxz3pJWiDFLebohZ9fFntX5ibzOkSsrJ0TEew8cAog=="
     },
     "node_modules/@types/qs": {
       "version": "6.9.8",
@@ -4259,7 +4537,6 @@
       "version": "18.2.23",
       "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.23.tgz",
       "integrity": "sha512-qHLW6n1q2+7KyBEYnrZpcsAmU/iiCh9WGCKgXvMxx89+TYdJWRjZohVIo9XTcoLhfX3+/hP0Pbulu3bCZQ9PSA==",
-      "devOptional": true,
       "dependencies": {
         "@types/prop-types": "*",
         "@types/scheduler": "*",
@@ -4275,6 +4552,14 @@
         "@types/react": "*"
       }
     },
+    "node_modules/@types/react-measure": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmjs.org/@types/react-measure/-/react-measure-2.0.9.tgz",
+      "integrity": "sha512-8h9n24GK9Ckg1IxDjZLIjUu7/LDNVx2NbQd6KoD9R0JRy8B4ipA5OGCpsYhB6VULc4KlhsINKYUjd8+Urecq1A==",
+      "dependencies": {
+        "@types/react": "*"
+      }
+    },
     "node_modules/@types/resolve": {
       "version": "1.17.1",
       "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz",
@@ -4291,8 +4576,7 @@
     "node_modules/@types/scheduler": {
       "version": "0.16.4",
       "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.4.tgz",
-      "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ==",
-      "devOptional": true
+      "integrity": "sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ=="
     },
     "node_modules/@types/semver": {
       "version": "7.5.3",
@@ -4345,9 +4629,9 @@
       "integrity": "sha512-IDaobHimLQhjwsQ/NMwRVfa/yL7L/wriQPMhw1ZJall0KX6E1oxk29XMDeilW5qTIg5aoiqf5Udy8U/51aNoQQ=="
     },
     "node_modules/@types/uuid": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz",
-      "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA=="
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.5.tgz",
+      "integrity": "sha512-xfHdwa1FMJ082prjSJpoEI57GZITiQz10r3vEJCHa2khEFQjKy91aWKz6+zybzssCvXUwE1LQWgWVwZ4nYUvHQ=="
     },
     "node_modules/@types/ws": {
       "version": "8.5.6",
@@ -5279,9 +5563,9 @@
       }
     },
     "node_modules/axios": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
-      "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz",
+      "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==",
       "dependencies": {
         "follow-redirects": "^1.15.0",
         "form-data": "^4.0.0",
@@ -6548,138 +6832,515 @@
         "cssesc": "bin/cssesc"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=4"
+      }
+    },
+    "node_modules/cssnano": {
+      "version": "5.1.15",
+      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
+      "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==",
+      "dependencies": {
+        "cssnano-preset-default": "^5.2.14",
+        "lilconfig": "^2.0.3",
+        "yaml": "^1.10.2"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/cssnano"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/cssnano-preset-default": {
+      "version": "5.2.14",
+      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz",
+      "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==",
+      "dependencies": {
+        "css-declaration-sorter": "^6.3.1",
+        "cssnano-utils": "^3.1.0",
+        "postcss-calc": "^8.2.3",
+        "postcss-colormin": "^5.3.1",
+        "postcss-convert-values": "^5.1.3",
+        "postcss-discard-comments": "^5.1.2",
+        "postcss-discard-duplicates": "^5.1.0",
+        "postcss-discard-empty": "^5.1.1",
+        "postcss-discard-overridden": "^5.1.0",
+        "postcss-merge-longhand": "^5.1.7",
+        "postcss-merge-rules": "^5.1.4",
+        "postcss-minify-font-values": "^5.1.0",
+        "postcss-minify-gradients": "^5.1.1",
+        "postcss-minify-params": "^5.1.4",
+        "postcss-minify-selectors": "^5.2.1",
+        "postcss-normalize-charset": "^5.1.0",
+        "postcss-normalize-display-values": "^5.1.0",
+        "postcss-normalize-positions": "^5.1.1",
+        "postcss-normalize-repeat-style": "^5.1.1",
+        "postcss-normalize-string": "^5.1.0",
+        "postcss-normalize-timing-functions": "^5.1.0",
+        "postcss-normalize-unicode": "^5.1.1",
+        "postcss-normalize-url": "^5.1.0",
+        "postcss-normalize-whitespace": "^5.1.1",
+        "postcss-ordered-values": "^5.1.3",
+        "postcss-reduce-initial": "^5.1.2",
+        "postcss-reduce-transforms": "^5.1.0",
+        "postcss-svgo": "^5.1.0",
+        "postcss-unique-selectors": "^5.1.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/cssnano-utils": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
+      "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
+      "engines": {
+        "node": "^10 || ^12 || >=14.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.15"
+      }
+    },
+    "node_modules/csso": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
+      "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+      "dependencies": {
+        "css-tree": "~2.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+        "npm": ">=7.0.0"
+      }
+    },
+    "node_modules/csso/node_modules/css-tree": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
+      "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+      "dependencies": {
+        "mdn-data": "2.0.28",
+        "source-map-js": "^1.0.1"
+      },
+      "engines": {
+        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
+        "npm": ">=7.0.0"
+      }
+    },
+    "node_modules/csso/node_modules/mdn-data": {
+      "version": "2.0.28",
+      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
+      "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="
+    },
+    "node_modules/cssom": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+      "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw=="
+    },
+    "node_modules/cssstyle": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+      "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+      "dependencies": {
+        "cssom": "~0.3.6"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cssstyle/node_modules/cssom": {
+      "version": "0.3.8",
+      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
+    },
+    "node_modules/csstype": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+    },
+    "node_modules/d3": {
+      "version": "7.8.5",
+      "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
+      "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
+      "dependencies": {
+        "d3-array": "3",
+        "d3-axis": "3",
+        "d3-brush": "3",
+        "d3-chord": "3",
+        "d3-color": "3",
+        "d3-contour": "4",
+        "d3-delaunay": "6",
+        "d3-dispatch": "3",
+        "d3-drag": "3",
+        "d3-dsv": "3",
+        "d3-ease": "3",
+        "d3-fetch": "3",
+        "d3-force": "3",
+        "d3-format": "3",
+        "d3-geo": "3",
+        "d3-hierarchy": "3",
+        "d3-interpolate": "3",
+        "d3-path": "3",
+        "d3-polygon": "3",
+        "d3-quadtree": "3",
+        "d3-random": "3",
+        "d3-scale": "4",
+        "d3-scale-chromatic": "3",
+        "d3-selection": "3",
+        "d3-shape": "3",
+        "d3-time": "3",
+        "d3-time-format": "4",
+        "d3-timer": "3",
+        "d3-transition": "3",
+        "d3-zoom": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "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-axis": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
+      "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-brush": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+      "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "3",
+        "d3-transition": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-chord": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
+      "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
+      "dependencies": {
+        "d3-path": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "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-contour": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",
+      "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
+      "dependencies": {
+        "d3-array": "^3.2.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-delaunay": {
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
+      "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
+      "dependencies": {
+        "delaunator": "5"
+      },
+      "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-dsv": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
+      "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+      "dependencies": {
+        "commander": "7",
+        "iconv-lite": "0.6",
+        "rw": "1"
+      },
+      "bin": {
+        "csv2json": "bin/dsv2json.js",
+        "csv2tsv": "bin/dsv2dsv.js",
+        "dsv2dsv": "bin/dsv2dsv.js",
+        "dsv2json": "bin/dsv2json.js",
+        "json2csv": "bin/json2dsv.js",
+        "json2dsv": "bin/json2dsv.js",
+        "json2tsv": "bin/json2dsv.js",
+        "tsv2csv": "bin/dsv2dsv.js",
+        "tsv2json": "bin/dsv2json.js"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-dsv/node_modules/commander": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+      "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "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-fetch": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
+      "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
+      "dependencies": {
+        "d3-dsv": "1 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-force": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
+      "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "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-geo": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz",
+      "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==",
+      "dependencies": {
+        "d3-array": "2.5.0 - 3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-hierarchy": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+      "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+      "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-path": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
+      "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-polygon": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
+      "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "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/cssnano": {
-      "version": "5.1.15",
-      "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz",
-      "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==",
+    "node_modules/d3-random": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+      "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+      "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": {
-        "cssnano-preset-default": "^5.2.14",
-        "lilconfig": "^2.0.3",
-        "yaml": "^1.10.2"
+        "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": "^10 || ^12 || >=14.0"
-      },
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/cssnano"
-      },
-      "peerDependencies": {
-        "postcss": "^8.2.15"
+        "node": ">=12"
       }
     },
-    "node_modules/cssnano-preset-default": {
-      "version": "5.2.14",
-      "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz",
-      "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==",
+    "node_modules/d3-scale-chromatic": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+      "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
       "dependencies": {
-        "css-declaration-sorter": "^6.3.1",
-        "cssnano-utils": "^3.1.0",
-        "postcss-calc": "^8.2.3",
-        "postcss-colormin": "^5.3.1",
-        "postcss-convert-values": "^5.1.3",
-        "postcss-discard-comments": "^5.1.2",
-        "postcss-discard-duplicates": "^5.1.0",
-        "postcss-discard-empty": "^5.1.1",
-        "postcss-discard-overridden": "^5.1.0",
-        "postcss-merge-longhand": "^5.1.7",
-        "postcss-merge-rules": "^5.1.4",
-        "postcss-minify-font-values": "^5.1.0",
-        "postcss-minify-gradients": "^5.1.1",
-        "postcss-minify-params": "^5.1.4",
-        "postcss-minify-selectors": "^5.2.1",
-        "postcss-normalize-charset": "^5.1.0",
-        "postcss-normalize-display-values": "^5.1.0",
-        "postcss-normalize-positions": "^5.1.1",
-        "postcss-normalize-repeat-style": "^5.1.1",
-        "postcss-normalize-string": "^5.1.0",
-        "postcss-normalize-timing-functions": "^5.1.0",
-        "postcss-normalize-unicode": "^5.1.1",
-        "postcss-normalize-url": "^5.1.0",
-        "postcss-normalize-whitespace": "^5.1.1",
-        "postcss-ordered-values": "^5.1.3",
-        "postcss-reduce-initial": "^5.1.2",
-        "postcss-reduce-transforms": "^5.1.0",
-        "postcss-svgo": "^5.1.0",
-        "postcss-unique-selectors": "^5.1.1"
+        "d3-color": "1 - 3",
+        "d3-interpolate": "1 - 3"
       },
       "engines": {
-        "node": "^10 || ^12 || >=14.0"
-      },
-      "peerDependencies": {
-        "postcss": "^8.2.15"
+        "node": ">=12"
       }
     },
-    "node_modules/cssnano-utils": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz",
-      "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==",
+    "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": "^10 || ^12 || >=14.0"
-      },
-      "peerDependencies": {
-        "postcss": "^8.2.15"
+        "node": ">=12"
       }
     },
-    "node_modules/csso": {
-      "version": "5.0.5",
-      "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz",
-      "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==",
+    "node_modules/d3-shape": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
+      "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
       "dependencies": {
-        "css-tree": "~2.2.0"
+        "d3-path": "^3.1.0"
       },
       "engines": {
-        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
-        "npm": ">=7.0.0"
+        "node": ">=12"
       }
     },
-    "node_modules/csso/node_modules/css-tree": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz",
-      "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==",
+    "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": {
-        "mdn-data": "2.0.28",
-        "source-map-js": "^1.0.1"
+        "d3-array": "2 - 3"
       },
       "engines": {
-        "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0",
-        "npm": ">=7.0.0"
+        "node": ">=12"
       }
     },
-    "node_modules/csso/node_modules/mdn-data": {
-      "version": "2.0.28",
-      "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz",
-      "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g=="
+    "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/cssom": {
-      "version": "0.4.4",
-      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
-      "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw=="
+    "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/cssstyle": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
-      "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+    "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": {
-        "cssom": "~0.3.6"
+        "d3-color": "1 - 3",
+        "d3-dispatch": "1 - 3",
+        "d3-ease": "1 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-timer": "1 - 3"
       },
       "engines": {
-        "node": ">=8"
+        "node": ">=12"
+      },
+      "peerDependencies": {
+        "d3-selection": "2 - 3"
       }
     },
-    "node_modules/cssstyle/node_modules/cssom": {
-      "version": "0.3.8",
-      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
-      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
-    },
-    "node_modules/csstype": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
-      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
-      "devOptional": true
+    "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/dagre": {
       "version": "0.8.5",
@@ -6819,6 +7480,14 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/delaunator": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
+      "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
+      "dependencies": {
+        "robust-predicates": "^3.0.0"
+      }
+    },
     "node_modules/delayed-stream": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -8373,11 +9042,11 @@
       "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ=="
     },
     "node_modules/focus-trap": {
-      "version": "7.4.3",
-      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
-      "integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
+      "version": "7.5.2",
+      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz",
+      "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==",
       "dependencies": {
-        "tabbable": "^6.1.2"
+        "tabbable": "^6.2.0"
       }
     },
     "node_modules/follow-redirects": {
@@ -8634,25 +9303,6 @@
         "node": ">= 0.6"
       }
     },
-    "node_modules/fromentries": {
-      "version": "1.3.2",
-      "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
-      "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ]
-    },
     "node_modules/fs-extra": {
       "version": "10.1.0",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
@@ -8749,6 +9399,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/get-node-dimensions": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/get-node-dimensions/-/get-node-dimensions-1.2.1.tgz",
+      "integrity": "sha512-2MSPMu7S1iOTL+BOa6K1S62hB2zUAYNF/lV0gSVlOaacd087lc6nR1H1r0e3B1CerTo+RceOmi1iJW+vp21xcQ=="
+    },
     "node_modules/get-own-enumerable-property-symbols": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz",
@@ -9419,6 +10074,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/ipaddr.js": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz",
@@ -12701,6 +13364,60 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/mobx": {
+      "version": "6.10.2",
+      "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.10.2.tgz",
+      "integrity": "sha512-B1UGC3ieK3boCjnMEcZSwxqRDMdzX65H/8zOHbuTY8ZhvrIjTUoLRR2TP2bPqIgYRfb3+dUigu8yMZufNjn0LQ==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      }
+    },
+    "node_modules/mobx-react": {
+      "version": "7.6.0",
+      "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-7.6.0.tgz",
+      "integrity": "sha512-+HQUNuh7AoQ9ZnU6c4rvbiVVl+wEkb9WqYsVDzGLng+Dqj1XntHu79PvEWKtSMoMj67vFp/ZPXcElosuJO8ckA==",
+      "dependencies": {
+        "mobx-react-lite": "^3.4.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      },
+      "peerDependencies": {
+        "mobx": "^6.1.0",
+        "react": "^16.8.0 || ^17 || ^18"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/mobx-react-lite": {
+      "version": "3.4.3",
+      "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-3.4.3.tgz",
+      "integrity": "sha512-NkJREyFTSUXR772Qaai51BnE1voWx56LOL80xG7qkZr6vo8vEaLF3sz1JNUVh+rxmUzxYaqOhfuxTfqUh0FXUg==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/mobx"
+      },
+      "peerDependencies": {
+        "mobx": "^6.1.0",
+        "react": "^16.8.0 || ^17 || ^18"
+      },
+      "peerDependenciesMeta": {
+        "react-dom": {
+          "optional": true
+        },
+        "react-native": {
+          "optional": true
+        }
+      }
+    },
     "node_modules/monaco-editor": {
       "version": "0.38.0",
       "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.38.0.tgz",
@@ -12787,25 +13504,6 @@
         "tslib": "^2.0.3"
       }
     },
-    "node_modules/node-fetch": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
-      "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
-      "dependencies": {
-        "whatwg-url": "^5.0.0"
-      },
-      "engines": {
-        "node": "4.x || >=6.0.0"
-      },
-      "peerDependencies": {
-        "encoding": "^0.1.0"
-      },
-      "peerDependenciesMeta": {
-        "encoding": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/node-forge": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
@@ -13001,22 +13699,23 @@
       "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg=="
     },
     "node_modules/octokit": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/octokit/-/octokit-2.1.0.tgz",
-      "integrity": "sha512-Pxi6uKTjBRZWgAwsw1NgHdRlL+QASCN35OYS7X79o7PtBME0CLXEroZmPtEwlWZbPTP+iDbEy2wCbSOgm0uGIQ==",
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/octokit/-/octokit-3.1.1.tgz",
+      "integrity": "sha512-AKJs5XYs7iAh7bskkYpxhUIpsYZdLqjnlnqrN5s9FFZuJ/a6ATUHivGpUKDpGB/xa+LGDtG9Lu8bOCfPM84vHQ==",
       "dependencies": {
-        "@octokit/app": "^13.1.5",
-        "@octokit/core": "^4.2.1",
-        "@octokit/oauth-app": "^4.2.1",
-        "@octokit/plugin-paginate-rest": "^6.1.0",
-        "@octokit/plugin-rest-endpoint-methods": "^7.1.1",
-        "@octokit/plugin-retry": "^4.1.3",
-        "@octokit/plugin-throttling": "^5.2.2",
-        "@octokit/request-error": "^v3.0.3",
-        "@octokit/types": "^9.2.2"
+        "@octokit/app": "^14.0.0",
+        "@octokit/core": "^5.0.0",
+        "@octokit/oauth-app": "^6.0.0",
+        "@octokit/plugin-paginate-graphql": "^4.0.0",
+        "@octokit/plugin-paginate-rest": "^9.0.0",
+        "@octokit/plugin-rest-endpoint-methods": "^10.0.0",
+        "@octokit/plugin-retry": "^6.0.0",
+        "@octokit/plugin-throttling": "^8.0.0",
+        "@octokit/request-error": "^5.0.0",
+        "@octokit/types": "^12.0.0"
       },
       "engines": {
-        "node": ">= 14"
+        "node": ">= 18"
       }
     },
     "node_modules/on-finished": {
@@ -13404,10 +14103,28 @@
         "node": ">=4"
       }
     },
+    "node_modules/point-in-svg-path": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/point-in-svg-path/-/point-in-svg-path-1.0.2.tgz",
+      "integrity": "sha512-+Smsf7B9e7eRFHIwpN+4rE8inF2APbFWeywPfUgbeh02xdJSkbTz6Pqdt7A36wVCR+CnLbaNkRnBjgOpF5RMVQ==",
+      "engines": {
+        "node": ">=8.x.x"
+      }
+    },
+    "node_modules/popper.js": {
+      "version": "1.16.1",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+      "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==",
+      "deprecated": "You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
     "node_modules/postcss": {
-      "version": "8.4.30",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.30.tgz",
-      "integrity": "sha512-7ZEao1g4kd68l97aWG/etQKPKq07us0ieSZ2TnFDk11i0ZfDW2AwKHYU8qv4MZKqN2fdBfg+7q0ES06UA73C1g==",
+      "version": "8.4.31",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
+      "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
       "funding": [
         {
           "type": "opencollective",
@@ -15051,6 +15768,21 @@
       "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
       "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
     },
+    "node_modules/react-measure": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/react-measure/-/react-measure-2.5.2.tgz",
+      "integrity": "sha512-M+rpbTLWJ3FD6FXvYV6YEGvQ5tMayQ3fGrZhRPHrE9bVlBYfDCLuDcgNttYfk8IqfOI03jz6cbpqMRTUclQnaA==",
+      "dependencies": {
+        "@babel/runtime": "^7.2.0",
+        "get-node-dimensions": "^1.2.1",
+        "prop-types": "^15.6.2",
+        "resize-observer-polyfill": "^1.5.0"
+      },
+      "peerDependencies": {
+        "react": ">0.13.0",
+        "react-dom": ">0.13.0"
+      }
+    },
     "node_modules/react-refresh": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@@ -15349,6 +16081,11 @@
       "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
       "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
     },
+    "node_modules/resize-observer-polyfill": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+      "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+    },
     "node_modules/resolve": {
       "version": "1.22.6",
       "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.6.tgz",
@@ -15492,6 +16229,11 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/robust-predicates": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
+      "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg=="
+    },
     "node_modules/rollup": {
       "version": "2.79.1",
       "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
@@ -15583,6 +16325,11 @@
         "queue-microtask": "^1.2.2"
       }
     },
+    "node_modules/rw": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+      "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
+    },
     "node_modules/rxjs": {
       "version": "7.8.1",
       "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
@@ -16845,11 +17592,6 @@
         "node": ">= 4.0.0"
       }
     },
-    "node_modules/tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
-    },
     "node_modules/tryer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",
@@ -17215,9 +17957,13 @@
       }
     },
     "node_modules/uuid": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
-      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
       "bin": {
         "uuid": "dist/bin/uuid"
       }
@@ -17296,6 +18042,54 @@
         "minimalistic-assert": "^1.0.0"
       }
     },
+    "node_modules/webcola": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/webcola/-/webcola-3.4.0.tgz",
+      "integrity": "sha512-4BiLXjXw3SJHo3Xd+rF+7fyClT6n7I+AR6TkBqyQ4kTsePSAMDLRCXY1f3B/kXJeP9tYn4G1TblxTO+jAt0gaw==",
+      "dependencies": {
+        "d3-dispatch": "^1.0.3",
+        "d3-drag": "^1.0.4",
+        "d3-shape": "^1.3.5",
+        "d3-timer": "^1.0.5"
+      }
+    },
+    "node_modules/webcola/node_modules/d3-dispatch": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.6.tgz",
+      "integrity": "sha512-fVjoElzjhCEy+Hbn8KygnmMS7Or0a9sI2UzGwoB7cCtvI1XpVN9GpoYlnb3xt2YV66oXYb1fLJ8GMvP4hdU1RA=="
+    },
+    "node_modules/webcola/node_modules/d3-drag": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.5.tgz",
+      "integrity": "sha512-rD1ohlkKQwMZYkQlYVCrSFxsWPzI97+W+PaEIBNTMxRuxz9RF0Hi5nJWHGVJ3Om9d2fRTe1yOBINJyy/ahV95w==",
+      "dependencies": {
+        "d3-dispatch": "1",
+        "d3-selection": "1"
+      }
+    },
+    "node_modules/webcola/node_modules/d3-path": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
+      "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
+    },
+    "node_modules/webcola/node_modules/d3-selection": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.4.2.tgz",
+      "integrity": "sha512-SJ0BqYihzOjDnnlfyeHT0e30k0K1+5sR3d5fNueCNeuhZTnGw4M4o8mqJchSwgKMXCNFo+e2VTChiSJ0vYtXkg=="
+    },
+    "node_modules/webcola/node_modules/d3-shape": {
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
+      "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
+      "dependencies": {
+        "d3-path": "1"
+      }
+    },
+    "node_modules/webcola/node_modules/d3-timer": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.10.tgz",
+      "integrity": "sha512-B1JDm0XDaQC+uvo4DT79H0XmBskgS3l6Ve+1SBCfxgmtIb1AVrPIoqd+nPSv+loMX8szQ0sVUhGngL7D5QPiXw=="
+    },
     "node_modules/webidl-conversions": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
@@ -17641,20 +18435,6 @@
       "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
       "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
     },
-    "node_modules/whatwg-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
-      "dependencies": {
-        "tr46": "~0.0.3",
-        "webidl-conversions": "^3.0.0"
-      }
-    },
-    "node_modules/whatwg-url/node_modules/webidl-conversions": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
-    },
     "node_modules/which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -18194,9 +18974,9 @@
       }
     },
     "node_modules/zustand": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.1.tgz",
-      "integrity": "sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==",
+      "version": "4.4.3",
+      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.3.tgz",
+      "integrity": "sha512-oRy+X3ZazZvLfmv6viIaQmtLOMeij1noakIsK/Y47PWYhT8glfXzQ4j0YcP5i0P0qI1A4rIB//SGROGyZhx91A==",
       "dependencies": {
         "use-sync-external-store": "1.2.0"
       },
diff --git a/karavan-space/package.json b/karavan-space/package.json
index cd98eba2..24dbc013 100644
--- a/karavan-space/package.json
+++ b/karavan-space/package.json
@@ -5,9 +5,10 @@
   "scripts": {
     "cp-designer": "cp -r ../karavan-designer/src/designer src",
     "cp-knowledgebase": "cp -r ../karavan-designer/src/knowledgebase src",
+    "cp-topology": "cp -r ../karavan-designer/src/topology src",
     "cp-public-kamelets": "cp -r ../karavan-designer/public/kamelets public",
     "cp-public-components": "cp -r ../karavan-designer/public/components public",
-    "copy": "npm run cp-designer && npm run cp-knowledgebase && npm run cp-public-components && npm run cp-public-kamelets",
+    "copy": "npm run cp-designer && npm run cp-knowledgebase && npm run cp-topology && npm run cp-public-components && npm run cp-public-kamelets",
     "start": "npm run copy && react-scripts start",
     "build": "npm run copy && react-scripts build",
     "prod": "npm run copy && react-scripts build --dest && rsync -a build/* ../resources/META-INF/resources"
@@ -31,25 +32,26 @@
     ]
   },
   "dependencies": {
-    "@monaco-editor/react": "4.5.0",
-    "@patternfly/patternfly": "^5.0.2",
-    "@patternfly/react-core": "^5.0.0",
-    "@patternfly/react-table": "^5.0.0",
+    "@monaco-editor/react": "4.6.0",
+    "@patternfly/patternfly": "^5.1.0",
+    "@patternfly/react-core": "^5.1.1",
+    "@patternfly/react-table": "^5.1.1",
+    "@patternfly/react-topology": "^5.1.0",
     "@types/js-yaml": "4.0.5",
     "@types/node": "18.15.3",
-    "@types/uuid": "9.0.1",
-    "axios": "1.4.0",
+    "@types/uuid": "9.0.5",
+    "axios": "1.5.1",
     "dagre": "0.8.5",
     "html-to-image": "1.11.11",
     "karavan-core": "file:../karavan-core",
     "netlify-auth-providers": "^1.0.0-alpha5",
-    "octokit": "^2.0.10",
+    "octokit": "^3.1.1",
     "react": "18.2.0",
     "react-dom": "18.2.0",
     "react-scripts": "5.0.1",
     "rxjs": "7.8.1",
-    "uuid": "9.0.0",
-    "zustand": "^4.4.1"
+    "uuid": "9.0.1",
+    "zustand": "^4.4.3"
   },
   "devDependencies": {
     "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
diff --git a/karavan-space/src/designer/route/DslElement.tsx b/karavan-space/src/designer/route/DslElement.tsx
index 0d246b20..305b7859 100644
--- a/karavan-space/src/designer/route/DslElement.tsx
+++ b/karavan-space/src/designer/route/DslElement.tsx
@@ -46,9 +46,9 @@ export function DslElement(props: Props) {
 
     const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
 
-    const [selectedUuids, setShowMoveConfirmation, hideLogDSL, setMoveElements] =
+    const [selectedUuids, selectedStep, showMoveConfirmation, setShowMoveConfirmation, hideLogDSL, setMoveElements] =
         useDesignerStore((s) =>
-            [s.selectedUuids, s.setShowMoveConfirmation, s.hideLogDSL, s.setMoveElements], shallow)
+            [s.selectedUuids, s.selectedStep, s.showMoveConfirmation, s.setShowMoveConfirmation, s.hideLogDSL, s.setMoveElements], shallow)
     const [isDragging, setIsDragging] = useState<boolean>(false);
 
     const [isDraggedOver, setIsDraggedOver] = useState<boolean>(false);
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx b/karavan-space/src/topology/CustomEdge.tsx
similarity index 87%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx
copy to karavan-space/src/topology/CustomEdge.tsx
index 0eb8e0eb..bd4fa92e 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx
+++ b/karavan-space/src/topology/CustomEdge.tsx
@@ -18,12 +18,10 @@
 import * as React from 'react';
 
 import './topology.css';
-import {DefaultEdge, DefaultGroup, observer} from '@patternfly/react-topology';
+import {DefaultEdge, observer} from '@patternfly/react-topology';
 
 
 const CustomEdge: React.FC<any> = observer(({ element, ...rest }) => {
-    const data = element.getData();
-
     return (
         <DefaultEdge element={element} {...rest}>
         </DefaultEdge>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx b/karavan-space/src/topology/CustomGroup.tsx
similarity index 94%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx
copy to karavan-space/src/topology/CustomGroup.tsx
index 7df861ce..9e366c7c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx
+++ b/karavan-space/src/topology/CustomGroup.tsx
@@ -22,7 +22,6 @@ import { DefaultGroup, observer} from '@patternfly/react-topology';
 
 
 const CustomGroup: React.FC<any> = observer(({ element, ...rest }) => {
-    const data = element.getData();
 
     return (
         <DefaultGroup element={element} {...rest}>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx b/karavan-space/src/topology/CustomNode.tsx
similarity index 92%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx
copy to karavan-space/src/topology/CustomNode.tsx
index 12492fdf..2d87457d 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx
+++ b/karavan-space/src/topology/CustomNode.tsx
@@ -19,8 +19,8 @@ import * as React from 'react';
 import {RegionsIcon} from '@patternfly/react-icons';
 
 import {DefaultNode, observer} from '@patternfly/react-topology';
-import {getDesignerIcon} from "../../designer/utils/KaravanIcons";
-import {CamelUi} from "../../designer/utils/CamelUi";
+import {getDesignerIcon} from "../designer/utils/KaravanIcons";
+import {CamelUi} from "../designer/utils/CamelUi";
 import './topology.css';
 
 function getIcon(data: any) {
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx b/karavan-space/src/topology/TopologyApi.tsx
similarity index 97%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx
copy to karavan-space/src/topology/TopologyApi.tsx
index d9ec3ba9..44ff57a2 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx
+++ b/karavan-space/src/topology/TopologyApi.tsx
@@ -29,7 +29,6 @@ import {
     withPanZoom, withSelection
 } from '@patternfly/react-topology';
 import CustomNode from "./CustomNode";
-import {ProjectFile} from "../../api/ProjectModels";
 import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
 import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
@@ -41,10 +40,11 @@ import {
 } from "karavan-core/lib/model/TopologyDefinition";
 import CustomGroup from "./CustomGroup";
 import CustomEdge from "./CustomEdge";
+import {IntegrationFile} from "./TopologyStore";
 
 const NODE_DIAMETER = 60;
 
-export function getIntegrations(files: ProjectFile[]): Integration[] {
+export function getIntegrations(files: IntegrationFile[]): Integration[] {
     return files.filter((file) => file.name.endsWith(".camel.yaml")).map((file) => {
         return CamelDefinitionYaml.yamlToIntegration(file.name, file.code);
     })
@@ -207,7 +207,7 @@ export function getInternalEdges(tons: TopologyOutgoingNode[], tins: TopologyInc
     return result;
 }
 
-export function getModel(files: ProjectFile[]): Model {
+export function getModel(files: IntegrationFile[]): Model {
     const integrations = getIntegrations(files);
     const tins = TopologyUtils.findTopologyIncomingNodes(integrations);
     const troutes = TopologyUtils.findTopologyRouteNodes(integrations);
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx b/karavan-space/src/topology/TopologyPropertiesPanel.tsx
similarity index 81%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx
copy to karavan-space/src/topology/TopologyPropertiesPanel.tsx
index 48aabcd7..24deca24 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-space/src/topology/TopologyPropertiesPanel.tsx
@@ -15,23 +15,23 @@
  * limitations under the License.
  */
 import React from 'react';
-import '../../designer/karavan.css';
+import '../designer/karavan.css';
 import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
-import {DslProperties} from "../../designer/route/DslProperties";
+import {DslProperties} from "../designer/route/DslProperties";
 import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
-import {useFilesStore, useFileStore} from "../../api/ProjectStore";
 
-export function TopologyPropertiesPanel () {
+interface Props {
+    onSetFile: (fileName: string) => void
+}
+
+export function TopologyPropertiesPanel (props: Props) {
 
-    const [setFile] = useFileStore((s) => [s.setFile], shallow);
-    const [files] = useFilesStore((s) => [s.files], shallow);
     const [selectedIds, setSelectedIds, fileName] = useTopologyStore((s) =>
         [s.selectedIds, s.setSelectedIds, s.fileName], shallow);
 
-
     function getHeader() {
         return (
             <Flex className="properties-header" direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
@@ -41,10 +41,7 @@ export function TopologyPropertiesPanel () {
                 <FlexItem>
                     <Button variant="link" onClick={event => {
                         if (fileName) {
-                            const file = files.filter(f => f.name === fileName)?.at(0);
-                            if (file) {
-                                setFile('select', file);
-                            }
+                            props.onSetFile(fileName);
                         }
                     }}
                     >{fileName}
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts b/karavan-space/src/topology/TopologyStore.ts
similarity index 89%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts
copy to karavan-space/src/topology/TopologyStore.ts
index 750d1e16..5bbdf124 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts
+++ b/karavan-space/src/topology/TopologyStore.ts
@@ -18,6 +18,16 @@
 import {createWithEqualityFn} from "zustand/traditional";
 import {shallow} from "zustand/shallow";
 
+export class IntegrationFile {
+    name: string = '';
+    code: string = '';
+
+    constructor(name: string, code: string) {
+        this.name = name;
+        this.code = code;
+    }
+}
+
 interface TopologyState {
     selectedIds: string []
     fileName?: string
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx b/karavan-space/src/topology/TopologyTab.tsx
similarity index 88%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx
copy to karavan-space/src/topology/TopologyTab.tsx
index 22e9dbc4..df48e0c0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx
+++ b/karavan-space/src/topology/TopologyTab.tsx
@@ -30,16 +30,21 @@ import {
     SELECTION_EVENT, Model,
 } from '@patternfly/react-topology';
 import {customComponentFactory, getModel} from "./TopologyApi";
-import {useFilesStore} from "../../api/ProjectStore";
 import {shallow} from "zustand/shallow";
-import {useTopologyStore} from "./TopologyStore";
+import {IntegrationFile, useTopologyStore} from "./TopologyStore";
 import {TopologyPropertiesPanel} from "./TopologyPropertiesPanel";
 import {TopologyToolbar} from "./TopologyToolbar";
-import {useDesignerStore} from "../../designer/DesignerStore";
+import {useDesignerStore} from "../designer/DesignerStore";
 
-export const TopologyTab: React.FC = () => {
 
-    const [files] = useFilesStore((s) => [s.files], shallow);
+interface Props {
+    files: IntegrationFile[],
+    onClickCreateButton: () => void
+    onSetFile: (fileName: string) => void
+}
+
+export function TopologyTab (props: Props) {
+
     const [selectedIds, setSelectedIds, setFileName] = useTopologyStore((s) =>
         [s.selectedIds, s.setSelectedIds, s.setFileName], shallow);
     const [setSelectedStep] = useDesignerStore((s) => [s.setSelectedStep], shallow)
@@ -62,7 +67,7 @@ export const TopologyTab: React.FC = () => {
     }
 
     const controller = React.useMemo(() => {
-        const model = getModel(files);
+        const model = getModel(props.files);
         const newController = new Visualization();
         newController.registerLayoutFactory((_, graph) => new DagreLayout(graph));
         newController.registerComponentFactory(customComponentFactory);
@@ -81,15 +86,15 @@ export const TopologyTab: React.FC = () => {
 
     React.useEffect(() => {
         setSelectedIds([])
-        const model = getModel(files);
+        const model = getModel(props.files);
         controller.fromModel(model, false);
     }, []);
 
     return (
         <TopologyView
             className="topology-panel"
-            contextToolbar={<TopologyToolbar/>}
-            sideBar={<TopologyPropertiesPanel/>}
+            contextToolbar={<TopologyToolbar onClickCreateButton={props.onClickCreateButton}/>}
+            sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
                 <TopologyControlBar
                     controlButtons={createTopologyControlButtons({
@@ -117,4 +122,4 @@ export const TopologyTab: React.FC = () => {
             </VisualizationProvider>
         </TopologyView>
     );
-};
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx b/karavan-space/src/topology/TopologyToolbar.tsx
similarity index 78%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
copy to karavan-space/src/topology/TopologyToolbar.tsx
index f77abafe..2d9fc55c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
+++ b/karavan-space/src/topology/TopologyToolbar.tsx
@@ -20,14 +20,13 @@ import {
     Button,
     ToolbarItem, Tooltip
 } from '@patternfly/react-core';
-import { useFileStore} from "../../api/ProjectStore";
-import {shallow} from "zustand/shallow";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {CreateFileModal} from "../files/CreateFileModal";
 
-export const TopologyToolbar: React.FC = () => {
+interface Props {
+    onClickCreateButton: () => void
+}
 
-    const [setFile] = useFileStore((s) => [s.setFile], shallow);
+export function TopologyToolbar (props: Props) {
 
     return (
         <ToolbarItem align={{default: "alignRight"}}>
@@ -35,12 +34,11 @@ export const TopologyToolbar: React.FC = () => {
                 <Button size="sm"
                         variant={"primary"}
                         icon={<PlusIcon/>}
-                        onClick={e => setFile("create")}
+                        onClick={e => props.onClickCreateButton()}
                 >
                     Create
                 </Button>
             </Tooltip>
-            <CreateFileModal types={['INTEGRATION']}/>
         </ToolbarItem>
     )
 }
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/topology.css b/karavan-space/src/topology/topology.css
similarity index 100%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/topology.css
copy to karavan-space/src/topology/topology.css
diff --git a/karavan-web/karavan-app/src/main/webui/package-lock.json b/karavan-web/karavan-app/src/main/webui/package-lock.json
index be575612..bd5209d3 100644
--- a/karavan-web/karavan-app/src/main/webui/package-lock.json
+++ b/karavan-web/karavan-app/src/main/webui/package-lock.json
@@ -9,29 +9,29 @@
       "version": "4.0.1",
       "dependencies": {
         "@microsoft/fetch-event-source": "^2.0.1",
-        "@monaco-editor/react": "4.5.1",
-        "@patternfly/patternfly": "^5.0.2",
-        "@patternfly/react-charts": "^7.0.0",
-        "@patternfly/react-core": "^5.0.0",
+        "@monaco-editor/react": "4.6.0",
+        "@patternfly/patternfly": "^5.1.0",
+        "@patternfly/react-charts": "^7.1.1",
+        "@patternfly/react-core": "^5.1.1",
         "@patternfly/react-log-viewer": "^5.0.0",
-        "@patternfly/react-table": "^5.0.0",
-        "@patternfly/react-topology": "^5.0.0",
-        "@types/js-yaml": "4.0.5",
+        "@patternfly/react-table": "^5.1.1",
+        "@patternfly/react-topology": "^5.1.0",
+        "@types/js-yaml": "4.0.7",
         "@types/node": "18.16.3",
         "@types/uuid": "9.0.1",
-        "axios": "1.4.0",
+        "axios": "1.5.1",
         "buffer": "6.0.3",
         "dagre": "0.8.5",
         "file-saver": "2.0.5",
         "html-to-image": "1.11.11",
         "karavan-core": "file:../../../../../karavan-core",
-        "keycloak-js": "22.0.3",
+        "keycloak-js": "22.0.4",
         "react": "18.2.0",
         "react-dom": "18.2.0",
         "react-router-dom": "^6.15.0",
         "rxjs": "7.8.1",
-        "uuid": "9.0.0",
-        "zustand": "^4.4.1"
+        "uuid": "9.0.1",
+        "zustand": "^4.4.3"
       },
       "devDependencies": {
         "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
@@ -3368,9 +3368,9 @@
       "integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA=="
     },
     "node_modules/@monaco-editor/loader": {
-      "version": "1.3.3",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.3.3.tgz",
-      "integrity": "sha512-6KKF4CTzcJiS8BJwtxtfyYt9shBiEv32ateQ9T4UVogwn4HM/uPo9iJd2Dmbkpz8CM6Y0PDUpjnZzCwC+eYo2Q==",
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz",
+      "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
       "dependencies": {
         "state-local": "^1.0.6"
       },
@@ -3379,11 +3379,11 @@
       }
     },
     "node_modules/@monaco-editor/react": {
-      "version": "4.5.1",
-      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.5.1.tgz",
-      "integrity": "sha512-NNDFdP+2HojtNhCkRfE6/D6ro6pBNihaOzMbGK84lNWzRu+CfBjwzGt4jmnqimLuqp5yE5viHS2vi+QOAnD5FQ==",
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz",
+      "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==",
       "dependencies": {
-        "@monaco-editor/loader": "^1.3.3"
+        "@monaco-editor/loader": "^1.4.0"
       },
       "peerDependencies": {
         "monaco-editor": ">= 0.25.0 < 1",
@@ -3436,17 +3436,17 @@
       }
     },
     "node_modules/@patternfly/patternfly": {
-      "version": "5.0.4",
-      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.0.4.tgz",
-      "integrity": "sha512-8akdWzFpG384Q6Es8lzkfuhAlzVGrNK7TJqXGecHDAg8u1JsYn3+Nw6gLRviI88z8Kjxmg5YKirILjpclGxkIA=="
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-5.1.0.tgz",
+      "integrity": "sha512-wzVgL/0xPsmuRKWc6lMNEo5gDcTUtyU231eJSBTapOKXiwBOv2flvLEHPYLO6oDYXO+hwUrVgbcZFWMd1UlLwA=="
     },
     "node_modules/@patternfly/react-charts": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-7.0.1.tgz",
-      "integrity": "sha512-CwzRWzQhsEuWDJaCA2k7DvCaEqX1hA6UteNlYU/9Oh7z4mfWIbE89DRdxBc1AFnWRZbbZQW9TXBU3IPe/qAdqQ==",
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-charts/-/react-charts-7.1.1.tgz",
+      "integrity": "sha512-X5T+wlbh+sNKIVScx3ykivu1+EIEcQvEdjv6vfyBlsBU8CzACgMRQff4buBL6um3Zv2kT4LPefd6zxoaerJdkg==",
       "dependencies": {
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
         "hoist-non-react-statics": "^3.3.0",
         "lodash": "^4.17.19",
         "tslib": "^2.5.0",
@@ -3474,14 +3474,14 @@
       }
     },
     "node_modules/@patternfly/react-core": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.0.1.tgz",
-      "integrity": "sha512-Eevd+8ACLFV733J+cpo4FRgNtRBObIgmUcrqLjf9H99jZ1hFpBgacFyHiALFi2cuoNVGmdEzskFl+4c7Uo0n+w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-5.1.1.tgz",
+      "integrity": "sha512-9DbgQMXYmF8A4aCNLKXwIN1H07SIPoPaVLvx+yiDuJfDx4Qi0T+H7j5cx0VfDfxuCpqea3POJWqBQn1HnwS4wQ==",
       "dependencies": {
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
-        "focus-trap": "7.4.3",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
+        "focus-trap": "7.5.2",
         "react-dropzone": "^14.2.3",
         "tslib": "^2.5.0"
       },
@@ -3491,9 +3491,9 @@
       }
     },
     "node_modules/@patternfly/react-icons": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.0.1.tgz",
-      "integrity": "sha512-MduetDRzve3eRlKAioM/UxmVuPyFccdeBWAKhbN4SBn7RaZWS7kO7/xZzNkpeT5pqQIeAACvz3uiV2/3uAf38w==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-5.1.1.tgz",
+      "integrity": "sha512-9gCxkWz2xcdi0rtXu2F0L68w4tLIlsgGTACo1ggr4aVng9jRX++o1PlCOqscOd9o0NiFnFD7BLlZUGvJWaYEZg==",
       "peerDependencies": {
         "react": "^17 || ^18",
         "react-dom": "^17 || ^18"
@@ -3515,19 +3515,19 @@
       }
     },
     "node_modules/@patternfly/react-styles": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.0.1.tgz",
-      "integrity": "sha512-kHP/lbvmhBnNfWiqJJLNwOQZnkcl6wfwAesRp22s4Lj941EWe0oFIqn925/uORIOAOz2du1121t7T4UTfLZg4w=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-5.1.1.tgz",
+      "integrity": "sha512-swO9X+WixYYDsMVsEJp1V8QUfhEQY91QfFm4phfYP4jc2TQ2opIFYdUIHkc+yrZwBhrgb/pPUUfemyqAoSbZcA=="
     },
     "node_modules/@patternfly/react-table": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.0.1.tgz",
-      "integrity": "sha512-2YbM6XvgG9ubJE4caPQKPMFBkcf7zYzLUFbHnkyfInpWeVNBs/+ZDAP2wnIHce7uaPLnJ1t0FVzGwaD/UuPwkg==",
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-table/-/react-table-5.1.1.tgz",
+      "integrity": "sha512-9tAtHj16hemJ6YRBWIm2O+QRNoFWYQt8ZLQ1G0KBwpg2t2G2CbGsS2RG+BamO4IVE6IPo3Yoo39p4UCNRiGVpA==",
       "dependencies": {
-        "@patternfly/react-core": "^5.0.1",
-        "@patternfly/react-icons": "^5.0.1",
-        "@patternfly/react-styles": "^5.0.1",
-        "@patternfly/react-tokens": "^5.0.1",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
+        "@patternfly/react-tokens": "^5.1.1",
         "lodash": "^4.17.19",
         "tslib": "^2.5.0"
       },
@@ -3537,18 +3537,18 @@
       }
     },
     "node_modules/@patternfly/react-tokens": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.0.1.tgz",
-      "integrity": "sha512-YafAGJYvxDP4GaQ0vMybalWmx7MJ+etUf1cGoaMh0wRD2eswltT/RckygtEBKR/M61qXbgG+CxKmMyY8leoiDw=="
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-5.1.1.tgz",
+      "integrity": "sha512-cHuNkzNA9IY9aDwfjSEkitQoVEvRhOJRKhH0yIRlRByEkbdoV9jJZ9xj20hNShE+bxmNuom+MCTQSkpkN1bV8A=="
     },
     "node_modules/@patternfly/react-topology": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.0.0.tgz",
-      "integrity": "sha512-DW1dXXff5X+5K3ZW8rn1eqSggGfq5My/BMMcyhO6ankgAxAA4uK96/DbWaUMmSxkeHDSF6tD5jTd/SiglQzR1A==",
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/@patternfly/react-topology/-/react-topology-5.1.0.tgz",
+      "integrity": "sha512-Qzu7GMxqCsRvQj4RF2AHOGSp0nPpVuDE2xpdAaj/yCKz0cqHhvrwpC4+qyVL3mlqIs5qb+Fxm2d81Do7YIx3ig==",
       "dependencies": {
-        "@patternfly/react-core": "^5.0.0",
-        "@patternfly/react-icons": "^5.0.0",
-        "@patternfly/react-styles": "^5.0.0",
+        "@patternfly/react-core": "^5.1.1",
+        "@patternfly/react-icons": "^5.1.1",
+        "@patternfly/react-styles": "^5.1.1",
         "@types/d3": "^7.4.0",
         "@types/d3-force": "^1.2.1",
         "@types/dagre": "0.7.42",
@@ -4456,9 +4456,9 @@
       }
     },
     "node_modules/@types/js-yaml": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz",
-      "integrity": "sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA=="
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.7.tgz",
+      "integrity": "sha512-RJZP9WAMMr1514KbdSXkLRrKvYQacjr1+HWnY8pui/uBTBoSgD9ZGR17u/d4nb9NpERp0FkdLBe7hq8NIPBgkg=="
     },
     "node_modules/@types/json-schema": {
       "version": "7.0.13",
@@ -5619,9 +5619,9 @@
       }
     },
     "node_modules/axios": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
-      "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz",
+      "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==",
       "dependencies": {
         "follow-redirects": "^1.15.0",
         "form-data": "^4.0.0",
@@ -9345,11 +9345,11 @@
       "dev": true
     },
     "node_modules/focus-trap": {
-      "version": "7.4.3",
-      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.4.3.tgz",
-      "integrity": "sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==",
+      "version": "7.5.2",
+      "resolved": "https://registry.npmjs.org/focus-trap/-/focus-trap-7.5.2.tgz",
+      "integrity": "sha512-p6vGNNWLDGwJCiEjkSK6oERj/hEyI9ITsSwIUICBoKLlWiTWXJRfQibCwcoi50rTZdbi87qDtUlMCmQwsGSgPw==",
       "dependencies": {
-        "tabbable": "^6.1.2"
+        "tabbable": "^6.2.0"
       }
     },
     "node_modules/follow-redirects": {
@@ -13487,9 +13487,9 @@
       "link": true
     },
     "node_modules/keycloak-js": {
-      "version": "22.0.3",
-      "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-22.0.3.tgz",
-      "integrity": "sha512-QV96sDngWMlJ8Mq5l+A0BNuzZqJT+d8UM9vvGsPXFT+TDfPjXuFjtrpHH26X6YMY3JaCvH2mH9PXb3DGvEkuOw==",
+      "version": "22.0.4",
+      "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-22.0.4.tgz",
+      "integrity": "sha512-PLEQSkEtv+CBcrfnL8/IqKDrWMAHdehCWzohORg7+lR7xpBkQOwpOh82+U/PXE44i9ZEXdRsvcKE9e4dqFUErA==",
       "dependencies": {
         "base64-js": "^1.5.1",
         "js-sha256": "^0.9.0"
@@ -18894,9 +18894,13 @@
       }
     },
     "node_modules/uuid": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
-      "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
       "bin": {
         "uuid": "dist/bin/uuid"
       }
@@ -20318,9 +20322,9 @@
       }
     },
     "node_modules/zustand": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.1.tgz",
-      "integrity": "sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==",
+      "version": "4.4.3",
+      "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.4.3.tgz",
+      "integrity": "sha512-oRy+X3ZazZvLfmv6viIaQmtLOMeij1noakIsK/Y47PWYhT8glfXzQ4j0YcP5i0P0qI1A4rIB//SGROGyZhx91A==",
       "dependencies": {
         "use-sync-external-store": "1.2.0"
       },
diff --git a/karavan-web/karavan-app/src/main/webui/package.json b/karavan-web/karavan-app/src/main/webui/package.json
index 78bd5f04..91fb88d5 100644
--- a/karavan-web/karavan-app/src/main/webui/package.json
+++ b/karavan-web/karavan-app/src/main/webui/package.json
@@ -3,8 +3,11 @@
   "version": "4.0.1",
   "private": true,
   "scripts": {
-    "copy-designer": "cp -r ../../../../../karavan-designer/src/designer src && cp -r ../../../../../karavan-designer/src/knowledgebase src",
-    "start": "export PORT=3003 && npm run copy-designer && react-scripts start",
+    "copy-designer": "cp -r ../../../../../karavan-designer/src/designer src",
+    "copy-knowledgebase": "cp -r ../../../../../karavan-designer/src/knowledgebase src",
+    "copy-topology": "cp -r ../../../../../karavan-designer/src/topology src",
+    "copy-code": " npm run copy-designer &&  npm run copy-knowledgebase &&  npm run copy-topology",
+    "start": "export PORT=3003 && npm run copy-code && react-scripts start",
     "build": "npm run copy-designer && DISABLE_ESLINT_PLUGIN=true react-scripts build"
   },
   "proxy": "http://127.0.0.1:8080/",
@@ -27,29 +30,29 @@
   },
   "dependencies": {
     "@microsoft/fetch-event-source": "^2.0.1",
-    "@monaco-editor/react": "4.5.1",
-    "@patternfly/patternfly": "^5.0.2",
-    "@patternfly/react-charts": "^7.0.0",
-    "@patternfly/react-core": "^5.0.0",
+    "@monaco-editor/react": "4.6.0",
+    "@patternfly/patternfly": "^5.1.0",
+    "@patternfly/react-charts": "^7.1.1",
+    "@patternfly/react-core": "^5.1.1",
     "@patternfly/react-log-viewer": "^5.0.0",
-    "@patternfly/react-table": "^5.0.0",
-    "@patternfly/react-topology": "^5.0.0",
-    "@types/js-yaml": "4.0.5",
+    "@patternfly/react-table": "^5.1.1",
+    "@patternfly/react-topology": "^5.1.0",
+    "@types/js-yaml": "4.0.7",
     "@types/node": "18.16.3",
     "@types/uuid": "9.0.1",
-    "axios": "1.4.0",
+    "axios": "1.5.1",
     "buffer": "6.0.3",
     "dagre": "0.8.5",
     "file-saver": "2.0.5",
     "html-to-image": "1.11.11",
     "karavan-core": "file:../../../../../karavan-core",
-    "keycloak-js": "22.0.3",
+    "keycloak-js": "22.0.4",
     "react": "18.2.0",
     "react-dom": "18.2.0",
     "react-router-dom": "^6.15.0",
     "rxjs": "7.8.1",
-    "uuid": "9.0.0",
-    "zustand": "^4.4.1"
+    "uuid": "9.0.1",
+    "zustand": "^4.4.3"
   },
   "devDependencies": {
     "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
diff --git a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx
index 0d246b20..305b7859 100644
--- a/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/designer/route/DslElement.tsx
@@ -46,9 +46,9 @@ export function DslElement(props: Props) {
 
     const [integration] = useIntegrationStore((s) => [s.integration, s.setIntegration], shallow)
 
-    const [selectedUuids, setShowMoveConfirmation, hideLogDSL, setMoveElements] =
+    const [selectedUuids, selectedStep, showMoveConfirmation, setShowMoveConfirmation, hideLogDSL, setMoveElements] =
         useDesignerStore((s) =>
-            [s.selectedUuids, s.setShowMoveConfirmation, s.hideLogDSL, s.setMoveElements], shallow)
+            [s.selectedUuids, s.selectedStep, s.showMoveConfirmation, s.setShowMoveConfirmation, s.hideLogDSL, s.setMoveElements], shallow)
     const [isDragging, setIsDragging] = useState<boolean>(false);
 
     const [isDraggedOver, setIsDraggedOver] = useState<boolean>(false);
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/ProjectPanel.tsx b/karavan-web/karavan-app/src/main/webui/src/project/ProjectPanel.tsx
index 422063df..577b400c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/ProjectPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/ProjectPanel.tsx
@@ -18,7 +18,7 @@
 import React, {useEffect} from 'react';
 import {
     Flex,
-    FlexItem, Tabs, Tab, PageSection, PageSectionVariants, Gallery
+    FlexItem, PageSection
 } from '@patternfly/react-core';
 import '../designer/karavan.css';
 import {FilesTab} from "./files/FilesTab";
@@ -29,11 +29,8 @@ import {ProjectBuildTab} from "./build/ProjectBuildTab";
 import {ProjectService} from "../api/ProjectService";
 import {shallow} from "zustand/shallow";
 import {ImagesPanel} from "./build/ImagesPanel";
-import {ContainerButtons} from "./container/ContainerButtons";
 import {ProjectContainerTab} from "./container/ProjectContainerTab";
-import {KameletModal} from "../knowledgebase/kamelets/KameletModal";
-import {KameletCard} from "../knowledgebase/kamelets/KameletCard";
-import {TopologyTab} from "./topology/TopologyTab";
+import {ProjectTopologyTab} from "./topology/ProjectTopologyTab";
 
 export function ProjectPanel() {
 
@@ -58,7 +55,7 @@ export function ProjectPanel() {
     const buildIn = isBuildIn();
     const isTopology = tab === 'topology';
     return isTopology
-        ? (<TopologyTab/>)
+        ? (<ProjectTopologyTab/>)
         : (<PageSection padding={{default: 'noPadding'}} className="scrollable-out">
             <PageSection isFilled padding={{default: 'noPadding'}} className="scrollable-in">
                 <Flex direction={{default: "column"}} spaceItems={{default: "spaceItemsNone"}}>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx b/karavan-web/karavan-app/src/main/webui/src/project/topology/ProjectTopologyTab.tsx
similarity index 52%
copy from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
copy to karavan-web/karavan-app/src/main/webui/src/project/topology/ProjectTopologyTab.tsx
index f77abafe..9df98a40 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/project/topology/ProjectTopologyTab.tsx
@@ -16,31 +16,39 @@
  */
 
 import * as React from 'react';
-import {
-    Button,
-    ToolbarItem, Tooltip
-} from '@patternfly/react-core';
-import { useFileStore} from "../../api/ProjectStore";
+import {useFilesStore, useFileStore} from "../../api/ProjectStore";
 import {shallow} from "zustand/shallow";
-import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
+import {TopologyTab} from "../../topology/TopologyTab";
+import {useEffect} from "react";
+import {IntegrationFile} from "../../topology/TopologyStore";
 import {CreateFileModal} from "../files/CreateFileModal";
 
-export const TopologyToolbar: React.FC = () => {
+export const ProjectTopologyTab: React.FC = () => {
 
     const [setFile] = useFileStore((s) => [s.setFile], shallow);
+    const [files] = useFilesStore((s) => [s.files], shallow);
+
+    useEffect(() => {
+        // console.log(files.map(f => f.name));
+        // setFiles(files.map(f => new IntegrationFile(f.name, f.code)));
+    }, []);
+
+
+    function selectFile(fileName: string) {
+        const file = files.filter(f => f.name === fileName)?.at(0);
+        if (file) {
+            setFile('select', file);
+        }
+    }
 
     return (
-        <ToolbarItem align={{default: "alignRight"}}>
-            <Tooltip content={"Add new integration"}>
-                <Button size="sm"
-                        variant={"primary"}
-                        icon={<PlusIcon/>}
-                        onClick={e => setFile("create")}
-                >
-                    Create
-                </Button>
-            </Tooltip>
+        <>
+            <TopologyTab
+                files={files.map(f => new IntegrationFile(f.name, f.code))}
+                onClickCreateButton={() => setFile('create')}
+                onSetFile={(fileName) => selectFile(fileName)}
+            />
             <CreateFileModal types={['INTEGRATION']}/>
-        </ToolbarItem>
-    )
-}
\ No newline at end of file
+        </>
+    );
+};
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/CustomEdge.tsx
similarity index 87%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx
rename to karavan-web/karavan-app/src/main/webui/src/topology/CustomEdge.tsx
index 0eb8e0eb..bd4fa92e 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomEdge.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/CustomEdge.tsx
@@ -18,12 +18,10 @@
 import * as React from 'react';
 
 import './topology.css';
-import {DefaultEdge, DefaultGroup, observer} from '@patternfly/react-topology';
+import {DefaultEdge, observer} from '@patternfly/react-topology';
 
 
 const CustomEdge: React.FC<any> = observer(({ element, ...rest }) => {
-    const data = element.getData();
-
     return (
         <DefaultEdge element={element} {...rest}>
         </DefaultEdge>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/CustomGroup.tsx
similarity index 94%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx
rename to karavan-web/karavan-app/src/main/webui/src/topology/CustomGroup.tsx
index 7df861ce..9e366c7c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomGroup.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/CustomGroup.tsx
@@ -22,7 +22,6 @@ import { DefaultGroup, observer} from '@patternfly/react-topology';
 
 
 const CustomGroup: React.FC<any> = observer(({ element, ...rest }) => {
-    const data = element.getData();
 
     return (
         <DefaultGroup element={element} {...rest}>
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/CustomNode.tsx
similarity index 92%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx
rename to karavan-web/karavan-app/src/main/webui/src/topology/CustomNode.tsx
index 12492fdf..2d87457d 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/CustomNode.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/CustomNode.tsx
@@ -19,8 +19,8 @@ import * as React from 'react';
 import {RegionsIcon} from '@patternfly/react-icons';
 
 import {DefaultNode, observer} from '@patternfly/react-topology';
-import {getDesignerIcon} from "../../designer/utils/KaravanIcons";
-import {CamelUi} from "../../designer/utils/CamelUi";
+import {getDesignerIcon} from "../designer/utils/KaravanIcons";
+import {CamelUi} from "../designer/utils/CamelUi";
 import './topology.css';
 
 function getIcon(data: any) {
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyApi.tsx
similarity index 97%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx
rename to karavan-web/karavan-app/src/main/webui/src/topology/TopologyApi.tsx
index d9ec3ba9..44ff57a2 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyApi.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyApi.tsx
@@ -29,7 +29,6 @@ import {
     withPanZoom, withSelection
 } from '@patternfly/react-topology';
 import CustomNode from "./CustomNode";
-import {ProjectFile} from "../../api/ProjectModels";
 import {Integration} from "karavan-core/lib/model/IntegrationDefinition";
 import {CamelDefinitionYaml} from "karavan-core/lib/api/CamelDefinitionYaml";
 import {TopologyUtils} from "karavan-core/lib/api/TopologyUtils";
@@ -41,10 +40,11 @@ import {
 } from "karavan-core/lib/model/TopologyDefinition";
 import CustomGroup from "./CustomGroup";
 import CustomEdge from "./CustomEdge";
+import {IntegrationFile} from "./TopologyStore";
 
 const NODE_DIAMETER = 60;
 
-export function getIntegrations(files: ProjectFile[]): Integration[] {
+export function getIntegrations(files: IntegrationFile[]): Integration[] {
     return files.filter((file) => file.name.endsWith(".camel.yaml")).map((file) => {
         return CamelDefinitionYaml.yamlToIntegration(file.name, file.code);
     })
@@ -207,7 +207,7 @@ export function getInternalEdges(tons: TopologyOutgoingNode[], tins: TopologyInc
     return result;
 }
 
-export function getModel(files: ProjectFile[]): Model {
+export function getModel(files: IntegrationFile[]): Model {
     const integrations = getIntegrations(files);
     const tins = TopologyUtils.findTopologyIncomingNodes(integrations);
     const troutes = TopologyUtils.findTopologyRouteNodes(integrations);
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyPropertiesPanel.tsx
similarity index 81%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx
rename to karavan-web/karavan-app/src/main/webui/src/topology/TopologyPropertiesPanel.tsx
index 48aabcd7..24deca24 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyPropertiesPanel.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyPropertiesPanel.tsx
@@ -15,23 +15,23 @@
  * limitations under the License.
  */
 import React from 'react';
-import '../../designer/karavan.css';
+import '../designer/karavan.css';
 import {shallow} from "zustand/shallow";
 import {TopologySideBar} from "@patternfly/react-topology";
 import {useTopologyStore} from "./TopologyStore";
-import {DslProperties} from "../../designer/route/DslProperties";
+import {DslProperties} from "../designer/route/DslProperties";
 import {Button, Flex, FlexItem, Text, Tooltip, TooltipPosition} from "@patternfly/react-core";
 import CloseIcon from "@patternfly/react-icons/dist/esm/icons/times-icon";
-import {useFilesStore, useFileStore} from "../../api/ProjectStore";
 
-export function TopologyPropertiesPanel () {
+interface Props {
+    onSetFile: (fileName: string) => void
+}
+
+export function TopologyPropertiesPanel (props: Props) {
 
-    const [setFile] = useFileStore((s) => [s.setFile], shallow);
-    const [files] = useFilesStore((s) => [s.files], shallow);
     const [selectedIds, setSelectedIds, fileName] = useTopologyStore((s) =>
         [s.selectedIds, s.setSelectedIds, s.fileName], shallow);
 
-
     function getHeader() {
         return (
             <Flex className="properties-header" direction={{default: "row"}} justifyContent={{default: "justifyContentFlexStart"}}>
@@ -41,10 +41,7 @@ export function TopologyPropertiesPanel () {
                 <FlexItem>
                     <Button variant="link" onClick={event => {
                         if (fileName) {
-                            const file = files.filter(f => f.name === fileName)?.at(0);
-                            if (file) {
-                                setFile('select', file);
-                            }
+                            props.onSetFile(fileName);
                         }
                     }}
                     >{fileName}
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyStore.ts
similarity index 89%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts
rename to karavan-web/karavan-app/src/main/webui/src/topology/TopologyStore.ts
index 750d1e16..5bbdf124 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyStore.ts
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyStore.ts
@@ -18,6 +18,16 @@
 import {createWithEqualityFn} from "zustand/traditional";
 import {shallow} from "zustand/shallow";
 
+export class IntegrationFile {
+    name: string = '';
+    code: string = '';
+
+    constructor(name: string, code: string) {
+        this.name = name;
+        this.code = code;
+    }
+}
+
 interface TopologyState {
     selectedIds: string []
     fileName?: string
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
similarity index 88%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx
rename to karavan-web/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
index 22e9dbc4..df48e0c0 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyTab.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyTab.tsx
@@ -30,16 +30,21 @@ import {
     SELECTION_EVENT, Model,
 } from '@patternfly/react-topology';
 import {customComponentFactory, getModel} from "./TopologyApi";
-import {useFilesStore} from "../../api/ProjectStore";
 import {shallow} from "zustand/shallow";
-import {useTopologyStore} from "./TopologyStore";
+import {IntegrationFile, useTopologyStore} from "./TopologyStore";
 import {TopologyPropertiesPanel} from "./TopologyPropertiesPanel";
 import {TopologyToolbar} from "./TopologyToolbar";
-import {useDesignerStore} from "../../designer/DesignerStore";
+import {useDesignerStore} from "../designer/DesignerStore";
 
-export const TopologyTab: React.FC = () => {
 
-    const [files] = useFilesStore((s) => [s.files], shallow);
+interface Props {
+    files: IntegrationFile[],
+    onClickCreateButton: () => void
+    onSetFile: (fileName: string) => void
+}
+
+export function TopologyTab (props: Props) {
+
     const [selectedIds, setSelectedIds, setFileName] = useTopologyStore((s) =>
         [s.selectedIds, s.setSelectedIds, s.setFileName], shallow);
     const [setSelectedStep] = useDesignerStore((s) => [s.setSelectedStep], shallow)
@@ -62,7 +67,7 @@ export const TopologyTab: React.FC = () => {
     }
 
     const controller = React.useMemo(() => {
-        const model = getModel(files);
+        const model = getModel(props.files);
         const newController = new Visualization();
         newController.registerLayoutFactory((_, graph) => new DagreLayout(graph));
         newController.registerComponentFactory(customComponentFactory);
@@ -81,15 +86,15 @@ export const TopologyTab: React.FC = () => {
 
     React.useEffect(() => {
         setSelectedIds([])
-        const model = getModel(files);
+        const model = getModel(props.files);
         controller.fromModel(model, false);
     }, []);
 
     return (
         <TopologyView
             className="topology-panel"
-            contextToolbar={<TopologyToolbar/>}
-            sideBar={<TopologyPropertiesPanel/>}
+            contextToolbar={<TopologyToolbar onClickCreateButton={props.onClickCreateButton}/>}
+            sideBar={<TopologyPropertiesPanel onSetFile={props.onSetFile}/>}
             controlBar={
                 <TopologyControlBar
                     controlButtons={createTopologyControlButtons({
@@ -117,4 +122,4 @@ export const TopologyTab: React.FC = () => {
             </VisualizationProvider>
         </TopologyView>
     );
-};
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyToolbar.tsx
similarity index 78%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
rename to karavan-web/karavan-app/src/main/webui/src/topology/TopologyToolbar.tsx
index f77abafe..2d9fc55c 100644
--- a/karavan-web/karavan-app/src/main/webui/src/project/topology/TopologyToolbar.tsx
+++ b/karavan-web/karavan-app/src/main/webui/src/topology/TopologyToolbar.tsx
@@ -20,14 +20,13 @@ import {
     Button,
     ToolbarItem, Tooltip
 } from '@patternfly/react-core';
-import { useFileStore} from "../../api/ProjectStore";
-import {shallow} from "zustand/shallow";
 import PlusIcon from "@patternfly/react-icons/dist/esm/icons/plus-icon";
-import {CreateFileModal} from "../files/CreateFileModal";
 
-export const TopologyToolbar: React.FC = () => {
+interface Props {
+    onClickCreateButton: () => void
+}
 
-    const [setFile] = useFileStore((s) => [s.setFile], shallow);
+export function TopologyToolbar (props: Props) {
 
     return (
         <ToolbarItem align={{default: "alignRight"}}>
@@ -35,12 +34,11 @@ export const TopologyToolbar: React.FC = () => {
                 <Button size="sm"
                         variant={"primary"}
                         icon={<PlusIcon/>}
-                        onClick={e => setFile("create")}
+                        onClick={e => props.onClickCreateButton()}
                 >
                     Create
                 </Button>
             </Tooltip>
-            <CreateFileModal types={['INTEGRATION']}/>
         </ToolbarItem>
     )
 }
\ No newline at end of file
diff --git a/karavan-web/karavan-app/src/main/webui/src/project/topology/topology.css b/karavan-web/karavan-app/src/main/webui/src/topology/topology.css
similarity index 100%
rename from karavan-web/karavan-app/src/main/webui/src/project/topology/topology.css
rename to karavan-web/karavan-app/src/main/webui/src/topology/topology.css