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

abhioncbr pushed a commit to branch release-1.3.0-rc1
in repository https://gitbox.apache.org/repos/asf/pinot.git

commit bae3fcc899be84fb965e2774f9134577e20d67e3
Author: Jayesh Choudhary <jayeshchoudhary...@gmail.com>
AuthorDate: Wed Jan 22 06:14:00 2025 -0800

    feat(ui): add option to show visualized query stats (#14848)
---
 .../components/Query/VisualizeQueryStageStats.tsx  | 201 ++++++
 .../src/main/resources/app/pages/Query.tsx         |  46 +-
 .../src/main/resources/package-lock.json           | 766 ++++++++++++++++++++-
 pinot-controller/src/main/resources/package.json   |   8 +-
 4 files changed, 994 insertions(+), 27 deletions(-)

diff --git 
a/pinot-controller/src/main/resources/app/components/Query/VisualizeQueryStageStats.tsx
 
b/pinot-controller/src/main/resources/app/components/Query/VisualizeQueryStageStats.tsx
new file mode 100644
index 0000000000..ddf7a3fc7e
--- /dev/null
+++ 
b/pinot-controller/src/main/resources/app/components/Query/VisualizeQueryStageStats.tsx
@@ -0,0 +1,201 @@
+/**
+ * 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 ReactFlow, { Background, Controls, MiniMap, Handle, Node, Edge } from 
"react-flow-renderer";
+import dagre from "dagre";
+import { Typography, useTheme } from "@material-ui/core";
+import "react-flow-renderer/dist/style.css";
+import isEmpty from "lodash/isEmpty";
+
+/**
+ * Main component to visualize query stage stats as a flowchart.
+ */
+export const VisualizeQueryStageStats = ({ stageStats }) => {
+  const { nodes, edges } = generateFlowElements(stageStats); // Generate nodes 
and edges from input data
+  
+  if(isEmpty(stageStats)) {
+    return (
+      <Typography style={{height: "100px", textAlign: "center"}} 
variant="body1">
+        No stats available
+      </Typography>
+    );
+  }
+
+  return (
+    <div style={{ height: 500 }}>
+      <ReactFlow
+        nodes={nodes}
+        edges={edges}
+        fitView
+        nodeTypes={nodeTypes} // Use custom node types
+        zoomOnScroll={false}
+      >
+        <Background />
+        <Controls showInteractive={false} />
+        <MiniMap />
+      </ReactFlow>
+    </div>
+  );
+};
+
+// ------------------------------------------------------------
+// Helper functions and constants
+
+// Constants for node styling and layout
+const NODE_PADDING = 10;
+const NODE_HEADER_CONTENT_MARGIN = 5;
+const NODE_HEADER_HEIGHT = 20;
+const NODE_CONTENT_HEIGHT = 16;
+const NODE_TEXT_CHAR_WIDTH = 7;
+const NODE_MIN_WIDTH = 150;
+
+/**
+ * Calculates the dimensions of a node based on its content.
+ */
+const calculateNodeDimensions = (data) => {
+  const contentWidth = Math.max(
+    Object.entries(data)
+      .map(([key, value]) => key.length + String(value).length + 1) // 
Estimate character count in the content
+      .reduce((max, length) => Math.max(max, length), 0) * 
NODE_TEXT_CHAR_WIDTH,
+    NODE_MIN_WIDTH
+  );
+
+  const contentHeight =
+    Object.keys(data).length * NODE_CONTENT_HEIGHT + // Height for each data 
line
+    NODE_HEADER_HEIGHT + // Height for the header
+    NODE_HEADER_CONTENT_MARGIN * 2 + // Margin between header and content
+    NODE_PADDING * 2; // Padding around the node
+
+  return { width: contentWidth + NODE_PADDING * 2, height: contentHeight };
+};
+
+/**
+ * Applies Dagre layout to position nodes and edges.
+ */
+const layoutNodesAndEdges = (nodes, edges, direction = "TB") => {
+  const dagreGraph = new dagre.graphlib.Graph();
+  dagreGraph.setDefaultEdgeLabel(() => ({})); // Default edge properties
+  dagreGraph.setGraph({ rankdir: direction }); // Layout direction
+
+  // Add nodes to the graph
+  nodes.forEach((node) => {
+    dagreGraph.setNode(node.id, { width: node.width, height: node.height });
+  });
+
+  // Add edges to the graph
+  edges.forEach((edge) => {
+    dagreGraph.setEdge(edge.source, edge.target);
+  });
+
+  // Perform Dagre layout
+  dagre.layout(dagreGraph);
+
+  const isHorizontal = direction === "LR";
+  return {
+    nodes: nodes.map((node) => {
+      const layoutedNode = dagreGraph.node(node.id); // Get node's position
+      return {
+        ...node,
+        position: {
+          x: layoutedNode.x - node.width / 2, // Center node horizontally
+          y: layoutedNode.y - node.height / 2, // Center node vertically
+        },
+        targetPosition: isHorizontal ? "left" : "top",
+        sourcePosition: isHorizontal ? "right" : "bottom",
+      };
+    }),
+    edges,
+  };
+};
+
+/**
+ * Recursively generates nodes and edges for the flowchart from a hierarchical 
data structure.
+ */
+const generateFlowElements = (stats) => {
+  const nodes: Node[] = [];
+  const edges: Edge[] = [];
+
+  /**
+   * Traverses the hierarchy and builds nodes and edges.
+   */
+  const traverseTree = (node, level, index, parentId) => {
+    const { children, ...data } = node;
+    const id = `${level}-${index}`; // Unique ID for the node
+    const { width, height } = calculateNodeDimensions(data);
+
+    // Add the node
+    nodes.push({ id, type: "customNode", data, position: { x: 0, y: 0 }, 
width, height });
+
+    // Add an edge if this node has a parent
+    if (parentId) {
+      edges.push({ id: `edge-${parentId}-${id}`, source: parentId, target: id 
});
+    }
+
+    // Recursively process children
+    children?.forEach((child, idx) => traverseTree(child, level + 1, index + 
idx, id));
+  };
+
+  traverseTree(stats, 0, 0, null); // Start traversal from the root node
+  return layoutNodesAndEdges(nodes, edges);
+};
+
+/**
+ * Custom Node Renderer for React Flow.
+ */
+const CustomNode = ({ data, ...props }) => {
+  const theme = useTheme();
+  return (
+    <div
+      style={{
+        border: "1px solid #ccc",
+        borderRadius: "8px",
+        backgroundColor: "#fff",
+        padding: NODE_PADDING,
+        boxShadow: "0 2px 5px rgba(0, 0, 0, 0.1)",
+        minWidth: NODE_MIN_WIDTH,
+      }}
+    >
+      <Handle type="source" position={props.sourcePosition} />
+      <div
+        style={{
+          fontWeight: "bold",
+          color: theme.palette.primary.main,
+          fontSize: "18px",
+          lineHeight: `${NODE_HEADER_HEIGHT}px`,
+        }}
+      >
+        {data.type || "Unknown Type"} {/* Display node type */}
+      </div>
+      <hr style={{ margin: NODE_HEADER_CONTENT_MARGIN, color: "#ddd" }} />
+      <div style={{ fontSize: "14px", lineHeight: `${NODE_CONTENT_HEIGHT}px` 
}}>
+        {Object.entries(data).map(([key, value]) => (
+          <div key={key}>
+            <strong>{key}:</strong> {String(value)} {/* Display key-value 
pairs */}
+          </div>
+        ))}
+      </div>
+      <Handle type="target" position={props.targetPosition} />
+    </div>
+  );
+};
+
+// Define custom node types for React Flow
+const nodeTypes = {
+  customNode: CustomNode,
+};
diff --git a/pinot-controller/src/main/resources/app/pages/Query.tsx 
b/pinot-controller/src/main/resources/app/pages/Query.tsx
index 364765c50c..7caee02661 100644
--- a/pinot-controller/src/main/resources/app/pages/Query.tsx
+++ b/pinot-controller/src/main/resources/app/pages/Query.tsx
@@ -20,7 +20,7 @@
 
 import React, { useEffect, useState } from 'react';
 import { makeStyles } from '@material-ui/core/styles';
-import { Grid, Checkbox, Button, FormControl, Input, InputLabel, Box, 
Typography } from '@material-ui/core';
+import { Grid, Checkbox, Button, FormControl, Input, InputLabel, Box, 
Typography, ButtonGroup } from '@material-ui/core';
 import Alert from '@material-ui/lab/Alert';
 import FileCopyIcon from '@material-ui/icons/FileCopy';
 import { SqlException, TableData } from 'Models';
@@ -48,6 +48,13 @@ import '../styles/styles.css';
 import {Resizable} from "re-resizable";
 import { useHistory, useLocation } from 'react-router';
 import sqlFormatter from '@sqltools/formatter';
+import { VisualizeQueryStageStats } from 
'../components/Query/VisualizeQueryStageStats';
+
+enum ResultViewType {
+  TABULAR = 'tabular',
+  JSON = 'json',
+  VISUAL = 'visual',
+}
 
 const useStyles = makeStyles((theme) => ({
   title: {
@@ -200,13 +207,14 @@ const QueryPage = () => {
     columns: [],
     records: [],
   });
+  const [resultViewType, setResultViewType] = useState(ResultViewType.TABULAR);
+  const [stageStats, setStageStats] = useState({});
 
   const [warnings, setWarnings] = useState<Array<string>>([]);
 
   const [checked, setChecked] = React.useState({
     tracing: queryParam.get('tracing') === 'true',
     useMSE: queryParam.get('useMSE') === 'true',
-    showResultJSON: false,
   });
 
   const queryExecuted = React.useRef(false);
@@ -325,6 +333,7 @@ const QueryPage = () => {
     setResultData(results.result || { columns: [], records: [] });
     setQueryStats(results.queryStats || { columns: responseStatCols, records: 
[] });
     setOutputResult(JSON.stringify(results.data, null, 2) || '');
+    setStageStats(results?.data?.stageStats || {});
     setWarnings(extractWarnings(results));
     setQueryLoader(false);
     queryExecuted.current = false;
@@ -405,8 +414,7 @@ const QueryPage = () => {
       setInputQuery(query);
       setChecked({
         tracing: queryParam.get('tracing') === 'true',
-        useMSE: queryParam.get('useMse') === 'true',
-        showResultJSON: checked.showResultJSON,
+        useMSE: queryParam.get('useMse') === 'true'
       });
       setQueryTimeout(Number(queryParam.get('timeout') || '') || '');
       setBoolFlag(!boolFlag);
@@ -663,19 +671,20 @@ const QueryPage = () => {
                         ) : null}
 
                         <FormControlLabel
+                          labelPlacement='start'
                           control={
-                            <Switch
-                              checked={checked.showResultJSON}
-                              onChange={handleChange}
-                              name="showResultJSON"
-                              color="primary"
-                            />
+                            <ButtonGroup color='primary' size='small'>
+                              <Button onClick={() => 
setResultViewType(ResultViewType.TABULAR)} variant={resultViewType === 
ResultViewType.TABULAR ? "contained" : "outlined"}>Tabular</Button>
+                              <Button onClick={() => 
setResultViewType(ResultViewType.JSON)} variant={resultViewType === 
ResultViewType.JSON ? "contained" : "outlined"}>Json</Button>
+                              <Button onClick={() => 
setResultViewType(ResultViewType.VISUAL)} variant={resultViewType === 
ResultViewType.VISUAL ? "contained" : "outlined"}>Visual</Button>
+                            </ButtonGroup>
                           }
-                          label="Show JSON format"
+                          label={<Typography style={{marginRight: 
"8px"}}>View</Typography>}
+                          style={{marginRight: 0}}
                           className={classes.runNowBtn}
                         />
                       </Grid>
-                      {!checked.showResultJSON ? (
+                      {resultViewType === ResultViewType.TABULAR && (
                         <CustomizedTables
                           title="Query Result"
                           data={resultData}
@@ -683,7 +692,8 @@ const QueryPage = () => {
                           showSearchBox={true}
                           inAccordionFormat={true}
                         />
-                      ) : resultData.columns.length ? (
+                      )} 
+                      {resultViewType === ResultViewType.JSON && (
                         <SimpleAccordion
                           headerTitle="Query Result (JSON Format)"
                           showSearchBox={false}
@@ -695,7 +705,15 @@ const QueryPage = () => {
                             autoCursor={false}
                           />
                         </SimpleAccordion>
-                      ) : null}
+                      )}
+                      {resultViewType === ResultViewType.VISUAL && (
+                        <SimpleAccordion
+                          headerTitle="Query Stats Visualized"
+                          showSearchBox={false}
+                        >
+                          <VisualizeQueryStageStats stageStats={stageStats} />
+                        </SimpleAccordion>
+                      )}
                     </>
                   ) : null}
                 </Grid>
diff --git a/pinot-controller/src/main/resources/package-lock.json 
b/pinot-controller/src/main/resources/package-lock.json
index cdcfdd9d33..fa11376ec2 100644
--- a/pinot-controller/src/main/resources/package-lock.json
+++ b/pinot-controller/src/main/resources/package-lock.json
@@ -24,6 +24,7 @@
         "clsx": "1.1.1",
         "codemirror": "5.65.5",
         "cross-fetch": "3.1.5",
+        "dagre": "^0.8.5",
         "export-from-json": "1.6.0",
         "file": "0.2.2",
         "json-bigint": "1.0.0",
@@ -37,6 +38,7 @@
         "react-codemirror2": "7.2.1",
         "react-diff-viewer": "3.1.1",
         "react-dom": "16.13.1",
+        "react-flow-renderer": "^10.3.17",
         "react-hook-form": "6.15.8",
         "react-router-dom": "5.3.3",
         "react-spring": "8.0.27"
@@ -259,11 +261,11 @@
       }
     },
     "node_modules/@babel/runtime": {
-      "version": "7.18.3",
-      "resolved": 
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz";,
-      "integrity": 
"sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==",
+      "version": "7.26.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz";,
+      "integrity": 
"sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
       "dependencies": {
-        "regenerator-runtime": "^0.13.4"
+        "regenerator-runtime": "^0.14.0"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -282,6 +284,11 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/runtime/node_modules/regenerator-runtime": {
+      "version": "0.14.1",
+      "resolved": 
"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz";,
+      "integrity": 
"sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+    },
     "node_modules/@babel/template": {
       "version": "7.24.0",
       "resolved": 
"https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz";,
@@ -696,6 +703,228 @@
         "@types/tern": "*"
       }
     },
+    "node_modules/@types/d3": {
+      "version": "7.4.3",
+      "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz";,
+      "integrity": 
"sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",
+      "dependencies": {
+        "@types/d3-array": "*",
+        "@types/d3-axis": "*",
+        "@types/d3-brush": "*",
+        "@types/d3-chord": "*",
+        "@types/d3-color": "*",
+        "@types/d3-contour": "*",
+        "@types/d3-delaunay": "*",
+        "@types/d3-dispatch": "*",
+        "@types/d3-drag": "*",
+        "@types/d3-dsv": "*",
+        "@types/d3-ease": "*",
+        "@types/d3-fetch": "*",
+        "@types/d3-force": "*",
+        "@types/d3-format": "*",
+        "@types/d3-geo": "*",
+        "@types/d3-hierarchy": "*",
+        "@types/d3-interpolate": "*",
+        "@types/d3-path": "*",
+        "@types/d3-polygon": "*",
+        "@types/d3-quadtree": "*",
+        "@types/d3-random": "*",
+        "@types/d3-scale": "*",
+        "@types/d3-scale-chromatic": "*",
+        "@types/d3-selection": "*",
+        "@types/d3-shape": "*",
+        "@types/d3-time": "*",
+        "@types/d3-time-format": "*",
+        "@types/d3-timer": "*",
+        "@types/d3-transition": "*",
+        "@types/d3-zoom": "*"
+      }
+    },
+    "node_modules/@types/d3-array": {
+      "version": "3.2.1",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz";,
+      "integrity": 
"sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
+    },
+    "node_modules/@types/d3-axis": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz";,
+      "integrity": 
"sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-brush": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz";,
+      "integrity": 
"sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-chord": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz";,
+      "integrity": 
"sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg=="
+    },
+    "node_modules/@types/d3-color": {
+      "version": "3.1.3",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz";,
+      "integrity": 
"sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="
+    },
+    "node_modules/@types/d3-contour": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz";,
+      "integrity": 
"sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",
+      "dependencies": {
+        "@types/d3-array": "*",
+        "@types/geojson": "*"
+      }
+    },
+    "node_modules/@types/d3-delaunay": {
+      "version": "6.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz";,
+      "integrity": 
"sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw=="
+    },
+    "node_modules/@types/d3-dispatch": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz";,
+      "integrity": 
"sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ=="
+    },
+    "node_modules/@types/d3-drag": {
+      "version": "3.0.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz";,
+      "integrity": 
"sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-dsv": {
+      "version": "3.0.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz";,
+      "integrity": 
"sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g=="
+    },
+    "node_modules/@types/d3-ease": {
+      "version": "3.0.2",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz";,
+      "integrity": 
"sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="
+    },
+    "node_modules/@types/d3-fetch": {
+      "version": "3.0.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz";,
+      "integrity": 
"sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",
+      "dependencies": {
+        "@types/d3-dsv": "*"
+      }
+    },
+    "node_modules/@types/d3-force": {
+      "version": "3.0.10",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz";,
+      "integrity": 
"sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw=="
+    },
+    "node_modules/@types/d3-format": {
+      "version": "3.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz";,
+      "integrity": 
"sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g=="
+    },
+    "node_modules/@types/d3-geo": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz";,
+      "integrity": 
"sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==",
+      "dependencies": {
+        "@types/geojson": "*"
+      }
+    },
+    "node_modules/@types/d3-hierarchy": {
+      "version": "3.1.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz";,
+      "integrity": 
"sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg=="
+    },
+    "node_modules/@types/d3-interpolate": {
+      "version": "3.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz";,
+      "integrity": 
"sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+      "dependencies": {
+        "@types/d3-color": "*"
+      }
+    },
+    "node_modules/@types/d3-path": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz";,
+      "integrity": 
"sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ=="
+    },
+    "node_modules/@types/d3-polygon": {
+      "version": "3.0.2",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz";,
+      "integrity": 
"sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA=="
+    },
+    "node_modules/@types/d3-quadtree": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz";,
+      "integrity": 
"sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg=="
+    },
+    "node_modules/@types/d3-random": {
+      "version": "3.0.3",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz";,
+      "integrity": 
"sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ=="
+    },
+    "node_modules/@types/d3-scale": {
+      "version": "4.0.8",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz";,
+      "integrity": 
"sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
+      "dependencies": {
+        "@types/d3-time": "*"
+      }
+    },
+    "node_modules/@types/d3-scale-chromatic": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz";,
+      "integrity": 
"sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ=="
+    },
+    "node_modules/@types/d3-selection": {
+      "version": "3.0.11",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz";,
+      "integrity": 
"sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="
+    },
+    "node_modules/@types/d3-shape": {
+      "version": "3.1.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz";,
+      "integrity": 
"sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
+      "dependencies": {
+        "@types/d3-path": "*"
+      }
+    },
+    "node_modules/@types/d3-time": {
+      "version": "3.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz";,
+      "integrity": 
"sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="
+    },
+    "node_modules/@types/d3-time-format": {
+      "version": "4.0.3",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz";,
+      "integrity": 
"sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg=="
+    },
+    "node_modules/@types/d3-timer": {
+      "version": "3.0.2",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz";,
+      "integrity": 
"sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="
+    },
+    "node_modules/@types/d3-transition": {
+      "version": "3.0.9",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz";,
+      "integrity": 
"sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
+      "dependencies": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "node_modules/@types/d3-zoom": {
+      "version": "3.0.8",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz";,
+      "integrity": 
"sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
+      "dependencies": {
+        "@types/d3-interpolate": "*",
+        "@types/d3-selection": "*"
+      }
+    },
     "node_modules/@types/eslint-visitor-keys": {
       "version": "1.0.0",
       "resolved": 
"https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz";,
@@ -707,6 +936,11 @@
       "resolved": 
"https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz";,
       "integrity": 
"sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ=="
     },
+    "node_modules/@types/geojson": {
+      "version": "7946.0.15",
+      "resolved": 
"https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz";,
+      "integrity": 
"sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA=="
+    },
     "node_modules/@types/glob": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz";,
@@ -812,6 +1046,11 @@
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz";,
       "integrity": 
"sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA=="
     },
+    "node_modules/@types/resize-observer-browser": {
+      "version": "0.1.11",
+      "resolved": 
"https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz";,
+      "integrity": 
"sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ=="
+    },
     "node_modules/@types/scheduler": {
       "version": "0.16.2",
       "resolved": 
"https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz";,
@@ -2302,6 +2541,11 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/classcat": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz";,
+      "integrity": 
"sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w=="
+    },
     "node_modules/classnames": {
       "version": "2.3.1",
       "resolved": 
"https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz";,
@@ -3020,6 +3264,111 @@
       "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
       "dev": true
     },
+    "node_modules/d3-color": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz";,
+      "integrity": 
"sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-dispatch": {
+      "version": "3.0.1",
+      "resolved": 
"https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz";,
+      "integrity": 
"sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-drag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz";,
+      "integrity": 
"sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
+      "dependencies": {
+        "d3-dispatch": "1 - 3",
+        "d3-selection": "3"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-ease": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz";,
+      "integrity": 
"sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/d3-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-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-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.5",
+      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz";,
+      "integrity": 
"sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
+      "dependencies": {
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      }
+    },
     "node_modules/damerau-levenshtein": {
       "version": "1.0.8",
       "resolved": 
"https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz";,
@@ -5693,6 +6042,14 @@
       "integrity": 
"sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "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/handle-thing": {
       "version": "2.0.1",
       "resolved": 
"https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz";,
@@ -10270,6 +10627,29 @@
         "react": "^16.13.1"
       }
     },
+    "node_modules/react-flow-renderer": {
+      "version": "10.3.17",
+      "resolved": 
"https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz";,
+      "integrity": 
"sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ==",
+      "deprecated": "react-flow-renderer has been renamed to reactflow, please 
use this package from now on https://reactflow.dev/docs/guides/migrate-to-v11/";,
+      "dependencies": {
+        "@babel/runtime": "^7.18.9",
+        "@types/d3": "^7.4.0",
+        "@types/resize-observer-browser": "^0.1.7",
+        "classcat": "^5.0.3",
+        "d3-drag": "^3.0.0",
+        "d3-selection": "^3.0.0",
+        "d3-zoom": "^3.0.0",
+        "zustand": "^3.7.2"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "peerDependencies": {
+        "react": "16 || 17 || 18",
+        "react-dom": "16 || 17 || 18"
+      }
+    },
     "node_modules/react-hook-form": {
       "version": "6.15.8",
       "resolved": 
"https://registry.npmjs.org/react-hook-form/-/react-hook-form-6.15.8.tgz";,
@@ -10519,7 +10899,8 @@
     "node_modules/regenerator-runtime": {
       "version": "0.13.9",
       "resolved": 
"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz";,
-      "integrity": 
"sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+      "integrity": 
"sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
+      "dev": true
     },
     "node_modules/regex-not": {
       "version": "1.0.2",
@@ -14352,6 +14733,22 @@
       "engines": {
         "node": ">=6"
       }
+    },
+    "node_modules/zustand": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz";,
+      "integrity": 
"sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==",
+      "engines": {
+        "node": ">=12.7.0"
+      },
+      "peerDependencies": {
+        "react": ">=16.8"
+      },
+      "peerDependenciesMeta": {
+        "react": {
+          "optional": true
+        }
+      }
     }
   },
   "dependencies": {
@@ -14491,11 +14888,18 @@
       "peer": true
     },
     "@babel/runtime": {
-      "version": "7.18.3",
-      "resolved": 
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz";,
-      "integrity": 
"sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==",
+      "version": "7.26.0",
+      "resolved": 
"https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz";,
+      "integrity": 
"sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
       "requires": {
-        "regenerator-runtime": "^0.13.4"
+        "regenerator-runtime": "^0.14.0"
+      },
+      "dependencies": {
+        "regenerator-runtime": {
+          "version": "0.14.1",
+          "resolved": 
"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz";,
+          "integrity": 
"sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+        }
       }
     },
     "@babel/runtime-corejs3": {
@@ -14791,6 +15195,228 @@
         "@types/tern": "*"
       }
     },
+    "@types/d3": {
+      "version": "7.4.3",
+      "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz";,
+      "integrity": 
"sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",
+      "requires": {
+        "@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": "*"
+      }
+    },
+    "@types/d3-array": {
+      "version": "3.2.1",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz";,
+      "integrity": 
"sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg=="
+    },
+    "@types/d3-axis": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz";,
+      "integrity": 
"sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",
+      "requires": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "@types/d3-brush": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz";,
+      "integrity": 
"sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",
+      "requires": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "@types/d3-chord": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz";,
+      "integrity": 
"sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg=="
+    },
+    "@types/d3-color": {
+      "version": "3.1.3",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz";,
+      "integrity": 
"sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="
+    },
+    "@types/d3-contour": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz";,
+      "integrity": 
"sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",
+      "requires": {
+        "@types/d3-array": "*",
+        "@types/geojson": "*"
+      }
+    },
+    "@types/d3-delaunay": {
+      "version": "6.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz";,
+      "integrity": 
"sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw=="
+    },
+    "@types/d3-dispatch": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz";,
+      "integrity": 
"sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ=="
+    },
+    "@types/d3-drag": {
+      "version": "3.0.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz";,
+      "integrity": 
"sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
+      "requires": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "@types/d3-dsv": {
+      "version": "3.0.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz";,
+      "integrity": 
"sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g=="
+    },
+    "@types/d3-ease": {
+      "version": "3.0.2",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz";,
+      "integrity": 
"sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="
+    },
+    "@types/d3-fetch": {
+      "version": "3.0.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz";,
+      "integrity": 
"sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",
+      "requires": {
+        "@types/d3-dsv": "*"
+      }
+    },
+    "@types/d3-force": {
+      "version": "3.0.10",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz";,
+      "integrity": 
"sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw=="
+    },
+    "@types/d3-format": {
+      "version": "3.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz";,
+      "integrity": 
"sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g=="
+    },
+    "@types/d3-geo": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz";,
+      "integrity": 
"sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==",
+      "requires": {
+        "@types/geojson": "*"
+      }
+    },
+    "@types/d3-hierarchy": {
+      "version": "3.1.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz";,
+      "integrity": 
"sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg=="
+    },
+    "@types/d3-interpolate": {
+      "version": "3.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz";,
+      "integrity": 
"sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+      "requires": {
+        "@types/d3-color": "*"
+      }
+    },
+    "@types/d3-path": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.0.tgz";,
+      "integrity": 
"sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ=="
+    },
+    "@types/d3-polygon": {
+      "version": "3.0.2",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz";,
+      "integrity": 
"sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA=="
+    },
+    "@types/d3-quadtree": {
+      "version": "3.0.6",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz";,
+      "integrity": 
"sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg=="
+    },
+    "@types/d3-random": {
+      "version": "3.0.3",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz";,
+      "integrity": 
"sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ=="
+    },
+    "@types/d3-scale": {
+      "version": "4.0.8",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz";,
+      "integrity": 
"sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
+      "requires": {
+        "@types/d3-time": "*"
+      }
+    },
+    "@types/d3-scale-chromatic": {
+      "version": "3.1.0",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz";,
+      "integrity": 
"sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ=="
+    },
+    "@types/d3-selection": {
+      "version": "3.0.11",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz";,
+      "integrity": 
"sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="
+    },
+    "@types/d3-shape": {
+      "version": "3.1.7",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz";,
+      "integrity": 
"sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
+      "requires": {
+        "@types/d3-path": "*"
+      }
+    },
+    "@types/d3-time": {
+      "version": "3.0.4",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz";,
+      "integrity": 
"sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="
+    },
+    "@types/d3-time-format": {
+      "version": "4.0.3",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz";,
+      "integrity": 
"sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg=="
+    },
+    "@types/d3-timer": {
+      "version": "3.0.2",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz";,
+      "integrity": 
"sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="
+    },
+    "@types/d3-transition": {
+      "version": "3.0.9",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz";,
+      "integrity": 
"sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
+      "requires": {
+        "@types/d3-selection": "*"
+      }
+    },
+    "@types/d3-zoom": {
+      "version": "3.0.8",
+      "resolved": 
"https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz";,
+      "integrity": 
"sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
+      "requires": {
+        "@types/d3-interpolate": "*",
+        "@types/d3-selection": "*"
+      }
+    },
     "@types/eslint-visitor-keys": {
       "version": "1.0.0",
       "resolved": 
"https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz";,
@@ -14802,6 +15428,11 @@
       "resolved": 
"https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz";,
       "integrity": 
"sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ=="
     },
+    "@types/geojson": {
+      "version": "7946.0.15",
+      "resolved": 
"https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.15.tgz";,
+      "integrity": 
"sha512-9oSxFzDCT2Rj6DfcHF8G++jxBKS7mBqXl5xrRW+Kbvjry6Uduya2iiwqHPhVXpasAVMBYKkEPGgKhd3+/HZ6xA=="
+    },
     "@types/glob": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz";,
@@ -14909,6 +15540,11 @@
         "@types/react": "*"
       }
     },
+    "@types/resize-observer-browser": {
+      "version": "0.1.11",
+      "resolved": 
"https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.11.tgz";,
+      "integrity": 
"sha512-cNw5iH8JkMkb3QkCoe7DaZiawbDQEUX8t7iuQaRTyLOyQCR2h+ibBD4GJt7p5yhUHrlOeL7ZtbxNHeipqNsBzQ=="
+    },
     "@types/scheduler": {
       "version": "0.16.2",
       "resolved": 
"https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz";,
@@ -16133,6 +16769,11 @@
         }
       }
     },
+    "classcat": {
+      "version": "5.0.5",
+      "resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz";,
+      "integrity": 
"sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w=="
+    },
     "classnames": {
       "version": "2.3.1",
       "resolved": 
"https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz";,
@@ -16709,6 +17350,81 @@
       "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
       "dev": true
     },
+    "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=="
+    },
+    "d3-dispatch": {
+      "version": "3.0.1",
+      "resolved": 
"https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz";,
+      "integrity": 
"sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="
+    },
+    "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==",
+      "requires": {
+        "d3-dispatch": "1 - 3",
+        "d3-selection": "3"
+      }
+    },
+    "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=="
+    },
+    "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==",
+      "requires": {
+        "d3-color": "1 - 3"
+      }
+    },
+    "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=="
+    },
+    "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=="
+    },
+    "d3-transition": {
+      "version": "3.0.1",
+      "resolved": 
"https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz";,
+      "integrity": 
"sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
+      "requires": {
+        "d3-color": "1 - 3",
+        "d3-dispatch": "1 - 3",
+        "d3-ease": "1 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-timer": "1 - 3"
+      }
+    },
+    "d3-zoom": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz";,
+      "integrity": 
"sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
+      "requires": {
+        "d3-dispatch": "1 - 3",
+        "d3-drag": "2 - 3",
+        "d3-interpolate": "1 - 3",
+        "d3-selection": "2 - 3",
+        "d3-transition": "2 - 3"
+      }
+    },
+    "dagre": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz";,
+      "integrity": 
"sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
+      "requires": {
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      }
+    },
     "damerau-levenshtein": {
       "version": "1.0.8",
       "resolved": 
"https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz";,
@@ -18808,6 +19524,14 @@
       "integrity": 
"sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
+    "graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz";,
+      "integrity": 
"sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
+      "requires": {
+        "lodash": "^4.17.15"
+      }
+    },
     "handle-thing": {
       "version": "2.0.1",
       "resolved": 
"https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz";,
@@ -22397,6 +23121,21 @@
         "scheduler": "^0.19.1"
       }
     },
+    "react-flow-renderer": {
+      "version": "10.3.17",
+      "resolved": 
"https://registry.npmjs.org/react-flow-renderer/-/react-flow-renderer-10.3.17.tgz";,
+      "integrity": 
"sha512-bywiqVErlh5kCDqw3x0an5Ur3mT9j9CwJsDwmhmz4i1IgYM1a0SPqqEhClvjX+s5pU4nHjmVaGXWK96pwsiGcQ==",
+      "requires": {
+        "@babel/runtime": "^7.18.9",
+        "@types/d3": "^7.4.0",
+        "@types/resize-observer-browser": "^0.1.7",
+        "classcat": "^5.0.3",
+        "d3-drag": "^3.0.0",
+        "d3-selection": "^3.0.0",
+        "d3-zoom": "^3.0.0",
+        "zustand": "^3.7.2"
+      }
+    },
     "react-hook-form": {
       "version": "6.15.8",
       "resolved": 
"https://registry.npmjs.org/react-hook-form/-/react-hook-form-6.15.8.tgz";,
@@ -22598,7 +23337,8 @@
     "regenerator-runtime": {
       "version": "0.13.9",
       "resolved": 
"https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz";,
-      "integrity": 
"sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA=="
+      "integrity": 
"sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==",
+      "dev": true
     },
     "regex-not": {
       "version": "1.0.2",
@@ -25752,6 +26492,12 @@
         "camelcase": "^5.0.0",
         "decamelize": "^1.2.0"
       }
+    },
+    "zustand": {
+      "version": "3.7.2",
+      "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz";,
+      "integrity": 
"sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==",
+      "requires": {}
     }
   }
 }
diff --git a/pinot-controller/src/main/resources/package.json 
b/pinot-controller/src/main/resources/package.json
index 865af39bd4..1bfcad07bf 100644
--- a/pinot-controller/src/main/resources/package.json
+++ b/pinot-controller/src/main/resources/package.json
@@ -49,9 +49,9 @@
     "prettier": "2.0.5",
     "prettier-eslint": "9.0.1",
     "prettier-eslint-cli": "5.0.0",
-    "system": "2.0.1",
     "source-map-loader": "0.2.4",
     "style-loader": "1.3.0",
+    "system": "2.0.1",
     "ts-loader": "7.0.5",
     "typescript": "3.8.3",
     "url-loader": "4.1.1",
@@ -66,6 +66,7 @@
     "@material-ui/core": "4.11.0",
     "@material-ui/icons": "4.11.3",
     "@material-ui/lab": "4.0.0-alpha.51",
+    "@sqltools/formatter": "1.2.5",
     "@types/codemirror": "0.0.104",
     "@types/react": "16.14.26",
     "@types/react-dom": "16.9.16",
@@ -75,6 +76,7 @@
     "clsx": "1.1.1",
     "codemirror": "5.65.5",
     "cross-fetch": "3.1.5",
+    "dagre": "^0.8.5",
     "export-from-json": "1.6.0",
     "file": "0.2.2",
     "json-bigint": "1.0.0",
@@ -88,9 +90,9 @@
     "react-codemirror2": "7.2.1",
     "react-diff-viewer": "3.1.1",
     "react-dom": "16.13.1",
+    "react-flow-renderer": "^10.3.17",
     "react-hook-form": "6.15.8",
     "react-router-dom": "5.3.3",
-    "react-spring": "8.0.27",
-    "@sqltools/formatter": "1.2.5"
+    "react-spring": "8.0.27"
   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pinot.apache.org
For additional commands, e-mail: commits-h...@pinot.apache.org

Reply via email to