diff --git a/backend/deployments/workflow1/deployment.js b/backend/deployments/workflow1/deployment.js index 28f097d..cbfc988 100644 --- a/backend/deployments/workflow1/deployment.js +++ b/backend/deployments/workflow1/deployment.js @@ -403,6 +403,7 @@ const refractored=[{ "original_func_ids": ["zxd0", "rysh", "37u3"] } ], + "wf_partitions": [ { "partition_label": "label for datacentre", diff --git a/backend/middelware.js b/backend/middelware.js index 4c9e3b9..7e3799f 100644 --- a/backend/middelware.js +++ b/backend/middelware.js @@ -476,4 +476,739 @@ var output2 = input.map(obj => { }); console.log(JSON.stringify(output2, null, 2)); - \ No newline at end of file + + +// +var inp={ + "WorkflowOwner": "String", + "Workflow Id": "uuid", + "Refactored Workflow Id": "82097845-56fb-48ec-8bcd-3f1ab70c46c1", + "WorkflowName": "ImgProcessingFanoutMulticloudAWSToAzure", + "WorkflowDescription": "String", + "WorkflowVersion": "String", + "refactoring_strategy": "", + "PackageUrl": "String", + "wf_fusion_config": [ + { + "fused_func_id": "3ycp", + "original_func_ids": ["zxd0", "rysh", "37u3"] + } + ], + "wf_partitions": [ + { + "partition_label": "label for datacentre", + "func_ids": ["zxd0", "rysh", "37u3"] + } + ], + "Nodes": [ + { + "NodeId": "fm9m", + "ModuleName": "String", + "NodeName": "Resize", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Resize", + "EntryPoint": "func.py", + "MemoryInMB": 512, + "IsFused": "boolean" , + "IsAutoGenerated": "boolean" + }, + { + "NodeId": "b74b", + "NodeName": "Mobilenet", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Mobilenet", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "3ycp", + "NodeName": "Resnet", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Resnet", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "bq21", + "NodeName": "Squeezenet", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Squeezenet", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "tyvq", + "NodeName": "Union", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/Union", + "EntryPoint": "func.py", + "MemoryInMB": 512 + }, + { + "NodeId": "256", + "NodeName": "CollectLogs", + "Path": "examples/image-processing-diamond-multicloud-aws-to-az/src/CollectLogs", + "EntryPoint": "func.py", + "MemoryInMB": 512 + } + ], + "graphs": { + "nodes": [ + { "id": 9, "label": "Mobilenet","color":"#0080FF" }, + { "id": 7, "label": "Resnet","color":"#FF9900" }, + { "id": 3, "label": "Squeezenet","color":"#0080FF" }, + { "id": 2, "label": "Union" ,"color":"#FF9900"}, + { "id": 4, "label": "CollectLogs","color":"#FF9900" } + ], + "edges": [ + { "from": 9, "to": 7 }, + { "from": 9, "to": 3 }, + { "from": 7, "to": 2 }, + { "from": 7, "to": 4 } + ] + }, + + "Edges": [ + { + "src_node_id": "fm9m", + "sink_node_id": "b74b", + "is_auto_generated": "boolean" + }, + { + "b74b": ["3ycp"] + }, + { + "3ycp": ["bq21"] + }, + { + "bq21": ["tyvq"] + } + ] +} +var inp1={ + "Nodes": { + "L": [ + { + "M": { + "NodeId": { + "S": "1" + }, + "NodeName": { + "S": "TaskA" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "2" + }, + "NodeName": { + "S": "TaskB" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "3" + }, + "NodeName": { + "S": "TaskC" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "4" + }, + "NodeName": { + "S": "TaskD" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "5" + }, + "NodeName": { + "S": "TaskE" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "6" + }, + "NodeName": { + "S": "TaskF" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "7" + }, + "NodeName": { + "S": "TaskG" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "8" + }, + "NodeName": { + "S": "TaskH" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "9" + }, + "NodeName": { + "S": "TaskI" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "10" + }, + "NodeName": { + "S": "TaskJ" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "11" + }, + "NodeName": { + "S": "TaskK" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "12" + }, + "NodeName": { + "S": "TaskL" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "13" + }, + "NodeName": { + "S": "TaskM" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "14" + }, + "NodeName": { + "S": "TaskN" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/iostress_512wr_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + }, + { + "M": { + "NodeId": { + "S": "15" + }, + "NodeName": { + "S": "TaskO" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/memstress_128MB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "256" + } + } + }, + { + "M": { + "NodeId": { + "S": "16" + }, + "NodeName": { + "S": "TaskP" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/resnet_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "512" + } + } + }, + { + "M": { + "NodeId": { + "S": "17" + }, + "NodeName": { + "S": "TaskQ" + }, + "Path": { + "S": "examples/smart-grid-fusion-aws/src/xmlparse_23KB_25KB" + }, + "EntryPoint": { + "S": "func.py" + }, + "CSP": { + "S": "Azure" + }, + "MemoryInMB": { + "N": "128" + } + } + } + ] + }, + "WorkflowName": { + "S": "SmartGridFusionAWS" + }, + "Edges": { + "L": [ + { + "M": { + "TaskA": { + "L": [ + { + "S": "TaskB" + } + ] + } + } + }, + { + "M": { + "TaskB": { + "L": [ + { + "S": "TaskC" + } + ] + } + } + }, + { + "M": { + "TaskC": { + "L": [ + { + "S": "TaskD" + }, + { + "S": "TaskE" + } + ] + } + } + }, + { + "M": { + "TaskD": { + "L": [ + { + "S": "TaskM" + } + ] + } + } + }, + { + "M": { + "TaskE": { + "L": [ + { + "S": "TaskF" + } + ] + } + } + }, + { + "M": { + "TaskF": { + "L": [ + { + "S": "TaskG" + }, + { + "S": "TaskH" + }, + { + "S": "TaskI" + } + ] + } + } + }, + { + "M": { + "TaskG": { + "L": [ + { + "S": "TaskK" + } + ] + } + } + }, + { + "M": { + "TaskH": { + "L": [ + { + "S": "TaskK" + } + ] + } + } + }, + { + "M": { + "TaskI": { + "L": [ + { + "S": "TaskJ" + } + ] + } + } + }, + { + "M": { + "TaskJ": { + "L": [ + { + "S": "TaskK" + } + ] + } + } + }, + { + "M": { + "TaskK": { + "L": [ + { + "S": "TaskL" + } + ] + } + } + }, + { + "M": { + "TaskL": { + "L": [ + { + "S": "TaskP" + } + ] + } + } + }, + { + "M": { + "TaskM": { + "L": [ + { + "S": "TaskN" + } + ] + } + } + }, + { + "M": { + "TaskN": { + "L": [ + { + "S": "TaskO" + } + ] + } + } + }, + { + "M": { + "TaskO": { + "L": [ + { + "S": "TaskL" + } + ] + } + } + }, + { + "M": { + "TaskP": { + "L": [ + { + "S": "TaskQ" + } + ] + } + } + } + ] + }, + "wf_refactored_id": { + "S": "6e975fc5-b2cb-4759-a5a0-ee49851d33ef" + }, + "refactoring_strategy": { + "S": "Function fusion" + }, + "wf_partitions": { + "L": [ + { + "M": { + "partition_label": { + "S": "AWS" + }, + "function_ids": { + "L": [ + { + "S": "4" + }, + { + "S": "7" + }, + { + "S": "8" + }, + { + "S": "9" + }, + { + "S": "10" + }, + { + "S": "11" + }, + { + "S": "13" + }, + { + "S": "14" + }, + { + "S": "15" + }, + { + "S": "5" + }, + { + "S": "12" + }, + { + "S": "1" + }, + { + "S": "256" + } + ] + } + } + } + ] + } +} \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index d6baf3d..78f9252 100644 --- a/backend/server.js +++ b/backend/server.js @@ -58,6 +58,7 @@ dynamodb.listTables({}, (err, data) => { } if(tableName=="workflow_invocation_table"){ INVOCATION_VARIABLE=scanData.Items + } @@ -101,6 +102,17 @@ app.post("/api/workflowId",(req,res)=>{ const input = SHARED_VARIABLE.find( (item) => item.wf_id.S == wfIdToFetch ); + //console.log(input); + + // fs.writeFile("eg.txt", JSON.stringify(input), { flag: 'a' }, (err) => { + // if (err) { + // console.error('Error writing to the file:', err); + // } else { + // console.log('Data has been written to the file.'); + // } + // }); + + var output = { "wfid": input.wf_id.S, "wfname": input.WorkflowName.S, @@ -114,8 +126,37 @@ app.post("/api/workflowId",(req,res)=>{ "to": parseInt(input.Nodes.L.find(node => node.M.NodeName.S === toNode).M.NodeId.S) })); }).flat() - } + }, + "mermaidGraphDefinition":"" }; + //console.log(output); + // fs.writeFile("op.txt", JSON.stringify(output), { flag: 'a' }, (err) => { + // if (err) { + // console.error('Error writing to the file:', err); + // } else { + // console.log('Data has been written to the file.'); + // } + // }); + + const graphData = output + const { nodes, edges } = graphData.graphs; + + // Start with the graph definition + let mermaidString = 'graph LR;\n'; + + // Convert nodes to Mermaid nodes + for (const node of nodes) { + mermaidString += ` ${node.id}["${node.label}"];\n`; + } + + // Convert edges to Mermaid edges + for (const edge of edges) { + mermaidString += ` ${edge.from} --> ${edge.to};\n`; + } + + console.log(mermaidString); + output.mermaidGraphDefinition=mermaidString + res.json(JSON.stringify(output)) }) @@ -239,6 +280,8 @@ app.post("/api/workflowId/deployments/deploymentId/", (req, res) => { //console.log(input) return res.json(output); }); + + //to get refractored wf details from depid/refid app.post("/api/workflowId/refactoredID/",(req,res)=>{ var clickedId = req.body.wf_deployment_id; @@ -272,13 +315,13 @@ app.post("/api/workflowId/refactoredID/",(req,res)=>{ let color = ""; if (csp === "Azure") { - color = "#0080FF"; + color = "dodgerblue"; //#0080FF } else if (csp === "AWS") { - color = "#FF9900"; + color = "orange"; //#FF9900 } else if (csp === "GCP") { - color = "#00CC00"; + color = "springgreen"; //#00CC00 } else { - color = "#FF9900"; // Default color if CSP is not defined + color = "orange"; // #FF9900 Default color if CSP is not defined } return { @@ -294,25 +337,96 @@ app.post("/api/workflowId/refactoredID/",(req,res)=>{ "from": parseInt(input.Nodes.L.find(node => node.M.NodeName.S === fromNode).M.NodeId.S), "to": parseInt(input.Nodes.L.find(node => node.M.NodeName.S === toNode).M.NodeId.S) })); - }).flat() + }).flat(), + "mermaidGraphDefinition": "" }, }; + const graphData = output + const { nodes, edges } = graphData.graphs; + + // Start with the graph definition + let mermaidString = 'graph LR;\n'; + + //Convert nodes to Mermaid nodes + for (const node of nodes) { + mermaidString += ` ${node.id}["${node.label}"];\n`; + } + + // Convert edges to Mermaid edges + for (const edge of edges) { + mermaidString += ` ${edge.from} --> ${edge.to};\n`; + } + + console.log(mermaidString); + output.graphs.mermaidGraphDefinition=mermaidString return res.json(output); }) + app.post("/api/deploymentId/invocations",(req,res)=>{ - const clickedId =req.body.wf_deployment_id;//"5fa74fb4-bb52-4ce7-932a-d0d30936b3d3" + const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed"//req.body.wf_deployment_id; var input=INVOCATION_VARIABLE.filter((item)=>item.workflow_deployment_id.S==clickedId); return res.json({"workflow_deployment_id":clickedId,"no_of_invocations":input.length}); }) +app.post("/api/deploymentId/invocations/workflowEndTime/",async(req,res)=>{ + const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed"//req.body.wf_deployment_id; + var inputArray=INVOCATION_VARIABLE.filter((item)=>item.workflow_deployment_id.S==clickedId); + const temp = await inputArray.map((input) => { + const functionKeys = Object.keys(input.functions.M); + const functions = {}; + + for (const key of functionKeys) { + const func = input.functions.M[key].M; + functions[key] = { + start_delta_ms: parseInt(func.start_delta.N), + end_delta_ms: parseInt(func.end_delta.N), + }; + } + + return { + workflow_deployment_id: input.workflow_deployment_id.S, + workflow_invocation_id: input.workflow_invocation_id.S, + client_request_time_ms: parseInt(input.client_request_time_ms.S), + invocation_start_time_ms: parseInt(input.invocation_start_time_ms.S), + functions, + }; + }); + +var output=[] + for (let i = temp.length - 1; i >= 0; i--) { + const obj = temp[i]; + const functions = obj.functions; + // Check if the function ID exists in the functions object. + if (!functions["254"]) { + return null; + } + //console.log(functions) + // Get the previous function ID. +const previousFunctionId = Object.keys(functions)[Object.keys(functions).indexOf("254") - 1]; + + // Get the previous function end time. + +const invocation_start_time_ms=obj["invocation_start_time_ms"]; +const workflowEndTime = functions[previousFunctionId].end_delta_ms+invocation_start_time_ms; + + output.push({ + workflowEndTime, + invocation_start_time_ms, + }); + } + + return res.json(output); + +}) + app.post("/api/deploymentId/listAllInvocations/",async(req,res)=>{ - const clickedId =req.body.wf_deployment_id; + const clickedId ="76154d98-a0d7-4fc7-8c3e-99c74d91e2ed";//req.body.wf_deployment_id;//"76154d98-a0d7-4fc7-8c3e-99c74d91e2ed" var inputArray=INVOCATION_VARIABLE.filter((item)=>item.workflow_deployment_id.S==clickedId); const output = await inputArray.map((input) => { const functionKeys = Object.keys(input.functions.M); @@ -338,7 +452,4 @@ app.post("/api/deploymentId/listAllInvocations/",async(req,res)=>{ }) app.listen(port, () => { console.log(`Server is running on http://localhost:${port}`); -}); - - - +}); \ No newline at end of file diff --git a/frontend/README.md b/frontend/README.md index 2f151bd..17eea5b 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -1,5 +1,4 @@ ### 'Create-react-app' - The app was built using create-react-app command, this is necessary to install all the node modules which is otherwise not present in this repository due to size constraints ### 'Visualizing the connected graph' @@ -10,13 +9,10 @@ In order to incorporate interactive features please the material UI libraries npm install @mui/material @emotion/react @emotion/styled npm install @mui/icons-material @mui/material @emotion/styled @emotion/react - ### 'npm start' - Runs the app in the development mode.\ Open [http://localhost:3000](http://localhost:3000) to view it in your browser. ### `npm test` - Launches the test runner in the interactive watch mode.\ See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b90cc60..190fcfa 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,17 +10,21 @@ "dependencies": { "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.13.4", + "@material/icon-button": "^14.0.0", + "@mui/icons-material": "^5.14.16", + "@mui/material": "^5.15.2", "@nivo/bar": "^0.83.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", + "@nivo/scatterplot": "^0.84.0", + "@passageidentity/passage-auth": "^0.1.0-beta.28", "@passageidentity/passage-elements": "^1.9.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.4.0", "dotenv": "^16.3.1", + "mermaid": "^10.6.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-graph-vis": "^1.0.7", @@ -2039,16 +2043,21 @@ "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" }, "node_modules/@babel/runtime": { - "version": "7.22.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz", - "integrity": "sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.6.tgz", + "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==", "dependencies": { - "regenerator-runtime": "^0.13.11" + "regenerator-runtime": "^0.14.0" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/runtime/node_modules/regenerator-runtime": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz", + "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==" + }, "node_modules/@babel/template": { "version": "7.21.9", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.21.9.tgz", @@ -2100,6 +2109,11 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "node_modules/@braintree/sanitize-url": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz", + "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==" + }, "node_modules/@csstools/normalize.css": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", @@ -2370,18 +2384,6 @@ "postcss-selector-parser": "^6.0.10" } }, - "node_modules/@egjs/hammerjs": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", - "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", - "peer": true, - "dependencies": { - "@types/hammerjs": "^2.0.36" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/@emotion/babel-plugin": { "version": "11.11.0", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz", @@ -2608,6 +2610,40 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@floating-ui/core": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.2.tgz", + "integrity": "sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==", + "dependencies": { + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz", + "integrity": "sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==", + "dependencies": { + "@floating-ui/core": "^1.4.2", + "@floating-ui/utils": "^0.1.3" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz", + "integrity": "sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ==", + "dependencies": { + "@floating-ui/dom": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz", + "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==" + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", @@ -3526,26 +3562,150 @@ "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" }, - "node_modules/@mui/base": { - "version": "5.0.0-beta.4", - "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.4.tgz", - "integrity": "sha512-ejhtqYJpjDgHGEljjMBQWZ22yEK0OzIXNa7toJmmXsP4TT3W7xVy8bTJ0TniPDf+JNjrsgfgiFTDGdlEhV1E+g==", + "node_modules/@material/animation": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/animation/-/animation-14.0.0.tgz", + "integrity": "sha512-VlYSfUaIj/BBVtRZI8Gv0VvzikFf+XgK0Zdgsok5c1v5DDnNz5tpB8mnGrveWz0rHbp1X4+CWLKrTwNmjrw3Xw==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@emotion/is-prop-valid": "^1.2.1", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/base/-/base-14.0.0.tgz", + "integrity": "sha512-Ou7vS7n1H4Y10MUZyYAbt6H0t67c6urxoCgeVT7M38aQlaNUwFMODp7KT/myjYz2YULfhu3PtfSV3Sltgac9mA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/density": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/density/-/density-14.0.0.tgz", + "integrity": "sha512-NlxXBV5XjNsKd8UXF4K/+fOXLxoFNecKbsaQO6O2u+iG8QBfFreKRmkhEBb2hPPwC3w8nrODwXX0lHV+toICQw==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/dom": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/dom/-/dom-14.0.0.tgz", + "integrity": "sha512-8t88XyacclTj8qsIw9q0vEj4PI2KVncLoIsIMzwuMx49P2FZg6TsLjor262MI3Qs00UWAifuLMrhnOnfyrbe7Q==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/elevation": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/elevation/-/elevation-14.0.0.tgz", + "integrity": "sha512-Di3tkxTpXwvf1GJUmaC8rd+zVh5dB2SWMBGagL4+kT8UmjSISif/OPRGuGnXs3QhF6nmEjkdC0ijdZLcYQkepw==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/feature-targeting": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/feature-targeting/-/feature-targeting-14.0.0.tgz", + "integrity": "sha512-a5WGgHEq5lJeeNL5yevtgoZjBjXWy6+klfVWQEh8oyix/rMJygGgO7gEc52uv8fB8uAIoYEB3iBMOv8jRq8FeA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@material/focus-ring": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/focus-ring/-/focus-ring-14.0.0.tgz", + "integrity": "sha512-fqqka6iSfQGJG3Le48RxPCtnOiaLGPDPikhktGbxlyW9srBVMgeCiONfHM7IT/1eu80O0Y67Lh/4ohu5+C+VAQ==", + "dependencies": { + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0" + } + }, + "node_modules/@material/icon-button": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/icon-button/-/icon-button-14.0.0.tgz", + "integrity": "sha512-wHMqzm7Q/UwbWLoWv32Li1r2iVYxadIrwTNxT0+p+7NdfI3lEwMN3NoB0CvoJnHTljjXDzce0KJ3nZloa0P0gA==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/density": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/elevation": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/focus-ring": "^14.0.0", + "@material/ripple": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "@material/touch-target": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/ripple": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/ripple/-/ripple-14.0.0.tgz", + "integrity": "sha512-9XoGBFd5JhFgELgW7pqtiLy+CnCIcV2s9cQ2BWbOQeA8faX9UZIDUx/g76nHLZ7UzKFtsULJxZTwORmsEt2zvw==", + "dependencies": { + "@material/animation": "^14.0.0", + "@material/base": "^14.0.0", + "@material/dom": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/rtl": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/rtl/-/rtl-14.0.0.tgz", + "integrity": "sha512-xl6OZYyRjuiW2hmbjV2omMV8sQtfmKAjeWnD1RMiAPLCTyOW9Lh/PYYnXjxUrNa0cRwIIbOn5J7OYXokja8puA==", + "dependencies": { + "@material/theme": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/theme": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/theme/-/theme-14.0.0.tgz", + "integrity": "sha512-6/SENWNIFuXzeHMPHrYwbsXKgkvCtWuzzQ3cUu4UEt3KcQ5YpViazIM6h8ByYKZP8A9d8QpkJ0WGX5btGDcVoA==", + "dependencies": { + "@material/feature-targeting": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@material/touch-target": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@material/touch-target/-/touch-target-14.0.0.tgz", + "integrity": "sha512-o3kvxmS4HkmZoQTvtzLJrqSG+ezYXkyINm3Uiwio1PTg67pDgK5FRwInkz0VNaWPcw9+5jqjUQGjuZMtjQMq8w==", + "dependencies": { + "@material/base": "^14.0.0", + "@material/feature-targeting": "^14.0.0", + "@material/rtl": "^14.0.0", + "tslib": "^2.1.0" + } + }, + "node_modules/@mui/base": { + "version": "5.0.0-beta.29", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.29.tgz", + "integrity": "sha512-OXfUssYrB6ch/xpBVHMKAjThPlI9VyGGKdvQLMXef2j39wXfcxPlUVQlwia/lmE3rxWIGvbwkZsDtNYzLMsDUg==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@floating-ui/react-dom": "^2.0.4", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", "@popperjs/core": "^2.11.8", - "clsx": "^1.2.1", - "prop-types": "^15.8.1", - "react-is": "^18.2.0" + "clsx": "^2.0.0", + "prop-types": "^15.8.1" }, "engines": { "node": ">=12.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -3559,20 +3719,20 @@ } }, "node_modules/@mui/core-downloads-tracker": { - "version": "5.13.4", - "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.13.4.tgz", - "integrity": "sha512-yFrMWcrlI0TqRN5jpb6Ma9iI7sGTHpytdzzL33oskFHNQ8UgrtPas33Y1K7sWAMwCrr1qbWDrOHLAQG4tAzuSw==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.2.tgz", + "integrity": "sha512-0vk4ckS2w1F5PmkSXSd7F/QuRlNcPqWTJ8CPl+HQRLTIhJVS/VKEI+3dQufOdKfn2wS+ecnvlvXerbugs+xZ8Q==", "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" } }, "node_modules/@mui/icons-material": { - "version": "5.11.16", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.11.16.tgz", - "integrity": "sha512-oKkx9z9Kwg40NtcIajF9uOXhxiyTZrrm9nmIJ4UjkU2IdHpd4QVLbCc/5hZN/y0C6qzi2Zlxyr9TGddQx2vx2A==", + "version": "5.14.16", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.14.16.tgz", + "integrity": "sha512-wmOgslMEGvbHZjFLru8uH5E+pif/ciXAvKNw16q6joK6EWVWU5rDYWFknDaZhCvz8ZE/K8ZnJQ+lMG6GgHzXbg==", "dependencies": { - "@babel/runtime": "^7.21.0" + "@babel/runtime": "^7.23.2" }, "engines": { "node": ">=12.0.0" @@ -3593,18 +3753,18 @@ } }, "node_modules/@mui/material": { - "version": "5.13.4", - "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.13.4.tgz", - "integrity": "sha512-Yq+4f1KLPa/Szd3xqra2hbOAf2Usl8GbubncArM6LIp40mBLtXIdPE29MNtHsbtuzz4g+eidrETgoi3wdbEYfQ==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/base": "5.0.0-beta.4", - "@mui/core-downloads-tracker": "^5.13.4", - "@mui/system": "^5.13.2", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", - "@types/react-transition-group": "^4.4.6", - "clsx": "^1.2.1", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.15.2.tgz", + "integrity": "sha512-JnoIrpNmEHG5uC1IyEdgsnDiaiuCZnUIh7f9oeAr87AvBmNiEJPbo7XrD7kBTFWwp+b97rQ12QdSs9CLhT2n/A==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@mui/base": "5.0.0-beta.29", + "@mui/core-downloads-tracker": "^5.15.2", + "@mui/system": "^5.15.2", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", + "@types/react-transition-group": "^4.4.10", + "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1", "react-is": "^18.2.0", @@ -3615,7 +3775,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -3637,12 +3797,12 @@ } }, "node_modules/@mui/private-theming": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.13.1.tgz", - "integrity": "sha512-HW4npLUD9BAkVppOUZHeO1FOKUJWAwbpy0VQoGe3McUYTlck1HezGHQCfBQ5S/Nszi7EViqiimECVl9xi+/WjQ==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.2.tgz", + "integrity": "sha512-KlXx5TH1Mw9omSY+Q6rz5TA/P71meSYaAOeopiW8s6o433+fnOxS17rZbmd1RnDZGCo+j24TfCavQuCMBAZnQA==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/utils": "^5.13.1", + "@babel/runtime": "^7.23.6", + "@mui/utils": "^5.15.2", "prop-types": "^15.8.1" }, "engines": { @@ -3650,7 +3810,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", @@ -3663,11 +3823,11 @@ } }, "node_modules/@mui/styled-engine": { - "version": "5.13.2", - "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.13.2.tgz", - "integrity": "sha512-VCYCU6xVtXOrIN8lcbuPmoG+u7FYuOERG++fpY74hPpEWkyFQG97F+/XfTQVYzlR2m7nPjnwVUgATcTCMEaMvw==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.2.tgz", + "integrity": "sha512-fYEN3IZzbebeHwAmQHhxwruiOIi8W74709qXg/7tgtHV4byQSmPgnnKsZkg0hFlzjEbcJIRZyZI0qEecgpR2cg==", "dependencies": { - "@babel/runtime": "^7.21.0", + "@babel/runtime": "^7.23.6", "@emotion/cache": "^11.11.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" @@ -3677,7 +3837,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.4.1", @@ -3694,16 +3854,16 @@ } }, "node_modules/@mui/system": { - "version": "5.13.2", - "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.13.2.tgz", - "integrity": "sha512-TPyWmRJPt0JPVxacZISI4o070xEJ7ftxpVtu6LWuYVOUOINlhoGOclam4iV8PDT3EMQEHuUrwU49po34UdWLlw==", - "dependencies": { - "@babel/runtime": "^7.21.0", - "@mui/private-theming": "^5.13.1", - "@mui/styled-engine": "^5.13.2", - "@mui/types": "^7.2.4", - "@mui/utils": "^5.13.1", - "clsx": "^1.2.1", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.15.2.tgz", + "integrity": "sha512-I7CzLiHDtU/BTobJgSk+wPGGWG95K8lYfdFEnq//wOgSrLDAdOVvl2gleDxJWO+yAbGz4RKEOnR9KuD+xQZH4A==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@mui/private-theming": "^5.15.2", + "@mui/styled-engine": "^5.15.2", + "@mui/types": "^7.2.11", + "@mui/utils": "^5.15.2", + "clsx": "^2.0.0", "csstype": "^3.1.2", "prop-types": "^15.8.1" }, @@ -3712,7 +3872,7 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { "@emotion/react": "^11.5.0", @@ -3733,11 +3893,11 @@ } }, "node_modules/@mui/types": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.4.tgz", - "integrity": "sha512-LBcwa8rN84bKF+f5sDyku42w1NTxaPgPyYKODsh01U1fVstTClbUoSA96oyRBnSNyEiAVjKm6Gwx9vjR+xyqHA==", + "version": "7.2.11", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.2.11.tgz", + "integrity": "sha512-KWe/QTEsFFlFSH+qRYf3zoFEj3z67s+qAuSnMMg+gFwbxG7P96Hm6g300inQL1Wy///gSRb8juX7Wafvp93m3w==", "peerDependencies": { - "@types/react": "*" + "@types/react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3746,13 +3906,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.13.1", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.13.1.tgz", - "integrity": "sha512-6lXdWwmlUbEU2jUI8blw38Kt+3ly7xkmV9ljzY4Q20WhsJMWiNry9CX8M+TaP/HbtuyR8XKsdMgQW7h7MM3n3A==", + "version": "5.15.2", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.15.2.tgz", + "integrity": "sha512-6dGM9/guFKBlFRHA7/mbM+E7wE7CYDy9Ny4JLtD3J+NTyhi8nd8YxlzgAgTaTVqY0BpdQ2zdfB/q6+p2EdGM0w==", "dependencies": { - "@babel/runtime": "^7.21.0", - "@types/prop-types": "^15.7.5", - "@types/react-is": "^18.2.0", + "@babel/runtime": "^7.23.6", + "@types/prop-types": "^15.7.11", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -3761,10 +3920,16 @@ }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/mui" + "url": "https://opencollective.com/mui-org" }, "peerDependencies": { + "@types/react": "^17.0.0 || ^18.0.0", "react": "^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { @@ -3975,6 +4140,213 @@ "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" }, + "node_modules/@nivo/scatterplot": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/scatterplot/-/scatterplot-0.84.0.tgz", + "integrity": "sha512-E4AE0vspLo/7CwTNbL/lAO1K//51CpJhtWTbZwWcmjdo/SKv559CA4PPqXBgS6QgdzzE6Kn3hgp2io76UqIZvQ==", + "dependencies": { + "@nivo/annotations": "0.84.0", + "@nivo/axes": "0.84.0", + "@nivo/colors": "0.84.0", + "@nivo/core": "0.84.0", + "@nivo/legends": "0.84.0", + "@nivo/scales": "0.84.0", + "@nivo/tooltip": "0.84.0", + "@nivo/voronoi": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-scale": "^3.2.3", + "@types/d3-shape": "^2.0.0", + "d3-scale": "^3.2.3", + "d3-shape": "^1.3.5", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/annotations": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/annotations/-/annotations-0.84.0.tgz", + "integrity": "sha512-g3n+WaZgRza7fZVQZrrxq1cLS+6vmjhWGmQqEynFmKM2f11F7gdkHLhGMYosayjZ0Sb/bMUXvBSkUbyKli7NVw==", + "dependencies": { + "@nivo/colors": "0.84.0", + "@nivo/core": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/prop-types": "^15.7.2", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/axes": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/axes/-/axes-0.84.0.tgz", + "integrity": "sha512-bC9Rx5ixGJiupTRXSnATIVRLPcx0HR8yXGBuO8GTy6K1DDnhaNWfhErnBLYbB9Sq13WQGrS2he6uvLVLd23CtA==", + "dependencies": { + "@nivo/core": "0.84.0", + "@nivo/scales": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-format": "^1.4.1", + "@types/d3-time-format": "^2.3.1", + "@types/prop-types": "^15.7.2", + "d3-format": "^1.4.4", + "d3-time-format": "^3.0.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/colors": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/colors/-/colors-0.84.0.tgz", + "integrity": "sha512-wNG1uYyDP5Owc1Pdkz0zesdZCrPAywmSssNzQ2Aju7nVs7Ru7iHNBIvOAGgyXTe2gcrIO9VSasXWR+jEYyxN2Q==", + "dependencies": { + "@nivo/core": "0.84.0", + "@types/d3-color": "^2.0.0", + "@types/d3-scale": "^3.2.3", + "@types/d3-scale-chromatic": "^2.0.0", + "@types/prop-types": "^15.7.2", + "d3-color": "^3.1.0", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^2.0.0", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/core": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/core/-/core-0.84.0.tgz", + "integrity": "sha512-HyQM4x4B7d4X9+xLPKkPxqIxhSDzbJUywGTDWHWx1daeX9VP8O+MqkTBsNsoB+tjxrbKrRJ0+ceS2w89JB+qrA==", + "dependencies": { + "@nivo/recompose": "0.84.0", + "@nivo/tooltip": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-shape": "^2.0.0", + "d3-color": "^3.1.0", + "d3-format": "^1.4.4", + "d3-interpolate": "^3.0.1", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^3.0.0", + "d3-shape": "^1.3.5", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nivo/donate" + }, + "peerDependencies": { + "prop-types": ">= 15.5.10 < 16.0.0", + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/core/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/@nivo/scatterplot/node_modules/@nivo/legends": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/legends/-/legends-0.84.0.tgz", + "integrity": "sha512-o0s1cXoIH6Km9A2zoKB8Ey99Oc1w5nymz0j8s7hR2B0EHo5HgVbYjSs2sZD7NSwLt3QM57Nzxw9VzJ+sqfV30Q==", + "dependencies": { + "@nivo/colors": "0.84.0", + "@nivo/core": "0.84.0", + "@types/d3-scale": "^3.2.3", + "@types/prop-types": "^15.7.2", + "d3-scale": "^3.2.3", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/recompose": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/recompose/-/recompose-0.84.0.tgz", + "integrity": "sha512-Odb+r0pEmGt4RV020jwvngF7PxBgxS1e1sy8bWlZKc5qkm6k3eVlZNuYU+zGbDxHMigImvrx5KfUv5iUqtQBZA==", + "dependencies": { + "@types/prop-types": "^15.7.2", + "@types/react-lifecycles-compat": "^3.0.1", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/scales": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/scales/-/scales-0.84.0.tgz", + "integrity": "sha512-Cayo9jFMpoF7Ha7eqOAucHLUG6zZLGpxiAtyZ/vTUCkRZPHmd/YMvrm8E6OyQCTBVf+aRtOKk9tQnMv8E9fWiw==", + "dependencies": { + "@types/d3-scale": "^3.2.3", + "@types/d3-time": "^1.1.1", + "@types/d3-time-format": "^3.0.0", + "d3-scale": "^3.2.3", + "d3-time": "^1.0.11", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/scales/node_modules/@types/d3-time-format": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.4.tgz", + "integrity": "sha512-or9DiDnYI1h38J9hxKEsw513+KVuFbEVhl7qdxcaudoiqWWepapUen+2vAriFGexr6W5+P4l9+HJrB39GG+oRg==" + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/tooltip": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.84.0.tgz", + "integrity": "sha512-x/6Vk4RXKHkG9q5dk4uFYwEfbMoIvJd5ahhVQ6bskuLks5FZoS6bkKoNggjxwmHbIWOVITGUXuykOfC54EWSpw==", + "dependencies": { + "@nivo/core": "0.84.0", + "@react-spring/web": "9.4.5 || ^9.7.2" + } + }, + "node_modules/@nivo/scatterplot/node_modules/@nivo/voronoi": { + "version": "0.84.0", + "resolved": "https://registry.npmjs.org/@nivo/voronoi/-/voronoi-0.84.0.tgz", + "integrity": "sha512-CJTb0sQWYNbfjjrCEK3W0jt1v+hqAd4fDUNJxB3SNRHEEQtF+MCr2EG3p/CWyxIb3avjF4N53/03tQpnuDwBvQ==", + "dependencies": { + "@nivo/core": "0.84.0", + "@types/d3-delaunay": "^5.3.0", + "@types/d3-scale": "^3.2.3", + "d3-delaunay": "^5.3.0", + "d3-scale": "^3.2.3" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/scatterplot/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/@nivo/scatterplot/node_modules/d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" + }, "node_modules/@nivo/tooltip": { "version": "0.83.0", "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.83.0.tgz", @@ -4031,6 +4403,34 @@ "node": ">= 8" } }, + "node_modules/@passageidentity/passage-auth": { + "version": "0.1.0-beta.28", + "resolved": "https://registry.npmjs.org/@passageidentity/passage-auth/-/passage-auth-0.1.0-beta.28.tgz", + "integrity": "sha512-+5YK66FuEt6n6zQLoA7SxOlKM/wARXVBdBsxDY0tb+jwATJT2GRysTQhCFb7km/eWFrcpIcpWg0jvr4sbBmsbA==", + "deprecated": "Package no longer supported. Upgrade to @passageidentity/passage-elements", + "dependencies": { + "@passageidentity/passage-js": "^2.0.2", + "bulma": "^0.9.3", + "intl-tel-input": "^17.0.13", + "vue": "^3.2.22" + } + }, + "node_modules/@passageidentity/passage-auth/node_modules/@passageidentity/passage-js": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@passageidentity/passage-js/-/passage-js-2.6.3.tgz", + "integrity": "sha512-DV/duYjcp7ZvJz8IOD+KKmGC8ktKq60zvb7cP1I1oqrQYnTj/cTMNr/CG6Q9Z1Y45a17WNqXi7VnooFXBNSUBw==", + "deprecated": "passage-js v2.x and earlier is no longer supported. Update to @passageidentity/passage-js@latest", + "dependencies": { + "@types/node": "^17.0.27", + "jwt-decode": "^3.1.2", + "ua-parser-js": "^1.0.2" + } + }, + "node_modules/@passageidentity/passage-auth/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + }, "node_modules/@passageidentity/passage-elements": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/@passageidentity/passage-elements/-/passage-elements-1.9.2.tgz", @@ -4541,25 +4941,6 @@ "url": "https://github.com/sponsors/gregberge" } }, - "node_modules/@testing-library/dom": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz", - "integrity": "sha512-0DGPd9AR3+iDTjGoMpxIkAsUihHZ3Ai6CneU6bRRrffXMgzCdlNk43jTrD2/5LT6CBb3MWTP8v510JzYtahD2w==", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@testing-library/jest-dom": { "version": "5.16.5", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz", @@ -4791,6 +5172,14 @@ "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.3.1.tgz", "integrity": "sha512-fck0Z9RGfIQn3GJIEKVrp15h9m6Vlg0d5XXeiE/6+CQiBmMDZxfR21XtjEPuDeg7gC3bBM0SdieA5XF3GW1wKA==" }, + "node_modules/@types/debug": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.10.tgz", + "integrity": "sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/eslint": { "version": "8.40.0", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz", @@ -4844,12 +5233,6 @@ "@types/node": "*" } }, - "node_modules/@types/hammerjs": { - "version": "2.0.41", - "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.41.tgz", - "integrity": "sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA==", - "peer": true - }, "node_modules/@types/hast": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz", @@ -4935,11 +5318,24 @@ "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" }, + "node_modules/@types/mdast": { + "version": "3.0.14", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.14.tgz", + "integrity": "sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw==", + "dependencies": { + "@types/unist": "^2" + } + }, "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" }, + "node_modules/@types/ms": { + "version": "0.7.33", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.33.tgz", + "integrity": "sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ==" + }, "node_modules/@types/node": { "version": "20.2.5", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", @@ -4956,9 +5352,9 @@ "integrity": "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==" }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" }, "node_modules/@types/q": { "version": "1.5.5", @@ -4993,14 +5389,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-1vz2yObaQkLL7YFe/pme2cpvDsCwI1WXIfL+5eLz0MI9gFG24Re16RzUsI8t9XZn9ZWvgLNDrJBmrqXJO7GNQQ==", - "dependencies": { - "@types/react": "*" - } - }, "node_modules/@types/react-lifecycles-compat": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/react-lifecycles-compat/-/react-lifecycles-compat-3.0.1.tgz", @@ -5010,9 +5398,9 @@ } }, "node_modules/@types/react-transition-group": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.6.tgz", - "integrity": "sha512-VnCdSxfcm08KjsJVQcfBmhEQAPnLB8G08hAxn39azX1qYBQ/5RVQuoHuKIcfKOdncuaUvEpFKFzEvbtIMsfVew==", + "version": "4.4.10", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz", + "integrity": "sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==", "dependencies": { "@types/react": "*" } @@ -6520,6 +6908,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/bulma": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz", + "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==" + }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -6763,9 +7156,9 @@ } }, "node_modules/clsx": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", "engines": { "node": ">=6" } @@ -6933,12 +7326,6 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "peer": true - }, "node_modules/compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -7077,9 +7464,17 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "node_modules/cose-base": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", + "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", + "dependencies": { + "layout-base": "^1.0.0" + } + }, + "node_modules/cosmiconfig": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dependencies": { "@types/parse-json": "^4.0.0", @@ -7508,6 +7903,93 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" }, + "node_modules/cytoscape": { + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.27.0.tgz", + "integrity": "sha512-pPZJilfX9BxESwujODz5pydeGi+FBrXq1rcaB1mfhFXXFJ9GjE6CNndAk+8jPzoXGD+16LtSS4xlYEIUiW4Abg==", + "dependencies": { + "heap": "^0.2.6", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/cytoscape-cose-bilkent": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", + "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", + "dependencies": { + "cose-base": "^1.0.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", + "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", + "dependencies": { + "cose-base": "^2.2.0" + }, + "peerDependencies": { + "cytoscape": "^3.2.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/cose-base": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", + "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", + "dependencies": { + "layout-base": "^2.0.0" + } + }, + "node_modules/cytoscape-fcose/node_modules/layout-base": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", + "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==" + }, + "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": "2.12.1", "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", @@ -7516,6 +7998,40 @@ "internmap": "^1.0.0" } }, + "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", @@ -7524,6 +8040,28 @@ "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-contour/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-delaunay": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", @@ -7532,11 +8070,114 @@ "delaunator": "4" } }, + "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": "1.4.5", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" }, + "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": "2.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", @@ -7555,6 +8196,39 @@ "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==" }, + "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-sankey": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", + "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", + "dependencies": { + "d3-array": "1 - 2", + "d3-shape": "^1.2.0" + } + }, "node_modules/d3-scale": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.3.0.tgz", @@ -7581,6 +8255,14 @@ "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" }, + "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": "1.3.7", "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", @@ -7605,6 +8287,173 @@ "d3-time": "1 - 2" } }, + "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/d3/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/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/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/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/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/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/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/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/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/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/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/dagre-d3-es": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz", + "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==", + "dependencies": { + "d3": "^7.8.2", + "lodash-es": "^4.17.21" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -7649,6 +8498,27 @@ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/decode-named-character-reference/node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -7750,6 +8620,14 @@ "node": ">= 0.8" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -7806,6 +8684,14 @@ "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==" }, + "node_modules/diff": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", + "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", @@ -7936,6 +8822,11 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, + "node_modules/dompurify": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz", + "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w==" + }, "node_modules/domutils": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", @@ -8003,6 +8894,11 @@ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.421.tgz", "integrity": "sha512-wZOyn3s/aQOtLGAwXMZfteQPN68kgls2wDAnYOA8kCjBvKVrW5RwmWVspxJYTqrcN7Y263XJVsC66VCIGzDO3g==" }, + "node_modules/elkjs": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz", + "integrity": "sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ==" + }, "node_modules/emittery": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", @@ -9817,6 +10713,11 @@ "he": "bin/he" } }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==" + }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", @@ -12725,11 +13626,10 @@ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz", "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==" }, - "node_modules/keycharm": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", - "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", - "peer": true + "node_modules/khroma": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", + "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" }, "node_modules/kind-of": { "version": "6.0.3", @@ -12777,6 +13677,11 @@ "shell-quote": "^1.7.3" } }, + "node_modules/layout-base": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", + "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==" + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -12850,6 +13755,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "node_modules/lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -12899,118 +13809,614 @@ "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", "integrity": "sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==", "dependencies": { - "fault": "^1.0.0", - "highlight.js": "~10.7.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "fault": "^1.0.0", + "highlight.js": "~10.7.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.2.tgz", + "integrity": "sha512-4kbWXbVZ+LU4XFDS2CuA7frnwz2HxCMB/0yOXc86q7aCQrfWKkL11t6al1e2CsVC7uhnBNTQ1TfUsAxVauO9IQ==", + "dependencies": { + "fs-monkey": "^1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/mermaid": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.6.0.tgz", + "integrity": "sha512-Hcti+Q2NiWnb2ZCijSX89Bn2i7TCUwosBdIn/d+u63Sz7y40XU6EKMctT4UX4qZuZGfKGZpfOeim2/KTrdR7aQ==", + "dependencies": { + "@braintree/sanitize-url": "^6.0.1", + "@types/d3-scale": "^4.0.3", + "@types/d3-scale-chromatic": "^3.0.0", + "cytoscape": "^3.23.0", + "cytoscape-cose-bilkent": "^4.1.0", + "cytoscape-fcose": "^2.1.0", + "d3": "^7.4.0", + "d3-sankey": "^0.12.3", + "dagre-d3-es": "7.0.10", + "dayjs": "^1.11.7", + "dompurify": "^3.0.5", + "elkjs": "^0.8.2", + "khroma": "^2.0.0", + "lodash-es": "^4.17.21", + "mdast-util-from-markdown": "^1.3.0", + "non-layered-tidy-tree-layout": "^2.0.2", + "stylis": "^4.1.3", + "ts-dedent": "^2.2.0", + "uuid": "^9.0.0", + "web-worker": "^1.2.0" + } + }, + "node_modules/mermaid/node_modules/@types/d3-scale": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.6.tgz", + "integrity": "sha512-lo3oMLSiqsQUovv8j15X4BNEDOsnHuGjeVg7GRbAuB2PUa1prK5BNSOu6xixgNf3nqxPl4I1BqJWrPvFGlQoGQ==", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/mermaid/node_modules/@types/d3-scale-chromatic": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.1.tgz", + "integrity": "sha512-Ob7OrwiTeQXY/WBBbRHGZBOn6rH1h7y3jjpTSKYqDEeqFjktql6k2XSgNwLrLDmAsXhEn8P9NHDY4VTuo0ZY1w==" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "yallist": "^3.0.2" + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" } }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "bin": { - "lz-string": "bin/bin.js" + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/magic-string": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", - "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "sourcemap-codec": "^1.4.8" + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "tmpl": "1.0.5" + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==" + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" - } + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/memfs": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.2.tgz", - "integrity": "sha512-4kbWXbVZ+LU4XFDS2CuA7frnwz2HxCMB/0yOXc86q7aCQrfWKkL11t6al1e2CsVC7uhnBNTQ1TfUsAxVauO9IQ==", + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "fs-monkey": "^1.0.3" - }, - "engines": { - "node": ">= 4.0.0" + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-types": "^1.0.0" + } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" } }, + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -13171,6 +14577,14 @@ "mkdirp": "bin/cmd.js" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -13265,6 +14679,11 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz", "integrity": "sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==" }, + "node_modules/non-layered-tidy-tree-layout": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz", + "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==" + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -15917,6 +17336,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", @@ -15989,6 +17413,22 @@ "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/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-array-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", @@ -17208,12 +18648,6 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, - "node_modules/timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==", - "peer": true - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -17284,6 +18718,14 @@ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==" }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "engines": { + "node": ">=6.10" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -17406,19 +18848,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/ua-parser-js": { "version": "1.0.35", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", @@ -17498,6 +18927,18 @@ "node": ">=8" } }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -17607,14 +19048,42 @@ } }, "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==", - "peer": true, + "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" } }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uvu/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/v8-to-istanbul": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", @@ -17677,23 +19146,6 @@ "vis-util": "^5.0.1" } }, - "node_modules/vis-util": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.3.tgz", - "integrity": "sha512-Wf9STUcFrDzK4/Zr7B6epW2Kvm3ORNWF+WiwEz2dpf5RdWkLUXFSbLcuB88n1W6tCdFwVN+v3V4/Xmn9PeL39g==", - "peer": true, - "engines": { - "node": ">=8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/visjs" - }, - "peerDependencies": { - "@egjs/hammerjs": "^2.0.0", - "component-emitter": "^1.3.0" - } - }, "node_modules/vue": { "version": "3.3.4", "resolved": "https://registry.npmjs.org/vue/-/vue-3.3.4.tgz", @@ -17784,6 +19236,11 @@ "resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz", "integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg==" }, + "node_modules/web-worker": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", + "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" + }, "node_modules/webidl-conversions": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index e78ef6d..69864c5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -6,17 +6,21 @@ "dependencies": { "@emotion/react": "^11.11.0", "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.11.16", - "@mui/material": "^5.13.4", + "@material/icon-button": "^14.0.0", + "@mui/icons-material": "^5.14.16", + "@mui/material": "^5.15.2", "@nivo/bar": "^0.83.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", + "@nivo/scatterplot": "^0.84.0", + "@passageidentity/passage-auth": "^0.1.0-beta.28", "@passageidentity/passage-elements": "^1.9.2", "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.4.0", "dotenv": "^16.3.1", + "mermaid": "^10.6.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-graph-vis": "^1.0.7", diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/frontend/public/favicon.ico and /dev/null differ diff --git a/frontend/public/index.html b/frontend/public/index.html index aa069f2..af0101c 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -24,20 +24,10 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + XFaaS
- diff --git a/frontend/public/manifest.json b/frontend/public/manifest.json index 080d6c7..fc7ce89 100644 --- a/frontend/public/manifest.json +++ b/frontend/public/manifest.json @@ -22,4 +22,4 @@ "display": "standalone", "theme_color": "#000000", "background_color": "#ffffff" -} +} \ No newline at end of file diff --git a/frontend/src/App.css b/frontend/src/App.css index 179572f..fd2a964 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -1,7 +1,11 @@ +* { + margin: 0px; + box-sizing: border-box; + scroll-behavior: smooth; +} -.App-header { - - height: 20vh; +.App-header { + height: 40vh; display: flex; flex-direction: column; align-items: center; @@ -9,11 +13,9 @@ color: white; } -/* -.App-link { - color: #61dafb; -} */ - +.App{ + margin: auto; +} .button-container { display: flex; @@ -22,15 +24,3 @@ margin-top: 5%; margin-bottom: 2% } - - -.FooterBox { - font-size: medium; - display: flex; - width: 100%; - height: 100px; - padding: 20px; - margin-top: 20px; - color:black; - -} diff --git a/frontend/src/App.js b/frontend/src/App.js index 316c38d..0314a4f 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,55 +1,24 @@ import AllwfTable from './components/Allwf'; import ResponsiveAppBar from './components/App-bar'; import "./App.css"; -import Welcome from './components/Welcome'; import { useMode } from './theme'; import {Box, ThemeProvider} from "@mui/material" -import { useAuthStatus } from './hooks/useAuthStatus'; -import { useEffect,useState } from 'react'; - +import TypewriterEffect from './components/TypeWriterEffect'; +import Footer from './components/Footer'; function App() { const [theme]=useMode(); - const [result,setResult]=useAuthStatus(); - const {isLoading,isAuthorized,username}=result; - const [showApp, setShowApp] = useState(false); - console.log(isAuthorized); - - useEffect(() => { - const timer = setTimeout(() => { - setShowApp(true); - }, 2000); - - return () => clearTimeout(timer); - }, []); return ( - - - -
- -
-
- -
- {/* {isAuthorized? -
- -
+ + +
+ +
- -
- : showApp?( <> - -

...404...

-
...NOT AUTHORISED USER...
-
-):(<>) -} */} - - +
+ ); } diff --git a/frontend/src/InvocationsPage.css b/frontend/src/InvocationsPage.css index 629e6d2..16849f9 100644 --- a/frontend/src/InvocationsPage.css +++ b/frontend/src/InvocationsPage.css @@ -1,41 +1,29 @@ -.header { - - height: 20vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - color: white; - } +.mermaidGraphh{ + margin: 2rem; + box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px; + border-radius: 10px; + overflow: hidden; + height: 95vh; +} - - .graphcontainer { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - } - - .graphbox{ - display: flex; - width: 80%; - height: 400px; - border: 1px solid gray; - border-radius: 30px; - padding: 20px; - margin: 20px; - background-color: #ced9ee; - margin: '0 auto'; - justify-content: center; - - } +.mermaidGraphhHeading{ + background-color: black; + color: white; + padding: 1rem; + font-size: 1.5rem; +} -.FooterBox { - display: flex; - width: 100%; - height: 100px; - padding: 20px; - margin-top: 20px; - color: #ffffff; - - } +/* For WebKit-based browsers (Chrome, Safari) */ +::-webkit-scrollbar { + width: 12px; /* Width of the scrollbar */ +} + +::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.785); /* Color of the scrollbar thumb */ +} + +/* For Firefox */ +* { + scrollbar-width: thin; /* Show the scrollbar in Firefox */ + scrollbar-color: rgba(0, 0, 0, 0.785); /* Color of the thumb and the track */ +} \ No newline at end of file diff --git a/frontend/src/InvocationsPage.js b/frontend/src/InvocationsPage.js index 6c2f5a9..ffb35c6 100644 --- a/frontend/src/InvocationsPage.js +++ b/frontend/src/InvocationsPage.js @@ -9,40 +9,84 @@ import Button from '@mui/material/Button'; import GraphTable from './components/GraphTable'; import axios from "axios"; import { useLocation } from "react-router-dom"; +import mermaid from "mermaid"; +const MermaidDiagram = ({ definition }) => { + const [mermaidInitialized, setMermaidInitialized] = useState(false); + + useEffect(() => { + // Initialize Mermaid when the component mounts + mermaid.initialize({ startOnLoad: true }); + setMermaidInitialized(true); + }, []); + + // useEffect(() => { + // const reloadCount = sessionStorage.getItem('reloadCount'); + + // if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { + // const timeout = setTimeout(() => { + // sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads + // window.location.reload(); + // }, 100); + + // return () => { + // clearTimeout(timeout); + // }; + // } + // }, [mermaidInitialized]); + + return ( +
+ {mermaidInitialized ? ( +
+ {definition} +
+ ) : ( +

Loading Mermaid diagram...

+ )} +
+ ); +}; const GraphWrapper = ({depdetails}) => { const depploymentdetails=depdetails; - console.log(depploymentdetails); + //console.log(depploymentdetails); const navigate = useNavigate(); const location=useLocation(); const [graphdet,setGraphdet]=useState({}); const [graph,setGraph]=useState({ nodes:[], - edges:[] + edges:[], + mermaidGraphDefinition: "" }); + useEffect(() => { const params = new URLSearchParams(location.search); const wf_deployment_id= params.get("wf_deployment_id"); - axios.post("/api/workflowId/refactoredID", { "wf_deployment_id": wf_deployment_id }) - .then(response => { + axios.post("/api/workflowId/refactoredID", { "wf_deployment_id": wf_deployment_id }) + .then(response => { const ref = response.data; - //console.log(ref); + //console.log("logging ref"); + //console.log(ref); + sessionStorage.removeItem('reloadCount'); setGraphdet(ref); + setGraph(ref.graphs) + // console.log("all logging"); + // console.log(ref); }) .catch(error => { console.error(error); }); }, [location]); -console.log(graph); + console.log(graph); + - const HandleNodeClick = (event) => { const nodeId = event.nodes[0]; @@ -84,25 +128,30 @@ console.log(graph); "size": 18, "face": "ariel", - }, - - - }, - - - + }, + }, }; - - - - return ( -
-
- -
+ //
+ //

+ // + //
+ //
+ //
Refactored Workflow! If graph is not visible, please reload the page
+ //

+ // + //
+ +
+
Refactored Workflow! If graph is not visible, please reload the page
+ {graph.mermaidGraphDefinition !== '' ? ( + + ) : ( +

No refactored workflow found

+ )}
+ ); }; @@ -114,10 +163,11 @@ console.log(graph); function InvocationsPage() { const location=useLocation(); const [depdetails,setDepdetails]=useState({}) - + const [deploymentId,setDeploymentId]=useState(""); useEffect(()=>{ const params=new URLSearchParams(location.search); const depid=params.get("wf_deployment_id"); + setDeploymentId(depid) axios.post("/api/workflowId/deployments/deploymentId/",{"wf_deployment_id":depid}).then(res=>{ const depObj=res.data console.log("res"); @@ -140,7 +190,7 @@ function InvocationsPage() { setActiveComponent('GraphTable'); }; const handleInvoClick=()=>{ - navigate("/wf/deployment/invocations"); + navigate(`/wf/deployment/invocations/?wfid=${deploymentId}`); } const [theme]=useMode(); @@ -156,25 +206,26 @@ const [theme]=useMode(); color="primary" size="large" variant="outlined" - onClick={handlegraphClick}>Graph View + onClick={handlegraphClick} + style={{backgroundColor:'black', color: 'white'}}>Graph View
- {activeComponent === 'GraphWrapper' ? : } - -
- + {activeComponent === 'GraphWrapper' ? : } +
diff --git a/frontend/src/components/Allwf.jsx b/frontend/src/components/Allwf.jsx index b9a92a4..58a061a 100644 --- a/frontend/src/components/Allwf.jsx +++ b/frontend/src/components/Allwf.jsx @@ -1,4 +1,110 @@ -import React, { useEffect } from 'react'; +// import React, { useEffect } from 'react'; +// import Paper from '@mui/material/Paper'; +// import Table from '@mui/material/Table'; +// import TableBody from '@mui/material/TableBody'; +// import TableCell from '@mui/material/TableCell'; +// import TableContainer from '@mui/material/TableContainer'; +// import TableHead from '@mui/material/TableHead'; +// import TablePagination from '@mui/material/TablePagination'; +// import TableRow from '@mui/material/TableRow'; +// import { Link} from 'react-router-dom'; +// import axios from 'axios' + +// const columns = [ +// { id: 'workflowID', label: 'Workflow ID', align: 'center', minWidth: 80 }, +// { id: 'workflow', label: 'Workflow Name', align: 'center', minWidth: 80 }, +// ]; + +// function createData(workflowID,workflow) { +// return {workflowID,workflow}; +// } + + + +// export default function AllwfTable() { +// const [page, setPage] = React.useState(0); +// const [rowsPerPage, setRowsPerPage] = React.useState(5); +// const [rows,setRows]=React.useState([]); + +// const handleChangePage = (event, newPage) => { +// setPage(newPage); +// }; + +// const handleChangeRowsPerPage = (event) => { +// setRowsPerPage(+event.target.value); +// setPage(0); +// }; +// React.useEffect(()=>{ +// axios.get('/api/allWorkflows').then(response=>{ +// var rows=[] +// response.data.forEach(ele=>{ +// rows.push(createData(ele["wfId"],ele["workflowName"])) +// }); +// setRows(rows); +// }).catch(err=>{ +// console.error(err) +// }) +// },[]) + + +// return ( +// +// +// +// +// +// {columns.map((column) => ( +// +// {column.label} +// +// ))} +// +// +// +// {rows +// .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) +// .map((row) => { +// return ( +// + +// +// +// {row[columns[0].id]} +// {/* {row[columns[0].id]} */} +// + +// +// +// {row[columns[1].id]} +// {/* {row[columns[1].id]} */} +// + +// +// ); +// })} +// +//
+//
+// +//
+// ); +// } + +import React, { useEffect, useState } from 'react'; import Paper from '@mui/material/Paper'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; @@ -7,25 +113,23 @@ import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TablePagination from '@mui/material/TablePagination'; import TableRow from '@mui/material/TableRow'; -import { Link } from 'react-router-dom'; -import axios from 'axios' +import { Link } from 'react-router-dom'; +import axios from 'axios'; const columns = [ - { id: 'workflowID', label: 'Workflows ID', align: 'center', minWidth: 80 }, - { id: 'workflow', label: 'All workflows', align: 'center', minWidth: 80 }, - { id: 'time', label: 'Executed at', align: 'center', minWidth:80}, + { id: 'workflowID', label: 'Workflow ID', align: 'center', minWidth: 80 }, + { id: 'workflow', label: 'Workflow Name', align: 'center', minWidth: 80 }, ]; -function createData(workflowID,workflow, time) { - return {workflowID,workflow,time}; +function createData(workflowID, workflow) { + return { workflowID, workflow }; } - - export default function AllwfTable() { - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(5); - const [rows,setRows]=React.useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(5); + const [rows, setRows] = useState([]); + const [searchQuery, setSearchQuery] = useState(''); const handleChangePage = (event, newPage) => { setPage(newPage); @@ -35,75 +139,108 @@ export default function AllwfTable() { setRowsPerPage(+event.target.value); setPage(0); }; - React.useEffect(()=>{ - axios.get('/api/allWorkflows').then(response=>{ - console.log(response) - var rows=[] - response.data.forEach(ele=>{ - rows.push(createData(ele["wfId"],ele["workflowName"],0)) - }); - setRows(rows); - }).catch(err=>{ - console.error(err) - }) - - },[]) - + useEffect(() => { + axios.get('/api/allWorkflows') + .then(response => { + const newRows = response.data.map(ele => createData(ele['wfId'], ele['workflowName'])); + setRows(newRows); + }) + .catch(err => { + console.error(err); + }); + }, []); - + // Create a function that filters rows based on the search query + const filteredRows = rows.filter((row) => { + const lowerCaseSearchQuery = searchQuery.toLowerCase(); + return ( + row.workflowID.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.workflow.toLowerCase().includes(lowerCaseSearchQuery) + ); + }); return ( - - - - - - {columns.map((column) => ( + +
+ setSearchQuery(e.target.value)} + style={{ + fontSize: '1rem', + padding: '8px', + width: '300px', // Adjust width as needed + height: '40px', // Adjust height as needed + background: 'black', + color: 'white', + border: 'none', + boxShadow: 'inset 0 0 5px rgba(0, 0, 0, 0.5), 0 0 5px rgba(255, 255, 255, 0.5)', + borderRadius: '10px' + }} + /> +
+ +
+ + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {filteredRows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + - {column.label} + + {row.workflowID} + - - ))} - - - - {rows - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map((row) => { - return ( - - - {row[columns[0].id]} - - - - {row[columns[1].id]} - - - {row[columns[2].id]} - - - ); - })} - -
-
- - -
- + + + {row.workflow} + + + + ); + })} + + + + + ); } diff --git a/frontend/src/components/App-bar.jsx b/frontend/src/components/App-bar.jsx index 70d08c7..984474e 100644 --- a/frontend/src/components/App-bar.jsx +++ b/frontend/src/components/App-bar.jsx @@ -17,12 +17,11 @@ import { useAuthStatus } from '../hooks/useAuthStatus'; -const pages = ['Main', 'About Us', 'Contact']; +const pages = ['Home', 'About Us', 'Contact']; const settings = ['Profile', 'Logout']; function ResponsiveAppBar() { const navigate = useNavigate(); - // const dispatch=useDispatch(); const [anchorElNav, setAnchorElNav] = React.useState(null); const [anchorElUser, setAnchorElUser] = React.useState(null); const [result,setResult]=useAuthStatus(); @@ -44,7 +43,6 @@ function ResponsiveAppBar() { isAuthorized: false, username: "", }); - // dispatch(setLogout()) navigate("/"); }; @@ -53,12 +51,11 @@ function ResponsiveAppBar() { - - XFAAS - + >XFaaS - + {/* - + ))} - + */} + + @@ -153,12 +152,12 @@ function ResponsiveAppBar() { anchorEl={anchorElUser} anchorOrigin={{ vertical: 'top', - horizontal: 'right', + horizontal: 'rightright', }} keepMounted transformOrigin={{ vertical: 'top', - horizontal: 'right', + horizontal: 'left', }} open={Boolean(anchorElUser)} onClose={handleCloseUserMenu} @@ -171,6 +170,7 @@ function ResponsiveAppBar() { ))} + diff --git a/frontend/src/components/DeployTable.jsx b/frontend/src/components/DeployTable.jsx index 773acfb..edd1c90 100644 --- a/frontend/src/components/DeployTable.jsx +++ b/frontend/src/components/DeployTable.jsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import Paper from '@mui/material/Paper'; import Table from '@mui/material/Table'; import TableBody from '@mui/material/TableBody'; @@ -7,43 +7,32 @@ import TableContainer from '@mui/material/TableContainer'; import TableHead from '@mui/material/TableHead'; import TablePagination from '@mui/material/TablePagination'; import TableRow from '@mui/material/TableRow'; -import { Link, Navigate, useLocation, useNavigate } from 'react-router-dom'; -import Invocation from '../scenes/invocations/Invocation' -import { ListItem } from '@mui/material'; -import { useState } from 'react'; -import { useEffect } from 'react'; - +import { Link } from 'react-router-dom'; const columns = [ { id: 'wf_deployment_id', label: 'Deployment ID', align: 'center', minWidth: 170 }, { id: 'wf_deployment_time', label: 'Deployment Date/Time', align: 'center', minWidth: 100 }, - { id: 'wf_deployment_name', label: 'Deployment name', align: 'center', minWidth: 100 }, + { id: 'wf_deployment_name', label: 'Deployment Name', align: 'center', minWidth: 100 }, ]; function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { - return {wf_deployment_id, wf_deployment_time, wf_deployment_name }; + return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; } +export default function DeployTable({ alldep }) { + const [searchQuery, setSearchQuery] = useState(''); + const [rows, setRows] = useState([]); + const [page, setPage] = useState(0); + const [rowsPerPage, setRowsPerPage] = useState(10); -export default function DeployTable({alldep}) { - const location=useLocation(); - const [rows,setRows]=useState([]) - const [page, setPage] = React.useState(0); - const [rowsPerPage, setRowsPerPage] = React.useState(10); - - -// console.log(deparray) -const temprows=[] -useEffect(() => { + const temprows = []; - alldep.forEach((dep)=>{ - temprows.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); - }) - - setRows(temprows); -},[alldep]); - -console.log(rows); + useEffect(() => { + alldep.forEach((dep) => { + temprows.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); + }); + setRows(temprows); + }, [alldep]); const handleChangePage = (event, newPage) => { setPage(newPage); @@ -53,61 +42,104 @@ console.log(rows); setRowsPerPage(+event.target.value); setPage(0); }; - + + // Create a function that filters rows based on the search query + const filteredRows = rows.filter((row) => { + const lowerCaseSearchQuery = searchQuery.toLowerCase(); + return ( + row.wf_deployment_id.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.wf_deployment_name.toLowerCase().includes(lowerCaseSearchQuery) + ); + }); return ( - - - - - - {columns.map((column) => ( - +
+ setSearchQuery(e.target.value)} + style={{ + fontSize: '1rem', + padding: '8px', + width: '300px', + height: '40px', + background: 'black', + color: 'white', + border: 'none', + boxShadow: 'inset 0 0 5px rgba(0, 0, 0, 0.5), 0 0 5px rgba(255, 255, 255, 0.5)', + borderRadius: '10px', + }} + /> +
+ +
+ + + {columns.map((column) => ( + + {column.label} + + ))} + + + + {filteredRows + .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) + .map((row) => { + return ( + + + + {row.wf_deployment_id} + + + + {row.wf_deployment_time} + + + - {column.label} - - ))} + {row.wf_deployment_name} + + - - - {rows - .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) - .map((row) => { - return ( - - - - {row[columns[0].id]} - - - - {row[columns[1].id]} - - - {row[columns[2].id]} - - - ); - })} - -
-
- - -
- + ); + })} + + + + + ); -} - - +} \ No newline at end of file diff --git a/frontend/src/components/Footer.css b/frontend/src/components/Footer.css new file mode 100644 index 0000000..db2b764 --- /dev/null +++ b/frontend/src/components/Footer.css @@ -0,0 +1,5 @@ +.footer{ + background-color: black; + height: 100px; + width: 100%; +} \ No newline at end of file diff --git a/frontend/src/components/Footer.jsx b/frontend/src/components/Footer.jsx new file mode 100644 index 0000000..2ce0893 --- /dev/null +++ b/frontend/src/components/Footer.jsx @@ -0,0 +1,9 @@ +import "./Footer.css"; +function Footer() { + + return ( +
+ ); +} + +export default Footer; diff --git a/frontend/src/components/GraphTable.css b/frontend/src/components/GraphTable.css new file mode 100644 index 0000000..e69de29 diff --git a/frontend/src/components/GraphTable.jsx b/frontend/src/components/GraphTable.jsx index 58d8a44..6bd38f9 100644 --- a/frontend/src/components/GraphTable.jsx +++ b/frontend/src/components/GraphTable.jsx @@ -13,7 +13,7 @@ import { useLocation } from "react-router-dom"; const columns = [ { id: 'Label', label: 'Label', align: 'center', minWidth: 100 }, - { id: 'ID', label: 'Func ID', align: 'center', minWidth: 170 }, + { id: 'ID', label: 'Function ID', align: 'center', minWidth: 170 }, { id: 'CSP', label: 'CSP', align: 'center', minWidth: 100 }, ]; @@ -25,11 +25,12 @@ export default function GraphTable() { const [rows, setRows] = useState([]); const [page, setPage] = useState(0); const [rowsPerPage, setRowsPerPage] = useState(10); - const location=useLocation(); + const [searchQuery, setSearchQuery] = useState(''); // Add searchQuery state + const location = useLocation(); useEffect(() => { const params = new URLSearchParams(location.search); - const wf_deployment_id= params.get("wf_deployment_id"); + const wf_deployment_id = params.get("wf_deployment_id"); axios.post("/api/workflowId/refactoredID", { "wf_deployment_id": wf_deployment_id }) .then(response => { const nodes = response.data.graphs.nodes; @@ -52,8 +53,37 @@ export default function GraphTable() { setPage(0); }; + // Create a function that filters rows based on the search query + const filteredRows = rows.filter((row) => { + const lowerCaseSearchQuery = searchQuery.toLowerCase(); + return ( + row.Label.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.ID.toString().toLowerCase().includes(lowerCaseSearchQuery) || + row.CSP.toLowerCase().includes(lowerCaseSearchQuery) + ); + }); + return ( - + +
+ setSearchQuery(e.target.value)} + style={{ + fontSize: '1rem', + padding: '8px', + width: '300px', + height: '40px', + background: 'black', + color: 'white', + border: 'none', + boxShadow: 'inset 0 0 5px rgba(0, 0, 0, 0.5), 0 0 5px rgba(255, 255, 255, 0.5)', + borderRadius: '10px' + }} + /> +
@@ -62,7 +92,7 @@ export default function GraphTable() { {column.label} @@ -70,19 +100,22 @@ export default function GraphTable() { - {rows + {filteredRows .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage) .map((row) => { return ( - - {row[columns[0].id]} + + {row[columns[0].id]} - + {row[columns[1].id]} - - {row[columns[2].id]} + +
+ {row[columns[2].id]} +
+
); @@ -93,7 +126,7 @@ export default function GraphTable() { ); } - - diff --git a/frontend/src/components/MermaidDiagram.css b/frontend/src/components/MermaidDiagram.css new file mode 100644 index 0000000..14d953e --- /dev/null +++ b/frontend/src/components/MermaidDiagram.css @@ -0,0 +1,24 @@ +/* Style the container for the Mermaid diagram */ +.mermaid-container { + width: 100%; /* Set the width as desired */ + height: 5rem; /* Set the height as desired */ + margin: 0 auto; /* Center the diagram horizontally */ +} + +/* Add additional styles for your diagram as needed */ +.mermaid-container .node rect { + fill: #009688; /* Example: Change the node rectangle fill color */ +} + +.mermaid-container .node text { + font-size: 14px; /* Example: Adjust the font size for node text */ +} + +.mermaid-container .edgePath path { + stroke: #333; /* Example: Change the edge path stroke color */ +} + +#mermaid-diagram{ + width: 100%; /* Set the width as desired */ + height: 20%; /* Set the height as desired */ +} \ No newline at end of file diff --git a/frontend/src/components/TypeWriterEffect.css b/frontend/src/components/TypeWriterEffect.css new file mode 100644 index 0000000..bc1cfd3 --- /dev/null +++ b/frontend/src/components/TypeWriterEffect.css @@ -0,0 +1,21 @@ +.typewriter-container { + text-align: center; + padding: 20px; + } + + .typewriter-text { + font-size: 24px; + font-weight: bold; + white-space: nowrap; + border-right: 3px solid transparent; /* Set the border to transparent */ + } + + @keyframes typing { + from { + width: 0; + } + to { + width: 100%; + } + } + \ No newline at end of file diff --git a/frontend/src/components/TypeWriterEffect.jsx b/frontend/src/components/TypeWriterEffect.jsx new file mode 100644 index 0000000..0805117 --- /dev/null +++ b/frontend/src/components/TypeWriterEffect.jsx @@ -0,0 +1,26 @@ +import React, { useState, useEffect } from 'react'; +import './TypeWriterEffect.css'; // Import the CSS file for styling + +const TypewriterEffect = ({ text }) => { + const [displayedText, setDisplayedText] = useState(''); + const [currentIndex, setCurrentIndex] = useState(0); + + useEffect(() => { + const typingInterval = 100; // Adjust typing speed (milliseconds) + + if (currentIndex < text.length) { + setTimeout(() => { + setDisplayedText(text.slice(0, currentIndex + 1)); + setCurrentIndex(currentIndex + 1); + }, typingInterval); + } + }, [currentIndex, text]); + + return ( +
+

{displayedText}

+
+ ); +}; + +export default TypewriterEffect; diff --git a/frontend/src/components/Welcome.jsx b/frontend/src/components/Welcome.jsx deleted file mode 100644 index 006bbd6..0000000 --- a/frontend/src/components/Welcome.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { createTheme, ThemeProvider, styled } from '@mui/material/styles'; - - -const BoxContainer = styled('div')(({ theme }) => ({ - width: '70%', - padding: theme.spacing(2), - backgroundColor: theme.palette.background.default, - opacity: 0, - transition: 'opacity 1s ease', -})); - -const Welcome = () => { - const [showText, setShowText] = useState(false); - - useEffect(() => { - // Delay the appearance of the text - const timer = setTimeout(() => { - setShowText(true); - }, 1000); - - return () => clearTimeout(timer); - }, []); - - return ( - -
-
- - {showText && ( -

Manage your workflows

with XFaaS

- - )} - -
-
-
-
- ); - }; - - -export default Welcome; diff --git a/frontend/src/components/Wf.css b/frontend/src/components/Wf.css index 77d78d4..96cec44 100644 --- a/frontend/src/components/Wf.css +++ b/frontend/src/components/Wf.css @@ -1,80 +1,70 @@ +* { + margin: 0px; + box-sizing: border-box; + scroll-behavior: smooth; +} -.wf-header { - - height: 20vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - color: white; - } - - - /* .App-link { - color: #61dafb; - } - */ - - .box-container { - display: flex; - flex-direction: column; - - position: absolute; - } - - .box { - display: flex; - width: 93%; - height: 43px; - border: 2px solid #000000; - border-radius: 20px; - padding: 20px; - margin: 20px; - background-color: #ffffff; - color: #000000; - - } - - .box1 { - display: flex; - width: 100%; - height: 40px; - border: 0px solid #e7d9d9; - padding: 20px; - margin: 20px; - background-color: #ffffff; - color: #000000; - margin-bottom: 5% - } - - .graphcontainer { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - } - - .graphbox{ - display: flex; - width: 60%; - height: 400px; - border: 2px solid rgb(0, 0, 0); - border-radius: 20px; - padding: 20px; - margin: 20px; - background-color: #ffffff; - margin: '0 auto'; - justify-content: center; - - } - - .FooterBox { - display: flex; - width: 100%; - height: 100px; - padding: 20px; - margin-top: 20px; - - color: #ffffff; - - } +.wf{ + margin: 2rem; +} + +.mermaidGraphh{ + box-shadow: rgba(50, 50, 93, 0.25) 0px 6px 12px -2px, rgba(0, 0, 0, 0.3) 0px 3px 7px -3px; + border-radius: 10px; + overflow: hidden; + height: 95vh; +} + +.mermaidGraphhHeader{ + width: 100%; +} + +.mermaidGraphhHeading{ + background-color: black; + color: white; + padding: 1rem; + font-size: 1.5rem; +} + +.caution{ + color: yellow; + font-size: 1rem; + padding-left: 2rem; +} + +.cautionMark{ + border-width: 1px; + border-color: yellow; + border-style: solid; + border-radius: 2px; + padding: 2px; +} + +.mermaidGraphhHeadingCaution{ + background-color: black; + color: yellow; + padding-top: 1rem; + font-size: 1rem; + flex: 1.2; +} + +.graphcontainer { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; +} + +.graphbox{ + display: flex; + width: 60%; + height: 400px; + border: 2px solid rgb(0, 0, 0); + border-radius: 20px; + padding: 20px; + margin: 20px; + background-color: #ffffff; + margin: '0 auto'; + justify-content: center; + +} \ No newline at end of file diff --git a/frontend/src/components/Wf.jsx b/frontend/src/components/Wf.jsx index f995d42..e0c299e 100644 --- a/frontend/src/components/Wf.jsx +++ b/frontend/src/components/Wf.jsx @@ -1,87 +1,427 @@ -import './Wf.css'; -import Graph from 'react-graph-vis'; -import DeploymentTable from './DeployTable'; -import ResponsiveAppBar from './App-bar'; -import { useNavigate } from 'react-router-dom'; -import { useMode } from '../theme'; -import {ThemeProvider} from "@mui/material" -import { useLocation } from 'react-router-dom'; -import { useEffect, useState } from 'react'; -import axios, { all } from 'axios'; +// import './Wf.css'; +// import Graph from 'react-graph-vis'; +// import DeploymentTable from './DeployTable'; +// import ResponsiveAppBar from './App-bar'; +// import { useNavigate } from 'react-router-dom'; +// import { useMode } from '../theme'; +// import {ThemeProvider} from "@mui/material" +// import { useLocation } from 'react-router-dom'; +// import { useEffect, useState } from 'react'; +// import axios, { all } from 'axios'; + +// const GraphWrapper = ({wfdetails}) => { +// //const {wfdetails} =wfdetails +// const graph={ +// nodes:wfdetails.graphs["nodes"], +// edges:wfdetails.graphs["edges"] +// } +// const navigate = useNavigate(); -const GraphWrapper = ({wfdetails}) => { - //const {wfdetails} =wfdetails - const graph={ - nodes:wfdetails.graphs["nodes"], - edges:wfdetails.graphs["edges"] - } - const navigate = useNavigate(); - - const HandleNodeClick = (event) => { - const nodeId = event.nodes[0]; - if (nodeId) { - navigate('/wf/CodeViewer'); - } - }; - - const options = { - layout: { - hierarchical: { - enabled:true, - direction:'LR', - }, +// const HandleNodeClick = (event) => { +// const nodeId = event.nodes[0]; +// if (nodeId) { +// navigate('/wf/CodeViewer'); +// } +// }; + +// const options = { +// layout: { +// hierarchical: { +// enabled:true, +// direction:'LR', +// }, - }, - edges: { - arrows: 'to', - }, - height: '400px', - interaction: { - zoomView: false, - hover: true, - hoverConnectedEdges: false, - selectConnectedEdges: true, +// }, +// edges: { +// arrows: 'to', +// }, +// height: '400px', +// interaction: { +// zoomView: false, +// hover: true, +// hoverConnectedEdges: false, +// selectConnectedEdges: true, - }, - nodes: { +// }, +// nodes: { - fixed:{ - x:true, - y:true - }, - opacity: 1, +// fixed:{ +// x:true, +// y:true +// }, +// opacity: 1, - shape:"square", +// shape:"square", - font: { - "size": 18, - "face": "ariel", +// font: { +// "size": 18, +// "face": "ariel", - }, +// }, - }, +// }, - }; +// }; - return ( -
-
- -
-
- ); -}; +// return ( +//
+//
+// +//
+//
+// ); +// }; + +// function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { +// return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; +// } + +// const Wf = () => { +// const [wfdetails,setWfdetails]=useState({ +// "wfid": "", +// "wfname": "", +// "executedTime": "", +// "graphs":{ +// "nodes": [], +// "edges": [] +// } +// }); +// const [alldep,setAlldep]=useState([]) +// const location=useLocation(); +// //console.log(location) +// useEffect(()=>{ +// const params=new URLSearchParams(location.search); +// const wfid=params.get("wfid"); +// axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ +// const resObj = JSON.parse(response.data); + +// setWfdetails(resObj); + +// }).catch(error => { +// console.error(error); +// }); + +// },[location]); + + +// var deployments=[] + +// useEffect(() => { +// const params = new URLSearchParams(location.search); +// const wfid = params.get("wfid"); +// axios.post("/api/workflowId/deployments", { "wfid": wfid }) +// .then(response => { +// console.log(response.data); +// response.data.forEach((dep)=>{ +// deployments.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); +// }) +// const depArr = response.data; + +// // console.log(depArr); + + +// setAlldep(depArr); + +// }) +// .catch(error => { +// console.error(error); +// }); +// }, [location]); +// console.log(alldep); +// console.log(deployments); + + +// const [theme]=useMode(); + +// return( + +// + +//
+ +// + + +// +//
+//

Workflow ID:

+ +//
{wfdetails.wfid}
+//
+ +//
+//

Workflow Name:

+ +//
{wfdetails.wfname}
+//
+ +//
+//

Workflow Description:

+//
{wfdetails.WorkflowDescription}
+//
+// +// + +// + +//
+//
+// ); +// }; + +// export default Wf; + +// import './Wf.css'; +// import Graph from 'react-graph-vis'; +// import DeploymentTable from './DeployTable'; +// import ResponsiveAppBar from './App-bar'; +// import { useNavigate } from 'react-router-dom'; +// import { useMode } from '../theme'; +// import {ThemeProvider} from "@mui/material" +// import { useLocation } from 'react-router-dom'; +// import { useEffect, useState } from 'react'; +// import axios, { all } from 'axios'; + + +// const GraphWrapper = ({wfdetails}) => { +// //const {wfdetails} =wfdetails +// const graph={ +// nodes:wfdetails.graphs["nodes"], +// edges:wfdetails.graphs["edges"] +// } +// const navigate = useNavigate(); + +// const HandleNodeClick = (event) => { +// const nodeId = event.nodes[0]; +// if (nodeId) { +// navigate('/wf/CodeViewer'); +// } +// }; + +// const options = { +// layout: { +// hierarchical: { +// enabled:true, +// direction:'LR', +// }, + +// }, +// edges: { +// arrows: 'to', +// }, +// height: '400px', +// interaction: { +// zoomView: false, +// hover: true, +// hoverConnectedEdges: false, +// selectConnectedEdges: true, + +// }, +// nodes: { + +// fixed:{ +// x:true, +// y:true +// }, +// opacity: 1, + +// shape:"square", + +// font: { +// "size": 18, +// "face": "ariel", + +// }, + + +// }, + + + +// }; + + +// return ( +//
+//
+// +//
+//
+// ); +// }; + +// function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { +// return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; +// } + +// const Wf = () => { +// const [wfdetails,setWfdetails]=useState({ +// "wfid": "", +// "wfname": "", +// "executedTime": "", +// "graphs":{ +// "nodes": [], +// "edges": [] +// } +// }); +// const [alldep,setAlldep]=useState([]) +// const location=useLocation(); +// //console.log(location) +// useEffect(()=>{ +// const params=new URLSearchParams(location.search); +// const wfid=params.get("wfid"); +// axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ +// const resObj = JSON.parse(response.data); + +// setWfdetails(resObj); + +// }).catch(error => { +// console.error(error); +// }); + +// },[location]); + + +// var deployments=[] + +// useEffect(() => { +// const params = new URLSearchParams(location.search); +// const wfid = params.get("wfid"); +// axios.post("/api/workflowId/deployments", { "wfid": wfid }) +// .then(response => { +// console.log(response.data); +// response.data.forEach((dep)=>{ +// deployments.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); +// }) +// const depArr = response.data; + +// // console.log(depArr); + + +// setAlldep(depArr); + +// }) +// .catch(error => { +// console.error(error); +// }); +// }, [location]); +// console.log(alldep); +// console.log(deployments); + + +// const [theme]=useMode(); + +// return( + +// + +//
+ +// + + +// +//
+//

Workflow ID:

+ +//
{wfdetails.wfid}
+//
+ +//
+//

Workflow Name:

+ +//
{wfdetails.wfname}
+//
+ +//
+//

Workflow Description:

+//
{wfdetails.WorkflowDescription}
+//
+// +// + +// + +//
+//
+// ); +// }; + +// export default Wf; + +import './Wf.css'; +import DeploymentTable from './DeployTable'; +import ResponsiveAppBar from './App-bar'; +import { useMode } from '../theme'; +import {ThemeProvider} from "@mui/material" +import { useLocation } from 'react-router-dom'; +import { useEffect, useState } from 'react'; +import axios, { all } from 'axios'; +//import MermaidDiagram from './MermaidDiagram.jsx'; +import mermaid from 'mermaid'; +import './MermaidDiagram.css' function createData(wf_deployment_id, wf_deployment_time, wf_deployment_name) { return { wf_deployment_id, wf_deployment_time, wf_deployment_name }; } -const Wf = () => { +// const MermaidDiagram = ({ definition }) => { +// useEffect(() => { +// // Initialize Mermaid when the component mounts +// mermaid.initialize({ startOnLoad: true }); + +// }, [definition]); + +// return ( +//
+// {definition} +//
+// ); +// };m + + +const MermaidDiagram = ({ definition }) => { + const [mermaidInitialized, setMermaidInitialized] = useState(false); + + useEffect(() => { + // Initialize Mermaid when the component mounts + mermaid.initialize({ startOnLoad: true }); + setMermaidInitialized(true); + }, [definition]); + + // useEffect(() => { + // const reloadCount = sessionStorage.getItem('reloadCount'); + + // if (mermaidInitialized && (!reloadCount || parseInt(reloadCount) === 0)) { + // const timeout = setTimeout(() => { + // sessionStorage.setItem('reloadCount', '1'); // Set the flag to prevent further reloads + // window.location.reload(); + // }, 100); + // return () => { + // clearTimeout(timeout); + // }; + // } + // }, [mermaidInitialized]); + + return ( +
+ {mermaidInitialized ? ( +
+ {definition} +
+ ) : ( +

Loading Mermaid diagram...

+ )} +
+ ); +}; + +const Wf = () => { const [wfdetails,setWfdetails]=useState({ "wfid": "", "wfname": "", @@ -89,89 +429,84 @@ const Wf = () => { "graphs":{ "nodes": [], "edges": [] - } + }, + "mermaidGraphDefinition": "" }); + + const [alldep,setAlldep]=useState([]) + + const location=useLocation(); - //console.log(location) useEffect(()=>{ const params=new URLSearchParams(location.search); const wfid=params.get("wfid"); - axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ - const resObj = JSON.parse(response.data); - - setWfdetails(resObj); - - }).catch(error => { - console.error(error); - }); - + {axios.post("/api/workflowId",{"wfid":wfid}).then(response=>{ + const resObj = JSON.parse(response.data); + sessionStorage.removeItem('reloadCount'); + setWfdetails(resObj); + }).catch(error => { + console.error(error); + }); } },[location]); -var deployments=[] - + var deployments=[] useEffect(() => { const params = new URLSearchParams(location.search); const wfid = params.get("wfid"); - axios.post("/api/workflowId/deployments", { "wfid": wfid }) - .then(response => { - console.log(response.data); + axios.post("/api/workflowId/deployments", { "wfid": wfid }) + .then(response => { response.data.forEach((dep)=>{ deployments.push(createData(dep.wf_deployment_id, dep.wf_deployment_time, dep.wf_deployment_name)); }) const depArr = response.data; - - // console.log(depArr); - - - setAlldep(depArr); - + setAlldep(depArr); }) .catch(error => { console.error(error); }); }, [location]); - console.log(alldep); - console.log(deployments); - - - const [theme]=useMode(); - return( - - -
- - + const [theme] = useMode(); + + return( + + +
+ + +
+
+

Workflow ID: {wfdetails.wfid}

+
+
+

Workflow Name: {wfdetails.wfname}

+
+
+

Workflow Description: {wfdetails.WorkflowDescription}

+
+
- -
-

Workflow ID:

- -
{wfdetails.wfid}
-
+
+
User Submitted Workflow! If graph is not visible, please reload the page
+ + +

+ {wfdetails.mermaidGraphDefinition !== '' ? ( + + ) : ( +

No user submitted workflow found

+ )} +
-
-

Workflow Name:

- -
{wfdetails.wfname}
-
- -
-

Workflow Description:

-
{wfdetails.WorkflowDescription}
-
- - - - - -
-
+ + +
+
); }; -export default Wf; +export default Wf; \ No newline at end of file diff --git a/frontend/src/index.js b/frontend/src/index.js index c43e5a9..d6f92c5 100644 --- a/frontend/src/index.js +++ b/frontend/src/index.js @@ -8,26 +8,20 @@ import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import CodeViewer from './components/CodeViewer'; import InvocationsPage from './InvocationsPage'; import Invocation from './scenes/invocations/Invocation'; -import Login from './scenes/login/Login'; - +import InvocationDetails from './scenes/invocations/InvocationDetails'; const root = ReactDOM.createRoot(document.getElementById('root')); -root.render( - +root.render( - {/* } /> */} - } /> + } /> }/> } /> } /> } /> - - + } /> - - ); reportWebVitals(); diff --git a/frontend/src/scenes/bar/Bar.jsx b/frontend/src/scenes/bar/Bar.jsx new file mode 100644 index 0000000..e9a15b8 --- /dev/null +++ b/frontend/src/scenes/bar/Bar.jsx @@ -0,0 +1,106 @@ +// import { Box } from "@mui/material"; + +// import BarChart from "../../components/BarChart"; + +// const Bar = () => { +// return ( +// +// +// +// +// +// ); +// }; + +// export default Bar; +import React, { useState } from "react"; +import { Box, Button, styled } from "@mui/material"; +import { ResponsiveBar } from "@nivo/bar"; +import axios from "axios"; + +const BarChart = ({ chartData }) => { + const [totalInvocations, setTotalInvocations] = useState(0); + + return ( + { + setTotalInvocations(0); + }} + /> + ); +}; + +const CustomButton = styled(Button)({ + background: "white", + color: "blue", + "&:hover": { + background: "white", + }, +}); + +const Bar = () => { + const [chartData, setChartData] = useState([]); + + const fetchData = async () => { + try { + const response = await axios.post("/api/deploymentId/invocations",{"wf_deployment_id":"5fa74fb4-bb52-4ce7-9324-d0d30936b3d3"}); + const { workflow_deployment_id, no_of_invocations } = response.data; + const currentTime = new Date().toLocaleTimeString(); + + setChartData((prevData) => [ + ...prevData, + { + x: currentTime, + y: no_of_invocations, + }, + ]); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + Invocations + + + + + + ); +}; + +export default Bar; diff --git a/frontend/src/scenes/bar/index.jsx b/frontend/src/scenes/bar/index.jsx deleted file mode 100644 index 4ee9c04..0000000 --- a/frontend/src/scenes/bar/index.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Box } from "@mui/material"; - -import BarChart from "../../components/BarChart"; - -const Bar = () => { - return ( - - - - - - ); -}; - -export default Bar; \ No newline at end of file diff --git a/frontend/src/scenes/invocations/Invocation.jsx b/frontend/src/scenes/invocations/Invocation.jsx index 21ffd70..a5c836a 100644 --- a/frontend/src/scenes/invocations/Invocation.jsx +++ b/frontend/src/scenes/invocations/Invocation.jsx @@ -1,114 +1,334 @@ +// import React, { useState, useEffect } from 'react'; +// import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, MenuItem, Select } from '@mui/material'; +// import { useLocation } from "react-router-dom"; +// import { Link } from 'react-router-dom'; +// import axios from "axios"; +// import Line from '../line/Line'; + +// const Invocation = () => { +// const [invocationList, setInvocationList] = useState([]); +// const [filterValue, setFilterValue] = useState(''); +// const [filterTime, setFilterTime] = useState('all'); +// const [deploymentId,setDeploymentId]=useState(""); + +// const location=useLocation(); + +// useEffect(() => { +// const params=new URLSearchParams(location.search); +// const depid=params.get("wf_deployment_id"); +// setDeploymentId(depid) +// axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ +// const invo=res.data + +// setInvocationList(invo); + +// }).catch(err=> +// console.error(err)) +// },[location]) + + +// const getLastFunctionEndTime = (functions, invocationStartTime) => { +// const functionEntries = Object.entries(functions); +// if (functionEntries.length === 0) { +// return null; +// } + +// const maxEndTime = Math.max(...functionEntries.map(([_, func]) => func.end_delta_ms)); +// const lastFunctionEndTime = new Date(invocationStartTime + maxEndTime).toLocaleString(); +// return lastFunctionEndTime; +// }; + +// const handleFilterChange = (event) => { +// setFilterValue(event.target.value); +// }; + +// const handleFilterByTime = (timeValue) => { +// setFilterTime(timeValue); +// }; + +// const applyTimeFilter = (filteredData) => { +// if (filterTime === 'all') { +// return filteredData; +// } else { +// const now = Date.now(); +// const filterTimes = { +// last1Hour: now - 3600000, +// lastDay: now - 86400000, +// lastMonth: now - 2629746000, +// last6Months: now - 15778476000, +// last12Months: now - 31556952000, +// }; +// return filteredData.filter(item => { +// const startTime = new Date(item.invocation_start_time_ms).getTime(); +// return startTime > filterTimes[filterTime]; +// }); +// } +// }; + +// const filteredInvocationListByID = invocationList.filter(item => item.workflow_invocation_id.startsWith(filterValue)); + +// const filteredByTime = applyTimeFilter(filteredInvocationListByID); + +// return ( +//
+// +// +// +// +// +// +// +// +//
+// +// +// Invocation ID +// Start Time +// End Time +// +// +// +// {filteredByTime.map(item => ( +// +// +// {item.workflow_invocation_id} +// +// {new Date(item.invocation_start_time_ms).toLocaleString()} +// +// {getLastFunctionEndTime(item.functions, item.invocation_start_time_ms)} +// +// +// ))} +// +//
+//
+// +// +// +// ); +// }; + +// export default Invocation + import React, { useState, useEffect } from 'react'; -import List from '@mui/material/List'; -import ListItem from '@mui/material/ListItem'; -import ListItemText from '@mui/material/ListItemText'; -import { Box, IconButton } from '@mui/material'; -import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; -import Line from '../line'; -import Bar from '../bar'; -import { useMode } from '../../theme'; -import { ThemeProvider } from '@emotion/react'; -import ResponsiveAppBar from "../../components/App-bar"; - - -const Invocation = (InvId) => { - const id= InvId; +import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, MenuItem, Select } from '@mui/material'; +import { useLocation } from "react-router-dom"; +import { Link } from 'react-router-dom'; +import axios from "axios"; +import Line from '../line/Line'; +import StartvsEndScatterPlot from '../line/StartvsEndScatterPlot'; +import ResponsiveAppBar from '../../components/App-bar'; +import {useMode} from '../../theme' +import {ThemeProvider} from "@mui/material" +import Paper from '@mui/material/Paper'; +import StartvsEndHistogram from '../line/StartvsEndHistogram'; + +const Invocation = () => { const [invocationList, setInvocationList] = useState([]); - const [selectedInvocation, setSelectedInvocation] = useState(null); + const [filterValue, setFilterValue] = useState(''); + const [filterTime, setFilterTime] = useState('all'); + const [deploymentId,setDeploymentId]=useState(""); + const location=useLocation(); + useEffect(() => { - // Simulating fetching data from an API - const fetchData = () => { - try { - // Replace this with your actual API call - // const response = await fetch('url'); - // const json = await response.json(); - var json={ "workflow_deployment_id": "uuid", - "workflow_invocation_id": "uuid", - "client_request_time_ms": 1669527328928, - "invocation_start_time_ms": 1669527329557, - "functions": { - "10": { - "start_delta_ms": 0, - "end_delta_ms": 100 - }, - "20": { - "start_delta": 462, - "end_delta": 562, - }, - "30": { - "end_delta": 1423, - "start_delta": 1323 - }, - "40": { - "end_delta": 1907, - "start_delta": 1807 - }, - "50": { - "end_delta": 2360, - "start_delta": 2260 - }, - "60": { - "end_delta": 2753, - "start_delta": 2653 - }, - "70": { - "end_delta": 3199, - "start_delta": 3099 - } - } - } - setInvocationList(json.functions); - } catch (err) { - console.log(err); - } - }; - - fetchData(); - }, []); - - const handleInvocation = (id) => { - if (id !== selectedInvocation) { - setSelectedInvocation(id); + const params=new URLSearchParams(location.search); +const depid=params.get("wf_deployment_id"); +setDeploymentId(depid) +axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ + const invo=res.data + + setInvocationList(invo); + +}).catch(err=> + console.error(err)) +},[location]) + + + + const getLastFunctionEndTime = (functions, invocationStartTime) => { + const functionEntries = Object.entries(functions); + if (functionEntries.length === 0) { + return null; } - - } - + const maxEndTime = Math.max(...functionEntries.map(([_, func]) => func.end_delta_ms)); + const lastFunctionEndTime = new Date(invocationStartTime + maxEndTime).toLocaleString(); + return lastFunctionEndTime; + }; + + const handleFilterChange = (event) => { + setFilterValue(event.target.value); + }; + + const handleFilterByTime = (timeValue) => { + setFilterTime(timeValue); + }; + + const applyTimeFilter = (filteredData) => { + if (filterTime === 'all') { + return filteredData; + } else { + const now = Date.now(); + const filterTimes = { + last1Hour: now - 3600000, + lastDay: now - 86400000, + lastMonth: now - 2629746000, + last6Months: now - 15778476000, + last12Months: now - 31556952000, + }; + return filteredData.filter(item => { + const startTime = new Date(item.invocation_start_time_ms).getTime(); + return startTime > filterTimes[filterTime]; + }); + } + }; + + const filteredInvocationListByID = invocationList.filter(item => item.workflow_invocation_id.startsWith(filterValue)); + + const filteredByTime = applyTimeFilter(filteredInvocationListByID); + const [theme]=useMode(); + return ( - <> - - - - -

Deployment Invocations

- {Object.keys(invocationList).map((key) => ( - handleInvocation(key)}> - - - } +<> + +
+ +
+ + + + {/* + + */} + + + + + + + + {/* + + */} + + + + + + + + - - - ))} + + + - - { selectedInvocation && } - - - - - + - - - + +
+ +
+ + + + + Invocation ID + Start Time + End Time + + + + {filteredByTime.map(item => ( + + + {item.workflow_invocation_id} + + {new Date(item.invocation_start_time_ms).toLocaleString()} + + {getLastFunctionEndTime(item.functions, item.invocation_start_time_ms)} + + + ))} + +
+
+
+ +
+
+
+ ); }; -export default Invocation; +export default Invocation \ No newline at end of file diff --git a/frontend/src/scenes/invocations/InvocationDetails.jsx b/frontend/src/scenes/invocations/InvocationDetails.jsx new file mode 100644 index 0000000..c8e63d3 --- /dev/null +++ b/frontend/src/scenes/invocations/InvocationDetails.jsx @@ -0,0 +1,288 @@ +import React, { useState, useEffect } from 'react'; +import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField } from '@mui/material'; +import { useParams } from 'react-router-dom'; +import { useLocation } from "react-router-dom"; +import axios from "axios"; +import Paper from '@mui/material/Paper'; +import {useMode} from '../../theme' +import {ThemeProvider} from "@mui/material" +import ResponsiveAppBar from '../../components/App-bar'; + + +const InvocationDetails = () => { + const [filterValue, setFilterValue] = useState(''); + const [invocationList, setInvocationList] = useState([]); + const [InvocationData,setInvocationData]=useState([]); + const { id } = useParams(); + const location=useLocation(); + + useEffect(() => { + const params=new URLSearchParams(location.search); + const depid=params.get("wf_deployment_id"); + axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ + const invo=res.data + + setInvocationData(invo); + + }).catch(err=> + console.error(err)) + },[location]) + + const convertInvocationList = () => { + const instance = InvocationData.find(data => data.workflow_invocation_id === id); + const invocationStartTime = instance ? instance.invocation_start_time_ms : 0; // Fetch the invocation start time + const functions = instance ? instance.functions : {}; + + const convertMsToDateTime = (ms) => { + const date = new Date(invocationStartTime + ms); // Calculate date based on the invocation start time + return date.toLocaleString(); + }; + + for (const key in functions) { + if (functions.hasOwnProperty(key)) { + const func = functions[key]; + func.start_time_formatted = convertMsToDateTime(func.start_delta_ms); + func.end_time_formatted = convertMsToDateTime(func.end_delta_ms); + } + } + return functions; + }; + +useEffect(() => { + + const formattedInvocationList = convertInvocationList(); + setInvocationList(formattedInvocationList); + + },) + + + const handleFilterChange = (event) => { + setFilterValue(event.target.value); + }; + + const [theme]=useMode(); + + // Filter and sort functions based on start time in ascending order + const filteredInvocationList = Object.entries(invocationList) + .filter(([key]) => key.startsWith(filterValue)) + .sort(([, a], [, b]) => b.end_delta_ms - a.end_delta_ms); + + + + return ( + <> + +
+ +
+ + + + + + + + + +
+ +
+ + + + + + Function ID + Start Time (UTC+5:30) + End Time (UTC+5:30) + Execution Time (ms) + + + + {filteredInvocationList.map(([key, value]) => { + const executionTime = value.end_delta_ms - value.start_delta_ms; + return ( + + {key} + {value.start_time_formatted} + {value.end_time_formatted} + {executionTime} + + ); + })} + +
+
+
+
+ +
+
+
+ + ); +}; + + export default InvocationDetails; + +// import React, { useState, useEffect } from 'react'; +// import { Box, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, TextField, Button, MenuItem, Select } from '@mui/material'; +// import { useParams } from 'react-router-dom'; +// import { useLocation } from "react-router-dom"; +// import axios from "axios"; + +// const InvocationDetails = () => { +// const [filterValue, setFilterValue] = useState(''); +// const [filterTime, setFilterTime] = useState('all'); +// const [invocationList, setInvocationList] = useState([]); +// const [InvocationData,setInvocationData]=useState([]); +// const { id } = useParams(); + +// const location=useLocation(); + +// useEffect(() => { +// const params=new URLSearchParams(location.search); +// const depid=params.get("wf_deployment_id"); +// axios.post("/api/deploymentId/listAllInvocations/",{"wf_deployment_id":depid}).then(res=>{ +// const invo=res.data + +// setInvocationData(invo); + +// }).catch(err=> +// console.error(err)) +// },[location]) +// const convertInvocationList = () => { +// const instance = InvocationData.find(data => data.workflow_invocation_id === id); +// const invocationStartTime = instance ? instance.invocation_start_time_ms : 0; +// const functions = instance ? instance.functions : {}; + +// const convertMsToDateTime = (ms) => { +// const date = new Date(invocationStartTime + ms); +// return date.toLocaleString(); +// }; + +// for (const key in functions) { +// if (functions.hasOwnProperty(key)) { +// const func = functions[key]; +// func.start_time_formatted = convertMsToDateTime(func.start_delta_ms); +// func.end_time_formatted = convertMsToDateTime(func.end_delta_ms); +// } +// } +// return functions; +// }; + +// useEffect(() => { +// const formattedInvocationList = convertInvocationList(); +// setInvocationList(formattedInvocationList); +// }, ); + +// const handleFilterChange = (event) => { +// setFilterValue(event.target.value); +// }; + +// const handleFilterByTime = (timeValue) => { +// setFilterTime(timeValue); +// }; + +// const applyTimeFilter = (filteredData) => { +// if (filterTime === 'all') { +// return filteredData; +// } else { +// const now = Date.now(); +// const filterTimes = { +// last1Hour: now - 3600000, +// lastDay: now - 86400000, +// lastMonth: now - 2629746000, +// last6Months: now - 15778476000, +// last12Months: now - 31556952000, +// }; + +// return filteredData.filter(([_key, value]) => { +// const startTime = new Date(value.start_time_formatted).getTime(); +// return startTime > filterTimes[filterTime]; +// }); +// } +// }; + +// const filteredInvocationList = Object.entries(invocationList) +// .filter(([key]) => key.startsWith(filterValue)) +// .sort(([, a], [, b]) => b.end_delta_ms - a.end_delta_ms); + +// const filteredByTime = applyTimeFilter(filteredInvocationList); + +// return ( +//
+// +// +// +// +// +// +// +// + +// +// +// +// +// +// Function ID +// Start Time (UTC+5:30) +// End Time (UTC+5:30) +// Execution Time (ms) +// +// +// +// {filteredByTime.map(([key, value]) => { +// const executionTime = value.end_delta_ms - value.start_delta_ms; +// return ( +// +// {key} +// {value.start_time_formatted} +// {value.end_time_formatted} +// {executionTime} +// +// ); +// })} +// +//
+//
+ +//
+//
+// ); +// }; + +// export default InvocationDetails; \ No newline at end of file diff --git a/frontend/src/scenes/line/Line.jsx b/frontend/src/scenes/line/Line.jsx new file mode 100644 index 0000000..9310dc0 --- /dev/null +++ b/frontend/src/scenes/line/Line.jsx @@ -0,0 +1,130 @@ +// import { Box } from "@mui/material"; + + +// import LineChart from "../../components/LineChart"; + +// const Line = ({invocationId}) => { + +// return ( +// +// +// +// +// +// ); +// }; + +// export default Line; +import React, { useState,useEffect } from "react"; +import { Box, Button, styled } from "@mui/material"; +import { ResponsiveLine } from "@nivo/line"; +import axios from "axios"; +import { useTheme } from "@emotion/react"; +import { tokens } from "../../theme"; + +const LineChart = ({ chartData }) => { + + return ( + + ); +}; + +const CustomButton = styled(Button)({ + background: "white", + color: "black", + "&:hover": { + background: "white", + }, +}); + +const Line = () => { + const [chartData, setChartData] = useState([]); +useEffect(() => { + axios.post("/api/deploymentId/invocations",{"wf_deployment_id":"5fa74fb4-bb52-4ce7-932a-d0d30936b3d3"}) + .then(response => { + const { workflow_deployment_id, no_of_invocations } = response.data; + const currentTime = new Date().toLocaleTimeString(); + // Update chartData with array of objects + setChartData(prevData => [ + ...prevData, + { + x: currentTime, + y: no_of_invocations, + } + ]); + }) + .catch(error => { + console.error("Error fetching data:", error); + }); +}, []); + + const fetchData = async () => { + try { + const response = await axios.post("/api/deploymentId/invocations",{"wf_deployment_id":"5fa74fb4-bb52-4ce7-932a-d0d30936b3d3"}); + const { workflow_deployment_id, no_of_invocations } = response.data; + const currentTime = new Date().toLocaleTimeString(); + + setChartData((prevData) => [ + ...prevData, + { + x: currentTime, + y: no_of_invocations, + }, + ]); + } catch (error) { + console.error("Error fetching data:", error); + } + }; + + return ( + + + Add Invocation + + + + + + ); +}; + +export default Line; \ No newline at end of file diff --git a/frontend/src/scenes/line/StartvsEndHistogram.jsx b/frontend/src/scenes/line/StartvsEndHistogram.jsx new file mode 100644 index 0000000..c5ffd96 --- /dev/null +++ b/frontend/src/scenes/line/StartvsEndHistogram.jsx @@ -0,0 +1,132 @@ +import React, { useState, useEffect } from 'react'; +import { ResponsiveBar } from '@nivo/bar'; +import { FormControl, InputLabel, Select, MenuItem } from '@mui/material'; +import axios from "axios"; +import { useLocation } from "react-router-dom"; + +const StartvsEndHistogram = (props) => { + const [selectedFilter, setSelectedFilter] = useState('all'); + const [execTime, setExecTimeList] = useState([]); + const location = useLocation(); + + const calculateExecutionTime = (startTime, endTime) => { + const start = new Date(startTime).getTime(); + const end = new Date(endTime).getTime(); + return (end - start) / 1000; // Returns execution time in seconds + }; + + useEffect(() => { + const params = new URLSearchParams(location.search); + const depid = params.get("wf_deployment_id"); + axios.post("/api/deploymentId/invocations/workflowEndTime/", { "wf_deployment_id": depid }) + .then(res => { + const list = res.data; + setExecTimeList(list); + }) + .catch(err => console.error(err)); + }, [selectedFilter]); + + useEffect(() => { + const filterData = () => { + const currentDate = new Date(); + switch (selectedFilter) { + case 'lastDay': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 24 * 60 * 60 * 1000; // 24 hours + }) + ); + break; + case 'lastMonth': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 30 * 24 * 60 * 60 * 1000; // 30 days + }) + ); + break; + case 'last6Months': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 6 * 30 * 24 * 60 * 60 * 1000; // 6 months + }) + ); + break; + case 'last12Months': + setExecTimeList( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 12 * 30 * 24 * 60 * 60 * 1000; // 12 months + }) + ); + break; + case 'all': + default: + setExecTimeList(execTime); + break; + } + }; + + filterData(); + }, [selectedFilter]); + const startTimeHistogramData = execTime.map(item => ({ + startTime: new Date(item.invocation_start_time_ms).toLocaleString(), + executionTime: calculateExecutionTime(item.invocation_start_time_ms, item.workflowEndTime), + })); + + return ( + <> + + Filter +
+ +
+ + + + ); +}; + +export default StartvsEndHistogram; diff --git a/frontend/src/scenes/line/StartvsEndScatterPlot.jsx b/frontend/src/scenes/line/StartvsEndScatterPlot.jsx new file mode 100644 index 0000000..bab4666 --- /dev/null +++ b/frontend/src/scenes/line/StartvsEndScatterPlot.jsx @@ -0,0 +1,163 @@ +import React, { useState, useEffect } from 'react'; +import { ResponsiveScatterPlot } from '@nivo/scatterplot' +import { FormControl, InputLabel, Select, MenuItem } from '@mui/material'; +import axios from "axios"; +import { useLocation } from "react-router-dom"; + +const StartvsEndScatterPlot = (props) => { + const [selectedFilter, setSelectedFilter] = useState('all'); + const [filteredData, setFilteredData] = useState([]); + const [execTime,setExecTimeList]=useState([]); + const location=useLocation(); + + const calculateExecutionTime = (startTime, endTime) => { + const start = new Date(startTime).getTime(); + const end = new Date(endTime).getTime(); + return end - start; // Returns execution time in milliseconds + }; + useEffect(() => { + const params=new URLSearchParams(location.search); + const depid=params.get("wf_deployment_id"); + axios.post("/api/deploymentId/invocations/workflowEndTime/",{"wf_deployment_id":depid}).then(res=>{ + const list=res.data + + setExecTimeList(list); + + }).catch(err=> + console.error(err)) + },[selectedFilter]) + + + useEffect(() => { + const filterData = () => { + const currentDate = new Date(); + switch (selectedFilter) { + case 'lastDay': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 24 * 60 * 60 * 1000; // 24 hours + }) + ); + break; + case 'lastMonth': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 30 * 24 * 60 * 60 * 1000; // 30 days + }) + ); + break; + case 'last6Months': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 6 * 30 * 24 * 60 * 60 * 1000; // 6 months + }) + ); + break; + case 'last12Months': + setFilteredData( + execTime.filter(item => { + const startTime = new Date(item.invocation_start_time_ms); + return currentDate - startTime <= 12 * 30 * 24 * 60 * 60 * 1000; // 12 months + }) + ); + break; + case 'all': + default: + setFilteredData(execTime); + break; + } + }; + + filterData(); + }, [selectedFilter]); + + const XsortedData = filteredData + .map(item => ({ + x: new Date(item.invocation_start_time_ms).toLocaleString(), + y: calculateExecutionTime(item.invocation_start_time_ms,item.workflowEndTime)/1000, + })) + .sort((a, b) => new Date(a.x) - new Date(b.x)); + + const YsortedData = [...XsortedData].sort((a, b) => new Date(a.y) - new Date(b.y)); + + const formattedData = [{ id: 'invocations', data: XsortedData }]; + + const startX = XsortedData[0]?.x || ''; + const endX = XsortedData[XsortedData.length - 1]?.x || ''; + const startY = YsortedData[0]?.y || ''; + const endY = YsortedData[YsortedData.length - 1]?.y || ''; + + return ( + <> + + Filter +
+ +
+ + ( +
+ Start Time: {node.data.x} +
+ Execution Time: {node.data.y} seconds +
+ )} + /> + + ); +}; + +export default StartvsEndScatterPlot; \ No newline at end of file diff --git a/frontend/src/scenes/line/index.jsx b/frontend/src/scenes/line/index.jsx deleted file mode 100644 index 8fd8157..0000000 --- a/frontend/src/scenes/line/index.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Box } from "@mui/material"; - - -import LineChart from "../../components/LineChart"; - -const Line = ({invocationId}) => { - - return ( - - - - - - ); -}; - -export default Line; \ No newline at end of file diff --git a/frontend/src/setupTests.js b/frontend/src/setupTests.js index 8f2609b..b28b910 100644 --- a/frontend/src/setupTests.js +++ b/frontend/src/setupTests.js @@ -2,4 +2,4 @@ // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; +import '@testing-library/jest-dom'; \ No newline at end of file diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6192697 --- /dev/null +++ b/readme.md @@ -0,0 +1,65 @@ +# XFaaS Dashboard Setup Guide + +## Prerequisites for Running XFaaS Dashboard + +Before you proceed with setting up the XFaaS dashboard, ensure the following prerequisites are met: + +1. **Git Installation**: + - Confirm that Git is installed on your system. If not, download and install Git for your respective operating system from [here](https://git-scm.com/). + +2. **Node.js Installation**: + - Install the latest version of Node.js. Visit Node.js's official website for detailed instructions on installation. + +3. **AWS CLI and SDK Setup**: + - Set up the AWS Command Line Interface (CLI) and AWS Software Development Kits (SDKs) to enable interactions with AWS services. + - Refer to the following link for comprehensive setup instructions: [Setting up AWS CLI and SDKs](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). + - Run this command to quickly set and view your credentials, Region, and output format. The following example shows sample values. + + ``` +$ aws configure +AWS Access Key ID [None]: *************** +AWS Secret Access Key [None]: ************ +Default region name [None]: us-west-2 +Default output format [None]: json + +``` + + + +- **Google Chrome**: Using Chrome as a default browser is mandatory for viewing XFaaS dashboard. + +## Cloning and Running XFaaS + +Follow these steps to clone and run the XFaaS dashboard: + +1. **Clone the Repository**: + - Clone the GitHub repository [XFaaS](https://github.com/itsCheithanya/XFaaS.git) using the following command: + ```bash + git clone https://github.com/itsCheithanya/XFaaS.git + ``` + - Alternatively, you can download the zip file of the repository and unzip it. + +2. **Frontend Setup**: + - Open your terminal and navigate to the `/XFaaS/frontend` directory using the following command: + ```bash + cd XFaaS/frontend + ``` + - Install all the npm packages by executing the command: + ```bash + npm install + ``` + - Start the frontend server by executing the command: + ```bash + npm start + ``` + +3. **Backend Setup**: + - Navigate to the `/XFaaS/backend` directory. + - Install all the backend packages by executing the command: + ```bash + npm install + ``` + - Start the backend server by executing the command: + ```bash + npm run dev + ```