diff --git a/package-lock.json b/package-lock.json
index fb83a8e79e068dc4f2275f77836236db8248d4b6..45c6287f8725e19e617dfef4de6a9ef61b8d5d8c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,7 @@
         "@aws-sdk/s3-request-presigner": "<3.530.0",
         "@fortawesome/fontawesome-free": "~6.5.0",
         "@popperjs/core": "~2.11.8",
-        "ajv": "~8.13.0",
+        "ajv": "~8.14.0",
         "bootstrap": "~5.3.0",
         "chart.js": "~4.4.0",
         "chartjs-plugin-zoom": "~2.0.1",
@@ -929,9 +929,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.24.5",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
-      "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
+      "version": "7.24.6",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.6.tgz",
+      "integrity": "sha512-eNZXdfU35nJC2h24RznROuOpO94h6x8sg9ju0tT9biNtLZ2vuP8SduLqqV+/8+cebSLV9SJEAN5Z3zQbJG/M+Q==",
       "bin": {
         "parser": "bin/babel-parser.js"
       },
@@ -962,9 +962,9 @@
       }
     },
     "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.3.tgz",
-      "integrity": "sha512-yTgnwQpFVYfvvo4SvRFB0SwrW8YjOxEoT7wfMT7Ol5v7v5LDNvSGo67aExmxOb87nQNeWPVvaGBNfQ7BXcrZ9w==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.4.tgz",
+      "integrity": "sha512-Zrm+B33R4LWPLjDEVnEqt2+SLTATlru1q/xYKVn8oVTbiRBGmK2VIMoIYGJDGyftnGaC788IuzGFAlb7IQ0Y8A==",
       "cpu": [
         "ppc64"
       ],
@@ -979,9 +979,9 @@
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.3.tgz",
-      "integrity": "sha512-bviJOLMgurLJtF1/mAoJLxDZDL6oU5/ztMHnJQRejbJrSc9FFu0QoUoFhvi6qSKJEw9y5oGyvr9fuDtzJ30rNQ==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.4.tgz",
+      "integrity": "sha512-E7H/yTd8kGQfY4z9t3nRPk/hrhaCajfA3YSQSBrst8B+3uTcgsi8N+ZWYCaeIDsiVs6m65JPCaQN/DxBRclF3A==",
       "cpu": [
         "arm"
       ],
@@ -996,9 +996,9 @@
       }
     },
     "node_modules/@esbuild/android-arm64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.3.tgz",
-      "integrity": "sha512-c+ty9necz3zB1Y+d/N+mC6KVVkGUUOcm4ZmT5i/Fk5arOaY3i6CA3P5wo/7+XzV8cb4GrI/Zjp8NuOQ9Lfsosw==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.4.tgz",
+      "integrity": "sha512-fYFnz+ObClJ3dNiITySBUx+oNalYUT18/AryMxfovLkYWbutXsct3Wz2ZWAcGGppp+RVVX5FiXeLYGi97umisA==",
       "cpu": [
         "arm64"
       ],
@@ -1013,9 +1013,9 @@
       }
     },
     "node_modules/@esbuild/android-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.3.tgz",
-      "integrity": "sha512-JReHfYCRK3FVX4Ra+y5EBH1b9e16TV2OxrPAvzMsGeES0X2Ndm9ImQRI4Ket757vhc5XBOuGperw63upesclRw==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.4.tgz",
+      "integrity": "sha512-mDqmlge3hFbEPbCWxp4fM6hqq7aZfLEHZAKGP9viq9wMUBVQx202aDIfc3l+d2cKhUJM741VrCXEzRFhPDKH3Q==",
       "cpu": [
         "x64"
       ],
@@ -1030,9 +1030,9 @@
       }
     },
     "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.3.tgz",
-      "integrity": "sha512-U3fuQ0xNiAkXOmQ6w5dKpEvXQRSpHOnbw7gEfHCRXPeTKW9sBzVck6C5Yneb8LfJm0l6le4NQfkNPnWMSlTFUQ==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.4.tgz",
+      "integrity": "sha512-72eaIrDZDSiWqpmCzVaBD58c8ea8cw/U0fq/PPOTqE3c53D0xVMRt2ooIABZ6/wj99Y+h4ksT/+I+srCDLU9TA==",
       "cpu": [
         "arm64"
       ],
@@ -1047,9 +1047,9 @@
       }
     },
     "node_modules/@esbuild/darwin-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.3.tgz",
-      "integrity": "sha512-3m1CEB7F07s19wmaMNI2KANLcnaqryJxO1fXHUV5j1rWn+wMxdUYoPyO2TnAbfRZdi7ADRwJClmOwgT13qlP3Q==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.4.tgz",
+      "integrity": "sha512-uBsuwRMehGmw1JC7Vecu/upOjTsMhgahmDkWhGLWxIgUn2x/Y4tIwUZngsmVb6XyPSTXJYS4YiASKPcm9Zitag==",
       "cpu": [
         "x64"
       ],
@@ -1064,9 +1064,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.3.tgz",
-      "integrity": "sha512-fsNAAl5pU6wmKHq91cHWQT0Fz0vtyE1JauMzKotrwqIKAswwP5cpHUCxZNSTuA/JlqtScq20/5KZ+TxQdovU/g==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.4.tgz",
+      "integrity": "sha512-8JfuSC6YMSAEIZIWNL3GtdUT5NhUA/CMUCpZdDRolUXNAXEE/Vbpe6qlGLpfThtY5NwXq8Hi4nJy4YfPh+TwAg==",
       "cpu": [
         "arm64"
       ],
@@ -1081,9 +1081,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.3.tgz",
-      "integrity": "sha512-tci+UJ4zP5EGF4rp8XlZIdq1q1a/1h9XuronfxTMCNBslpCtmk97Q/5qqy1Mu4zIc0yswN/yP/BLX+NTUC1bXA==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.4.tgz",
+      "integrity": "sha512-8d9y9eQhxv4ef7JmXny7591P/PYsDFc4+STaxC1GBv0tMyCdyWfXu2jBuqRsyhY8uL2HU8uPyscgE2KxCY9imQ==",
       "cpu": [
         "x64"
       ],
@@ -1098,9 +1098,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.3.tgz",
-      "integrity": "sha512-f6kz2QpSuyHHg01cDawj0vkyMwuIvN62UAguQfnNVzbge2uWLhA7TCXOn83DT0ZvyJmBI943MItgTovUob36SQ==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.4.tgz",
+      "integrity": "sha512-2rqFFefpYmpMs+FWjkzSgXg5vViocqpq5a1PSRgT0AvSgxoXmGF17qfGAzKedg6wAwyM7UltrKVo9kxaJLMF/g==",
       "cpu": [
         "arm"
       ],
@@ -1115,9 +1115,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.3.tgz",
-      "integrity": "sha512-vvG6R5g5ieB4eCJBQevyDMb31LMHthLpXTc2IGkFnPWS/GzIFDnaYFp558O+XybTmYrVjxnryru7QRleJvmZ6Q==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.4.tgz",
+      "integrity": "sha512-/GLD2orjNU50v9PcxNpYZi+y8dJ7e7/LhQukN3S4jNDXCKkyyiyAz9zDw3siZ7Eh1tRcnCHAo/WcqKMzmi4eMQ==",
       "cpu": [
         "arm64"
       ],
@@ -1132,9 +1132,9 @@
       }
     },
     "node_modules/@esbuild/linux-ia32": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.3.tgz",
-      "integrity": "sha512-HjCWhH7K96Na+66TacDLJmOI9R8iDWDDiqe17C7znGvvE4sW1ECt9ly0AJ3dJH62jHyVqW9xpxZEU1jKdt+29A==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.4.tgz",
+      "integrity": "sha512-pNftBl7m/tFG3t2m/tSjuYeWIffzwAZT9m08+9DPLizxVOsUl8DdFzn9HvJrTQwe3wvJnwTdl92AonY36w/25g==",
       "cpu": [
         "ia32"
       ],
@@ -1149,9 +1149,9 @@
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.3.tgz",
-      "integrity": "sha512-BGpimEccmHBZRcAhdlRIxMp7x9PyJxUtj7apL2IuoG9VxvU/l/v1z015nFs7Si7tXUwEsvjc1rOJdZCn4QTU+Q==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.4.tgz",
+      "integrity": "sha512-cSD2gzCK5LuVX+hszzXQzlWya6c7hilO71L9h4KHwqI4qeqZ57bAtkgcC2YioXjsbfAv4lPn3qe3b00Zt+jIfQ==",
       "cpu": [
         "loong64"
       ],
@@ -1166,9 +1166,9 @@
       }
     },
     "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.3.tgz",
-      "integrity": "sha512-5rMOWkp7FQGtAH3QJddP4w3s47iT20hwftqdm7b+loe95o8JU8ro3qZbhgMRy0VuFU0DizymF1pBKkn3YHWtsw==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.4.tgz",
+      "integrity": "sha512-qtzAd3BJh7UdbiXCrg6npWLYU0YpufsV9XlufKhMhYMJGJCdfX/G6+PNd0+v877X1JG5VmjBLUiFB0o8EUSicA==",
       "cpu": [
         "mips64el"
       ],
@@ -1183,9 +1183,9 @@
       }
     },
     "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.3.tgz",
-      "integrity": "sha512-h0zj1ldel89V5sjPLo5H1SyMzp4VrgN1tPkN29TmjvO1/r0MuMRwJxL8QY05SmfsZRs6TF0c/IDH3u7XYYmbAg==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.4.tgz",
+      "integrity": "sha512-yB8AYzOTaL0D5+2a4xEy7OVvbcypvDR05MsB/VVPVA7nL4hc5w5Dyd/ddnayStDgJE59fAgNEOdLhBxjfx5+dg==",
       "cpu": [
         "ppc64"
       ],
@@ -1200,9 +1200,9 @@
       }
     },
     "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.3.tgz",
-      "integrity": "sha512-dkAKcTsTJ+CRX6bnO17qDJbLoW37npd5gSNtSzjYQr0svghLJYGYB0NF1SNcU1vDcjXLYS5pO4qOW4YbFama4A==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.4.tgz",
+      "integrity": "sha512-Y5AgOuVzPjQdgU59ramLoqSSiXddu7F3F+LI5hYy/d1UHN7K5oLzYBDZe23QmQJ9PIVUXwOdKJ/jZahPdxzm9w==",
       "cpu": [
         "riscv64"
       ],
@@ -1217,9 +1217,9 @@
       }
     },
     "node_modules/@esbuild/linux-s390x": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.3.tgz",
-      "integrity": "sha512-vnD1YUkovEdnZWEuMmy2X2JmzsHQqPpZElXx6dxENcIwTu+Cu5ERax6+Ke1QsE814Zf3c6rxCfwQdCTQ7tPuXA==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.4.tgz",
+      "integrity": "sha512-Iqc/l/FFwtt8FoTK9riYv9zQNms7B8u+vAI/rxKuN10HgQIXaPzKZc479lZ0x6+vKVQbu55GdpYpeNWzjOhgbA==",
       "cpu": [
         "s390x"
       ],
@@ -1234,9 +1234,9 @@
       }
     },
     "node_modules/@esbuild/linux-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.3.tgz",
-      "integrity": "sha512-IOXOIm9WaK7plL2gMhsWJd+l2bfrhfilv0uPTptoRoSb2p09RghhQQp9YY6ZJhk/kqmeRt6siRdMSLLwzuT0KQ==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.4.tgz",
+      "integrity": "sha512-Td9jv782UMAFsuLZINfUpoF5mZIbAj+jv1YVtE58rFtfvoKRiKSkRGQfHTgKamLVT/fO7203bHa3wU122V/Bdg==",
       "cpu": [
         "x64"
       ],
@@ -1251,9 +1251,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.3.tgz",
-      "integrity": "sha512-uTgCwsvQ5+vCQnqM//EfDSuomo2LhdWhFPS8VL8xKf+PKTCrcT/2kPPoWMTs22aB63MLdGMJiE3f1PHvCDmUOw==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.4.tgz",
+      "integrity": "sha512-Awn38oSXxsPMQxaV0Ipb7W/gxZtk5Tx3+W+rAPdZkyEhQ6968r9NvtkjhnhbEgWXYbgV+JEONJ6PcdBS+nlcpA==",
       "cpu": [
         "x64"
       ],
@@ -1268,9 +1268,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.3.tgz",
-      "integrity": "sha512-vNAkR17Ub2MgEud2Wag/OE4HTSI6zlb291UYzHez/psiKarp0J8PKGDnAhMBcHFoOHMXHfExzmjMojJNbAStrQ==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.4.tgz",
+      "integrity": "sha512-IsUmQeCY0aU374R82fxIPu6vkOybWIMc3hVGZ3ChRwL9hA1TwY+tS0lgFWV5+F1+1ssuvvXt3HFqe8roCip8Hg==",
       "cpu": [
         "x64"
       ],
@@ -1285,9 +1285,9 @@
       }
     },
     "node_modules/@esbuild/sunos-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.3.tgz",
-      "integrity": "sha512-W8H9jlGiSBomkgmouaRoTXo49j4w4Kfbl6I1bIdO/vT0+0u4f20ko3ELzV3hPI6XV6JNBVX+8BC+ajHkvffIJA==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.4.tgz",
+      "integrity": "sha512-hsKhgZ4teLUaDA6FG/QIu2q0rI6I36tZVfM4DBZv3BG0mkMIdEnMbhc4xwLvLJSS22uWmaVkFkqWgIS0gPIm+A==",
       "cpu": [
         "x64"
       ],
@@ -1302,9 +1302,9 @@
       }
     },
     "node_modules/@esbuild/win32-arm64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.3.tgz",
-      "integrity": "sha512-EjEomwyLSCg8Ag3LDILIqYCZAq/y3diJ04PnqGRgq8/4O3VNlXyMd54j/saShaN4h5o5mivOjAzmU6C3X4v0xw==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.4.tgz",
+      "integrity": "sha512-UUfMgMoXPoA/bvGUNfUBFLCh0gt9dxZYIx9W4rfJr7+hKe5jxxHmfOK8YSH4qsHLLN4Ck8JZ+v7Q5fIm1huErg==",
       "cpu": [
         "arm64"
       ],
@@ -1319,9 +1319,9 @@
       }
     },
     "node_modules/@esbuild/win32-ia32": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.3.tgz",
-      "integrity": "sha512-WGiE/GgbsEwR33++5rzjiYsKyHywE8QSZPF7Rfx9EBfK3Qn3xyR6IjyCr5Uk38Kg8fG4/2phN7sXp4NPWd3fcw==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.4.tgz",
+      "integrity": "sha512-yIxbspZb5kGCAHWm8dexALQ9en1IYDfErzjSEq1KzXFniHv019VT3mNtTK7t8qdy4TwT6QYHI9sEZabONHg+aw==",
       "cpu": [
         "ia32"
       ],
@@ -1336,9 +1336,9 @@
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.3.tgz",
-      "integrity": "sha512-xRxC0jaJWDLYvcUvjQmHCJSfMrgmUuvsoXgDeU/wTorQ1ngDdUBuFtgY3W1Pc5sprGAvZBtWdJX7RPg/iZZUqA==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.4.tgz",
+      "integrity": "sha512-sywLRD3UK/qRJt0oBwdpYLBibk7KiRfbswmWRDabuncQYSlf8aLEEUor/oP6KRz8KEG+HoiVLBhPRD5JWjS8Sg==",
       "cpu": [
         "x64"
       ],
@@ -1589,9 +1589,9 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz",
-      "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
+      "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
       "cpu": [
         "arm"
       ],
@@ -1602,9 +1602,9 @@
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz",
-      "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
+      "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
       "cpu": [
         "arm64"
       ],
@@ -1615,9 +1615,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz",
-      "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
+      "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
       "cpu": [
         "arm64"
       ],
@@ -1628,9 +1628,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz",
-      "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
+      "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
       "cpu": [
         "x64"
       ],
@@ -1641,9 +1641,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz",
-      "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
+      "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
       "cpu": [
         "arm"
       ],
@@ -1654,9 +1654,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz",
-      "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
+      "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
       "cpu": [
         "arm"
       ],
@@ -1667,9 +1667,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz",
-      "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
+      "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
       "cpu": [
         "arm64"
       ],
@@ -1680,9 +1680,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz",
-      "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
+      "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
       "cpu": [
         "arm64"
       ],
@@ -1693,9 +1693,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz",
-      "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
+      "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
       "cpu": [
         "ppc64"
       ],
@@ -1706,9 +1706,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz",
-      "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
+      "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
       "cpu": [
         "riscv64"
       ],
@@ -1719,9 +1719,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz",
-      "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
+      "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
       "cpu": [
         "s390x"
       ],
@@ -1732,9 +1732,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz",
-      "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
+      "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
       "cpu": [
         "x64"
       ],
@@ -1745,9 +1745,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz",
-      "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
+      "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
       "cpu": [
         "x64"
       ],
@@ -1758,9 +1758,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz",
-      "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
+      "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
       "cpu": [
         "arm64"
       ],
@@ -1771,9 +1771,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz",
-      "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
+      "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
       "cpu": [
         "ia32"
       ],
@@ -1784,9 +1784,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz",
-      "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
+      "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
       "cpu": [
         "x64"
       ],
@@ -2509,16 +2509,16 @@
       "dev": true
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.10.0.tgz",
-      "integrity": "sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz",
+      "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==",
       "dev": true,
       "dependencies": {
         "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "7.10.0",
-        "@typescript-eslint/type-utils": "7.10.0",
-        "@typescript-eslint/utils": "7.10.0",
-        "@typescript-eslint/visitor-keys": "7.10.0",
+        "@typescript-eslint/scope-manager": "7.11.0",
+        "@typescript-eslint/type-utils": "7.11.0",
+        "@typescript-eslint/utils": "7.11.0",
+        "@typescript-eslint/visitor-keys": "7.11.0",
         "graphemer": "^1.4.0",
         "ignore": "^5.3.1",
         "natural-compare": "^1.4.0",
@@ -2542,15 +2542,15 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.10.0.tgz",
-      "integrity": "sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz",
+      "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/scope-manager": "7.10.0",
-        "@typescript-eslint/types": "7.10.0",
-        "@typescript-eslint/typescript-estree": "7.10.0",
-        "@typescript-eslint/visitor-keys": "7.10.0",
+        "@typescript-eslint/scope-manager": "7.11.0",
+        "@typescript-eslint/types": "7.11.0",
+        "@typescript-eslint/typescript-estree": "7.11.0",
+        "@typescript-eslint/visitor-keys": "7.11.0",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -2570,13 +2570,13 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.10.0.tgz",
-      "integrity": "sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz",
+      "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.10.0",
-        "@typescript-eslint/visitor-keys": "7.10.0"
+        "@typescript-eslint/types": "7.11.0",
+        "@typescript-eslint/visitor-keys": "7.11.0"
       },
       "engines": {
         "node": "^18.18.0 || >=20.0.0"
@@ -2587,13 +2587,13 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.10.0.tgz",
-      "integrity": "sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz",
+      "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "7.10.0",
-        "@typescript-eslint/utils": "7.10.0",
+        "@typescript-eslint/typescript-estree": "7.11.0",
+        "@typescript-eslint/utils": "7.11.0",
         "debug": "^4.3.4",
         "ts-api-utils": "^1.3.0"
       },
@@ -2614,9 +2614,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.10.0.tgz",
-      "integrity": "sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz",
+      "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==",
       "dev": true,
       "engines": {
         "node": "^18.18.0 || >=20.0.0"
@@ -2627,13 +2627,13 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.10.0.tgz",
-      "integrity": "sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz",
+      "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.10.0",
-        "@typescript-eslint/visitor-keys": "7.10.0",
+        "@typescript-eslint/types": "7.11.0",
+        "@typescript-eslint/visitor-keys": "7.11.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
@@ -2655,15 +2655,15 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.10.0.tgz",
-      "integrity": "sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz",
+      "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==",
       "dev": true,
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
-        "@typescript-eslint/scope-manager": "7.10.0",
-        "@typescript-eslint/types": "7.10.0",
-        "@typescript-eslint/typescript-estree": "7.10.0"
+        "@typescript-eslint/scope-manager": "7.11.0",
+        "@typescript-eslint/types": "7.11.0",
+        "@typescript-eslint/typescript-estree": "7.11.0"
       },
       "engines": {
         "node": "^18.18.0 || >=20.0.0"
@@ -2677,12 +2677,12 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "7.10.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.10.0.tgz",
-      "integrity": "sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==",
+      "version": "7.11.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz",
+      "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==",
       "dev": true,
       "dependencies": {
-        "@typescript-eslint/types": "7.10.0",
+        "@typescript-eslint/types": "7.11.0",
         "eslint-visitor-keys": "^3.4.3"
       },
       "engines": {
@@ -2713,30 +2713,30 @@
       }
     },
     "node_modules/@volar/language-core": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.4.tgz",
-      "integrity": "sha512-7As47GndxGxsqqYnbreLrfB5NDUeQioPM2LJKUuB4/34c0NpEJ2byVl3c9KYdjIdiEstWZ9JLtLKNTaPWb5jtA==",
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.5.tgz",
+      "integrity": "sha512-2htyAuxRrAgETmFeUhT4XLELk3LiEcqoW/B8YUXMF6BrGWLMwIR09MFaZYvrA2UhbdAeSyeQ726HaWSWkexUcQ==",
       "dev": true,
       "dependencies": {
-        "@volar/source-map": "2.2.4"
+        "@volar/source-map": "2.2.5"
       }
     },
     "node_modules/@volar/source-map": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.4.tgz",
-      "integrity": "sha512-m92FLpR9vB1YEZfiZ+bfgpLrToL/DNkOrorWVep3pffHrwwI4Tx2oIQN+sqHJfKkiT5N3J1owC+8crhAEinfjg==",
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.5.tgz",
+      "integrity": "sha512-wrOEIiZNf4E+PWB0AxyM4tfhkfldPsb3bxg8N6FHrxJH2ohar7aGu48e98bp3pR9HUA7P/pR9VrLmkTrgCCnWQ==",
       "dev": true,
       "dependencies": {
         "muggle-string": "^0.4.0"
       }
     },
     "node_modules/@volar/typescript": {
-      "version": "2.2.4",
-      "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.4.tgz",
-      "integrity": "sha512-uAQC53tgEbHO62G8NXMfmBrJAlP2QJ9WxVEEQqqK3I6VSy8frL5LbH3hAWODxiwMWixv74wJLWlKbWXOgdIoRQ==",
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.5.tgz",
+      "integrity": "sha512-eSV/n75+ppfEVugMC/salZsI44nXDPAyL6+iTYCNLtiLHGJsnMv9GwiDMujrvAUj/aLQyqRJgYtXRoxop2clCw==",
       "dev": true,
       "dependencies": {
-        "@volar/language-core": "2.2.4",
+        "@volar/language-core": "2.2.5",
         "path-browserify": "^1.0.1"
       }
     },
@@ -2942,9 +2942,9 @@
       }
     },
     "node_modules/ajv": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.13.0.tgz",
-      "integrity": "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.14.0.tgz",
+      "integrity": "sha512-oYs1UUtO97ZO2lJ4bwnWeQW8/zvOIQLGKcvPTsWmvc2SYgBb+upuNS5NxoLaMU4h8Ju3Nbj6Cq8mD2LQoqVKFA==",
       "dependencies": {
         "fast-deep-equal": "^3.1.3",
         "json-schema-traverse": "^1.0.0",
@@ -2993,18 +2993,6 @@
         "node": ">= 8"
       }
     },
-    "node_modules/anymatch/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
     "node_modules/argparse": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -3684,9 +3672,9 @@
       }
     },
     "node_modules/esbuild": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.3.tgz",
-      "integrity": "sha512-Kgq0/ZsAPzKrbOjCQcjoSmPoWhlcVnGAUo7jvaLHoxW1Drto0KGkR1xBNg2Cp43b9ImvxmPEJZ9xkfcnqPsfBw==",
+      "version": "0.21.4",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.4.tgz",
+      "integrity": "sha512-sFMcNNrj+Q0ZDolrp5pDhH0nRPN9hLIM3fRPwgbLYJeSHHgnXSnbV3xYgSVuOeLWH9c73VwmEverVzupIv5xuA==",
       "dev": true,
       "hasInstallScript": true,
       "peer": true,
@@ -3697,29 +3685,29 @@
         "node": ">=12"
       },
       "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.21.3",
-        "@esbuild/android-arm": "0.21.3",
-        "@esbuild/android-arm64": "0.21.3",
-        "@esbuild/android-x64": "0.21.3",
-        "@esbuild/darwin-arm64": "0.21.3",
-        "@esbuild/darwin-x64": "0.21.3",
-        "@esbuild/freebsd-arm64": "0.21.3",
-        "@esbuild/freebsd-x64": "0.21.3",
-        "@esbuild/linux-arm": "0.21.3",
-        "@esbuild/linux-arm64": "0.21.3",
-        "@esbuild/linux-ia32": "0.21.3",
-        "@esbuild/linux-loong64": "0.21.3",
-        "@esbuild/linux-mips64el": "0.21.3",
-        "@esbuild/linux-ppc64": "0.21.3",
-        "@esbuild/linux-riscv64": "0.21.3",
-        "@esbuild/linux-s390x": "0.21.3",
-        "@esbuild/linux-x64": "0.21.3",
-        "@esbuild/netbsd-x64": "0.21.3",
-        "@esbuild/openbsd-x64": "0.21.3",
-        "@esbuild/sunos-x64": "0.21.3",
-        "@esbuild/win32-arm64": "0.21.3",
-        "@esbuild/win32-ia32": "0.21.3",
-        "@esbuild/win32-x64": "0.21.3"
+        "@esbuild/aix-ppc64": "0.21.4",
+        "@esbuild/android-arm": "0.21.4",
+        "@esbuild/android-arm64": "0.21.4",
+        "@esbuild/android-x64": "0.21.4",
+        "@esbuild/darwin-arm64": "0.21.4",
+        "@esbuild/darwin-x64": "0.21.4",
+        "@esbuild/freebsd-arm64": "0.21.4",
+        "@esbuild/freebsd-x64": "0.21.4",
+        "@esbuild/linux-arm": "0.21.4",
+        "@esbuild/linux-arm64": "0.21.4",
+        "@esbuild/linux-ia32": "0.21.4",
+        "@esbuild/linux-loong64": "0.21.4",
+        "@esbuild/linux-mips64el": "0.21.4",
+        "@esbuild/linux-ppc64": "0.21.4",
+        "@esbuild/linux-riscv64": "0.21.4",
+        "@esbuild/linux-s390x": "0.21.4",
+        "@esbuild/linux-x64": "0.21.4",
+        "@esbuild/netbsd-x64": "0.21.4",
+        "@esbuild/openbsd-x64": "0.21.4",
+        "@esbuild/sunos-x64": "0.21.4",
+        "@esbuild/win32-arm64": "0.21.4",
+        "@esbuild/win32-ia32": "0.21.4",
+        "@esbuild/win32-x64": "0.21.4"
       }
     },
     "node_modules/escape-string-regexp": {
@@ -4300,6 +4288,7 @@
       "version": "7.2.3",
       "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
       "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "deprecated": "Glob versions prior to v9 are no longer supported",
       "dev": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
@@ -4627,6 +4616,7 @@
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
       "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
       "dev": true,
       "dependencies": {
         "once": "^1.3.0",
@@ -5073,13 +5063,13 @@
       }
     },
     "node_modules/micromatch": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.6.tgz",
-      "integrity": "sha512-Y4Ypn3oujJYxJcMacVgcs92wofTHxp9FzfDpQON4msDefoC0lb3ETvQLOdLcbhSwU1bz8HrL/1sygfBIHudrkQ==",
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
+      "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
       "dev": true,
       "dependencies": {
         "braces": "^3.0.3",
-        "picomatch": "^4.0.2"
+        "picomatch": "^2.3.1"
       },
       "engines": {
         "node": ">=8.6"
@@ -5591,12 +5581,12 @@
       "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
     },
     "node_modules/picomatch": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
-      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
       "dev": true,
       "engines": {
-        "node": ">=12"
+        "node": ">=8.6"
       },
       "funding": {
         "url": "https://github.com/sponsors/jonschlinkert"
@@ -5710,9 +5700,9 @@
       }
     },
     "node_modules/postcss-selector-parser": {
-      "version": "6.0.16",
-      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
-      "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
+      "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
       "dev": true,
       "dependencies": {
         "cssesc": "^3.0.0",
@@ -5843,18 +5833,6 @@
         "node": ">=8.10.0"
       }
     },
-    "node_modules/readdirp/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
     "node_modules/regexp.prototype.flags": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
@@ -5921,6 +5899,7 @@
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
       "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+      "deprecated": "Rimraf versions prior to v4 are no longer supported",
       "dev": true,
       "dependencies": {
         "glob": "^7.1.3"
@@ -5933,9 +5912,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "4.17.2",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz",
-      "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==",
+      "version": "4.18.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
+      "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
       "dev": true,
       "dependencies": {
         "@types/estree": "1.0.5"
@@ -5948,22 +5927,22 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.17.2",
-        "@rollup/rollup-android-arm64": "4.17.2",
-        "@rollup/rollup-darwin-arm64": "4.17.2",
-        "@rollup/rollup-darwin-x64": "4.17.2",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.17.2",
-        "@rollup/rollup-linux-arm-musleabihf": "4.17.2",
-        "@rollup/rollup-linux-arm64-gnu": "4.17.2",
-        "@rollup/rollup-linux-arm64-musl": "4.17.2",
-        "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2",
-        "@rollup/rollup-linux-riscv64-gnu": "4.17.2",
-        "@rollup/rollup-linux-s390x-gnu": "4.17.2",
-        "@rollup/rollup-linux-x64-gnu": "4.17.2",
-        "@rollup/rollup-linux-x64-musl": "4.17.2",
-        "@rollup/rollup-win32-arm64-msvc": "4.17.2",
-        "@rollup/rollup-win32-ia32-msvc": "4.17.2",
-        "@rollup/rollup-win32-x64-msvc": "4.17.2",
+        "@rollup/rollup-android-arm-eabi": "4.18.0",
+        "@rollup/rollup-android-arm64": "4.18.0",
+        "@rollup/rollup-darwin-arm64": "4.18.0",
+        "@rollup/rollup-darwin-x64": "4.18.0",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
+        "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
+        "@rollup/rollup-linux-arm64-gnu": "4.18.0",
+        "@rollup/rollup-linux-arm64-musl": "4.18.0",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
+        "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
+        "@rollup/rollup-linux-s390x-gnu": "4.18.0",
+        "@rollup/rollup-linux-x64-gnu": "4.18.0",
+        "@rollup/rollup-linux-x64-musl": "4.18.0",
+        "@rollup/rollup-win32-arm64-msvc": "4.18.0",
+        "@rollup/rollup-win32-ia32-msvc": "4.18.0",
+        "@rollup/rollup-win32-x64-msvc": "4.18.0",
         "fsevents": "~2.3.2"
       }
     },
@@ -6270,9 +6249,9 @@
       }
     },
     "node_modules/spdx-license-ids": {
-      "version": "3.0.17",
-      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz",
-      "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==",
+      "version": "3.0.18",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
+      "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
       "dev": true
     },
     "node_modules/stream-browserify": {
diff --git a/package.json b/package.json
index f4119d1f2a6d0131d82ebd32f067cc729c53cd34..142ddef1ccc6fa6f09741e4161fc2fa9c6a973a6 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
     "@aws-sdk/s3-request-presigner": "<3.530.0",
     "@fortawesome/fontawesome-free": "~6.5.0",
     "@popperjs/core": "~2.11.8",
-    "ajv": "~8.13.0",
+    "ajv": "~8.14.0",
     "bootstrap": "~5.3.0",
     "chart.js": "~4.4.0",
     "chartjs-plugin-zoom": "~2.0.1",
diff --git a/src/components/parameter-schema/ParameterSchemaFormComponent.vue b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
index 80dea09b5255e29f4e5fd2723940d10f561c9f90..1955f1d9baa9347dfbbc54a13b6c91b3f8ec9781 100644
--- a/src/components/parameter-schema/ParameterSchemaFormComponent.vue
+++ b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
@@ -14,12 +14,14 @@ import { useRoute, useRouter } from "vue-router";
 import type { ClowmInfo } from "@/types/ClowmInfo";
 import UploadParameterFileModal from "@/components/parameter-schema/UploadParameterFileModal.vue";
 import type {
+  NestedWorkflowParameters,
   TemporaryParams,
   WorkflowMetaParameters,
-  WorkflowParameters,
+  FlatWorkflowParameters,
 } from "@/types/WorkflowParameters";
 import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
 import type { ParameterExtension } from "@/client";
+import { flattenParameters, nestParameters } from "@/utils/Workflow";
 
 const bucketRepository = useBucketStore();
 const resourceRepository = useResourceStore();
@@ -60,7 +62,7 @@ const props = defineProps({
 const emit = defineEmits<{
   (
     e: "start-workflow",
-    parameters: WorkflowParameters,
+    parameters: NestedWorkflowParameters,
     metaParameters: WorkflowMetaParameters,
   ): void;
 }>();
@@ -91,7 +93,7 @@ let validateSchema: ValidateFunction;
 const launchForm = ref<HTMLFormElement | null>(null);
 
 const formState = reactive<{
-  formInput: WorkflowParameters;
+  formInput: FlatWorkflowParameters;
   validated: boolean;
   metaParameters: WorkflowMetaParameters;
   errorType?: string;
@@ -211,7 +213,11 @@ function startWorkflow() {
       console.error(validateSchema.errors);
       errorToast?.show();
     } else {
-      emit("start-workflow", formState.formInput, formState.metaParameters);
+      emit(
+        "start-workflow",
+        nestParameters(formState.formInput),
+        formState.metaParameters,
+      );
     }
   } else {
     formState.errorType = "form";
@@ -224,9 +230,10 @@ function loadParameters(
   showSuccessToast: boolean = true,
 ) {
   if (tempParams?.params) {
-    for (const param in tempParams.params) {
+    const flatTempParams = flattenParameters(tempParams.params);
+    for (const param in flatTempParams) {
       if (param in formState.formInput) {
-        formState.formInput[param] = tempParams.params[param];
+        formState.formInput[param] = flatTempParams[param];
       }
     }
   }
@@ -285,7 +292,7 @@ onMounted(() => {
   <upload-parameter-file-modal
     modal-id="parameterUploadModal"
     @parameters-uploaded="
-      (params: WorkflowParameters) =>
+      (params: FlatWorkflowParameters) =>
         loadParameters({
           params: params,
           metaParams: {},
diff --git a/src/components/parameter-schema/UploadParameterFileModal.vue b/src/components/parameter-schema/UploadParameterFileModal.vue
index 5c4cbbec09477d086d82c0cead2c85eb7f654ff9..b2584c629248d0bc5ccf9be9e97fe04347c946f3 100644
--- a/src/components/parameter-schema/UploadParameterFileModal.vue
+++ b/src/components/parameter-schema/UploadParameterFileModal.vue
@@ -1,14 +1,18 @@
 <script setup lang="ts">
 import BootstrapModal from "@/components/modals/BootstrapModal.vue";
-import { reactive, ref } from "vue";
-import type { WorkflowParameters } from "@/types/WorkflowParameters";
+import { computed, reactive, ref } from "vue";
+import type {
+  NestedWorkflowParameters,
+  FlatWorkflowParameters,
+} from "@/types/WorkflowParameters";
+import { flattenParameters } from "@/utils/Workflow";
 
 const props = defineProps<{
   modalId: string;
 }>();
 
 const parameterState = reactive<{
-  params?: Record<string, string | number | boolean | undefined>;
+  params?: NestedWorkflowParameters;
   error?: string;
 }>({
   params: undefined,
@@ -19,7 +23,7 @@ const randomIDSuffix = Math.random().toString(16).substring(2, 8);
 const parameterFileInput = ref<HTMLInputElement | undefined>(undefined);
 
 const emit = defineEmits<{
-  (e: "parameters-uploaded", params: WorkflowParameters): void;
+  (e: "parameters-uploaded", params: NestedWorkflowParameters): void;
 }>();
 
 function emitParameters() {
@@ -32,6 +36,13 @@ function emitParameters() {
   }
 }
 
+const flatParameters = computed<FlatWorkflowParameters | undefined>(() => {
+  if (parameterState.params == undefined) {
+    return undefined;
+  }
+  return flattenParameters(parameterState.params);
+});
+
 function fileChange() {
   if (!parameterFileInput.value?.value?.length) return;
   parameterFileInput.value?.files?.[0].text().then((str) => {
@@ -79,17 +90,17 @@ function fileChange() {
         <h5 class="text-danger">Error parsing JSON</h5>
         <p class="text-danger">{{ parameterState.error }}</p>
       </template>
-      <template v-else-if="parameterState.params">
+      <template v-else-if="flatParameters">
         <h5>Uploaded Parameters:</h5>
         <table class="table table-bordered">
           <caption>
             {{
-              Object.keys(parameterState.params).length
+              Object.keys(flatParameters).length
             }}
             Parameters
           </caption>
           <tbody>
-            <tr v-for="(value, name) in parameterState.params" :key="name">
+            <tr v-for="(value, name) in flatParameters" :key="name">
               <th scope="row" style="width: 10%" class="text-end">
                 <b>{{ name }}</b>
               </th>
diff --git a/src/components/parameter-schema/form-mode/ParameterGroupForm.vue b/src/components/parameter-schema/form-mode/ParameterGroupForm.vue
index c36f61227585a05f4ad28b48e5b1c60de7b655b4..0d8c400a6323c038d281926b604a912758ef4d38 100644
--- a/src/components/parameter-schema/form-mode/ParameterGroupForm.vue
+++ b/src/components/parameter-schema/form-mode/ParameterGroupForm.vue
@@ -2,10 +2,10 @@
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import { computed, type PropType } from "vue";
 import MarkdownRenderer from "@/components/MarkdownRenderer.vue";
-import type { WorkflowParameters } from "@/types/WorkflowParameters";
+import type { FlatWorkflowParameters } from "@/types/WorkflowParameters";
 import ParameterInput from "@/components/parameter-schema/form-mode/ParameterInput.vue";
 
-const model = defineModel<WorkflowParameters>({ required: true });
+const model = defineModel<FlatWorkflowParameters>({ required: true });
 
 const props = defineProps({
   parameterGroup: {
diff --git a/src/components/workflows/modals/ParameterModal.vue b/src/components/workflows/modals/ParameterModal.vue
index ff06cf6ad68bfc2020d4bb81c5ba35455f1a8785..3ce9657903d6fe6b5554e6983cbc3b19d87c4dc2 100644
--- a/src/components/workflows/modals/ParameterModal.vue
+++ b/src/components/workflows/modals/ParameterModal.vue
@@ -10,7 +10,11 @@ import type { WorkflowExecutionOut, WorkflowVersion } from "@/client";
 import { useNameStore } from "@/stores/names";
 import { useWorkflowStore } from "@/stores/workflows";
 import { createDownloadUrl } from "@/utils/DownloadJson";
-import type { WorkflowParameters } from "@/types/WorkflowParameters";
+import type {
+  NestedWorkflowParameters,
+  FlatWorkflowParameters,
+} from "@/types/WorkflowParameters";
+import { flattenParameters } from "@/utils/Workflow";
 
 const nameRepository = useNameStore();
 const executionRepository = useWorkflowExecutionStore();
@@ -70,13 +74,20 @@ const notes = computed<string | undefined>(
   () => execution.value?.notes ?? undefined,
 );
 
-const parameters = computed<WorkflowParameters | undefined>(() => {
+const parameters = computed<NestedWorkflowParameters | undefined>(() => {
   if (props.executionId == undefined) {
     return undefined;
   }
   return executionRepository.parameters[props.executionId] ?? undefined;
 });
 
+const flatParameters = computed<FlatWorkflowParameters | undefined>(() => {
+  if (parameters.value == undefined) {
+    return undefined;
+  }
+  return flattenParameters(flattenParameters(parameters.value));
+});
+
 const parameterDownloadUrl = computed<string | undefined>(() => {
   if (parameters.value == undefined) {
     return undefined;
@@ -201,10 +212,7 @@ onMounted(() => {
         <caption class="placeholder-glow">
           <span v-if="parameterState.loading" class="placeholder col-1"></span>
           <template v-else>
-            {{
-              Object.keys(executionRepository.parameters[props.executionId])
-                .length
-            }}
+            {{ Object.keys(flatParameters ?? {}).length }}
           </template>
           Parameters
         </caption>
@@ -290,7 +298,7 @@ onMounted(() => {
                 </router-link>
               </td>
             </tr>
-            <tr v-for="(value, name) in parameters" :key="name">
+            <tr v-for="(value, name) in flatParameters" :key="name">
               <th scope="row" style="width: 10%" class="text-end">
                 <b>{{ name }}</b>
               </th>
diff --git a/src/stores/workflowExecutions.ts b/src/stores/workflowExecutions.ts
index 19204773832ae69d105468255e957381ff2d8666..d7bfd93dcee26b5c183092f811648e86a656a041 100644
--- a/src/stores/workflowExecutions.ts
+++ b/src/stores/workflowExecutions.ts
@@ -14,7 +14,7 @@ import { useUserStore } from "@/stores/users";
 import dayjs from "dayjs";
 import { set, get } from "idb-keyval";
 import type {
-  WorkflowParameters,
+  FlatWorkflowParameters,
   WorkflowMetaParameters,
   TemporaryParams,
 } from "@/types/WorkflowParameters";
@@ -31,8 +31,8 @@ export const useWorkflowExecutionStore = defineStore({
     }) as {
       executionMapping: Record<string, WorkflowExecutionOut>;
       anonymizedExecutions: AnonymizedWorkflowExecution[];
-      parameters: Record<string, WorkflowParameters>;
-      __temporaryParameters?: WorkflowParameters;
+      parameters: Record<string, FlatWorkflowParameters>;
+      __temporaryParameters?: FlatWorkflowParameters;
       __temporaryMetaParameters?: Record<string, string>;
     },
   getters: {
@@ -42,7 +42,7 @@ export const useWorkflowExecutionStore = defineStore({
   },
   actions: {
     pushTemporaryParameters(
-      params: WorkflowParameters,
+      params: FlatWorkflowParameters,
       metaParams?: WorkflowMetaParameters,
     ) {
       this.__temporaryParameters = params;
diff --git a/src/types/WorkflowParameters.ts b/src/types/WorkflowParameters.ts
index 7201b000114dd8d46c704e8cf68a8526d61d3b0e..51b702e09f5ad66d5c6cd783e9a7b8afe8760acc 100644
--- a/src/types/WorkflowParameters.ts
+++ b/src/types/WorkflowParameters.ts
@@ -1,8 +1,11 @@
-export type WorkflowParameters = Record<
+export type FlatWorkflowParameters = Record<
   string,
   string | number | boolean | undefined
 >;
 
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+export type NestedWorkflowParameters = Record<string, any>;
+
 export type WorkflowMetaParameters = {
   logs_s3_path?: string;
   debug_s3_path?: string;
@@ -11,6 +14,6 @@ export type WorkflowMetaParameters = {
 };
 
 export type TemporaryParams = {
-  params?: WorkflowParameters;
+  params?: NestedWorkflowParameters;
   metaParams?: WorkflowMetaParameters;
 };
diff --git a/src/utils/Workflow.ts b/src/utils/Workflow.ts
index 9ca73748f3637d5e53abbded76f00b07db39a393..5fb69a8cc392be7b25b28b86346a477eeaeaaccb 100644
--- a/src/utils/Workflow.ts
+++ b/src/utils/Workflow.ts
@@ -1,4 +1,8 @@
 import type { WorkflowVersion } from "@/client";
+import type {
+  NestedWorkflowParameters,
+  FlatWorkflowParameters,
+} from "@/types/WorkflowParameters";
 
 export function sortedVersions(
   versions: WorkflowVersion[],
@@ -22,3 +26,70 @@ export function latestVersion(
   const vs = sortedVersions(versions);
   return vs[0];
 }
+
+export function flattenParameters(
+  params: NestedWorkflowParameters,
+  parents: string[] = [],
+): FlatWorkflowParameters {
+  let newParams: FlatWorkflowParameters = {};
+  for (const paramName of Object.keys(params)) {
+    if (typeof params[paramName] === "object" && params[paramName] !== null) {
+      newParams = {
+        ...newParams,
+        ...flattenParameters(params[paramName], [...parents, paramName]),
+      };
+      continue;
+    }
+    newParams[[...parents, paramName].join(".")] = params[paramName];
+  }
+  return newParams;
+}
+
+export function nestParameters(
+  params: FlatWorkflowParameters,
+): NestedWorkflowParameters {
+  const newParams: NestedWorkflowParameters = {};
+  for (const paramName of Object.keys(params)) {
+    const paramParts = paramName.split(".");
+    if (paramParts.length === 1) {
+      newParams[paramParts[0]] = params[paramParts[0]];
+      continue;
+    }
+    let local = newParams;
+    let lastKnownPartNumber = 0;
+    for (const partNumber in paramParts) {
+      if (local[paramParts[partNumber]] != undefined) {
+        local = local[paramParts[partNumber]];
+        lastKnownPartNumber++;
+        continue;
+      }
+      break;
+    }
+    local[paramParts[lastKnownPartNumber]] = createNestedObjectFromArray(
+      paramParts.slice(lastKnownPartNumber + 1),
+      params[paramName],
+    );
+  }
+  return newParams;
+}
+
+function createNestedObjectFromArray(
+  arr: string[],
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  key: any,
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+): Record<string, any> | any {
+  // eslint-disable-next-line @typescript-eslint/no-explicit-any
+  const f: Record<string, any> = {};
+  switch (arr.length) {
+    case 0:
+      return key;
+    case 1:
+      f[arr[0]] = key;
+      break;
+    default:
+      f[arr[0]] = createNestedObjectFromArray(arr.slice(1), key);
+      break;
+  }
+  return f;
+}
diff --git a/src/views/LoginView.vue b/src/views/LoginView.vue
index 1c041e6f9e00ddc7ef7176ae9c844204d3058885..c5eb8488445084d5b11c82baa2ebc2553fb3451d 100644
--- a/src/views/LoginView.vue
+++ b/src/views/LoginView.vue
@@ -27,7 +27,6 @@ onBeforeMount(() => {
 
 const loginPath = computed<string>(() => {
   const loginUrl = new URL(`${OpenAPI.BASE}/auth/login?provider=lifescience`);
-  console.log(props);
   if (props.returnPath) {
     loginUrl.searchParams.append("next", encodeURI(props.returnPath));
   }
diff --git a/src/views/workflows/ArbitraryWorkflowView.vue b/src/views/workflows/ArbitraryWorkflowView.vue
index 665ab1c9c1336c76b4e30baf65031c438f4c8bc1..4ef84be317ba3757605ffaac7f5f8116e837bd4b 100644
--- a/src/views/workflows/ArbitraryWorkflowView.vue
+++ b/src/views/workflows/ArbitraryWorkflowView.vue
@@ -13,7 +13,7 @@ import ParameterSchemaFormComponent from "@/components/parameter-schema/Paramete
 import BootstrapToast from "@/components/BootstrapToast.vue";
 import type {
   WorkflowMetaParameters,
-  WorkflowParameters,
+  FlatWorkflowParameters,
 } from "@/types/WorkflowParameters";
 
 const props = defineProps<{
@@ -97,7 +97,7 @@ watch(
 );
 
 function startWorkflow(
-  parameters: WorkflowParameters,
+  parameters: FlatWorkflowParameters,
   metaParameters: WorkflowMetaParameters,
 ) {
   if (workflowState.workflow) {
diff --git a/src/views/workflows/StartWorkflowView.vue b/src/views/workflows/StartWorkflowView.vue
index 84612546ef51419895d1f689d41a3ee7eec06ccc..f9f4103c3cf33f01c31635389d95e2fea99c99b1 100644
--- a/src/views/workflows/StartWorkflowView.vue
+++ b/src/views/workflows/StartWorkflowView.vue
@@ -9,8 +9,8 @@ import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
 import BootstrapToast from "@/components/BootstrapToast.vue";
 import { useWorkflowStore } from "@/stores/workflows";
 import type {
+  NestedWorkflowParameters,
   WorkflowMetaParameters,
-  WorkflowParameters,
 } from "@/types/WorkflowParameters";
 
 const executionRepository = useWorkflowExecutionStore();
@@ -73,7 +73,7 @@ function downloadParameterSchema() {
 }
 
 function startWorkflow(
-  parameters: WorkflowParameters,
+  parameters: NestedWorkflowParameters,
   metaParameters: WorkflowMetaParameters,
 ) {
   if (props.versionId) {