diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 411cd34fe1f7fac4c3f994a9e6c138540d21814d..d14f478476c1e118876384c14812abbc33c5b683 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/node:20
+image: ${CI_DEPENDENCY_PROXY_DIRECT_GROUP_IMAGE_PREFIX}/node:22
 cache:
   paths:
     - node_modules
diff --git a/Dockerfile b/Dockerfile
index 9232a56c2ed56c7ec10638a956378f08265f8b1a..4d2e59825efd8be458bb1952ac2a5ebaf25166b0 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
 # build stage
-FROM node:20 AS build-stage
+FROM node:22 AS build-stage
 WORKDIR /app
 COPY package.json ./
 COPY package-lock.json ./
diff --git a/package-lock.json b/package-lock.json
index 910946d4433704f8ffa48f5cfc403bf9a977d6d7..9beef9856f211deaa6676c86f6b8a75ca7bcde38 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -20,7 +20,7 @@
         "chart.js": "~4.4.0",
         "chartjs-plugin-zoom": "~2.0.1",
         "dayjs": "~1.11.0",
-        "dompurify": "~3.1.0",
+        "dompurify": "~3.2.0",
         "filesize": "~10.1.0",
         "idb-keyval": "^6.2.1",
         "pinia": "~2.2.0",
@@ -37,7 +37,7 @@
         "@eslint/compat": "^1.2.0",
         "@hey-api/openapi-ts": "^0.55.0",
         "@rushstack/eslint-patch": "~1.10.0",
-        "@tsconfig/node20": "^20.1.2",
+        "@tsconfig/node22": "^22.0.0",
         "@types/bootstrap": "~5.2.0",
         "@types/dompurify": "~3.0.0",
         "@types/node": "^20.11.0",
@@ -45,12 +45,12 @@
         "@types/semver": "~7.5.1",
         "@types/showdown": "~2.0.1",
         "@types/sortablejs": "^1.15.7",
-        "@vitejs/plugin-vue": "~5.1.0",
+        "@vitejs/plugin-vue": "~5.2.0",
         "@vue/eslint-config-prettier": "~10.1.0",
         "@vue/eslint-config-typescript": "~14.1.0",
-        "@vue/tsconfig": "~0.5.0",
+        "@vue/tsconfig": "~0.6.0",
         "eslint": "~9.12.0",
-        "eslint-plugin-vue": "~9.30.0",
+        "eslint-plugin-vue": "~9.31.0",
         "highlight.js": "^11.9.0",
         "npm-run-all": "~4.1.5",
         "prettier": "~3.3.0",
@@ -282,34 +282,34 @@
       }
     },
     "node_modules/@aws-sdk/client-s3": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.687.0.tgz",
-      "integrity": "sha512-2IoaVAd7HCIDhfeTTrk8CAosEVqnQig47Tra2uOBEyzpcCFQLmcY57/sbHCpJ3ntnU8see53q0bQ+fdew4MGLA==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.691.0.tgz",
+      "integrity": "sha512-GrcFakf5sZDSFtQGIPzT/5CTl9rLCsua0+yrmz/zidCvd7HFiwPrmyLQSv+MwgEUqHb4unnqUMSo2HKfkV3AIQ==",
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha1-browser": "5.2.0",
         "@aws-crypto/sha256-browser": "5.2.0",
         "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.687.0",
-        "@aws-sdk/client-sts": "3.687.0",
-        "@aws-sdk/core": "3.686.0",
-        "@aws-sdk/credential-provider-node": "3.687.0",
+        "@aws-sdk/client-sso-oidc": "3.691.0",
+        "@aws-sdk/client-sts": "3.691.0",
+        "@aws-sdk/core": "3.691.0",
+        "@aws-sdk/credential-provider-node": "3.691.0",
         "@aws-sdk/middleware-bucket-endpoint": "3.686.0",
         "@aws-sdk/middleware-expect-continue": "3.686.0",
-        "@aws-sdk/middleware-flexible-checksums": "3.687.0",
+        "@aws-sdk/middleware-flexible-checksums": "3.691.0",
         "@aws-sdk/middleware-host-header": "3.686.0",
         "@aws-sdk/middleware-location-constraint": "3.686.0",
         "@aws-sdk/middleware-logger": "3.686.0",
         "@aws-sdk/middleware-recursion-detection": "3.686.0",
-        "@aws-sdk/middleware-sdk-s3": "3.687.0",
+        "@aws-sdk/middleware-sdk-s3": "3.691.0",
         "@aws-sdk/middleware-ssec": "3.686.0",
-        "@aws-sdk/middleware-user-agent": "3.687.0",
+        "@aws-sdk/middleware-user-agent": "3.691.0",
         "@aws-sdk/region-config-resolver": "3.686.0",
-        "@aws-sdk/signature-v4-multi-region": "3.687.0",
+        "@aws-sdk/signature-v4-multi-region": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@aws-sdk/util-endpoints": "3.686.0",
         "@aws-sdk/util-user-agent-browser": "3.686.0",
-        "@aws-sdk/util-user-agent-node": "3.687.0",
+        "@aws-sdk/util-user-agent-node": "3.691.0",
         "@aws-sdk/xml-builder": "3.686.0",
         "@smithy/config-resolver": "^3.0.10",
         "@smithy/core": "^2.5.1",
@@ -351,23 +351,23 @@
       }
     },
     "node_modules/@aws-sdk/client-sso": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.687.0.tgz",
-      "integrity": "sha512-dfj0y9fQyX4kFill/ZG0BqBTLQILKlL7+O5M4F9xlsh2WNuV2St6WtcOg14Y1j5UODPJiJs//pO+mD1lihT5Kw==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.691.0.tgz",
+      "integrity": "sha512-bzp4ni6zGxwrlSWhG0MfOh57ORgzdUFlIc2JeQHLO9b6n0iNnG57ILHzo90sQxom6LfW1bXZrsKvYH3vAU8sdA==",
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-browser": "5.2.0",
         "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/core": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/middleware-host-header": "3.686.0",
         "@aws-sdk/middleware-logger": "3.686.0",
         "@aws-sdk/middleware-recursion-detection": "3.686.0",
-        "@aws-sdk/middleware-user-agent": "3.687.0",
+        "@aws-sdk/middleware-user-agent": "3.691.0",
         "@aws-sdk/region-config-resolver": "3.686.0",
         "@aws-sdk/types": "3.686.0",
         "@aws-sdk/util-endpoints": "3.686.0",
         "@aws-sdk/util-user-agent-browser": "3.686.0",
-        "@aws-sdk/util-user-agent-node": "3.687.0",
+        "@aws-sdk/util-user-agent-node": "3.691.0",
         "@smithy/config-resolver": "^3.0.10",
         "@smithy/core": "^2.5.1",
         "@smithy/fetch-http-handler": "^4.0.0",
@@ -400,24 +400,24 @@
       }
     },
     "node_modules/@aws-sdk/client-sso-oidc": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.687.0.tgz",
-      "integrity": "sha512-Rdd8kLeTeh+L5ZuG4WQnWgYgdv7NorytKdZsGjiag1D8Wv3PcJvPqqWdgnI0Og717BSXVoaTYaN34FyqFYSx6Q==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.691.0.tgz",
+      "integrity": "sha512-3njUhD4buM1RfigU6IXZ18/R9V5mbqNrAftgDabnNn4/V4Qly32nz+KQONXT5x0GqPszGhp+0mmwuLai9DxSrQ==",
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-browser": "5.2.0",
         "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/core": "3.686.0",
-        "@aws-sdk/credential-provider-node": "3.687.0",
+        "@aws-sdk/core": "3.691.0",
+        "@aws-sdk/credential-provider-node": "3.691.0",
         "@aws-sdk/middleware-host-header": "3.686.0",
         "@aws-sdk/middleware-logger": "3.686.0",
         "@aws-sdk/middleware-recursion-detection": "3.686.0",
-        "@aws-sdk/middleware-user-agent": "3.687.0",
+        "@aws-sdk/middleware-user-agent": "3.691.0",
         "@aws-sdk/region-config-resolver": "3.686.0",
         "@aws-sdk/types": "3.686.0",
         "@aws-sdk/util-endpoints": "3.686.0",
         "@aws-sdk/util-user-agent-browser": "3.686.0",
-        "@aws-sdk/util-user-agent-node": "3.687.0",
+        "@aws-sdk/util-user-agent-node": "3.691.0",
         "@smithy/config-resolver": "^3.0.10",
         "@smithy/core": "^2.5.1",
         "@smithy/fetch-http-handler": "^4.0.0",
@@ -449,29 +449,29 @@
         "node": ">=16.0.0"
       },
       "peerDependencies": {
-        "@aws-sdk/client-sts": "^3.687.0"
+        "@aws-sdk/client-sts": "^3.691.0"
       }
     },
     "node_modules/@aws-sdk/client-sts": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.687.0.tgz",
-      "integrity": "sha512-SQjDH8O4XCTtouuCVYggB0cCCrIaTzUZIkgJUpOsIEJBLlTbNOb/BZqUShAQw2o9vxr2rCeOGjAQOYPysW/Pmg==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.691.0.tgz",
+      "integrity": "sha512-Qmj2euPnmIni/eFSrc9LUkg52/2D487fTcKMwZh0ldHv4fD4ossuXX7AaDur8SD9Lc9EOxn/hXCsI644YnGwew==",
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/sha256-browser": "5.2.0",
         "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.687.0",
-        "@aws-sdk/core": "3.686.0",
-        "@aws-sdk/credential-provider-node": "3.687.0",
+        "@aws-sdk/client-sso-oidc": "3.691.0",
+        "@aws-sdk/core": "3.691.0",
+        "@aws-sdk/credential-provider-node": "3.691.0",
         "@aws-sdk/middleware-host-header": "3.686.0",
         "@aws-sdk/middleware-logger": "3.686.0",
         "@aws-sdk/middleware-recursion-detection": "3.686.0",
-        "@aws-sdk/middleware-user-agent": "3.687.0",
+        "@aws-sdk/middleware-user-agent": "3.691.0",
         "@aws-sdk/region-config-resolver": "3.686.0",
         "@aws-sdk/types": "3.686.0",
         "@aws-sdk/util-endpoints": "3.686.0",
         "@aws-sdk/util-user-agent-browser": "3.686.0",
-        "@aws-sdk/util-user-agent-node": "3.687.0",
+        "@aws-sdk/util-user-agent-node": "3.691.0",
         "@smithy/config-resolver": "^3.0.10",
         "@smithy/core": "^2.5.1",
         "@smithy/fetch-http-handler": "^4.0.0",
@@ -504,17 +504,17 @@
       }
     },
     "node_modules/@aws-sdk/core": {
-      "version": "3.686.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.686.0.tgz",
-      "integrity": "sha512-Xt3DV4DnAT3v2WURwzTxWQK34Ew+iiLzoUoguvLaZrVMFOqMMrwVjP+sizqIaHp1j7rGmFcN5I8saXnsDLuQLA==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.691.0.tgz",
+      "integrity": "sha512-5hyCj6gX92fXRf1kyfIpJetjVx0NxHbNmcLcrMy6oXuGNIBeJkMp+ZC6uJo3PsIjyPgGQSC++EhjLxpWiF/wHg==",
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.686.0",
         "@smithy/core": "^2.5.1",
         "@smithy/node-config-provider": "^3.1.9",
-        "@smithy/property-provider": "^3.1.7",
+        "@smithy/property-provider": "^3.1.8",
         "@smithy/protocol-http": "^4.1.5",
-        "@smithy/signature-v4": "^4.2.0",
+        "@smithy/signature-v4": "^4.2.1",
         "@smithy/smithy-client": "^3.4.2",
         "@smithy/types": "^3.6.0",
         "@smithy/util-middleware": "^3.0.8",
@@ -526,14 +526,14 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-env": {
-      "version": "3.686.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.686.0.tgz",
-      "integrity": "sha512-osD7lPO8OREkgxPiTWmA1i6XEmOth1uW9HWWj/+A2YGCj1G/t2sHu931w4Qj9NWHYZtbTTXQYVRg+TErALV7nQ==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.691.0.tgz",
+      "integrity": "sha512-c4Ip7tSNxt5VANVyryl6XjfEUCbm7f+iCUEfEWEezywll4DjNZ1N0l7nNmX4dDbwRAB42XH3rk5fbqBe0lXT8g==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/core": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/types": "3.686.0",
-        "@smithy/property-provider": "^3.1.7",
+        "@smithy/property-provider": "^3.1.8",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -542,16 +542,16 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-http": {
-      "version": "3.686.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.686.0.tgz",
-      "integrity": "sha512-xyGAD/f3vR/wssUiZrNFWQWXZvI4zRm2wpHhoHA1cC2fbRMNFYtFn365yw6dU7l00ZLcdFB1H119AYIUZS7xbw==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.691.0.tgz",
+      "integrity": "sha512-RL2/d4DbUGeX8xKhXcwQvhAqd+WM3P87znSS5nEQA5pSwqeJsC3l2DCj+09yUM6I9n7nOppe5XephiiBpq190w==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/core": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@smithy/fetch-http-handler": "^4.0.0",
         "@smithy/node-http-handler": "^3.2.5",
-        "@smithy/property-provider": "^3.1.7",
+        "@smithy/property-provider": "^3.1.8",
         "@smithy/protocol-http": "^4.1.5",
         "@smithy/smithy-client": "^3.4.2",
         "@smithy/types": "^3.6.0",
@@ -563,21 +563,21 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-ini": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.687.0.tgz",
-      "integrity": "sha512-6d5ZJeZch+ZosJccksN0PuXv7OSnYEmanGCnbhUqmUSz9uaVX6knZZfHCZJRgNcfSqg9QC0zsFA/51W5HCUqSQ==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.691.0.tgz",
+      "integrity": "sha512-NB5jbiBLAWD/oz2CHksKRHo+Q8KI8ljyZUDW091j7IDYEYZZ/c2jDkYWX7eGnJqKNZLxGtcc1B+yYJrE9xXnbQ==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/core": "3.686.0",
-        "@aws-sdk/credential-provider-env": "3.686.0",
-        "@aws-sdk/credential-provider-http": "3.686.0",
-        "@aws-sdk/credential-provider-process": "3.686.0",
-        "@aws-sdk/credential-provider-sso": "3.687.0",
-        "@aws-sdk/credential-provider-web-identity": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
+        "@aws-sdk/credential-provider-env": "3.691.0",
+        "@aws-sdk/credential-provider-http": "3.691.0",
+        "@aws-sdk/credential-provider-process": "3.691.0",
+        "@aws-sdk/credential-provider-sso": "3.691.0",
+        "@aws-sdk/credential-provider-web-identity": "3.691.0",
         "@aws-sdk/types": "3.686.0",
-        "@smithy/credential-provider-imds": "^3.2.4",
-        "@smithy/property-provider": "^3.1.7",
-        "@smithy/shared-ini-file-loader": "^3.1.8",
+        "@smithy/credential-provider-imds": "^3.2.5",
+        "@smithy/property-provider": "^3.1.8",
+        "@smithy/shared-ini-file-loader": "^3.1.9",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -585,25 +585,25 @@
         "node": ">=16.0.0"
       },
       "peerDependencies": {
-        "@aws-sdk/client-sts": "^3.687.0"
+        "@aws-sdk/client-sts": "^3.691.0"
       }
     },
     "node_modules/@aws-sdk/credential-provider-node": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.687.0.tgz",
-      "integrity": "sha512-Pqld8Nx11NYaBUrVk3bYiGGpLCxkz8iTONlpQWoVWFhSOzlO7zloNOaYbD2XgFjjqhjlKzE91drs/f41uGeCTA==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.691.0.tgz",
+      "integrity": "sha512-GjQvajKDz6nKWS1Cxdzz2Ecu9R8aojOhRIPAgnG62MG5BvlqDddanF6szcDVSYtlWx+cv2SZ6lDYjoHnDnideQ==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/credential-provider-env": "3.686.0",
-        "@aws-sdk/credential-provider-http": "3.686.0",
-        "@aws-sdk/credential-provider-ini": "3.687.0",
-        "@aws-sdk/credential-provider-process": "3.686.0",
-        "@aws-sdk/credential-provider-sso": "3.687.0",
-        "@aws-sdk/credential-provider-web-identity": "3.686.0",
+        "@aws-sdk/credential-provider-env": "3.691.0",
+        "@aws-sdk/credential-provider-http": "3.691.0",
+        "@aws-sdk/credential-provider-ini": "3.691.0",
+        "@aws-sdk/credential-provider-process": "3.691.0",
+        "@aws-sdk/credential-provider-sso": "3.691.0",
+        "@aws-sdk/credential-provider-web-identity": "3.691.0",
         "@aws-sdk/types": "3.686.0",
-        "@smithy/credential-provider-imds": "^3.2.4",
-        "@smithy/property-provider": "^3.1.7",
-        "@smithy/shared-ini-file-loader": "^3.1.8",
+        "@smithy/credential-provider-imds": "^3.2.5",
+        "@smithy/property-provider": "^3.1.8",
+        "@smithy/shared-ini-file-loader": "^3.1.9",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -612,15 +612,15 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-process": {
-      "version": "3.686.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.686.0.tgz",
-      "integrity": "sha512-sXqaAgyzMOc+dm4CnzAR5Q6S9OWVHyZjLfW6IQkmGjqeQXmZl24c4E82+w64C+CTkJrFLzH1VNOYp1Hy5gE6Qw==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.691.0.tgz",
+      "integrity": "sha512-tEoLkcxhF98aVHEyJ0n50rnNRewGUYYXszrNi8/sLh8enbDMWWByWReFPhNriE9oOdcrS5AKU7lCoY9i6zXQ3A==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/core": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/types": "3.686.0",
-        "@smithy/property-provider": "^3.1.7",
-        "@smithy/shared-ini-file-loader": "^3.1.8",
+        "@smithy/property-provider": "^3.1.8",
+        "@smithy/shared-ini-file-loader": "^3.1.9",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -629,17 +629,17 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-sso": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.687.0.tgz",
-      "integrity": "sha512-N1YCoE7DovIRF2ReyRrA4PZzF0WNi4ObPwdQQkVxhvSm7PwjbWxrfq7rpYB+6YB1Uq3QPzgVwUFONE36rdpxUQ==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.691.0.tgz",
+      "integrity": "sha512-CxEiF2LMesk93dG+fCglLyVS9m7rjkWAZFUSSbjW7YbJC0VDks83hQG8EsFv+Grl/kvFITEvU0NoiavI6hbDlw==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/client-sso": "3.687.0",
-        "@aws-sdk/core": "3.686.0",
-        "@aws-sdk/token-providers": "3.686.0",
+        "@aws-sdk/client-sso": "3.691.0",
+        "@aws-sdk/core": "3.691.0",
+        "@aws-sdk/token-providers": "3.691.0",
         "@aws-sdk/types": "3.686.0",
-        "@smithy/property-provider": "^3.1.7",
-        "@smithy/shared-ini-file-loader": "^3.1.8",
+        "@smithy/property-provider": "^3.1.8",
+        "@smithy/shared-ini-file-loader": "^3.1.9",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -648,14 +648,14 @@
       }
     },
     "node_modules/@aws-sdk/credential-provider-web-identity": {
-      "version": "3.686.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.686.0.tgz",
-      "integrity": "sha512-40UqCpPxyHCXDP7CGd9JIOZDgDZf+u1OyLaGBpjQJlz1HYuEsIWnnbTe29Yg3Ah/Zc3g4NBWcUdlGVotlnpnDg==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.691.0.tgz",
+      "integrity": "sha512-54FgLnyWpSTlQ8/plZRFSXkI83wgPhJ4zqcX+n+K3BcGil4/Vsn/8+JQSY+6CA6JtDSqhpKAe54o+2DbDexsVg==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/core": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/types": "3.686.0",
-        "@smithy/property-provider": "^3.1.7",
+        "@smithy/property-provider": "^3.1.8",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -663,16 +663,16 @@
         "node": ">=16.0.0"
       },
       "peerDependencies": {
-        "@aws-sdk/client-sts": "^3.686.0"
+        "@aws-sdk/client-sts": "^3.691.0"
       }
     },
     "node_modules/@aws-sdk/lib-storage": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.687.0.tgz",
-      "integrity": "sha512-LAJOH1Ddm8vlA6j8WyFAt1Ithfj58XuJN1d2WJSDZLhGDGQp3+nDFzovOKODw/Bc9x6ZnDYm9rE+QMTbGSvqkA==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/lib-storage/-/lib-storage-3.691.0.tgz",
+      "integrity": "sha512-sX1005ICZhXlWOI/H/EXU/LU6a57zlt7cLPjk+T/JlCldDVGccDTcZh3MFS3DB1FioTlXqf9oSSVoBvJQCNg6g==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@smithy/abort-controller": "^3.1.5",
+        "@smithy/abort-controller": "^3.1.6",
         "@smithy/middleware-endpoint": "^3.2.1",
         "@smithy/smithy-client": "^3.4.2",
         "buffer": "5.6.0",
@@ -684,7 +684,7 @@
         "node": ">=16.0.0"
       },
       "peerDependencies": {
-        "@aws-sdk/client-s3": "^3.687.0"
+        "@aws-sdk/client-s3": "^3.691.0"
       }
     },
     "node_modules/@aws-sdk/middleware-bucket-endpoint": {
@@ -721,14 +721,15 @@
       }
     },
     "node_modules/@aws-sdk/middleware-flexible-checksums": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.687.0.tgz",
-      "integrity": "sha512-hsEr3eiJs7gOzj9nDMCMfhLkoYv4Z8m7fbic63TkeyimXvsHycqqF6PX0TkPykwa1ueyxVpz0vtO5u1rlucN2w==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.691.0.tgz",
+      "integrity": "sha512-jBKW3hZ8YpxlAecwuvMDWvs5tqu2I3BubptKeVJiwrEhNR1Yy3gtsZ1RnxCfGEEdVLS4fxc5JRF/jxPFnTT00Q==",
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-crypto/crc32": "5.2.0",
         "@aws-crypto/crc32c": "5.2.0",
-        "@aws-sdk/core": "3.686.0",
+        "@aws-crypto/util": "5.2.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@smithy/is-array-buffer": "^3.0.0",
         "@smithy/node-config-provider": "^3.1.9",
@@ -802,18 +803,18 @@
       }
     },
     "node_modules/@aws-sdk/middleware-sdk-s3": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.687.0.tgz",
-      "integrity": "sha512-YGHYqiyRiNNucmvLrfx3QxIkjSDWR/+cc72bn0lPvqFUQBRHZgmYQLxVYrVZSmRzzkH2FQ1HsZcXhOafLbq4vQ==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.691.0.tgz",
+      "integrity": "sha512-JYtpQNy9/M0qgihu7RY9vdrtuF+71H3U/BK7EqtskM/ioNL7twAAonCmXA2NXxYjS9bG+/3hw3xZkWSWfYvYFA==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/core": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@aws-sdk/util-arn-parser": "3.679.0",
         "@smithy/core": "^2.5.1",
         "@smithy/node-config-provider": "^3.1.9",
         "@smithy/protocol-http": "^4.1.5",
-        "@smithy/signature-v4": "^4.2.0",
+        "@smithy/signature-v4": "^4.2.1",
         "@smithy/smithy-client": "^3.4.2",
         "@smithy/types": "^3.6.0",
         "@smithy/util-config-provider": "^3.0.0",
@@ -841,12 +842,12 @@
       }
     },
     "node_modules/@aws-sdk/middleware-user-agent": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.687.0.tgz",
-      "integrity": "sha512-nUgsKiEinyA50CaDXojAkOasAU3Apdg7Qox6IjNUC4ZjgOu7QWsCDB5N28AYMUt06cNYeYQdfMX1aEzG85a1Mg==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.691.0.tgz",
+      "integrity": "sha512-d1ieFuOw7Lh4PQguSWceOgX0B4YkZOuYPRZhlAbwx/LQayoZ7LDh//0bbdDdgDgKyNxCTN5EjdoCh/MAPaKIjQ==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/core": "3.686.0",
+        "@aws-sdk/core": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@aws-sdk/util-endpoints": "3.686.0",
         "@smithy/core": "^2.5.1",
@@ -876,12 +877,12 @@
       }
     },
     "node_modules/@aws-sdk/s3-request-presigner": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.687.0.tgz",
-      "integrity": "sha512-/fX3F4nYjVEgdlVamsb2tDgnFA5dtzxkeN+hH91e+ZoBMJBow+FUb2EEtjloreGUynPx6E00UxdDXIKWmt99lA==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.691.0.tgz",
+      "integrity": "sha512-aDGp+7uL9p+HXeG28pVS8z1VSqNOscbK9QcemRCHiIZCXUi+IzUTP0G7tzTQN4WjxYkjRC9dC9QEKE3KTh7z2Q==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/signature-v4-multi-region": "3.687.0",
+        "@aws-sdk/signature-v4-multi-region": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@aws-sdk/util-format-url": "3.686.0",
         "@smithy/middleware-endpoint": "^3.2.1",
@@ -895,15 +896,15 @@
       }
     },
     "node_modules/@aws-sdk/signature-v4-multi-region": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.687.0.tgz",
-      "integrity": "sha512-vdOQHCRHJPX9mT8BM6xOseazHD6NodvHl9cyF5UjNtLn+gERRJEItIA9hf0hlt62odGD8Fqp+rFRuqdmbNkcNw==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.691.0.tgz",
+      "integrity": "sha512-xCKaOoKJMTHxDWA82KTFOqAQUyGEKUqH+Est9aruR9alawbRx+qiLNt/+AhLrGT8IaFNycuD7P73V8yScJKE2g==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/middleware-sdk-s3": "3.687.0",
+        "@aws-sdk/middleware-sdk-s3": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@smithy/protocol-http": "^4.1.5",
-        "@smithy/signature-v4": "^4.2.0",
+        "@smithy/signature-v4": "^4.2.1",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -912,14 +913,14 @@
       }
     },
     "node_modules/@aws-sdk/token-providers": {
-      "version": "3.686.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.686.0.tgz",
-      "integrity": "sha512-9oL4kTCSePFmyKPskibeiOXV6qavPZ63/kXM9Wh9V6dTSvBtLeNnMxqGvENGKJcTdIgtoqyqA6ET9u0PJ5IRIg==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.691.0.tgz",
+      "integrity": "sha512-XtBnNUOzdezdC/7bFYAenrUQCZI5raHZ1F+7qWEbEDbshz4nR6v0MczVXkaPsSJ6mel0sQMhYs7b3Y/0yUkB6w==",
       "license": "Apache-2.0",
       "dependencies": {
         "@aws-sdk/types": "3.686.0",
-        "@smithy/property-provider": "^3.1.7",
-        "@smithy/shared-ini-file-loader": "^3.1.8",
+        "@smithy/property-provider": "^3.1.8",
+        "@smithy/shared-ini-file-loader": "^3.1.9",
         "@smithy/types": "^3.6.0",
         "tslib": "^2.6.2"
       },
@@ -927,7 +928,7 @@
         "node": ">=16.0.0"
       },
       "peerDependencies": {
-        "@aws-sdk/client-sso-oidc": "^3.686.0"
+        "@aws-sdk/client-sso-oidc": "^3.691.0"
       }
     },
     "node_modules/@aws-sdk/types": {
@@ -1010,12 +1011,12 @@
       }
     },
     "node_modules/@aws-sdk/util-user-agent-node": {
-      "version": "3.687.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.687.0.tgz",
-      "integrity": "sha512-idkP6ojSTZ4ek1pJ8wIN7r9U3KR5dn0IkJn3KQBXQ58LWjkRqLtft2vxzdsktWwhPKjjmIKl1S0kbvqLawf8XQ==",
+      "version": "3.691.0",
+      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.691.0.tgz",
+      "integrity": "sha512-n+g337W2W/S3Ju47vBNs970477WsLidmdQp1jaxFaBYjSV8l7Tm4dZNMtrq4AEvS+2ErkLpm9BmTiREoWR38Ag==",
       "license": "Apache-2.0",
       "dependencies": {
-        "@aws-sdk/middleware-user-agent": "3.687.0",
+        "@aws-sdk/middleware-user-agent": "3.691.0",
         "@aws-sdk/types": "3.686.0",
         "@smithy/node-config-provider": "^3.1.9",
         "@smithy/types": "^3.6.0",
@@ -1694,21 +1695,21 @@
       }
     },
     "node_modules/@hey-api/client-axios": {
-      "version": "0.2.9",
-      "resolved": "https://registry.npmjs.org/@hey-api/client-axios/-/client-axios-0.2.9.tgz",
-      "integrity": "sha512-K4T0KdBKl4LKbAVtfL1E9y9l2Q79NskptPBQcV1+RayjADCJctOtwdjwJitkpxj31UfQ79TSKHH96mMs9HrSsQ==",
+      "version": "0.2.10",
+      "resolved": "https://registry.npmjs.org/@hey-api/client-axios/-/client-axios-0.2.10.tgz",
+      "integrity": "sha512-EXTf9WcZCyzRIi1JEbKbJ4JvB+TLy9WsSaBKRUwd7d8c6PYQ+MRJCTnkzGJk1wXkeBLqJEwyf2IZH/qmCkDhqg==",
       "license": "MIT",
       "funding": {
-        "url": "https://github.com/sponsors/mrlubos"
+        "url": "https://github.com/sponsors/hey-api"
       },
       "peerDependencies": {
         "axios": ">= 1.0.0 < 2"
       }
     },
     "node_modules/@hey-api/openapi-ts": {
-      "version": "0.55.1",
-      "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.55.1.tgz",
-      "integrity": "sha512-wLwrnb/MrwRpPCywizrbegZdXbdWWtiC7JerInGhkDksaigihszRyq3GHsibZsvs6gvpPQk0OioaSvgKoNP6ZA==",
+      "version": "0.55.3",
+      "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.55.3.tgz",
+      "integrity": "sha512-eboeFHqMimdTwhO5VrBl2HoPzby0wlbO8900N3ukvGu8dG9PgXGzHBcLF2ukwt4TReNcsIm3daj/9cqcJ5LWUQ==",
       "dev": true,
       "license": "FSL-1.1-MIT",
       "dependencies": {
@@ -1724,7 +1725,7 @@
         "node": "^18.0.0 || >=20.0.0"
       },
       "funding": {
-        "url": "https://github.com/sponsors/mrlubos"
+        "url": "https://github.com/sponsors/hey-api"
       },
       "peerDependencies": {
         "typescript": "^5.x"
@@ -2232,9 +2233,9 @@
       }
     },
     "node_modules/@rollup/rollup-android-arm-eabi": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.4.tgz",
-      "integrity": "sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.26.0.tgz",
+      "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==",
       "cpu": [
         "arm"
       ],
@@ -2246,9 +2247,9 @@
       ]
     },
     "node_modules/@rollup/rollup-android-arm64": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.4.tgz",
-      "integrity": "sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.26.0.tgz",
+      "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==",
       "cpu": [
         "arm64"
       ],
@@ -2260,9 +2261,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-arm64": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.4.tgz",
-      "integrity": "sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.26.0.tgz",
+      "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==",
       "cpu": [
         "arm64"
       ],
@@ -2274,9 +2275,9 @@
       ]
     },
     "node_modules/@rollup/rollup-darwin-x64": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.4.tgz",
-      "integrity": "sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.26.0.tgz",
+      "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==",
       "cpu": [
         "x64"
       ],
@@ -2288,9 +2289,9 @@
       ]
     },
     "node_modules/@rollup/rollup-freebsd-arm64": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.4.tgz",
-      "integrity": "sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.26.0.tgz",
+      "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==",
       "cpu": [
         "arm64"
       ],
@@ -2302,9 +2303,9 @@
       ]
     },
     "node_modules/@rollup/rollup-freebsd-x64": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.4.tgz",
-      "integrity": "sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.26.0.tgz",
+      "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==",
       "cpu": [
         "x64"
       ],
@@ -2316,9 +2317,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.4.tgz",
-      "integrity": "sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.26.0.tgz",
+      "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==",
       "cpu": [
         "arm"
       ],
@@ -2330,9 +2331,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm-musleabihf": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.4.tgz",
-      "integrity": "sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.26.0.tgz",
+      "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==",
       "cpu": [
         "arm"
       ],
@@ -2344,9 +2345,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-gnu": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.4.tgz",
-      "integrity": "sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.26.0.tgz",
+      "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==",
       "cpu": [
         "arm64"
       ],
@@ -2358,9 +2359,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-arm64-musl": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.4.tgz",
-      "integrity": "sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.26.0.tgz",
+      "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==",
       "cpu": [
         "arm64"
       ],
@@ -2372,9 +2373,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.4.tgz",
-      "integrity": "sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.26.0.tgz",
+      "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==",
       "cpu": [
         "ppc64"
       ],
@@ -2386,9 +2387,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-riscv64-gnu": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.4.tgz",
-      "integrity": "sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.26.0.tgz",
+      "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==",
       "cpu": [
         "riscv64"
       ],
@@ -2400,9 +2401,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-s390x-gnu": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.4.tgz",
-      "integrity": "sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.26.0.tgz",
+      "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==",
       "cpu": [
         "s390x"
       ],
@@ -2414,9 +2415,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-gnu": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.4.tgz",
-      "integrity": "sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.26.0.tgz",
+      "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==",
       "cpu": [
         "x64"
       ],
@@ -2428,9 +2429,9 @@
       ]
     },
     "node_modules/@rollup/rollup-linux-x64-musl": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.4.tgz",
-      "integrity": "sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.26.0.tgz",
+      "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==",
       "cpu": [
         "x64"
       ],
@@ -2442,9 +2443,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-arm64-msvc": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.4.tgz",
-      "integrity": "sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.26.0.tgz",
+      "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==",
       "cpu": [
         "arm64"
       ],
@@ -2456,9 +2457,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-ia32-msvc": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.4.tgz",
-      "integrity": "sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.26.0.tgz",
+      "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==",
       "cpu": [
         "ia32"
       ],
@@ -2470,9 +2471,9 @@
       ]
     },
     "node_modules/@rollup/rollup-win32-x64-msvc": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.4.tgz",
-      "integrity": "sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.26.0.tgz",
+      "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==",
       "cpu": [
         "x64"
       ],
@@ -3180,10 +3181,10 @@
         "node": ">=16.0.0"
       }
     },
-    "node_modules/@tsconfig/node20": {
-      "version": "20.1.4",
-      "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.4.tgz",
-      "integrity": "sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==",
+    "node_modules/@tsconfig/node22": {
+      "version": "22.0.0",
+      "resolved": "https://registry.npmjs.org/@tsconfig/node22/-/node22-22.0.0.tgz",
+      "integrity": "sha512-twLQ77zevtxobBOD4ToAtVmuYrpeYUh3qh+TEp+08IWhpsrIflVHqQ1F1CiPxQGL7doCdBIOOCF+1Tm833faNg==",
       "dev": true,
       "license": "MIT"
     },
@@ -3267,17 +3268,17 @@
       "license": "MIT"
     },
     "node_modules/@typescript-eslint/eslint-plugin": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.13.0.tgz",
-      "integrity": "sha512-nQtBLiZYMUPkclSeC3id+x4uVd1SGtHuElTxL++SfP47jR0zfkZBJHc+gL4qPsgTuypz0k8Y2GheaDYn6Gy3rg==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.14.0.tgz",
+      "integrity": "sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/regexpp": "^4.10.0",
-        "@typescript-eslint/scope-manager": "8.13.0",
-        "@typescript-eslint/type-utils": "8.13.0",
-        "@typescript-eslint/utils": "8.13.0",
-        "@typescript-eslint/visitor-keys": "8.13.0",
+        "@typescript-eslint/scope-manager": "8.14.0",
+        "@typescript-eslint/type-utils": "8.14.0",
+        "@typescript-eslint/utils": "8.14.0",
+        "@typescript-eslint/visitor-keys": "8.14.0",
         "graphemer": "^1.4.0",
         "ignore": "^5.3.1",
         "natural-compare": "^1.4.0",
@@ -3301,16 +3302,16 @@
       }
     },
     "node_modules/@typescript-eslint/parser": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.13.0.tgz",
-      "integrity": "sha512-w0xp+xGg8u/nONcGw1UXAr6cjCPU1w0XVyBs6Zqaj5eLmxkKQAByTdV/uGgNN5tVvN/kKpoQlP2cL7R+ajZZIQ==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.14.0.tgz",
+      "integrity": "sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA==",
       "dev": true,
       "license": "BSD-2-Clause",
       "dependencies": {
-        "@typescript-eslint/scope-manager": "8.13.0",
-        "@typescript-eslint/types": "8.13.0",
-        "@typescript-eslint/typescript-estree": "8.13.0",
-        "@typescript-eslint/visitor-keys": "8.13.0",
+        "@typescript-eslint/scope-manager": "8.14.0",
+        "@typescript-eslint/types": "8.14.0",
+        "@typescript-eslint/typescript-estree": "8.14.0",
+        "@typescript-eslint/visitor-keys": "8.14.0",
         "debug": "^4.3.4"
       },
       "engines": {
@@ -3330,14 +3331,14 @@
       }
     },
     "node_modules/@typescript-eslint/scope-manager": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.13.0.tgz",
-      "integrity": "sha512-XsGWww0odcUT0gJoBZ1DeulY1+jkaHUciUq4jKNv4cpInbvvrtDoyBH9rE/n2V29wQJPk8iCH1wipra9BhmiMA==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.14.0.tgz",
+      "integrity": "sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.13.0",
-        "@typescript-eslint/visitor-keys": "8.13.0"
+        "@typescript-eslint/types": "8.14.0",
+        "@typescript-eslint/visitor-keys": "8.14.0"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3348,14 +3349,14 @@
       }
     },
     "node_modules/@typescript-eslint/type-utils": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.13.0.tgz",
-      "integrity": "sha512-Rqnn6xXTR316fP4D2pohZenJnp+NwQ1mo7/JM+J1LWZENSLkJI8ID8QNtlvFeb0HnFSK94D6q0cnMX6SbE5/vA==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.14.0.tgz",
+      "integrity": "sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/typescript-estree": "8.13.0",
-        "@typescript-eslint/utils": "8.13.0",
+        "@typescript-eslint/typescript-estree": "8.14.0",
+        "@typescript-eslint/utils": "8.14.0",
         "debug": "^4.3.4",
         "ts-api-utils": "^1.3.0"
       },
@@ -3373,9 +3374,9 @@
       }
     },
     "node_modules/@typescript-eslint/types": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.13.0.tgz",
-      "integrity": "sha512-4cyFErJetFLckcThRUFdReWJjVsPCqyBlJTi6IDEpc1GWCIIZRFxVppjWLIMcQhNGhdWJJRYFHpHoDWvMlDzng==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.14.0.tgz",
+      "integrity": "sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -3387,14 +3388,14 @@
       }
     },
     "node_modules/@typescript-eslint/typescript-estree": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.13.0.tgz",
-      "integrity": "sha512-v7SCIGmVsRK2Cy/LTLGN22uea6SaUIlpBcO/gnMGT/7zPtxp90bphcGf4fyrCQl3ZtiBKqVTG32hb668oIYy1g==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.14.0.tgz",
+      "integrity": "sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==",
       "dev": true,
       "license": "BSD-2-Clause",
       "dependencies": {
-        "@typescript-eslint/types": "8.13.0",
-        "@typescript-eslint/visitor-keys": "8.13.0",
+        "@typescript-eslint/types": "8.14.0",
+        "@typescript-eslint/visitor-keys": "8.14.0",
         "debug": "^4.3.4",
         "fast-glob": "^3.3.2",
         "is-glob": "^4.0.3",
@@ -3416,16 +3417,16 @@
       }
     },
     "node_modules/@typescript-eslint/utils": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.13.0.tgz",
-      "integrity": "sha512-A1EeYOND6Uv250nybnLZapeXpYMl8tkzYUxqmoKAWnI4sei3ihf2XdZVd+vVOmHGcp3t+P7yRrNsyyiXTvShFQ==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.14.0.tgz",
+      "integrity": "sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
-        "@typescript-eslint/scope-manager": "8.13.0",
-        "@typescript-eslint/types": "8.13.0",
-        "@typescript-eslint/typescript-estree": "8.13.0"
+        "@typescript-eslint/scope-manager": "8.14.0",
+        "@typescript-eslint/types": "8.14.0",
+        "@typescript-eslint/typescript-estree": "8.14.0"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -3439,13 +3440,13 @@
       }
     },
     "node_modules/@typescript-eslint/visitor-keys": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.13.0.tgz",
-      "integrity": "sha512-7N/+lztJqH4Mrf0lb10R/CbI1EaAMMGyF5y0oJvFoAhafwgiRA7TXyd8TFn8FC8k5y2dTsYogg238qavRGNnlw==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.14.0.tgz",
+      "integrity": "sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/types": "8.13.0",
+        "@typescript-eslint/types": "8.14.0",
         "eslint-visitor-keys": "^3.4.3"
       },
       "engines": {
@@ -3457,9 +3458,9 @@
       }
     },
     "node_modules/@vitejs/plugin-vue": {
-      "version": "5.1.4",
-      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz",
-      "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==",
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.0.tgz",
+      "integrity": "sha512-7n7KdUEtx/7Yl7I/WVAMZ1bEb0eVvXF3ummWTeLcs/9gvo9pJhuLdouSXGjdZ/MKD1acf1I272+X0RMua4/R3g==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -3683,11 +3684,23 @@
       "license": "MIT"
     },
     "node_modules/@vue/tsconfig": {
-      "version": "0.5.1",
-      "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.5.1.tgz",
-      "integrity": "sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==",
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/@vue/tsconfig/-/tsconfig-0.6.0.tgz",
+      "integrity": "sha512-MHXNd6lzugsEHvuA6l1GqrF5jROqUon8sP/HInLPnthJiYvB0VvpHMywg7em1dBZfFZNBSkR68qH37zOdRHmCw==",
       "dev": true,
-      "license": "MIT"
+      "license": "MIT",
+      "peerDependencies": {
+        "typescript": "5.x",
+        "vue": "^3.3.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        },
+        "vue": {
+          "optional": true
+        }
+      }
     },
     "node_modules/acorn": {
       "version": "8.14.0",
@@ -3729,9 +3742,9 @@
       }
     },
     "node_modules/alien-signals": {
-      "version": "0.2.0",
-      "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-0.2.0.tgz",
-      "integrity": "sha512-StlonZhBBrsPPwrDjiPAiVTf/rolxffLxVPT60Qv/t88BZ81BvUVzHgGqEFvJ1ii8HXtm1+zU2Icr59tfWEcag==",
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-0.2.2.tgz",
+      "integrity": "sha512-cZIRkbERILsBOXTQmMrxc9hgpxglstn69zm+F1ARf4aPAzdAFYd6sBq87ErO0Fj3DV94tglcyHG5kQz9nDC/8A==",
       "dev": true,
       "license": "MIT"
     },
@@ -3811,9 +3824,9 @@
       }
     },
     "node_modules/asn1.js/node_modules/bn.js": {
-      "version": "4.12.0",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
-      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+      "version": "4.12.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
       "dev": true,
       "license": "MIT"
     },
@@ -4375,9 +4388,9 @@
       }
     },
     "node_modules/create-ecdh/node_modules/bn.js": {
-      "version": "4.12.0",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
-      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+      "version": "4.12.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
       "dev": true,
       "license": "MIT"
     },
@@ -4667,9 +4680,9 @@
       }
     },
     "node_modules/diffie-hellman/node_modules/bn.js": {
-      "version": "4.12.0",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
-      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+      "version": "4.12.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
       "dev": true,
       "license": "MIT"
     },
@@ -4687,9 +4700,9 @@
       }
     },
     "node_modules/dompurify": {
-      "version": "3.1.7",
-      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.7.tgz",
-      "integrity": "sha512-VaTstWtsneJY8xzy7DekmYWEOZcmzIe3Qb3zPd4STve1OBTa+e+WmS1ITQec1fZYXI3HCsOZZiSMpG6oxoWMWQ==",
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.0.tgz",
+      "integrity": "sha512-AMdOzK44oFWqHEi0wpOqix/fUNY707OmoeFDnbi3Q5I8uOpy21ufUA5cDJPr0bosxrflOVD/H2DMSvuGKJGfmQ==",
       "license": "(MPL-2.0 OR Apache-2.0)"
     },
     "node_modules/dotenv": {
@@ -4706,9 +4719,9 @@
       }
     },
     "node_modules/elliptic": {
-      "version": "6.6.0",
-      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.0.tgz",
-      "integrity": "sha512-dpwoQcLc/2WLQvJvLRHKZ+f9FgOdjnq11rurqwekGQygGPsYSK29OMMD2WalatiqQ+XGFDglTNixpPfI+lpaAA==",
+      "version": "6.6.1",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz",
+      "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -4722,9 +4735,9 @@
       }
     },
     "node_modules/elliptic/node_modules/bn.js": {
-      "version": "4.12.0",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
-      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+      "version": "4.12.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
       "dev": true,
       "license": "MIT"
     },
@@ -4751,9 +4764,9 @@
       }
     },
     "node_modules/es-abstract": {
-      "version": "1.23.3",
-      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
-      "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
+      "version": "1.23.4",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.4.tgz",
+      "integrity": "sha512-HR1gxH5OaiN7XH7uiWH0RLw0RcFySiSoW1ctxmD1ahTw3uGBtkmm/ng0tDU1OtYx5OK6EOL5Y6O21cDflG3Jcg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -4772,7 +4785,7 @@
         "function.prototype.name": "^1.1.6",
         "get-intrinsic": "^1.2.4",
         "get-symbol-description": "^1.0.2",
-        "globalthis": "^1.0.3",
+        "globalthis": "^1.0.4",
         "gopd": "^1.0.1",
         "has-property-descriptors": "^1.0.2",
         "has-proto": "^1.0.3",
@@ -4788,10 +4801,10 @@
         "is-string": "^1.0.7",
         "is-typed-array": "^1.1.13",
         "is-weakref": "^1.0.2",
-        "object-inspect": "^1.13.1",
+        "object-inspect": "^1.13.3",
         "object-keys": "^1.1.1",
         "object.assign": "^4.1.5",
-        "regexp.prototype.flags": "^1.5.2",
+        "regexp.prototype.flags": "^1.5.3",
         "safe-array-concat": "^1.1.2",
         "safe-regex-test": "^1.0.3",
         "string.prototype.trim": "^1.2.9",
@@ -5036,9 +5049,9 @@
       }
     },
     "node_modules/eslint-plugin-vue": {
-      "version": "9.30.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.30.0.tgz",
-      "integrity": "sha512-CyqlRgShvljFkOeYK8wN5frh/OGTvkj1S7wlr2Q2pUvwq+X5VYiLd6ZjujpgSgLnys2W8qrBLkXQ41SUYaoPIQ==",
+      "version": "9.31.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.31.0.tgz",
+      "integrity": "sha512-aYMUCgivhz1o4tLkRHj5oq9YgYPM4/EJc0M7TAKRLCUA5OYxRLAhYEVD2nLtTwLyixEFI+/QXSvKU9ESZFgqjQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -5957,9 +5970,9 @@
       }
     },
     "node_modules/immutable": {
-      "version": "4.3.7",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz",
-      "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==",
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.2.tgz",
+      "integrity": "sha512-1NU7hWZDkV7hJ4PJ9dur9gTNQ4ePNPN4k9/0YhwjzykTi/+3Q5pF93YU5QoVj8BuOnhLgaY8gs0U2pj4kSYVcw==",
       "dev": true,
       "license": "MIT"
     },
@@ -6565,9 +6578,9 @@
       }
     },
     "node_modules/miller-rabin/node_modules/bn.js": {
-      "version": "4.12.0",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
-      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+      "version": "4.12.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
       "dev": true,
       "license": "MIT"
     },
@@ -6698,15 +6711,15 @@
       }
     },
     "node_modules/mlly": {
-      "version": "1.7.2",
-      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.2.tgz",
-      "integrity": "sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==",
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.3.tgz",
+      "integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "acorn": "^8.12.1",
+        "acorn": "^8.14.0",
         "pathe": "^1.1.2",
-        "pkg-types": "^1.2.0",
+        "pkg-types": "^1.2.1",
         "ufo": "^1.5.4"
       }
     },
@@ -7130,9 +7143,9 @@
       }
     },
     "node_modules/object-inspect": {
-      "version": "1.13.2",
-      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
-      "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
+      "version": "1.13.3",
+      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
+      "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -7527,9 +7540,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.47",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
-      "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
+      "version": "8.4.49",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
+      "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
       "funding": [
         {
           "type": "opencollective",
@@ -7547,7 +7560,7 @@
       "license": "MIT",
       "dependencies": {
         "nanoid": "^3.3.7",
-        "picocolors": "^1.1.0",
+        "picocolors": "^1.1.1",
         "source-map-js": "^1.2.1"
       },
       "engines": {
@@ -7647,9 +7660,9 @@
       }
     },
     "node_modules/public-encrypt/node_modules/bn.js": {
-      "version": "4.12.0",
-      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
-      "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+      "version": "4.12.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.1.tgz",
+      "integrity": "sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==",
       "dev": true,
       "license": "MIT"
     },
@@ -7859,9 +7872,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "4.24.4",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.4.tgz",
-      "integrity": "sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==",
+      "version": "4.26.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.26.0.tgz",
+      "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -7875,24 +7888,24 @@
         "npm": ">=8.0.0"
       },
       "optionalDependencies": {
-        "@rollup/rollup-android-arm-eabi": "4.24.4",
-        "@rollup/rollup-android-arm64": "4.24.4",
-        "@rollup/rollup-darwin-arm64": "4.24.4",
-        "@rollup/rollup-darwin-x64": "4.24.4",
-        "@rollup/rollup-freebsd-arm64": "4.24.4",
-        "@rollup/rollup-freebsd-x64": "4.24.4",
-        "@rollup/rollup-linux-arm-gnueabihf": "4.24.4",
-        "@rollup/rollup-linux-arm-musleabihf": "4.24.4",
-        "@rollup/rollup-linux-arm64-gnu": "4.24.4",
-        "@rollup/rollup-linux-arm64-musl": "4.24.4",
-        "@rollup/rollup-linux-powerpc64le-gnu": "4.24.4",
-        "@rollup/rollup-linux-riscv64-gnu": "4.24.4",
-        "@rollup/rollup-linux-s390x-gnu": "4.24.4",
-        "@rollup/rollup-linux-x64-gnu": "4.24.4",
-        "@rollup/rollup-linux-x64-musl": "4.24.4",
-        "@rollup/rollup-win32-arm64-msvc": "4.24.4",
-        "@rollup/rollup-win32-ia32-msvc": "4.24.4",
-        "@rollup/rollup-win32-x64-msvc": "4.24.4",
+        "@rollup/rollup-android-arm-eabi": "4.26.0",
+        "@rollup/rollup-android-arm64": "4.26.0",
+        "@rollup/rollup-darwin-arm64": "4.26.0",
+        "@rollup/rollup-darwin-x64": "4.26.0",
+        "@rollup/rollup-freebsd-arm64": "4.26.0",
+        "@rollup/rollup-freebsd-x64": "4.26.0",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.26.0",
+        "@rollup/rollup-linux-arm-musleabihf": "4.26.0",
+        "@rollup/rollup-linux-arm64-gnu": "4.26.0",
+        "@rollup/rollup-linux-arm64-musl": "4.26.0",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0",
+        "@rollup/rollup-linux-riscv64-gnu": "4.26.0",
+        "@rollup/rollup-linux-s390x-gnu": "4.26.0",
+        "@rollup/rollup-linux-x64-gnu": "4.26.0",
+        "@rollup/rollup-linux-x64-musl": "4.26.0",
+        "@rollup/rollup-win32-arm64-msvc": "4.26.0",
+        "@rollup/rollup-win32-ia32-msvc": "4.26.0",
+        "@rollup/rollup-win32-x64-msvc": "4.26.0",
         "fsevents": "~2.3.2"
       }
     },
@@ -7978,14 +7991,14 @@
       }
     },
     "node_modules/sass": {
-      "version": "1.80.6",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.6.tgz",
-      "integrity": "sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg==",
+      "version": "1.80.7",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.7.tgz",
+      "integrity": "sha512-MVWvN0u5meytrSjsU7AWsbhoXi1sc58zADXFllfZzbsBT1GHjjar6JwBINYPRrkx/zqnQ6uqbQuHgE95O+C+eQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "chokidar": "^4.0.0",
-        "immutable": "^4.0.0",
+        "immutable": "^5.0.2",
         "source-map-js": ">=0.6.2 <2.0.0"
       },
       "bin": {
@@ -8597,15 +8610,15 @@
       }
     },
     "node_modules/typescript-eslint": {
-      "version": "8.13.0",
-      "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.13.0.tgz",
-      "integrity": "sha512-vIMpDRJrQd70au2G8w34mPps0ezFSPMEX4pXkTzUkrNbRX+36ais2ksGWN0esZL+ZMaFJEneOBHzCgSqle7DHw==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.14.0.tgz",
+      "integrity": "sha512-K8fBJHxVL3kxMmwByvz8hNdBJ8a0YqKzKDX6jRlrjMuNXyd5T2V02HIq37+OiWXvUUOXgOOGiSSOh26Mh8pC3w==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@typescript-eslint/eslint-plugin": "8.13.0",
-        "@typescript-eslint/parser": "8.13.0",
-        "@typescript-eslint/utils": "8.13.0"
+        "@typescript-eslint/eslint-plugin": "8.14.0",
+        "@typescript-eslint/parser": "8.14.0",
+        "@typescript-eslint/utils": "8.14.0"
       },
       "engines": {
         "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@@ -8743,9 +8756,9 @@
       }
     },
     "node_modules/vite": {
-      "version": "5.4.10",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz",
-      "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==",
+      "version": "5.4.11",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.11.tgz",
+      "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
diff --git a/package.json b/package.json
index 4052dab2197201613c418301b76aa18acbb4cbd2..84696ec4d5e8adb4bd3d6e5cb6b435647bbb085c 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,7 @@
     "chart.js": "~4.4.0",
     "chartjs-plugin-zoom": "~2.0.1",
     "dayjs": "~1.11.0",
-    "dompurify": "~3.1.0",
+    "dompurify": "~3.2.0",
     "filesize": "~10.1.0",
     "idb-keyval": "^6.2.1",
     "pinia": "~2.2.0",
@@ -41,7 +41,7 @@
     "@eslint/compat": "^1.2.0",
     "@hey-api/openapi-ts": "^0.55.0",
     "@rushstack/eslint-patch": "~1.10.0",
-    "@tsconfig/node20": "^20.1.2",
+    "@tsconfig/node22": "^22.0.0",
     "@types/bootstrap": "~5.2.0",
     "@types/dompurify": "~3.0.0",
     "@types/node": "^20.11.0",
@@ -49,12 +49,12 @@
     "@types/semver": "~7.5.1",
     "@types/showdown": "~2.0.1",
     "@types/sortablejs": "^1.15.7",
-    "@vitejs/plugin-vue": "~5.1.0",
+    "@vitejs/plugin-vue": "~5.2.0",
     "@vue/eslint-config-prettier": "~10.1.0",
     "@vue/eslint-config-typescript": "~14.1.0",
-    "@vue/tsconfig": "~0.5.0",
+    "@vue/tsconfig": "~0.6.0",
     "eslint": "~9.12.0",
-    "eslint-plugin-vue": "~9.30.0",
+    "eslint-plugin-vue": "~9.31.0",
     "highlight.js": "^11.9.0",
     "npm-run-all": "~4.1.5",
     "prettier": "~3.3.0",
diff --git a/src/assets/main.css b/src/assets/main.css
index 78974d49d17a8fe984d9746478ee8462aac507a7..0409e705a7f134cc895ac2c58aa18b6ceb835a67 100644
--- a/src/assets/main.css
+++ b/src/assets/main.css
@@ -42,3 +42,7 @@ pre {
 .execution-notes p {
     margin-bottom: 0;
 }
+
+.parameter-form-tooltip {
+    --bs-tooltip-max-width: 350px;
+}
diff --git a/src/components/MarkdownRenderer.vue b/src/components/MarkdownRenderer.vue
index 906e7d5ba849cfedb744a53d043ae44eb295d540..936b9bc66d5ce768029d15662e324e98d6141d46 100644
--- a/src/components/MarkdownRenderer.vue
+++ b/src/components/MarkdownRenderer.vue
@@ -5,7 +5,7 @@ import DOMPurify from "dompurify";
 import { computed } from "vue";
 
 const props = defineProps<{
-  markdown: string;
+  markdown?: string;
 }>();
 
 const converter = new showdown.Converter({
@@ -14,7 +14,7 @@ const converter = new showdown.Converter({
 });
 converter.setFlavor("github");
 const outputHtml = computed<string>(() => {
-  const dirtyHTML = converter.makeHtml(props.markdown);
+  const dirtyHTML = converter.makeHtml(props.markdown ?? "");
   return DOMPurify.sanitize(dirtyHTML);
 });
 </script>
diff --git a/src/components/parameter-schema/ParameterSchemaDescriptionComponent.vue b/src/components/parameter-schema/ParameterSchemaDescriptionComponent.vue
index c1517193021a794f021b68df27680975374a3ca4..9e401bef0ed515301edc01ba9cdbc981ac29cdba 100644
--- a/src/components/parameter-schema/ParameterSchemaDescriptionComponent.vue
+++ b/src/components/parameter-schema/ParameterSchemaDescriptionComponent.vue
@@ -44,10 +44,16 @@ const navParameterGroups = computed<ParameterGroup[]>(() => {
   return groups;
 });
 
+const schemaDefinitions = computed<Record<string, never>>(
+  () => props.schema?.["definitions"] ?? props.schema?.["$defs"],
+);
+
+/* eslint-disable @typescript-eslint/ban-ts-comment */
+// @ts-ignore
 const parameterGroups = computed<Record<string, never>>(() => {
   if (Object.keys(props.schema?.["properties"] ?? {}).length > 0) {
     return {
-      ...props.schema?.["definitions"],
+      ...schemaDefinitions.value,
       ungrouped_parameters: {
         title: "Ungrouped Parameters",
         properties: props.schema?.["properties"],
@@ -55,7 +61,7 @@ const parameterGroups = computed<Record<string, never>>(() => {
       },
     };
   }
-  return props.schema?.["definitions"];
+  return schemaDefinitions.value;
 });
 </script>
 
@@ -64,7 +70,7 @@ const parameterGroups = computed<Record<string, never>>(() => {
     <div class="col-9">
       <div v-for="(group, groupName) in parameterGroups" :key="groupName">
         <parameter-group-description
-          :parameter-group="group"
+          :schema-properties="parameterGroups"
           class="schema-group-description"
           :parameter-group-name="groupName"
           :show-hidden="showHidden"
diff --git a/src/components/parameter-schema/ParameterSchemaFormComponent.vue b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
index cac3540d96b9128f7337232f52c0f8a12f0ce53e..a0c2069bef6e9a11ab17355e129a463981a602e8 100644
--- a/src/components/parameter-schema/ParameterSchemaFormComponent.vue
+++ b/src/components/parameter-schema/ParameterSchemaFormComponent.vue
@@ -20,7 +20,7 @@ import type {
   FlatWorkflowParameters,
 } from "@/types/WorkflowParameters";
 import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
-import { NextflowVersion, type ParameterExtension } from "@/client";
+import { NextflowVersion, type ParameterExtension } from "@/client/types.gen";
 import { flattenParameters, nestParameters } from "@/utils/Workflow";
 
 const bucketRepository = useBucketStore();
@@ -115,10 +115,16 @@ const formState = reactive<{
 
 // Computed Properties
 // =============================================================================
+const schemaDefinitions = computed<Record<string, never>>(
+  () => props.schema?.["definitions"] ?? props.schema?.["$defs"],
+);
+
+/* eslint-disable @typescript-eslint/ban-ts-comment */
+// @ts-ignore
 const parameterGroups = computed<Record<string, never>>(() => {
   if (Object.keys(props.schema?.["properties"] ?? {}).length > 0) {
     return {
-      ...props.schema?.["definitions"],
+      ...schemaDefinitions.value,
       ungrouped_parameters: {
         title: "Ungrouped Parameters",
         properties: props.schema?.["properties"],
@@ -126,7 +132,7 @@ const parameterGroups = computed<Record<string, never>>(() => {
       },
     };
   }
-  return props.schema?.["definitions"];
+  return schemaDefinitions.value;
 });
 
 // Create a list with the names of all parameter groups
@@ -318,7 +324,7 @@ onMounted(() => {
           v-if="formState.formInput"
           v-model="formState.formInput"
           :parameter-group-name="groupName"
-          :parameter-group="group"
+          :schema-properties="parameterGroups"
           :show-hidden="showHidden"
           :show-optional="showOptional"
           :resource-parameters="props.clowmInfo?.resourceParameters"
@@ -347,14 +353,15 @@ onMounted(() => {
                 <font-awesome-icon icon="fa-solid fa-sticky-note" />
               </span>
               <textarea
+                id="pipelineNotes"
                 v-model="formState.metaParameters.notes"
                 class="form-control border border-secondary"
                 rows="2"
               />
             </div>
-            <label class="mb-3" for="pipelineNotes"
-              >Personal notes about the pipeline execution</label
-            >
+            <div class="mb-3 d-inline-block">
+              Personal notes about the pipeline execution
+            </div>
           </div>
           <div>
             <code
@@ -374,9 +381,9 @@ onMounted(() => {
                 border="secondary"
               />
             </div>
-            <label class="mb-3" for="logsS3Path">
+            <div class="mb-3 d-inline-block">
               Directory in bucket where to save Nextflow log and reports
-            </label>
+            </div>
           </div>
           <div v-if="props.nextflowVersion >= NextflowVersion._23_04_0">
             <code
@@ -396,10 +403,10 @@ onMounted(() => {
                 border="secondary"
               />
             </div>
-            <label class="mb-3" for="provenanceS3Path">
+            <div class="mb-3 d-inline-block">
               Directory in bucket where to save provenance information about the
               workflow execution
-            </label>
+            </div>
           </div>
           <div :hidden="!showHidden">
             <code
@@ -419,10 +426,10 @@ onMounted(() => {
                 border="secondary"
               />
             </div>
-            <label class="mb-3" for="debugS3Path">
+            <div class="mb-3 d-inline-block">
               Directory in bucket where to save debug information about the
               workflow execution
-            </label>
+            </div>
           </div>
         </div>
       </div>
diff --git a/src/components/parameter-schema/description-mode/ParameterDescription.vue b/src/components/parameter-schema/description-mode/ParameterDescription.vue
index 33f35f1a8efd775ef256b8a2c1d4749017571530..0a3cfbd6698378f24ef1180036682afc62f437f3 100644
--- a/src/components/parameter-schema/description-mode/ParameterDescription.vue
+++ b/src/components/parameter-schema/description-mode/ParameterDescription.vue
@@ -1,14 +1,18 @@
 <script setup lang="ts">
-import { computed } from "vue";
+import { computed, onMounted, type PropType } from "vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import MarkdownRenderer from "@/components/MarkdownRenderer.vue";
+import type { ParameterAnyOfDependencies } from "@/types/WorkflowParameters.ts";
+import { Tooltip } from "bootstrap";
 
 const props = defineProps({
   parameter: {
     type: Object,
     required: true,
     validator(value: Record<string, never>) {
-      return ["boolean", "array", "number", "string"].includes(value["type"]);
+      return ["boolean", "array", "number", "string", "integer"].includes(
+        value["type"],
+      );
     },
   },
   required: Boolean,
@@ -24,6 +28,11 @@ const props = defineProps({
     type: Boolean,
     default: false,
   },
+  dependencies: {
+    type: Array as PropType<string[]>,
+    required: false,
+  },
+  anyOfDependencies: Object as PropType<ParameterAnyOfDependencies>,
 });
 
 const randomIDSuffix = Math.random().toString(16).substring(2, 8);
@@ -51,19 +60,85 @@ const showRightColum = computed<boolean>(
     props.required ||
     defaultValue.value != undefined,
 );
+
+const anyOfTooltip = computed<string | undefined>(() => {
+  let labelText: string | undefined = undefined;
+  if (props.anyOfDependencies != undefined) {
+    labelText = "<ul class='ps-3 ms-0 mb-0 text-start'>";
+    if (props.anyOfDependencies.group.length > 0) {
+      labelText +=
+        "<li>When this is set, these parameters are also required:<ul >" +
+        props.anyOfDependencies.group
+          .map((a) => "<li>--" + a + "</li>")
+          .join("") +
+        "</ul></li>";
+    }
+    labelText +=
+      "<li>Set this or any of these parameters:<ul>" +
+      props.anyOfDependencies.dependencies
+        .map((a) => "<li>" + a.map((b) => "--" + b).join(",") + "</li>")
+        .join("") +
+      "</ul></li></ul>";
+  }
+  return labelText;
+});
+
+// object with parameter name as key and tooltip string for dependentRequired label as value
+const dependentTooltip = computed<string | undefined>(() => {
+  if (props.dependencies != undefined) {
+    return (
+      "Required when these parameters are set: <ul class='ps-4 mb-0 text-start'>" +
+      props.dependencies.map((a) => "<li>--" + a + "</li>").join("") +
+      "</ul></li>"
+    );
+  }
+  return undefined;
+});
+onMounted(() => {
+  document
+    ?.querySelector(`#parameter-${randomIDSuffix}`)
+    ?.querySelectorAll("[data-bs-toggle=tooltip]")
+    .forEach((tooltipTriggerEl) => {
+      Tooltip.getOrCreateInstance(tooltipTriggerEl);
+    });
+});
 </script>
 
 <template>
-  <div v-if="showHidden || !hidden" class="border-top">
+  <div
+    :id="`parameter-${randomIDSuffix}`"
+    :hidden="!showHidden && hidden"
+    class="border-top"
+  >
     <div class="d-flex pt-2 justify-content-between">
       <div class="flex-fill ps-2">
         <div class="row">
-          <div class="fs-6">
+          <span class="fs-6 w-fit">
             <font-awesome-icon v-if="icon" :icon="icon" class="me-2" />
             <code :id="props.parameterName" class="border rounded p-1"
               >--{{ props.parameterName }}</code
             >
-          </div>
+          </span>
+          <span
+            v-if="anyOfTooltip != undefined"
+            class="rounded py-0 px-1 bg-secondary ms-2 label w-fit fs-6"
+            data-bs-toggle="tooltip"
+            data-bs-placement="bottom"
+            :data-bs-title="anyOfTooltip"
+            data-bs-custom-class="parameter-form-tooltip"
+            data-bs-html="true"
+            >anyOf</span
+          >
+          <span
+            v-if="dependentTooltip != undefined"
+            class="rounded py-0 px-1 bg-secondary ms-2 label w-fit fs-6"
+            data-bs-toggle="tooltip"
+            data-bs-placement="bottom"
+            :data-bs-title="dependentTooltip"
+            data-bs-custom-class="parameter-form-tooltip"
+            data-bs-html="true"
+            >dependency</span
+          >
         </div>
         <div class="row align-items-start mt-2">
           <div class="col-auto">
@@ -155,4 +230,8 @@ a:hover {
 code.border {
   backdrop-filter: brightness(0.95);
 }
+
+.label {
+  cursor: help;
+}
 </style>
diff --git a/src/components/parameter-schema/description-mode/ParameterGroupDescription.vue b/src/components/parameter-schema/description-mode/ParameterGroupDescription.vue
index acd145139016082edfbba47cc5f3df6780e2d26d..d74b54577016444ff55f790e21e5d086f7edc5b2 100644
--- a/src/components/parameter-schema/description-mode/ParameterGroupDescription.vue
+++ b/src/components/parameter-schema/description-mode/ParameterGroupDescription.vue
@@ -2,19 +2,17 @@
 import { computed, type PropType } from "vue";
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
 import ParameterDescription from "@/components/parameter-schema/description-mode/ParameterDescription.vue";
+import type { ParameterAnyOfDependencies } from "@/types/WorkflowParameters.ts";
 
 const props = defineProps({
-  parameterGroup: {
-    type: Object,
-    required: true,
-    validator(value: Record<string, never>) {
-      return "object" === value["type"];
-    },
-  },
   parameterGroupName: {
     type: String,
     required: true,
   },
+  schemaProperties: {
+    type: Object,
+    required: true,
+  },
   showHidden: {
     type: Boolean,
     default: false,
@@ -25,9 +23,12 @@ const props = defineProps({
   },
 });
 
-const title = computed<string>(() => props.parameterGroup["title"]);
-const icon = computed<string>(() => props.parameterGroup["fa_icon"]);
-const description = computed<string>(() => props.parameterGroup["description"]);
+const title = computed<string>(() => parameterGroup.value["title"]);
+const icon = computed<string>(() => parameterGroup.value["fa_icon"]);
+const description = computed<string>(() => parameterGroup.value["description"]);
+const parameters = computed<Record<string, never>>(
+  () => parameterGroup.value["properties"],
+);
 
 const groupHidden = computed<boolean>(() =>
   Object.keys(parameters.value).reduce(
@@ -36,16 +37,65 @@ const groupHidden = computed<boolean>(() =>
   ),
 );
 
-const parameters = computed<Record<string, never>>(
-  () => props.parameterGroup["properties"],
+const parameterGroup = computed(
+  () => props.schemaProperties[props.parameterGroupName],
+);
+
+/*
+Object with parameter name as key and list of parameters that make the parameter required if they are set as value
+JSONSchema DependentRequired
+ */
+const parameterDependenciesPerParameter = computed<Record<string, string[]>>(
+  () => {
+    const r: Record<string, string[]> = {};
+    for (const groupName of Object.keys(props.schemaProperties)) {
+      const dep =
+        props.schemaProperties[groupName]["dependentRequired"] ??
+        props.schemaProperties[groupName]["dependencies"] ??
+        {};
+      for (const paramName of Object.keys(dep)) {
+        for (const depParam of dep[paramName]) {
+          if (parameters.value[depParam] != undefined) {
+            if (r[depParam] == undefined) {
+              r[depParam] = [paramName];
+            } else {
+              r[depParam].push(depParam);
+            }
+          }
+        }
+      }
+    }
+    return r;
+  },
 );
+
+// object with parameter name as key and anyOf dependencies as value
+const parameterAnyOfDependenciesPerParameter = computed<
+  Record<string, ParameterAnyOfDependencies>
+>(() => {
+  const b: string[][] =
+    parameterGroup.value["anyOf"]
+      ?.map((b: Record<string, string[]>) => b["required"] ?? [])
+      ?.filter((b: string[]) => b.length > 0) ?? [];
+  const r: Record<string, ParameterAnyOfDependencies> = {};
+  for (const paramName of b.flat()) {
+    r[paramName] = {
+      group:
+        b.find((a) => a.includes(paramName))?.filter((a) => a != paramName) ??
+        [],
+      dependencies: b.filter((a) => !a.includes(paramName)),
+    };
+  }
+  return r;
+});
 </script>
 
 <template>
-  <div v-if="props.showHidden || !groupHidden" class="mb-5">
+  <div :hidden="!props.showHidden && groupHidden" class="mb-5">
     <div class="row">
       <h2 :id="props.parameterGroupName">
-        <font-awesome-icon v-if="icon" :icon="icon" class="me-3" />{{ title }}
+        <font-awesome-icon v-if="icon" :icon="icon" class="me-3" />
+        {{ title }}
       </h2>
       <h4>{{ description }}</h4>
     </div>
@@ -57,11 +107,13 @@ const parameters = computed<Record<string, never>>(
         v-if="parameter['type'] !== 'object'"
         :parameter-name="parameterName"
         :parameter="parameter"
-        :required="
-          props.parameterGroup['required']?.includes(parameterName) ?? false
-        "
+        :required="parameterGroup['required']?.includes(parameterName) ?? false"
         :show-hidden="showHidden"
         :clowm-resource="resourceParameters?.includes(parameterName)"
+        :dependencies="parameterDependenciesPerParameter[parameterName]"
+        :any-of-dependencies="
+          parameterAnyOfDependenciesPerParameter[parameterName]
+        "
       />
     </template>
   </div>
diff --git a/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue b/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue
index 75529fc9efbdf31699b0aa024728cc8c03ceec64..567eec0000a8f1d2cf4c4241d0cba83bf3582261 100644
--- a/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterBooleanInput.vue
@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { computed, onMounted, type PropType, watch } from "vue";
+import { computed, onMounted, type PropType, ref, watch } from "vue";
 import type { ExtendedColors } from "@/types/PropTypes";
 
 const model = defineModel({ required: true });
@@ -13,13 +13,16 @@ const props = defineProps({
     },
   },
   border: String as PropType<ExtendedColors>,
+  required: Boolean,
+  id: String,
 });
 
-const randomIDSuffix = Math.random().toString(16).substring(2, 8);
-
 const helpTextPresent = computed<boolean>(() => props.parameter["help_text"]);
 const iconPresent = computed<boolean>(() => props.parameter["fa_icon"]);
 
+const trueOption = ref<HTMLInputElement | undefined>(undefined);
+const falseOption = ref<HTMLInputElement | undefined>(undefined);
+
 const dynamicCssClasses = computed<string[]>(() => {
   const cssClasses = [];
   if (props.border) {
@@ -39,13 +42,34 @@ watch(model, (newVal) => {
     // type conversion if true/false is represented by 0/1
     model.value = !!newVal;
   }
+  /* eslint-disable @typescript-eslint/ban-ts-comment */
+  // @ts-ignore
+  setCustomValidity(props.required, newVal);
 });
 
+watch(
+  () => props.required,
+  (newVal) => {
+    /* eslint-disable @typescript-eslint/ban-ts-comment */
+    // @ts-ignore
+    setCustomValidity(newVal, model.value);
+  },
+);
+
+function setCustomValidity(required: boolean, value: boolean | undefined) {
+  const reason = required && value == undefined ? "Unset" : "";
+  trueOption.value?.setCustomValidity(reason);
+  falseOption.value?.setCustomValidity(reason);
+}
+
 onMounted(() => {
   if (model.value != undefined) {
     // type conversion if true/false is represented by 0/1
     model.value = model.value ? true : false;
   }
+  /* eslint-disable @typescript-eslint/ban-ts-comment */
+  // @ts-ignore
+  setCustomValidity(props.required, model.value);
 });
 </script>
 
@@ -55,30 +79,28 @@ onMounted(() => {
     :class="dynamicCssClasses"
   >
     <div class="form-check form-check-inline mb-0">
-      <label class="form-check-label" :for="'trueOption' + randomIDSuffix"
-        >True</label
-      >
       <input
-        :id="'trueOption' + randomIDSuffix"
+        :id="id + 'TrueOption'"
+        ref="trueOption"
         v-model="model"
         class="form-check-input"
         type="radio"
-        :name="'inlineRadioOptions' + randomIDSuffix"
+        :name="id + 'inlineRadioOptions'"
         :value="true"
       />
+      <label class="form-check-label" :for="id + 'TrueOption'">True</label>
     </div>
     <div class="form-check form-check-inline mb-0">
       <input
-        :id="'falseOption' + randomIDSuffix"
+        :id="id + 'FalseOption'"
+        ref="falseOption"
         v-model="model"
         class="form-check-input"
         type="radio"
-        :name="'inlineRadioOptions' + randomIDSuffix"
+        :name="id + 'inlineRadioOptions'"
         :value="false"
       />
-      <label class="form-check-label" :for="'falseOption' + randomIDSuffix"
-        >False</label
-      >
+      <label class="form-check-label" :for="id + 'FalseOption'">False</label>
     </div>
   </div>
 </template>
diff --git a/src/components/parameter-schema/form-mode/ParameterEnumInput.vue b/src/components/parameter-schema/form-mode/ParameterEnumInput.vue
index 06b03081dc04371c190e0aba9e462c9def5ee9fc..76d5f455f9274152eb79638d5465f401951cf9d7 100644
--- a/src/components/parameter-schema/form-mode/ParameterEnumInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterEnumInput.vue
@@ -17,6 +17,7 @@ const props = defineProps({
     type: String as PropType<SizeModifierType>,
   },
   border: String as PropType<ExtendedColors>,
+  id: String,
 });
 
 const possibleValues = computed<string[]>(() => props.parameter["enum"]);
@@ -35,6 +36,7 @@ const dynamicCssClasses = computed<string[]>(() => {
 
 <template>
   <select
+    :id="id"
     v-model="model"
     class="form-select"
     :class="dynamicCssClasses"
diff --git a/src/components/parameter-schema/form-mode/ParameterFileInput.vue b/src/components/parameter-schema/form-mode/ParameterFileInput.vue
index ac590d8e57b346fb788b29073302c1415a629b7a..3880a82cee4c371aee21c1c98b7e3b5b25b1a74e 100644
--- a/src/components/parameter-schema/form-mode/ParameterFileInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterFileInput.vue
@@ -24,6 +24,7 @@ const props = defineProps({
   },
   border: String as PropType<ExtendedColors>,
   allowRaw: Boolean,
+  id: String,
 });
 
 const emit = defineEmits<{
@@ -167,6 +168,7 @@ onMounted(() => {
 
 <template>
   <select
+    :id="id + 'BucketSelect'"
     class="form-select"
     :class="selectDynamicClass"
     :required="props.required"
@@ -191,6 +193,7 @@ onMounted(() => {
     </option>
   </select>
   <input
+    :id="id + 'FilePath'"
     v-model="s3Path.key"
     class="form-control"
     :list="'keys-options-' + randomIDSuffix"
diff --git a/src/components/parameter-schema/form-mode/ParameterGroupForm.vue b/src/components/parameter-schema/form-mode/ParameterGroupForm.vue
index 6d3235eae10864efb5758eeac2b5dd0e6ce3eddf..2553b343e90f00cc7de2d51d7ed4f35b2d6de738 100644
--- a/src/components/parameter-schema/form-mode/ParameterGroupForm.vue
+++ b/src/components/parameter-schema/form-mode/ParameterGroupForm.vue
@@ -1,20 +1,20 @@
 <script setup lang="ts">
 import FontAwesomeIcon from "@/components/FontAwesomeIcon.vue";
-import { computed, type PropType } from "vue";
+import { computed, onMounted, type PropType } from "vue";
 import MarkdownRenderer from "@/components/MarkdownRenderer.vue";
-import type { FlatWorkflowParameters } from "@/types/WorkflowParameters";
+import type {
+  FlatWorkflowParameters,
+  ParameterAnyOfDependencies,
+} from "@/types/WorkflowParameters";
 import ParameterInput from "@/components/parameter-schema/form-mode/ParameterInput.vue";
+import { Tooltip } from "bootstrap";
+import { md5 } from "@/utils/md5";
 
 const model = defineModel<FlatWorkflowParameters>({ required: true });
 
+const groupId = Math.random().toString(16).substring(2, 8);
+
 const props = defineProps({
-  parameterGroup: {
-    type: Object,
-    required: true,
-    validator(value: Record<string, never>) {
-      return "object" === value["type"];
-    },
-  },
   parameterGroupName: {
     type: String,
     required: true,
@@ -32,10 +32,14 @@ const props = defineProps({
     required: false,
   },
   mapping: Object as PropType<Record<string, Record<string, string | number>>>,
+  schemaProperties: {
+    type: Object,
+    required: true,
+  },
 });
-const title = computed<string>(() => props.parameterGroup["title"]);
-const icon = computed<string>(() => props.parameterGroup["fa_icon"]);
-const description = computed<string>(() => props.parameterGroup["description"]);
+const title = computed<string>(() => parameterGroup.value["title"]);
+const icon = computed<string>(() => parameterGroup.value["fa_icon"]);
+const description = computed<string>(() => parameterGroup.value["description"]);
 const groupHidden = computed<boolean>(() =>
   Object.keys(parameters.value).reduce(
     (acc: boolean, val: string) => acc && parameters.value[val]["hidden"],
@@ -43,39 +47,190 @@ const groupHidden = computed<boolean>(() =>
   ),
 );
 const groupRequired = computed<boolean>(
-  () => (props.parameterGroup["required"] ?? []).length > 0,
+  () =>
+    (parameterGroup.value["required"] ?? parameterGroup.value["anyOf"] ?? [])
+      .length > 0,
 );
 const parameters = computed<Record<string, never>>(
-  () => props.parameterGroup["properties"],
+  () => parameterGroup.value["properties"],
+);
+
+const parameterGroup = computed(
+  () => props.schemaProperties[props.parameterGroupName],
 );
 
-function parameterRequired(
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  parameterGroup: Record<string, any>,
-  parameterName: string,
-): boolean {
+/*
+Object with parameter name as key and list of parameters that make the parameter required if they are set as value
+JSONSchema DependentRequired
+ */
+const parameterDependenciesPerParameter = computed<Record<string, string[]>>(
+  () => {
+    const r: Record<string, string[]> = {};
+    for (const groupName of Object.keys(props.schemaProperties)) {
+      const dep =
+        props.schemaProperties[groupName]["dependentRequired"] ??
+        props.schemaProperties[groupName]["dependencies"] ??
+        {};
+      for (const paramName of Object.keys(dep)) {
+        for (const depParam of dep[paramName]) {
+          if (parameters.value[depParam] != undefined) {
+            if (r[depParam] == undefined) {
+              r[depParam] = [paramName];
+            } else {
+              r[depParam].push(depParam);
+            }
+          }
+        }
+      }
+    }
+    return r;
+  },
+);
+
+// Object with parameter name as key and boolean flag if the parameter is required as value
+const parameterRequired = computed<Record<string, boolean>>(() => {
+  const r: Record<string, boolean> = {};
+  for (const parameterName of Object.keys(parameters.value)) {
+    r[parameterName] =
+      parameterDirectlyRequired(parameterName) || // parameter is directly required
+      parameterDependentRequired(parameterName) || // parameter is required depending on other parameters
+      parameterAnyOfRequired(parameterName); // parameter is required in a OR parameter group
+  }
+  return r;
+});
+
+// evaluate if the parameter is required directly
+function parameterDirectlyRequired(parameterName: string): boolean {
+  return parameterGroup.value["required"]?.includes(parameterName) ?? false;
+}
+
+// evaluate if a parameter is required due to a anyOf constraint
+function parameterDependentRequired(parameterName: string): boolean {
+  return parameterDependenciesPerParameter.value[parameterName] // parameter is required when another parameter is set
+    ?.reduce(
+      (acc: boolean, param: string) => acc || model.value[param] != undefined,
+      false,
+    );
+}
+
+// evaluate of a parameter is required du to a dependentRequired constraint
+function parameterAnyOfRequired(parameterName: string): boolean {
   return (
-    parameterGroup["required"]?.includes(parameterName) || // parameter is required
-    parameterGroup["dependentRequired"]?.[parameterName] // parameter is required when another parameter is set
-      ?.map((param: string) => model.value[param])
-      ?.reduce((acc: boolean, val: string) => acc || val, false)
+    parameterAnyOfDependenciesPerParameter.value[parameterName] != undefined &&
+    parameterAnyOfDependenciesPerParameter.value[parameterName].dependencies
+      .flat()
+      .reduce(
+        (acc, groupParam) => acc && model.value[groupParam] == undefined,
+        true,
+      ) &&
+    (model.value[parameterName] == undefined ||
+      parameterAnyOfDependenciesPerParameter.value[parameterName].group.reduce(
+        (acc, groupParam) => acc && model.value[groupParam] == undefined,
+        true,
+      ))
   );
 }
 
-function parameterId(parameterName: string): string {
-  return parameterName.replace(/\./g, "");
-}
+// object with parameter name as key and anyOf dependencies as value
+const parameterAnyOfDependenciesPerParameter = computed<
+  Record<string, ParameterAnyOfDependencies>
+>(() => {
+  const b: string[][] =
+    parameterGroup.value["anyOf"]
+      ?.map((b: Record<string, string[]>) => b["required"] ?? [])
+      ?.filter((b: string[]) => b.length > 0) ?? [];
+  const r: Record<string, ParameterAnyOfDependencies> = {};
+  for (const paramName of b.flat()) {
+    r[paramName] = {
+      group:
+        b.find((a) => a.includes(paramName))?.filter((a) => a != paramName) ??
+        [],
+      dependencies: b.filter((a) => !a.includes(paramName)),
+    };
+  }
+  return r;
+});
+
+// object with parameter name as key and tooltip string for dependentRequired label as value
+const dependentTooltip = computed<Record<string, string>>(() => {
+  const r: Record<string, string> = {};
+  for (const paramName of Object.keys(parameters.value)) {
+    let labelText = "";
+    if (parameterDependenciesPerParameter.value[paramName] != undefined) {
+      labelText +=
+        "Required when these parameters are set: <ul class='ps-4 mb-0 text-start'>" +
+        parameterDependenciesPerParameter.value[paramName]
+          .map((a) => "<li>--" + a + "</li>")
+          .join("") +
+        "</ul></li>";
+    }
+    if (labelText.length > 0) {
+      r[paramName] = labelText;
+    }
+  }
+  return r;
+});
+
+// object with parameter name as key and tooltip string for anyOf label as value
+const anyOfTooltip = computed<Record<string, string>>(() => {
+  const r: Record<string, string> = {};
+  for (const paramName of Object.keys(parameters.value)) {
+    let labelText = "";
+    if (parameterAnyOfDependenciesPerParameter.value[paramName] != undefined) {
+      labelText += "<ul class='ps-3 ms-0 mb-0 text-start'>";
+      if (
+        parameterAnyOfDependenciesPerParameter.value[paramName].group.length > 0
+      ) {
+        labelText +=
+          "<li>When this is set, these are also required:<ul >" +
+          parameterAnyOfDependenciesPerParameter.value[paramName].group
+            .map((a) => "<li>--" + a + "</li>")
+            .join("") +
+          "</ul></li>";
+      }
+      labelText +=
+        "<li>Set this or any of these parameters:<ul>" +
+        parameterAnyOfDependenciesPerParameter.value[paramName].dependencies
+          .map((a) => "<li>" + a.map((b) => "--" + b).join(",") + "</li>")
+          .join("") +
+        "</ul></li></ul>";
+    }
+    if (labelText.length > 0) {
+      r[paramName] = labelText;
+    }
+  }
+  return r;
+});
+
+// object with parameter name as key and id for html attributes as value
+const parameterIds = computed<Record<string, string>>(() => {
+  const r: Record<string, string> = {};
+  for (const parameterName of Object.keys(parameters.value)) {
+    r[parameterName] = md5(parameterName);
+  }
+  return r;
+});
+
+onMounted(() => {
+  document
+    ?.querySelector(`#group-${groupId}`)
+    ?.querySelectorAll("[data-bs-toggle=tooltip]")
+    .forEach((tooltipTriggerEl) => {
+      Tooltip.getOrCreateInstance(tooltipTriggerEl);
+    });
+});
 </script>
 
 <template>
   <div
+    :id="`group-${groupId}`"
     class="card mb-3"
     :hidden="
       (!props.showHidden && groupHidden) ||
       (!props.showOptional && !groupRequired)
     "
   >
-    <h3 :id="props.parameterGroupName" class="card-header">
+    <h3 :id="parameterGroup.valueName" class="card-header">
       <font-awesome-icon v-if="icon" :icon="icon" class="me-2" />
       {{ title }}
     </h3>
@@ -89,18 +244,50 @@ function parameterId(parameterName: string): string {
           :hidden="
             (!props.showHidden && parameter['hidden']) ||
             (!props.showOptional &&
-              !parameterRequired(props.parameterGroup, parameterName))
+              !(
+                parameterRequired[parameterName] ||
+                parameterAnyOfDependenciesPerParameter[parameterName] !=
+                  undefined ||
+                parameterDependenciesPerParameter[parameterName] != undefined
+              ))
           "
         >
           <code
             class="p-2 rounded-top border-bottom-0 border bg-secondary-subtle border-secondary"
-            >--{{ parameter["name"] ?? parameterName }}</code
-          ><span
-            v-if="parameterRequired(props.parameterGroup, parameterName)"
-            class="rounded p-1 bg-warning text-light ms-2"
-            >required</span
           >
-          <div class="input-group">
+            --{{ parameter["name"] ?? parameterName }}
+          </code>
+          <span
+            v-if="parameterDirectlyRequired(parameterName)"
+            class="rounded p-1 bg-warning ms-2"
+          >
+            required
+          </span>
+          <span
+            v-if="anyOfTooltip[parameterName] != undefined"
+            class="rounded p-1 bg-secondary ms-2 label"
+            data-bs-toggle="tooltip"
+            data-bs-placement="bottom"
+            :data-bs-title="anyOfTooltip[parameterName]"
+            data-bs-custom-class="parameter-form-tooltip"
+            data-bs-html="true"
+            >anyOf</span
+          >
+          <span
+            v-if="dependentTooltip[parameterName] != undefined"
+            class="rounded p-1 bg-secondary ms-2 label"
+            data-bs-toggle="tooltip"
+            data-bs-placement="bottom"
+            :data-bs-title="dependentTooltip[parameterName]"
+            data-bs-custom-class="parameter-form-tooltip"
+            data-bs-html="true"
+          >
+            dependency
+          </span>
+          <div
+            class="input-group"
+            :class="{ 'mb-3': parameter['description'] == undefined }"
+          >
             <span
               v-if="parameter['fa_icon']"
               class="input-group-text border-end-0 border border-secondary"
@@ -108,9 +295,10 @@ function parameterId(parameterName: string): string {
               <font-awesome-icon :icon="parameter['fa_icon']" />
             </span>
             <parameter-input
+              :id="parameterIds[parameterName]"
               v-model="model[parameterName]"
               :parameter="parameter"
-              :required="parameterRequired(props.parameterGroup, parameterName)"
+              :required="parameterRequired[parameterName]"
               border="secondary"
               :resource-parameter="
                 props.resourceParameters?.includes(parameterName)
@@ -122,9 +310,9 @@ function parameterId(parameterName: string): string {
               v-if="parameter['help_text']"
               class="input-group-text cursor-pointer px-2 border border-secondary"
               data-bs-toggle="collapse"
-              :data-bs-target="'#help-collapse-' + parameterId(parameterName)"
+              :data-bs-target="'#help-collapse-' + parameterIds[parameterName]"
               aria-expanded="false"
-              :aria-controls="'help-collapse-' + parameterId(parameterName)"
+              :aria-controls="'help-collapse-' + parameterIds[parameterName]"
             >
               <font-awesome-icon
                 class="cursor-pointer"
@@ -132,12 +320,12 @@ function parameterId(parameterName: string): string {
               />
             </span>
           </div>
-          <label v-if="parameter['description']">
+          <div v-if="parameter['description']" class="d-inline-block">
             <markdown-renderer :markdown="parameter['description']" />
-          </label>
+          </div>
           <div
             v-if="parameter['help_text']"
-            :id="'help-collapse-' + parameterId(parameterName)"
+            :id="'help-collapse-' + parameterIds[parameterName]"
             class="collapse"
           >
             <div class="p-2 pb-0 mx-2 mb-3 flex-shrink-1 border rounded">
@@ -156,7 +344,7 @@ function parameterId(parameterName: string): string {
   </div>
 </template>
 
-<style scoped>
+<style>
 div.card-body {
   backdrop-filter: brightness(1.2);
 }
@@ -164,4 +352,8 @@ div.card-body {
 span.cursor-pointer:hover {
   color: var(--bs-info);
 }
+
+.label {
+  cursor: help;
+}
 </style>
diff --git a/src/components/parameter-schema/form-mode/ParameterInput.vue b/src/components/parameter-schema/form-mode/ParameterInput.vue
index 3e4a76f8125ce654c0a3a13f27e6c8521ad4579c..72ebea2f2d6c7cf6ed6bdc1f40946f48d23c4ee9 100644
--- a/src/components/parameter-schema/form-mode/ParameterInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterInput.vue
@@ -14,6 +14,7 @@ const model = defineModel({
 });
 
 const rawInput = ref<boolean>(false);
+const randomIDSuffix = Math.random().toString(16).substring(2, 8);
 
 const props = defineProps<{
   // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -25,16 +26,20 @@ const props = defineProps<{
   allowRaw?: boolean;
   forceRawFile?: boolean;
   mapping?: Record<string, string | number>;
+  id?: string;
 }>();
 
 const parameterType = computed<string>(
   () => props.parameter["type"] ?? "string",
 );
+
+const elemId = computed<string>(() => props.id ?? randomIDSuffix);
 </script>
 
 <template>
   <parameter-mapping-input
     v-if="mapping && Object.keys(mapping ?? {}).length > 0 && !rawInput"
+    :id="elemId"
     v-model="model as string | number | undefined"
     :required="required"
     :size-modifier="sizeModifier"
@@ -45,6 +50,7 @@ const parameterType = computed<string>(
   />
   <parameter-number-input
     v-else-if="parameterType === 'number' || parameterType === 'integer'"
+    :id="elemId"
     v-model="model"
     :parameter="parameter"
     :required="required"
@@ -53,12 +59,15 @@ const parameterType = computed<string>(
   />
   <parameter-boolean-input
     v-else-if="parameterType === 'boolean'"
+    :id="elemId"
     v-model="model"
     :parameter="parameter"
     :border="border"
+    :required="required"
   />
   <parameter-enum-input
     v-else-if="parameter['enum']"
+    :id="elemId"
     v-model="model"
     :required="required"
     :parameter="parameter"
@@ -68,6 +77,7 @@ const parameterType = computed<string>(
   <template v-else>
     <parameter-resource-input
       v-if="resourceParameter && !rawInput"
+      :id="elemId"
       v-model="model"
       :parameter="parameter"
       :required="required"
@@ -78,6 +88,7 @@ const parameterType = computed<string>(
     />
     <parameter-file-input
       v-else-if="parameter['format'] && !rawInput && !forceRawFile"
+      :id="elemId"
       v-model="model"
       :required="required"
       :parameter="parameter"
@@ -88,6 +99,7 @@ const parameterType = computed<string>(
     />
     <parameter-string-input
       v-else
+      :id="elemId"
       v-model="model"
       :parameter="parameter"
       :required="required"
diff --git a/src/components/parameter-schema/form-mode/ParameterMappingInput.vue b/src/components/parameter-schema/form-mode/ParameterMappingInput.vue
index d10dddab9db3a6e344a597af872878365c32b532..837788fddd83c8904a1e3b216d521825464342ff 100644
--- a/src/components/parameter-schema/form-mode/ParameterMappingInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterMappingInput.vue
@@ -10,6 +10,7 @@ const props = defineProps<{
   border?: ExtendedColors;
   mapping: Record<string, string | number>;
   allowRaw?: boolean;
+  id: string;
 }>();
 
 const emit = defineEmits<{
@@ -30,6 +31,7 @@ const dynamicCssClasses = computed<string[]>(() => {
 
 <template>
   <select
+    :id="id"
     v-model="model"
     class="form-select"
     :class="dynamicCssClasses"
diff --git a/src/components/parameter-schema/form-mode/ParameterNumberInput.vue b/src/components/parameter-schema/form-mode/ParameterNumberInput.vue
index 1a37ea7f2db40cbf3e11460bc82676a9c586f1f4..f717ee796621a45b2354e745f41b0c02585d2cb7 100644
--- a/src/components/parameter-schema/form-mode/ParameterNumberInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterNumberInput.vue
@@ -20,6 +20,7 @@ const props = defineProps({
     type: String as PropType<SizeModifierType>,
   },
   border: String as PropType<ExtendedColors>,
+  id: String,
 });
 
 const dynamicCssClasses = computed<string[]>(() => {
@@ -36,6 +37,7 @@ const dynamicCssClasses = computed<string[]>(() => {
 
 <template>
   <input
+    :id="id"
     v-model="model"
     class="form-control flex-fill"
     :class="dynamicCssClasses"
diff --git a/src/components/parameter-schema/form-mode/ParameterResourceInput.vue b/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
index d9dd92e0eab7f5e00f628f5944c2274e1679ddf9..20818256bfddc4ef1060de95830fea6ee6f7809b 100644
--- a/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterResourceInput.vue
@@ -17,6 +17,7 @@ const props = defineProps<{
   sizeModifier?: SizeModifierType;
   border?: ExtendedColors;
   allowRaw?: boolean;
+  id: string;
 }>();
 
 const emit = defineEmits<{
@@ -24,7 +25,6 @@ const emit = defineEmits<{
 }>();
 
 const resourceRepository = useResourceStore();
-const randomIDSuffix = Math.random().toString(16).substring(2, 8);
 
 type ResourcePath = {
   resource_id: string;
@@ -158,6 +158,7 @@ onMounted(() => {
 
 <template>
   <select
+    :id="id + 'Resource'"
     class="form-select"
     :class="selectDynamicClass"
     :required="props.required"
@@ -177,6 +178,7 @@ onMounted(() => {
     </option>
   </select>
   <select
+    :id="id + 'ResourceVersion'"
     class="form-select"
     :class="selectDynamicClass"
     :required="resource.resource_id.length > 0"
@@ -199,6 +201,7 @@ onMounted(() => {
     </option>
   </select>
   <input
+    :id="id + 'ResourcePath'"
     v-model="resource.suffix"
     type="text"
     class="form-control"
@@ -207,9 +210,9 @@ onMounted(() => {
     minlength="2"
     maxlength="256"
     pattern="\/\S*"
-    :list="'resource-tree-options-' + randomIDSuffix"
+    :list="'resource-tree-options-' + id"
   />
-  <datalist :id="'resource-tree-options-' + randomIDSuffix">
+  <datalist :id="'resource-tree-options-' + id">
     <option
       v-for="file in resourceRepository.resourceTreeList[
         resource.resource_version_id
diff --git a/src/components/parameter-schema/form-mode/ParameterStringInput.vue b/src/components/parameter-schema/form-mode/ParameterStringInput.vue
index 95bab5216a091f18204e4af7f20c736349f841af..97bf0211e95e23c8051b1ca308999244110e3713 100644
--- a/src/components/parameter-schema/form-mode/ParameterStringInput.vue
+++ b/src/components/parameter-schema/form-mode/ParameterStringInput.vue
@@ -21,6 +21,7 @@ const props = defineProps({
   border: String as PropType<ExtendedColors>,
   resourceParameter: Boolean,
   allowSwitch: Boolean,
+  id: String,
 });
 
 const emit = defineEmits<{
@@ -54,6 +55,7 @@ const helpTextPresent = computed<boolean>(() => props.parameter["help_text"]);
 
 <template>
   <input
+    :id="id"
     ref="stringInput"
     v-model="model"
     class="form-control"
diff --git a/src/components/workflows/modals/CreateWorkflowModal.vue b/src/components/workflows/modals/CreateWorkflowModal.vue
index 03392577827cb2a675c326a8832f4b7f1ae05b43..3a863871873ca8aa8db713b32f74954548b6a0e6 100644
--- a/src/components/workflows/modals/CreateWorkflowModal.vue
+++ b/src/components/workflows/modals/CreateWorkflowModal.vue
@@ -512,6 +512,7 @@ onMounted(() => {
                 class="form-control"
                 placeholder="v1.0.0"
                 maxlength="10"
+                required
                 @change="checkVersionValidity"
               />
               <div
diff --git a/src/types/WorkflowParameters.ts b/src/types/WorkflowParameters.ts
index 51b702e09f5ad66d5c6cd783e9a7b8afe8760acc..eec9f79e5a89c92bc24e51dc0ddbc39d0d77efcd 100644
--- a/src/types/WorkflowParameters.ts
+++ b/src/types/WorkflowParameters.ts
@@ -17,3 +17,8 @@ export type TemporaryParams = {
   params?: NestedWorkflowParameters;
   metaParams?: WorkflowMetaParameters;
 };
+
+export interface ParameterAnyOfDependencies {
+  group: string[]; // AND group in OR combination
+  dependencies: string[][]; // OR combination to fulfill
+}
diff --git a/src/utils/md5.d.ts b/src/utils/md5.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..db8c804abff0d60689c2d31887b55ac5195d8cef
--- /dev/null
+++ b/src/utils/md5.d.ts
@@ -0,0 +1,7 @@
+/**
+ * Calculate MD5 hash of a string
+ *
+ * @param {string} d The string to hash.
+ * @returns {number} The hexdigest.
+ */
+export declare function md5(d: string): string;
diff --git a/src/utils/md5.js b/src/utils/md5.js
new file mode 100644
index 0000000000000000000000000000000000000000..b464d8b698c97f9f96ff3136d3d1eee03dc9510c
--- /dev/null
+++ b/src/utils/md5.js
@@ -0,0 +1,498 @@
+export function md5(d) {
+  var r = M(V(Y(X(d), 8 * d.length)));
+  return r.toLowerCase();
+}
+
+function M(d) {
+  for (var _, m = "0123456789ABCDEF", f = "", r = 0; r < d.length; r++)
+    _ = d.charCodeAt(r);
+  f += m.charAt((_ >>> 4) & 15) + m.charAt(15 & _);
+  return f;
+}
+
+function X(d) {
+  for (var _ = Array(d.length >> 2), m = 0; m < _.length; m++) _[m] = 0;
+  for (m = 0; m < 8 * d.length; m += 8)
+    _[m >> 5] |= (255 & d.charCodeAt(m / 8)) << m % 32;
+  return _;
+}
+
+function V(d) {
+  for (var _ = "", m = 0; m < 32 * d.length; m += 8)
+    _ += String.fromCharCode((d[m >> 5] >>> m % 32) & 255);
+  return _;
+}
+
+function Y(d, _) {
+  d[_ >> 5] |= 128 << _ % 32;
+  d[14 + (((_ + 64) >>> 9) << 4)] = _;
+  for (
+    var m = 1732584193, f = -271733879, r = -1732584194, i = 271733878, n = 0;
+    n < d.length;
+    n += 16
+  ) {
+    var h = m,
+      t = f,
+      g = r,
+      e = i;
+    f = md5_ii(
+      (f = md5_ii(
+        (f = md5_ii(
+          (f = md5_ii(
+            (f = md5_hh(
+              (f = md5_hh(
+                (f = md5_hh(
+                  (f = md5_hh(
+                    (f = md5_gg(
+                      (f = md5_gg(
+                        (f = md5_gg(
+                          (f = md5_gg(
+                            (f = md5_ff(
+                              (f = md5_ff(
+                                (f = md5_ff(
+                                  (f = md5_ff(
+                                    f,
+                                    (r = md5_ff(
+                                      r,
+                                      (i = md5_ff(
+                                        i,
+                                        (m = md5_ff(
+                                          m,
+                                          f,
+                                          r,
+                                          i,
+                                          d[n + 0],
+                                          7,
+                                          -680876936,
+                                        )),
+                                        f,
+                                        r,
+                                        d[n + 1],
+                                        12,
+                                        -389564586,
+                                      )),
+                                      m,
+                                      f,
+                                      d[n + 2],
+                                      17,
+                                      606105819,
+                                    )),
+                                    i,
+                                    m,
+                                    d[n + 3],
+                                    22,
+                                    -1044525330,
+                                  )),
+                                  (r = md5_ff(
+                                    r,
+                                    (i = md5_ff(
+                                      i,
+                                      (m = md5_ff(
+                                        m,
+                                        f,
+                                        r,
+                                        i,
+                                        d[n + 4],
+                                        7,
+                                        -176418897,
+                                      )),
+                                      f,
+                                      r,
+                                      d[n + 5],
+                                      12,
+                                      1200080426,
+                                    )),
+                                    m,
+                                    f,
+                                    d[n + 6],
+                                    17,
+                                    -1473231341,
+                                  )),
+                                  i,
+                                  m,
+                                  d[n + 7],
+                                  22,
+                                  -45705983,
+                                )),
+                                (r = md5_ff(
+                                  r,
+                                  (i = md5_ff(
+                                    i,
+                                    (m = md5_ff(
+                                      m,
+                                      f,
+                                      r,
+                                      i,
+                                      d[n + 8],
+                                      7,
+                                      1770035416,
+                                    )),
+                                    f,
+                                    r,
+                                    d[n + 9],
+                                    12,
+                                    -1958414417,
+                                  )),
+                                  m,
+                                  f,
+                                  d[n + 10],
+                                  17,
+                                  -42063,
+                                )),
+                                i,
+                                m,
+                                d[n + 11],
+                                22,
+                                -1990404162,
+                              )),
+                              (r = md5_ff(
+                                r,
+                                (i = md5_ff(
+                                  i,
+                                  (m = md5_ff(
+                                    m,
+                                    f,
+                                    r,
+                                    i,
+                                    d[n + 12],
+                                    7,
+                                    1804603682,
+                                  )),
+                                  f,
+                                  r,
+                                  d[n + 13],
+                                  12,
+                                  -40341101,
+                                )),
+                                m,
+                                f,
+                                d[n + 14],
+                                17,
+                                -1502002290,
+                              )),
+                              i,
+                              m,
+                              d[n + 15],
+                              22,
+                              1236535329,
+                            )),
+                            (r = md5_gg(
+                              r,
+                              (i = md5_gg(
+                                i,
+                                (m = md5_gg(
+                                  m,
+                                  f,
+                                  r,
+                                  i,
+                                  d[n + 1],
+                                  5,
+                                  -165796510,
+                                )),
+                                f,
+                                r,
+                                d[n + 6],
+                                9,
+                                -1069501632,
+                              )),
+                              m,
+                              f,
+                              d[n + 11],
+                              14,
+                              643717713,
+                            )),
+                            i,
+                            m,
+                            d[n + 0],
+                            20,
+                            -373897302,
+                          )),
+                          (r = md5_gg(
+                            r,
+                            (i = md5_gg(
+                              i,
+                              (m = md5_gg(m, f, r, i, d[n + 5], 5, -701558691)),
+                              f,
+                              r,
+                              d[n + 10],
+                              9,
+                              38016083,
+                            )),
+                            m,
+                            f,
+                            d[n + 15],
+                            14,
+                            -660478335,
+                          )),
+                          i,
+                          m,
+                          d[n + 4],
+                          20,
+                          -405537848,
+                        )),
+                        (r = md5_gg(
+                          r,
+                          (i = md5_gg(
+                            i,
+                            (m = md5_gg(m, f, r, i, d[n + 9], 5, 568446438)),
+                            f,
+                            r,
+                            d[n + 14],
+                            9,
+                            -1019803690,
+                          )),
+                          m,
+                          f,
+                          d[n + 3],
+                          14,
+                          -187363961,
+                        )),
+                        i,
+                        m,
+                        d[n + 8],
+                        20,
+                        1163531501,
+                      )),
+                      (r = md5_gg(
+                        r,
+                        (i = md5_gg(
+                          i,
+                          (m = md5_gg(m, f, r, i, d[n + 13], 5, -1444681467)),
+                          f,
+                          r,
+                          d[n + 2],
+                          9,
+                          -51403784,
+                        )),
+                        m,
+                        f,
+                        d[n + 7],
+                        14,
+                        1735328473,
+                      )),
+                      i,
+                      m,
+                      d[n + 12],
+                      20,
+                      -1926607734,
+                    )),
+                    (r = md5_hh(
+                      r,
+                      (i = md5_hh(
+                        i,
+                        (m = md5_hh(m, f, r, i, d[n + 5], 4, -378558)),
+                        f,
+                        r,
+                        d[n + 8],
+                        11,
+                        -2022574463,
+                      )),
+                      m,
+                      f,
+                      d[n + 11],
+                      16,
+                      1839030562,
+                    )),
+                    i,
+                    m,
+                    d[n + 14],
+                    23,
+                    -35309556,
+                  )),
+                  (r = md5_hh(
+                    r,
+                    (i = md5_hh(
+                      i,
+                      (m = md5_hh(m, f, r, i, d[n + 1], 4, -1530992060)),
+                      f,
+                      r,
+                      d[n + 4],
+                      11,
+                      1272893353,
+                    )),
+                    m,
+                    f,
+                    d[n + 7],
+                    16,
+                    -155497632,
+                  )),
+                  i,
+                  m,
+                  d[n + 10],
+                  23,
+                  -1094730640,
+                )),
+                (r = md5_hh(
+                  r,
+                  (i = md5_hh(
+                    i,
+                    (m = md5_hh(m, f, r, i, d[n + 13], 4, 681279174)),
+                    f,
+                    r,
+                    d[n + 0],
+                    11,
+                    -358537222,
+                  )),
+                  m,
+                  f,
+                  d[n + 3],
+                  16,
+                  -722521979,
+                )),
+                i,
+                m,
+                d[n + 6],
+                23,
+                76029189,
+              )),
+              (r = md5_hh(
+                r,
+                (i = md5_hh(
+                  i,
+                  (m = md5_hh(m, f, r, i, d[n + 9], 4, -640364487)),
+                  f,
+                  r,
+                  d[n + 12],
+                  11,
+                  -421815835,
+                )),
+                m,
+                f,
+                d[n + 15],
+                16,
+                530742520,
+              )),
+              i,
+              m,
+              d[n + 2],
+              23,
+              -995338651,
+            )),
+            (r = md5_ii(
+              r,
+              (i = md5_ii(
+                i,
+                (m = md5_ii(m, f, r, i, d[n + 0], 6, -198630844)),
+                f,
+                r,
+                d[n + 7],
+                10,
+                1126891415,
+              )),
+              m,
+              f,
+              d[n + 14],
+              15,
+              -1416354905,
+            )),
+            i,
+            m,
+            d[n + 5],
+            21,
+            -57434055,
+          )),
+          (r = md5_ii(
+            r,
+            (i = md5_ii(
+              i,
+              (m = md5_ii(m, f, r, i, d[n + 12], 6, 1700485571)),
+              f,
+              r,
+              d[n + 3],
+              10,
+              -1894986606,
+            )),
+            m,
+            f,
+            d[n + 10],
+            15,
+            -1051523,
+          )),
+          i,
+          m,
+          d[n + 1],
+          21,
+          -2054922799,
+        )),
+        (r = md5_ii(
+          r,
+          (i = md5_ii(
+            i,
+            (m = md5_ii(m, f, r, i, d[n + 8], 6, 1873313359)),
+            f,
+            r,
+            d[n + 15],
+            10,
+            -30611744,
+          )),
+          m,
+          f,
+          d[n + 6],
+          15,
+          -1560198380,
+        )),
+        i,
+        m,
+        d[n + 13],
+        21,
+        1309151649,
+      )),
+      (r = md5_ii(
+        r,
+        (i = md5_ii(
+          i,
+          (m = md5_ii(m, f, r, i, d[n + 4], 6, -145523070)),
+          f,
+          r,
+          d[n + 11],
+          10,
+          -1120210379,
+        )),
+        m,
+        f,
+        d[n + 2],
+        15,
+        718787259,
+      )),
+      i,
+      m,
+      d[n + 9],
+      21,
+      -343485551,
+    );
+    m = safe_add(m, h);
+    f = safe_add(f, t);
+    r = safe_add(r, g);
+    i = safe_add(i, e);
+  }
+  return [m, f, r, i];
+}
+
+function md5_cmn(d, _, m, f, r, i) {
+  return safe_add(bit_rol(safe_add(safe_add(_, d), safe_add(f, i)), r), m);
+}
+
+function md5_ff(d, _, m, f, r, i, n) {
+  return md5_cmn((_ & m) | (~_ & f), d, _, r, i, n);
+}
+
+function md5_gg(d, _, m, f, r, i, n) {
+  return md5_cmn((_ & f) | (m & ~f), d, _, r, i, n);
+}
+
+function md5_hh(d, _, m, f, r, i, n) {
+  return md5_cmn(_ ^ m ^ f, d, _, r, i, n);
+}
+
+function md5_ii(d, _, m, f, r, i, n) {
+  return md5_cmn(m ^ (_ | ~f), d, _, r, i, n);
+}
+
+function safe_add(d, _) {
+  var m = (65535 & d) + (65535 & _);
+  return (((d >> 16) + (_ >> 16) + (m >> 16)) << 16) | (65535 & m);
+}
+
+function bit_rol(d, _) {
+  return (d << _) | (d >>> (32 - _));
+}
diff --git a/src/views/DashboardView.vue b/src/views/DashboardView.vue
index 685cb7c0ecf4bb9c6441765f617219df1a98e012..5d79dfe4f6231337f35ea91ae9c277ac4bfdfa16 100644
--- a/src/views/DashboardView.vue
+++ b/src/views/DashboardView.vue
@@ -21,6 +21,7 @@ import type {
 import dayjs from "dayjs";
 import { useWorkflowExecutionStore } from "@/stores/workflowExecutions";
 import { useResourceStore } from "@/stores/resources";
+import { latestVersion } from "@/utils/Workflow.ts";
 
 const authStore = useUserStore();
 const bucketStore = useBucketStore();
@@ -259,7 +260,18 @@ function accumulateWorkflowStatus(
                 v-for="workflow in processedWorkflows.slice(0, 3)"
                 :key="workflow.workflow_id"
               >
-                {{ workflow.name }} <br />
+                <router-link
+                  :to="{
+                    name: 'workflow-version',
+                    params: {
+                      workflowId: workflow.workflow_id,
+                      versionId: latestVersion(workflow.versions)
+                        ?.workflow_version_id,
+                    },
+                  }"
+                  >{{ workflow.name }}
+                </router-link>
+                <br />
                 <span class="text-secondary" style="font-size: 0.8rem">
                   Last update
                   {{
diff --git a/tsconfig.json b/tsconfig.json
index 508ccb807ef68c2ebafee5bfc71d6ab098825b00..9871f9e444c705ae4fa0f651263ef9ccc03308e5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,6 +1,6 @@
 {
   "extends": [
-    "@tsconfig/node20/tsconfig.json",
+    "@tsconfig/node22/tsconfig.json",
     "@vue/tsconfig/tsconfig.json"
   ],
   "include": [