diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b58b603fea78041071d125a30db58d79b3d49217
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,5 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/dojobackendapi.iml b/.idea/dojobackendapi.iml
new file mode 100644
index 0000000000000000000000000000000000000000..24643cc37449b4bde54411a80b8ed61258225e34
--- /dev/null
+++ b/.idea/dojobackendapi.iml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="WEB_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.tmp" />
+      <excludeFolder url="file://$MODULE_DIR$/temp" />
+      <excludeFolder url="file://$MODULE_DIR$/tmp" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000000000000000000000000000000000000..53aaca2013eb5b498566e71713e4c4feca197ee3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/dojobackendapi.iml" filepath="$PROJECT_DIR$/.idea/dojobackendapi.iml" />
+    </modules>
+  </component>
+</project>
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..35eb1ddfbbc029bcab630581847471d7f238ec53
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7faee3126e000d77f46aed6099fed53d814b8550..f3c6c00f54d85622ce195983e315b762f36cd686 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,8 +17,13 @@
 - No modifications / Keep major and minors versions in sync with all parts of the project
 -->
 
+## 4.2.0 (Upcoming)
 
-## 4.1.0 (Upcoming)
+### ✨ Feature
+- Add support for tags on assignments and exercises
+
+
+## 4.1.0 (2024-05-28)
 
 ### ✨ Feature
 - Add features related to corrige (commentary, commit specific link / update, delete link)
diff --git a/ExpressAPI/.env.vault b/ExpressAPI/.env.vault
index 22cc6dca141b734cda92ccf8dd7563c76c93a6a2..9ef7138fd136d8b0846f7b733085911a1f2b9696 100644
--- a/ExpressAPI/.env.vault
+++ b/ExpressAPI/.env.vault
@@ -4,11 +4,11 @@
 #/--------------------------------------------------/
 
 # development
-DOTENV_VAULT_DEVELOPMENT="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"
+DOTENV_VAULT_DEVELOPMENT="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"
 
 # production
-DOTENV_VAULT_PRODUCTION="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"
+DOTENV_VAULT_PRODUCTION="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"
 
 # test
-DOTENV_VAULT_TEST="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"
+DOTENV_VAULT_TEST="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"
 
diff --git a/ExpressAPI/.idea/material_theme_project_new.xml b/ExpressAPI/.idea/material_theme_project_new.xml
new file mode 100644
index 0000000000000000000000000000000000000000..16e830f2d917c0815e814dcbf57e219c3b85c2e2
--- /dev/null
+++ b/ExpressAPI/.idea/material_theme_project_new.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="MaterialThemeProjectNewConfig">
+    <option name="metadata">
+      <MTProjectMetadataState>
+        <option name="migrated" value="true" />
+        <option name="pristineConfig" value="false" />
+        <option name="userId" value="104e8585:19002424fea:-7ffe" />
+      </MTProjectMetadataState>
+    </option>
+  </component>
+</project>
\ No newline at end of file
diff --git a/ExpressAPI/assets/OpenAPI/OpenAPI.yaml b/ExpressAPI/assets/OpenAPI/OpenAPI.yaml
index 8ebb21662faad48639bce22286e04c0d2f7c4450..23d099e0a7b64cb6a9bff5c5fe886336cbe3d1d8 100644
--- a/ExpressAPI/assets/OpenAPI/OpenAPI.yaml
+++ b/ExpressAPI/assets/OpenAPI/OpenAPI.yaml
@@ -1,7 +1,7 @@
 openapi: 3.1.0
 info:
     title: Dojo API
-    version: 4.1.0
+    version: 4.2.0
     description: |
         **Backend API of the Dojo project.**
         
diff --git a/ExpressAPI/package-lock.json b/ExpressAPI/package-lock.json
index 0027a6b91b80290192918c9dc84d9c3b7da28385..331702eac921eafa560421b6a286e1ad20230e4d 100644
--- a/ExpressAPI/package-lock.json
+++ b/ExpressAPI/package-lock.json
@@ -1,17 +1,17 @@
 {
     "name": "dojo_backend_api",
-    "version": "4.1.0",
+    "version": "4.2.0",
     "lockfileVersion": 3,
     "requires": true,
     "packages": {
         "": {
             "name": "dojo_backend_api",
-            "version": "4.1.0",
+            "version": "4.2.0",
             "license": "AGPLv3",
             "dependencies": {
-                "@dotenvx/dotenvx": "^0.44.1",
+                "@dotenvx/dotenvx": "^0.45.0",
                 "@gitbeaker/rest": "^40.0.3",
-                "@prisma/client": "^5.14.0",
+                "@prisma/client": "^5.16.1",
                 "axios": "^1.7.2",
                 "compression": "^1.7.4",
                 "cors": "^2.8.5",
@@ -25,38 +25,39 @@
                 "morgan": "^1.10.0",
                 "multer": "^1.4.5-lts.1",
                 "mysql": "^2.18.1",
-                "node": "^20.11.0",
+                "node": "^20.15.0",
                 "parse-link-header": "^2.0.0",
                 "semver": "^7.6.2",
-                "swagger-ui-express": "^5.0.0",
+                "swagger-ui-express": "^5.0.1",
                 "tar-stream": "^3.1.7",
-                "uuid": "^9.0.1",
+                "uuid": "^10.0.0",
                 "winston": "^3.13.0",
                 "zod": "^3.23.8",
                 "zod-validation-error": "^3.3.0"
             },
             "devDependencies": {
-                "@redocly/cli": "^1.13.0",
+                "@redocly/cli": "^1.17.0",
                 "@types/compression": "^1.7.5",
                 "@types/cors": "^2.8.17",
                 "@types/express": "^4.17.21",
                 "@types/jsonwebtoken": "^9.0.6",
                 "@types/morgan": "^1.9.9",
                 "@types/multer": "^1.4.11",
-                "@types/node": "^20.12.12",
+                "@types/node": "^20.14.9",
                 "@types/parse-link-header": "^2.0.3",
                 "@types/semver": "^7.5.8",
                 "@types/swagger-ui-express": "^4.1.6",
                 "@types/tar-stream": "^3.1.3",
-                "@types/uuid": "^9.0.8",
+                "@types/uuid": "^10.0.0",
+                "dotenv-cli": "^7.4.2",
                 "eslint": "^8.57.0",
                 "genversion": "^3.2.0",
-                "nodemon": "^3.1.1",
-                "npm": "^10.8.0",
-                "prisma": "^5.14.0",
-                "tsx": "^4.11.0",
-                "typescript": "^5.4.5",
-                "typescript-eslint": "^7.11.0"
+                "nodemon": "^3.1.4",
+                "npm": "^10.8.1",
+                "prisma": "^5.16.1",
+                "tsx": "^4.16.2",
+                "typescript": "^5.5.3",
+                "typescript-eslint": "^7.15.0"
             }
         },
         "node_modules/@aashutoshrathi/word-wrap": {
@@ -69,9 +70,9 @@
             }
         },
         "node_modules/@babel/runtime": {
-            "version": "7.24.1",
-            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz",
-            "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==",
+            "version": "7.24.7",
+            "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
+            "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
             "dev": true,
             "dependencies": {
                 "regenerator-runtime": "^0.14.0"
@@ -80,6 +81,24 @@
                 "node": ">=6.9.0"
             }
         },
+        "node_modules/@cfaester/enzyme-adapter-react-18": {
+            "version": "0.8.0",
+            "resolved": "https://registry.npmjs.org/@cfaester/enzyme-adapter-react-18/-/enzyme-adapter-react-18-0.8.0.tgz",
+            "integrity": "sha512-3Z3ThTUouHwz8oIyhTYQljEMNRFtlVyc3VOOHCbxs47U6cnXs8K9ygi/c1tv49s7MBlTXeIcuN+Ttd9aPtILFQ==",
+            "dev": true,
+            "dependencies": {
+                "enzyme-shallow-equal": "^1.0.0",
+                "function.prototype.name": "^1.1.6",
+                "has": "^1.0.4",
+                "react-is": "^18.2.0",
+                "react-shallow-renderer": "^16.15.0"
+            },
+            "peerDependencies": {
+                "enzyme": "^3.11.0",
+                "react": ">=18",
+                "react-dom": ">=18"
+            }
+        },
         "node_modules/@colors/colors": {
             "version": "1.6.0",
             "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
@@ -99,9 +118,9 @@
             }
         },
         "node_modules/@dotenvx/dotenvx": {
-            "version": "0.44.1",
-            "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-0.44.1.tgz",
-            "integrity": "sha512-OmOU7CRwhXydZUHeTP46GNZsGpwQ3mwrr3cUAWod+FmrKW3ib4GYe1jU++ZFyEEUNvg532QvvM7hQ44YyJrgfw==",
+            "version": "0.45.0",
+            "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-0.45.0.tgz",
+            "integrity": "sha512-qjW6PDX3mONGQHSrI6LPzOCHn/RZPZuHThPrRZOvyo90pTMGQaCqRbcastl1Y3ZQlw0igdcKnk9pJSh5uYNLbg==",
             "dependencies": {
                 "@inquirer/confirm": "^2.0.17",
                 "arch": "^2.1.1",
@@ -134,9 +153,9 @@
             }
         },
         "node_modules/@emotion/is-prop-valid": {
-            "version": "1.2.1",
-            "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz",
-            "integrity": "sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw==",
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
+            "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
             "dev": true,
             "dependencies": {
                 "@emotion/memoize": "^0.8.1"
@@ -149,15 +168,15 @@
             "dev": true
         },
         "node_modules/@emotion/unitless": {
-            "version": "0.8.0",
-            "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz",
-            "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==",
+            "version": "0.8.1",
+            "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
+            "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
             "dev": true
         },
         "node_modules/@esbuild/aix-ppc64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
-            "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
+            "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
             "cpu": [
                 "ppc64"
             ],
@@ -171,9 +190,9 @@
             }
         },
         "node_modules/@esbuild/android-arm": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
-            "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
+            "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
             "cpu": [
                 "arm"
             ],
@@ -187,9 +206,9 @@
             }
         },
         "node_modules/@esbuild/android-arm64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
-            "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
+            "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
             "cpu": [
                 "arm64"
             ],
@@ -203,9 +222,9 @@
             }
         },
         "node_modules/@esbuild/android-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
-            "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
+            "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
             "cpu": [
                 "x64"
             ],
@@ -219,9 +238,9 @@
             }
         },
         "node_modules/@esbuild/darwin-arm64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
-            "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
+            "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
             "cpu": [
                 "arm64"
             ],
@@ -235,9 +254,9 @@
             }
         },
         "node_modules/@esbuild/darwin-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
-            "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
+            "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
             "cpu": [
                 "x64"
             ],
@@ -251,9 +270,9 @@
             }
         },
         "node_modules/@esbuild/freebsd-arm64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
-            "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
+            "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
             "cpu": [
                 "arm64"
             ],
@@ -267,9 +286,9 @@
             }
         },
         "node_modules/@esbuild/freebsd-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
-            "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
+            "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
             "cpu": [
                 "x64"
             ],
@@ -283,9 +302,9 @@
             }
         },
         "node_modules/@esbuild/linux-arm": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
-            "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
+            "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
             "cpu": [
                 "arm"
             ],
@@ -299,9 +318,9 @@
             }
         },
         "node_modules/@esbuild/linux-arm64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
-            "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
+            "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
             "cpu": [
                 "arm64"
             ],
@@ -315,9 +334,9 @@
             }
         },
         "node_modules/@esbuild/linux-ia32": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
-            "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
+            "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
             "cpu": [
                 "ia32"
             ],
@@ -331,9 +350,9 @@
             }
         },
         "node_modules/@esbuild/linux-loong64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
-            "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
+            "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
             "cpu": [
                 "loong64"
             ],
@@ -347,9 +366,9 @@
             }
         },
         "node_modules/@esbuild/linux-mips64el": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
-            "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
+            "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
             "cpu": [
                 "mips64el"
             ],
@@ -363,9 +382,9 @@
             }
         },
         "node_modules/@esbuild/linux-ppc64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
-            "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
+            "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
             "cpu": [
                 "ppc64"
             ],
@@ -379,9 +398,9 @@
             }
         },
         "node_modules/@esbuild/linux-riscv64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
-            "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
+            "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
             "cpu": [
                 "riscv64"
             ],
@@ -395,9 +414,9 @@
             }
         },
         "node_modules/@esbuild/linux-s390x": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
-            "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
+            "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
             "cpu": [
                 "s390x"
             ],
@@ -411,9 +430,9 @@
             }
         },
         "node_modules/@esbuild/linux-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
-            "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
+            "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
             "cpu": [
                 "x64"
             ],
@@ -427,9 +446,9 @@
             }
         },
         "node_modules/@esbuild/netbsd-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
-            "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
+            "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
             "cpu": [
                 "x64"
             ],
@@ -443,9 +462,9 @@
             }
         },
         "node_modules/@esbuild/openbsd-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
-            "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
+            "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
             "cpu": [
                 "x64"
             ],
@@ -459,9 +478,9 @@
             }
         },
         "node_modules/@esbuild/sunos-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
-            "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
+            "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
             "cpu": [
                 "x64"
             ],
@@ -475,9 +494,9 @@
             }
         },
         "node_modules/@esbuild/win32-arm64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
-            "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
+            "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
             "cpu": [
                 "arm64"
             ],
@@ -491,9 +510,9 @@
             }
         },
         "node_modules/@esbuild/win32-ia32": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
-            "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
+            "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
             "cpu": [
                 "ia32"
             ],
@@ -507,9 +526,9 @@
             }
         },
         "node_modules/@esbuild/win32-x64": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
-            "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
+            "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
             "cpu": [
                 "x64"
             ],
@@ -985,9 +1004,9 @@
             }
         },
         "node_modules/@prisma/client": {
-            "version": "5.14.0",
-            "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.14.0.tgz",
-            "integrity": "sha512-akMSuyvLKeoU4LeyBAUdThP/uhVP3GuLygFE3MlYzaCb3/J8SfsYBE5PkaFuLuVpLyA6sFoW+16z/aPhNAESqg==",
+            "version": "5.16.1",
+            "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.16.1.tgz",
+            "integrity": "sha512-wM9SKQjF0qLxdnOZIVAIMKiz6Hu7vDt4FFAih85K1dk/Rr2mdahy6d3QP41K62N9O0DJJA//gUDA3Mp49xsKIg==",
             "hasInstallScript": true,
             "engines": {
                 "node": ">=16.13"
@@ -1002,48 +1021,48 @@
             }
         },
         "node_modules/@prisma/debug": {
-            "version": "5.14.0",
-            "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.14.0.tgz",
-            "integrity": "sha512-iq56qBZuFfX3fCxoxT8gBX33lQzomBU0qIUaEj1RebsKVz1ob/BVH1XSBwwwvRVtZEV1b7Fxx2eVu34Ge/mg3w==",
+            "version": "5.16.1",
+            "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.16.1.tgz",
+            "integrity": "sha512-JsNgZAg6BD9RInLSrg7ZYzo11N7cVvYArq3fHGSD89HSgtN0VDdjV6bib7YddbcO6snzjchTiLfjeTqBjtArVQ==",
             "devOptional": true
         },
         "node_modules/@prisma/engines": {
-            "version": "5.14.0",
-            "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.14.0.tgz",
-            "integrity": "sha512-lgxkKZ6IEygVcw6IZZUlPIfLQ9hjSYAtHjZ5r64sCLDgVzsPFCi2XBBJgzPMkOQ5RHzUD4E/dVdpn9+ez8tk1A==",
+            "version": "5.16.1",
+            "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.16.1.tgz",
+            "integrity": "sha512-KkyF3eIUtBIyp5A/rJHCtwQO18OjpGgx18PzjyGcJDY/+vNgaVyuVd+TgwBgeq6NLdd1XMwRCI+58vinHsAdfA==",
             "devOptional": true,
             "hasInstallScript": true,
             "dependencies": {
-                "@prisma/debug": "5.14.0",
-                "@prisma/engines-version": "5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48",
-                "@prisma/fetch-engine": "5.14.0",
-                "@prisma/get-platform": "5.14.0"
+                "@prisma/debug": "5.16.1",
+                "@prisma/engines-version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303",
+                "@prisma/fetch-engine": "5.16.1",
+                "@prisma/get-platform": "5.16.1"
             }
         },
         "node_modules/@prisma/engines-version": {
-            "version": "5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48",
-            "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48.tgz",
-            "integrity": "sha512-ip6pNkRo1UxWv+6toxNcYvItNYaqQjXdFNGJ+Nuk2eYtRoEdoF13wxo7/jsClJFFenMPVNVqXQDV0oveXnR1cA==",
+            "version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303",
+            "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303.tgz",
+            "integrity": "sha512-HkT2WbfmFZ9WUPyuJHhkiADxazHg8Y4gByrTSVeb3OikP6tjQ7txtSUGu9OBOBH0C13dPKN2qqH12xKtHu/Hiw==",
             "devOptional": true
         },
         "node_modules/@prisma/fetch-engine": {
-            "version": "5.14.0",
-            "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.14.0.tgz",
-            "integrity": "sha512-VrheA9y9DMURK5vu8OJoOgQpxOhas3qF0IBHJ8G/0X44k82kc8E0w98HCn2nhnbOOMwbWsJWXfLC2/F8n5u0gQ==",
+            "version": "5.16.1",
+            "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.16.1.tgz",
+            "integrity": "sha512-oOkjaPU1lhcA/Rvr4GVfd1NLJBwExgNBE36Ueq7dr71kTMwy++a3U3oLd2ZwrV9dj9xoP6LjCcky799D9nEt4w==",
             "devOptional": true,
             "dependencies": {
-                "@prisma/debug": "5.14.0",
-                "@prisma/engines-version": "5.14.0-25.e9771e62de70f79a5e1c604a2d7c8e2a0a874b48",
-                "@prisma/get-platform": "5.14.0"
+                "@prisma/debug": "5.16.1",
+                "@prisma/engines-version": "5.16.0-24.34ace0eb2704183d2c05b60b52fba5c43c13f303",
+                "@prisma/get-platform": "5.16.1"
             }
         },
         "node_modules/@prisma/get-platform": {
-            "version": "5.14.0",
-            "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.14.0.tgz",
-            "integrity": "sha512-/yAyBvcEjRv41ynZrhdrPtHgk47xLRRq/o5eWGcUpBJ1YrUZTYB8EoPiopnP7iQrMATK8stXQdPOoVlrzuTQZw==",
+            "version": "5.16.1",
+            "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.16.1.tgz",
+            "integrity": "sha512-R4IKnWnMkR2nUAbU5gjrPehdQYUUd7RENFD2/D+xXTNhcqczp0N+WEGQ3ViyI3+6mtVcjjNIMdnUTNyu3GxIgA==",
             "devOptional": true,
             "dependencies": {
-                "@prisma/debug": "5.14.0"
+                "@prisma/debug": "5.16.1"
             }
         },
         "node_modules/@redocly/ajv": {
@@ -1063,12 +1082,12 @@
             }
         },
         "node_modules/@redocly/cli": {
-            "version": "1.13.0",
-            "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.13.0.tgz",
-            "integrity": "sha512-2oC8SN+hGtfrFBX2LadFOAzA1ika+2IDmAg9pRl8+yualfmEdxiOuP8rltKeDZ1Uj3NGXyR42g7+CvMj55pKkw==",
+            "version": "1.17.1",
+            "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-1.17.1.tgz",
+            "integrity": "sha512-a7OIlsGQT8OBRMPswqcJzCoub/nvm1zYvOCOBnaLt1cYeYK9nRzYCXA6Bnx0I7wMCXf5YmL7rVTMG8RJTC+3mA==",
             "dev": true,
             "dependencies": {
-                "@redocly/openapi-core": "1.13.0",
+                "@redocly/openapi-core": "1.17.1",
                 "abort-controller": "^3.0.0",
                 "chokidar": "^3.5.1",
                 "colorette": "^1.2.0",
@@ -1081,7 +1100,7 @@
                 "node-fetch": "^2.6.1",
                 "react": "^17.0.0 || ^18.2.0",
                 "react-dom": "^17.0.0 || ^18.2.0",
-                "redoc": "~2.1.3",
+                "redoc": "~2.1.5",
                 "semver": "^7.5.2",
                 "simple-websocket": "^9.0.0",
                 "styled-components": "^6.0.7",
@@ -1139,20 +1158,21 @@
             }
         },
         "node_modules/@redocly/config": {
-            "version": "0.5.0",
-            "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.5.0.tgz",
-            "integrity": "sha512-oA1ezWPT2tSV9CLk0FtZlViaFKtp+id3iAVeKBme1DdP4xUCdxEdP8umB21iLKdc6leRd5uGa+T5Ox4nHBAXWg==",
+            "version": "0.6.2",
+            "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.6.2.tgz",
+            "integrity": "sha512-c3K5u64eMnr2ootPcpEI0ioIRLE8QP8ptvLxG9MwAmb2sU8HMRfVwXDU3AZiMVY2w4Ts0mDc+Xv4HTIk8DRqFw==",
             "dev": true
         },
         "node_modules/@redocly/openapi-core": {
-            "version": "1.13.0",
-            "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.13.0.tgz",
-            "integrity": "sha512-lPvVE4+QjWMXCEIui994pYBZGqvEsodaCJPCJLkx6RK3OL/6Ss8wN17YTDmF49tzw3xgA8t4+x7TqelUSRcZUQ==",
+            "version": "1.17.1",
+            "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.17.1.tgz",
+            "integrity": "sha512-PQxDLLNk5cBatJBBxvfk49HFw/nVozw1XZ6Dw/GX0Tviq+WxeEjEuLAKfnLVvb5L0wgs4TNmVG4Y+JyofSPu1A==",
             "dev": true,
             "dependencies": {
                 "@redocly/ajv": "^8.11.0",
-                "@redocly/config": "^0.5.0",
+                "@redocly/config": "^0.6.2",
                 "colorette": "^1.2.0",
+                "https-proxy-agent": "^7.0.4",
                 "js-levenshtein": "^1.1.6",
                 "js-yaml": "^4.1.0",
                 "lodash.isequal": "^4.5.0",
@@ -1281,9 +1301,9 @@
             }
         },
         "node_modules/@types/node": {
-            "version": "20.12.12",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
-            "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
+            "version": "20.14.9",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
+            "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
             "dependencies": {
                 "undici-types": "~5.26.4"
             }
@@ -1334,9 +1354,9 @@
             }
         },
         "node_modules/@types/stylis": {
-            "version": "4.2.0",
-            "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.0.tgz",
-            "integrity": "sha512-n4sx2bqL0mW1tvDf/loQ+aMX7GQD3lc3fkCMC55VFNDu/vBOabO+LTIeXKM14xK0ppk5TUGcWRjiSpIlUpghKw==",
+            "version": "4.2.5",
+            "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
+            "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==",
             "dev": true
         },
         "node_modules/@types/swagger-ui-express": {
@@ -1364,9 +1384,9 @@
             "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="
         },
         "node_modules/@types/uuid": {
-            "version": "9.0.8",
-            "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
-            "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
+            "version": "10.0.0",
+            "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
+            "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
             "dev": true
         },
         "node_modules/@types/wrap-ansi": {
@@ -1375,16 +1395,16 @@
             "integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g=="
         },
         "node_modules/@typescript-eslint/eslint-plugin": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz",
-            "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.15.0.tgz",
+            "integrity": "sha512-uiNHpyjZtFrLwLDpHnzaDlP3Tt6sGMqTCiqmxaN4n4RP0EfYZDODJyddiFDF44Hjwxr5xAcaYxVKm9QKQFJFLA==",
             "dev": true,
             "dependencies": {
                 "@eslint-community/regexpp": "^4.10.0",
-                "@typescript-eslint/scope-manager": "7.11.0",
-                "@typescript-eslint/type-utils": "7.11.0",
-                "@typescript-eslint/utils": "7.11.0",
-                "@typescript-eslint/visitor-keys": "7.11.0",
+                "@typescript-eslint/scope-manager": "7.15.0",
+                "@typescript-eslint/type-utils": "7.15.0",
+                "@typescript-eslint/utils": "7.15.0",
+                "@typescript-eslint/visitor-keys": "7.15.0",
                 "graphemer": "^1.4.0",
                 "ignore": "^5.3.1",
                 "natural-compare": "^1.4.0",
@@ -1408,15 +1428,15 @@
             }
         },
         "node_modules/@typescript-eslint/parser": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.11.0.tgz",
-            "integrity": "sha512-yimw99teuaXVWsBcPO1Ais02kwJ1jmNA1KxE7ng0aT7ndr1pT1wqj0OJnsYVGKKlc4QJai86l/025L6z8CljOg==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.15.0.tgz",
+            "integrity": "sha512-k9fYuQNnypLFcqORNClRykkGOMOj+pV6V91R4GO/l1FDGwpqmSwoOQrOHo3cGaH63e+D3ZiCAOsuS/D2c99j/A==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/scope-manager": "7.11.0",
-                "@typescript-eslint/types": "7.11.0",
-                "@typescript-eslint/typescript-estree": "7.11.0",
-                "@typescript-eslint/visitor-keys": "7.11.0",
+                "@typescript-eslint/scope-manager": "7.15.0",
+                "@typescript-eslint/types": "7.15.0",
+                "@typescript-eslint/typescript-estree": "7.15.0",
+                "@typescript-eslint/visitor-keys": "7.15.0",
                 "debug": "^4.3.4"
             },
             "engines": {
@@ -1436,9 +1456,9 @@
             }
         },
         "node_modules/@typescript-eslint/parser/node_modules/debug": {
-            "version": "4.3.4",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "version": "4.3.5",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+            "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
             "dev": true,
             "dependencies": {
                 "ms": "2.1.2"
@@ -1459,13 +1479,13 @@
             "dev": true
         },
         "node_modules/@typescript-eslint/scope-manager": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz",
-            "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.15.0.tgz",
+            "integrity": "sha512-Q/1yrF/XbxOTvttNVPihxh1b9fxamjEoz2Os/Pe38OHwxC24CyCqXxGTOdpb4lt6HYtqw9HetA/Rf6gDGaMPlw==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "7.11.0",
-                "@typescript-eslint/visitor-keys": "7.11.0"
+                "@typescript-eslint/types": "7.15.0",
+                "@typescript-eslint/visitor-keys": "7.15.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -1476,13 +1496,13 @@
             }
         },
         "node_modules/@typescript-eslint/type-utils": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz",
-            "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.15.0.tgz",
+            "integrity": "sha512-SkgriaeV6PDvpA6253PDVep0qCqgbO1IOBiycjnXsszNTVQe5flN5wR5jiczoEoDEnAqYFSFFc9al9BSGVltkg==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/typescript-estree": "7.11.0",
-                "@typescript-eslint/utils": "7.11.0",
+                "@typescript-eslint/typescript-estree": "7.15.0",
+                "@typescript-eslint/utils": "7.15.0",
                 "debug": "^4.3.4",
                 "ts-api-utils": "^1.3.0"
             },
@@ -1503,9 +1523,9 @@
             }
         },
         "node_modules/@typescript-eslint/type-utils/node_modules/debug": {
-            "version": "4.3.4",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "version": "4.3.5",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+            "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
             "dev": true,
             "dependencies": {
                 "ms": "2.1.2"
@@ -1526,9 +1546,9 @@
             "dev": true
         },
         "node_modules/@typescript-eslint/types": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz",
-            "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.15.0.tgz",
+            "integrity": "sha512-aV1+B1+ySXbQH0pLK0rx66I3IkiZNidYobyfn0WFsdGhSXw+P3YOqeTq5GED458SfB24tg+ux3S+9g118hjlTw==",
             "dev": true,
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -1539,13 +1559,13 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz",
-            "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.15.0.tgz",
+            "integrity": "sha512-gjyB/rHAopL/XxfmYThQbXbzRMGhZzGw6KpcMbfe8Q3nNQKStpxnUKeXb0KiN/fFDR42Z43szs6rY7eHk0zdGQ==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "7.11.0",
-                "@typescript-eslint/visitor-keys": "7.11.0",
+                "@typescript-eslint/types": "7.15.0",
+                "@typescript-eslint/visitor-keys": "7.15.0",
                 "debug": "^4.3.4",
                 "globby": "^11.1.0",
                 "is-glob": "^4.0.3",
@@ -1567,9 +1587,9 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree/node_modules/debug": {
-            "version": "4.3.4",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "version": "4.3.5",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+            "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
             "dev": true,
             "dependencies": {
                 "ms": "2.1.2"
@@ -1584,9 +1604,9 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
-            "version": "9.0.4",
-            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
-            "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+            "version": "9.0.5",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+            "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
             "dev": true,
             "dependencies": {
                 "brace-expansion": "^2.0.1"
@@ -1605,15 +1625,15 @@
             "dev": true
         },
         "node_modules/@typescript-eslint/utils": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz",
-            "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.15.0.tgz",
+            "integrity": "sha512-hfDMDqaqOqsUVGiEPSMLR/AjTSCsmJwjpKkYQRo1FNbmW4tBwBspYDwO9eh7sKSTwMQgBw9/T4DHudPaqshRWA==",
             "dev": true,
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.4.0",
-                "@typescript-eslint/scope-manager": "7.11.0",
-                "@typescript-eslint/types": "7.11.0",
-                "@typescript-eslint/typescript-estree": "7.11.0"
+                "@typescript-eslint/scope-manager": "7.15.0",
+                "@typescript-eslint/types": "7.15.0",
+                "@typescript-eslint/typescript-estree": "7.15.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -1627,12 +1647,12 @@
             }
         },
         "node_modules/@typescript-eslint/visitor-keys": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz",
-            "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.15.0.tgz",
+            "integrity": "sha512-Hqgy/ETgpt2L5xueA/zHHIl4fJI2O4XUE9l4+OIfbJIRSnTJb/QscncdqqZzofQegIJugRIF57OJea1khw2SDw==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "7.11.0",
+                "@typescript-eslint/types": "7.15.0",
                 "eslint-visitor-keys": "^3.4.3"
             },
             "engines": {
@@ -1700,6 +1720,41 @@
                 "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
             }
         },
+        "node_modules/agent-base": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz",
+            "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==",
+            "dev": true,
+            "dependencies": {
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/agent-base/node_modules/debug": {
+            "version": "4.3.5",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+            "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+            "dev": true,
+            "dependencies": {
+                "ms": "2.1.2"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/agent-base/node_modules/ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+            "dev": true
+        },
         "node_modules/ajv": {
             "version": "8.12.0",
             "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
@@ -1810,6 +1865,22 @@
             "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
             "dev": true
         },
+        "node_modules/array-buffer-byte-length": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
+            "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.5",
+                "is-array-buffer": "^3.0.4"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/array-flatten": {
             "version": "1.1.1",
             "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@@ -1824,6 +1895,68 @@
                 "node": ">=8"
             }
         },
+        "node_modules/array.prototype.filter": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/array.prototype.filter/-/array.prototype.filter-1.0.4.tgz",
+            "integrity": "sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "define-properties": "^1.2.1",
+                "es-abstract": "^1.23.2",
+                "es-array-method-boxes-properly": "^1.0.0",
+                "es-object-atoms": "^1.0.0",
+                "is-string": "^1.0.7"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/array.prototype.flat": {
+            "version": "1.3.2",
+            "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
+            "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "define-properties": "^1.2.0",
+                "es-abstract": "^1.22.1",
+                "es-shim-unscopables": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/arraybuffer.prototype.slice": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
+            "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+            "dev": true,
+            "dependencies": {
+                "array-buffer-byte-length": "^1.0.1",
+                "call-bind": "^1.0.5",
+                "define-properties": "^1.2.1",
+                "es-abstract": "^1.22.3",
+                "es-errors": "^1.2.1",
+                "get-intrinsic": "^1.2.3",
+                "is-array-buffer": "^3.0.4",
+                "is-shared-array-buffer": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/async": {
             "version": "3.2.5",
             "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz",
@@ -1842,6 +1975,21 @@
                 "node": ">=10.12.0"
             }
         },
+        "node_modules/available-typed-arrays": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+            "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+            "dev": true,
+            "dependencies": {
+                "possible-typed-array-names": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/axios": {
             "version": "1.7.2",
             "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
@@ -1986,6 +2134,13 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/boolbase": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+            "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+            "dev": true,
+            "peer": true
+        },
         "node_modules/brace-expansion": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
@@ -2115,6 +2270,46 @@
                 "url": "https://github.com/chalk/chalk?sponsor=1"
             }
         },
+        "node_modules/cheerio": {
+            "version": "1.0.0-rc.12",
+            "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+            "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "cheerio-select": "^2.1.0",
+                "dom-serializer": "^2.0.0",
+                "domhandler": "^5.0.3",
+                "domutils": "^3.0.1",
+                "htmlparser2": "^8.0.1",
+                "parse5": "^7.0.0",
+                "parse5-htmlparser2-tree-adapter": "^7.0.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+            }
+        },
+        "node_modules/cheerio-select": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+            "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-select": "^5.1.0",
+                "css-what": "^6.1.0",
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.3",
+                "domutils": "^3.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
         "node_modules/chokidar": {
             "version": "3.6.0",
             "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
@@ -2212,9 +2407,9 @@
             }
         },
         "node_modules/clsx": {
-            "version": "1.2.1",
-            "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
-            "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
+            "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
             "dev": true,
             "engines": {
                 "node": ">=6"
@@ -2424,9 +2619,9 @@
             "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
         },
         "node_modules/core-js": {
-            "version": "3.36.1",
-            "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.1.tgz",
-            "integrity": "sha512-BTvUrwxVBezj5SZ3f10ImnX2oRByMxql3EimVqMysepbC9EeMUOpLwdy6Eoili2x6E4kf+ZUB5k/+Jv55alPfA==",
+            "version": "3.37.1",
+            "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz",
+            "integrity": "sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==",
             "dev": true,
             "hasInstallScript": true,
             "funding": {
@@ -2492,6 +2687,23 @@
                 "node": ">=4"
             }
         },
+        "node_modules/css-select": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+            "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-what": "^6.1.0",
+                "domhandler": "^5.0.2",
+                "domutils": "^3.0.1",
+                "nth-check": "^2.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
         "node_modules/css-to-react-native": {
             "version": "3.2.0",
             "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
@@ -2503,10 +2715,23 @@
                 "postcss-value-parser": "^4.0.2"
             }
         },
+        "node_modules/css-what": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+            "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+            "dev": true,
+            "peer": true,
+            "engines": {
+                "node": ">= 6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
         "node_modules/csstype": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
-            "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+            "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
             "dev": true
         },
         "node_modules/cuint": {
@@ -2514,6 +2739,57 @@
             "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz",
             "integrity": "sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw=="
         },
+        "node_modules/data-view-buffer": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
+            "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.6",
+                "es-errors": "^1.3.0",
+                "is-data-view": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/data-view-byte-length": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
+            "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "es-errors": "^1.3.0",
+                "is-data-view": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/data-view-byte-offset": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
+            "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.6",
+                "es-errors": "^1.3.0",
+                "is-data-view": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/debounce-fn": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz",
@@ -2583,6 +2859,23 @@
                 "node": ">=8"
             }
         },
+        "node_modules/define-properties": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
+            "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
+            "dev": true,
+            "dependencies": {
+                "define-data-property": "^1.0.1",
+                "has-property-descriptors": "^1.0.0",
+                "object-keys": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/delayed-stream": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -2628,6 +2921,13 @@
                 "node": ">=8"
             }
         },
+        "node_modules/discontinuous-range": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz",
+            "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==",
+            "dev": true,
+            "peer": true
+        },
         "node_modules/doctrine": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
@@ -2640,12 +2940,71 @@
                 "node": ">=6.0.0"
             }
         },
+        "node_modules/dom-serializer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+            "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.2",
+                "entities": "^4.2.0"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+            }
+        },
+        "node_modules/domelementtype": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+            "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ],
+            "peer": true
+        },
+        "node_modules/domhandler": {
+            "version": "5.0.3",
+            "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+            "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "domelementtype": "^2.3.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domhandler?sponsor=1"
+            }
+        },
         "node_modules/dompurify": {
-            "version": "2.4.9",
-            "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.9.tgz",
-            "integrity": "sha512-iHtnxYMotKgOTvxIqq677JsKHvCOkAFqj9x8Mek2zdeHW1XjuFKwjpmZeMaXQRQ8AbJZDbcRz/+r1QhwvFtmQg==",
+            "version": "3.1.6",
+            "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz",
+            "integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==",
             "dev": true
         },
+        "node_modules/domutils": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+            "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "dom-serializer": "^2.0.0",
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.3"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domutils?sponsor=1"
+            }
+        },
         "node_modules/dot-prop": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
@@ -2671,6 +3030,30 @@
                 "url": "https://dotenvx.com"
             }
         },
+        "node_modules/dotenv-cli": {
+            "version": "7.4.2",
+            "resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-7.4.2.tgz",
+            "integrity": "sha512-SbUj8l61zIbzyhIbg0FwPJq6+wjbzdn9oEtozQpZ6kW2ihCcapKVZj49oCT3oPM+mgQm+itgvUQcG5szxVrZTA==",
+            "dev": true,
+            "dependencies": {
+                "cross-spawn": "^7.0.3",
+                "dotenv": "^16.3.0",
+                "dotenv-expand": "^10.0.0",
+                "minimist": "^1.2.6"
+            },
+            "bin": {
+                "dotenv": "cli.js"
+            }
+        },
+        "node_modules/dotenv-cli/node_modules/dotenv-expand": {
+            "version": "10.0.0",
+            "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-10.0.0.tgz",
+            "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==",
+            "dev": true,
+            "engines": {
+                "node": ">=12"
+            }
+        },
         "node_modules/dotenv-expand": {
             "version": "11.0.6",
             "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.6.tgz",
@@ -2749,6 +3132,19 @@
                 "node": ">= 0.8"
             }
         },
+        "node_modules/entities": {
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+            "dev": true,
+            "peer": true,
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
         "node_modules/env-paths": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
@@ -2757,6 +3153,120 @@
                 "node": ">=6"
             }
         },
+        "node_modules/enzyme": {
+            "version": "3.11.0",
+            "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz",
+            "integrity": "sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "array.prototype.flat": "^1.2.3",
+                "cheerio": "^1.0.0-rc.3",
+                "enzyme-shallow-equal": "^1.0.1",
+                "function.prototype.name": "^1.1.2",
+                "has": "^1.0.3",
+                "html-element-map": "^1.2.0",
+                "is-boolean-object": "^1.0.1",
+                "is-callable": "^1.1.5",
+                "is-number-object": "^1.0.4",
+                "is-regex": "^1.0.5",
+                "is-string": "^1.0.5",
+                "is-subset": "^0.1.1",
+                "lodash.escape": "^4.0.1",
+                "lodash.isequal": "^4.5.0",
+                "object-inspect": "^1.7.0",
+                "object-is": "^1.0.2",
+                "object.assign": "^4.1.0",
+                "object.entries": "^1.1.1",
+                "object.values": "^1.1.1",
+                "raf": "^3.4.1",
+                "rst-selector-parser": "^2.2.3",
+                "string.prototype.trim": "^1.2.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/enzyme-shallow-equal": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.7.tgz",
+            "integrity": "sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==",
+            "dev": true,
+            "dependencies": {
+                "hasown": "^2.0.0",
+                "object-is": "^1.1.5"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "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==",
+            "dev": true,
+            "dependencies": {
+                "array-buffer-byte-length": "^1.0.1",
+                "arraybuffer.prototype.slice": "^1.0.3",
+                "available-typed-arrays": "^1.0.7",
+                "call-bind": "^1.0.7",
+                "data-view-buffer": "^1.0.1",
+                "data-view-byte-length": "^1.0.1",
+                "data-view-byte-offset": "^1.0.0",
+                "es-define-property": "^1.0.0",
+                "es-errors": "^1.3.0",
+                "es-object-atoms": "^1.0.0",
+                "es-set-tostringtag": "^2.0.3",
+                "es-to-primitive": "^1.2.1",
+                "function.prototype.name": "^1.1.6",
+                "get-intrinsic": "^1.2.4",
+                "get-symbol-description": "^1.0.2",
+                "globalthis": "^1.0.3",
+                "gopd": "^1.0.1",
+                "has-property-descriptors": "^1.0.2",
+                "has-proto": "^1.0.3",
+                "has-symbols": "^1.0.3",
+                "hasown": "^2.0.2",
+                "internal-slot": "^1.0.7",
+                "is-array-buffer": "^3.0.4",
+                "is-callable": "^1.2.7",
+                "is-data-view": "^1.0.1",
+                "is-negative-zero": "^2.0.3",
+                "is-regex": "^1.1.4",
+                "is-shared-array-buffer": "^1.0.3",
+                "is-string": "^1.0.7",
+                "is-typed-array": "^1.1.13",
+                "is-weakref": "^1.0.2",
+                "object-inspect": "^1.13.1",
+                "object-keys": "^1.1.1",
+                "object.assign": "^4.1.5",
+                "regexp.prototype.flags": "^1.5.2",
+                "safe-array-concat": "^1.1.2",
+                "safe-regex-test": "^1.0.3",
+                "string.prototype.trim": "^1.2.9",
+                "string.prototype.trimend": "^1.0.8",
+                "string.prototype.trimstart": "^1.0.8",
+                "typed-array-buffer": "^1.0.2",
+                "typed-array-byte-length": "^1.0.1",
+                "typed-array-byte-offset": "^1.0.2",
+                "typed-array-length": "^1.0.6",
+                "unbox-primitive": "^1.0.2",
+                "which-typed-array": "^1.1.15"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/es-array-method-boxes-properly": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz",
+            "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==",
+            "dev": true,
+            "peer": true
+        },
         "node_modules/es-define-property": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
@@ -2776,6 +3286,59 @@
                 "node": ">= 0.4"
             }
         },
+        "node_modules/es-object-atoms": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
+            "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+            "dev": true,
+            "dependencies": {
+                "es-errors": "^1.3.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-set-tostringtag": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
+            "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+            "dev": true,
+            "dependencies": {
+                "get-intrinsic": "^1.2.4",
+                "has-tostringtag": "^1.0.2",
+                "hasown": "^2.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-shim-unscopables": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
+            "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "hasown": "^2.0.0"
+            }
+        },
+        "node_modules/es-to-primitive": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+            "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+            "dev": true,
+            "dependencies": {
+                "is-callable": "^1.1.4",
+                "is-date-object": "^1.0.1",
+                "is-symbol": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/es6-promise": {
             "version": "3.3.1",
             "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
@@ -2783,9 +3346,9 @@
             "dev": true
         },
         "node_modules/esbuild": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
-            "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+            "version": "0.21.5",
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
+            "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
             "dev": true,
             "hasInstallScript": true,
             "bin": {
@@ -2795,29 +3358,29 @@
                 "node": ">=12"
             },
             "optionalDependencies": {
-                "@esbuild/aix-ppc64": "0.20.2",
-                "@esbuild/android-arm": "0.20.2",
-                "@esbuild/android-arm64": "0.20.2",
-                "@esbuild/android-x64": "0.20.2",
-                "@esbuild/darwin-arm64": "0.20.2",
-                "@esbuild/darwin-x64": "0.20.2",
-                "@esbuild/freebsd-arm64": "0.20.2",
-                "@esbuild/freebsd-x64": "0.20.2",
-                "@esbuild/linux-arm": "0.20.2",
-                "@esbuild/linux-arm64": "0.20.2",
-                "@esbuild/linux-ia32": "0.20.2",
-                "@esbuild/linux-loong64": "0.20.2",
-                "@esbuild/linux-mips64el": "0.20.2",
-                "@esbuild/linux-ppc64": "0.20.2",
-                "@esbuild/linux-riscv64": "0.20.2",
-                "@esbuild/linux-s390x": "0.20.2",
-                "@esbuild/linux-x64": "0.20.2",
-                "@esbuild/netbsd-x64": "0.20.2",
-                "@esbuild/openbsd-x64": "0.20.2",
-                "@esbuild/sunos-x64": "0.20.2",
-                "@esbuild/win32-arm64": "0.20.2",
-                "@esbuild/win32-ia32": "0.20.2",
-                "@esbuild/win32-x64": "0.20.2"
+                "@esbuild/aix-ppc64": "0.21.5",
+                "@esbuild/android-arm": "0.21.5",
+                "@esbuild/android-arm64": "0.21.5",
+                "@esbuild/android-x64": "0.21.5",
+                "@esbuild/darwin-arm64": "0.21.5",
+                "@esbuild/darwin-x64": "0.21.5",
+                "@esbuild/freebsd-arm64": "0.21.5",
+                "@esbuild/freebsd-x64": "0.21.5",
+                "@esbuild/linux-arm": "0.21.5",
+                "@esbuild/linux-arm64": "0.21.5",
+                "@esbuild/linux-ia32": "0.21.5",
+                "@esbuild/linux-loong64": "0.21.5",
+                "@esbuild/linux-mips64el": "0.21.5",
+                "@esbuild/linux-ppc64": "0.21.5",
+                "@esbuild/linux-riscv64": "0.21.5",
+                "@esbuild/linux-s390x": "0.21.5",
+                "@esbuild/linux-x64": "0.21.5",
+                "@esbuild/netbsd-x64": "0.21.5",
+                "@esbuild/openbsd-x64": "0.21.5",
+                "@esbuild/sunos-x64": "0.21.5",
+                "@esbuild/win32-arm64": "0.21.5",
+                "@esbuild/win32-ia32": "0.21.5",
+                "@esbuild/win32-x64": "0.21.5"
             }
         },
         "node_modules/escalade": {
@@ -3085,9 +3648,9 @@
             }
         },
         "node_modules/eventemitter3": {
-            "version": "4.0.7",
-            "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
-            "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+            "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
             "dev": true
         },
         "node_modules/execa": {
@@ -3402,6 +3965,15 @@
                 }
             }
         },
+        "node_modules/for-each": {
+            "version": "0.3.3",
+            "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+            "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+            "dev": true,
+            "dependencies": {
+                "is-callable": "^1.1.3"
+            }
+        },
         "node_modules/foreach": {
             "version": "2.0.6",
             "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz",
@@ -3480,6 +4052,33 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/function.prototype.name": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
+            "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "define-properties": "^1.2.0",
+                "es-abstract": "^1.22.1",
+                "functions-have-names": "^1.2.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/functions-have-names": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
+            "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+            "dev": true,
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/genversion": {
             "version": "3.2.0",
             "resolved": "https://registry.npmjs.org/genversion/-/genversion-3.2.0.tgz",
@@ -3550,6 +4149,23 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/get-symbol-description": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
+            "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.5",
+                "es-errors": "^1.3.0",
+                "get-intrinsic": "^1.2.4"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/get-tsconfig": {
             "version": "4.7.5",
             "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz",
@@ -3636,6 +4252,22 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/globalthis": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
+            "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
+            "dev": true,
+            "dependencies": {
+                "define-properties": "^1.2.1",
+                "gopd": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/globby": {
             "version": "11.1.0",
             "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -3694,6 +4326,24 @@
                 "uglify-js": "^3.1.4"
             }
         },
+        "node_modules/has": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
+            "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/has-bigints": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
+            "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+            "dev": true,
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/has-flag": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -3735,6 +4385,21 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/has-tostringtag": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+            "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+            "dev": true,
+            "dependencies": {
+                "has-symbols": "^1.0.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/hasown": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
@@ -3754,6 +4419,40 @@
                 "node": ">=16.0.0"
             }
         },
+        "node_modules/html-element-map": {
+            "version": "1.3.1",
+            "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.1.tgz",
+            "integrity": "sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "array.prototype.filter": "^1.0.0",
+                "call-bind": "^1.0.2"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/htmlparser2": {
+            "version": "8.0.2",
+            "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+            "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+            "dev": true,
+            "funding": [
+                "https://github.com/fb55/htmlparser2?sponsor=1",
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ],
+            "peer": true,
+            "dependencies": {
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.3",
+                "domutils": "^3.0.1",
+                "entities": "^4.4.0"
+            }
+        },
         "node_modules/http-errors": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -3780,6 +4479,42 @@
             "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==",
             "dev": true
         },
+        "node_modules/https-proxy-agent": {
+            "version": "7.0.5",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz",
+            "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==",
+            "dev": true,
+            "dependencies": {
+                "agent-base": "^7.0.2",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/https-proxy-agent/node_modules/debug": {
+            "version": "4.3.5",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
+            "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+            "dev": true,
+            "dependencies": {
+                "ms": "2.1.2"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/https-proxy-agent/node_modules/ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+            "dev": true
+        },
         "node_modules/human-signals": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
@@ -3872,6 +4607,20 @@
             "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
             "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
         },
+        "node_modules/internal-slot": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
+            "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
+            "dev": true,
+            "dependencies": {
+                "es-errors": "^1.3.0",
+                "hasown": "^2.0.0",
+                "side-channel": "^1.0.4"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/ipaddr.js": {
             "version": "1.9.1",
             "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -3880,11 +4629,39 @@
                 "node": ">= 0.10"
             }
         },
+        "node_modules/is-array-buffer": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
+            "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "get-intrinsic": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-arrayish": {
             "version": "0.3.2",
             "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
             "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
         },
+        "node_modules/is-bigint": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
+            "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+            "dev": true,
+            "dependencies": {
+                "has-bigints": "^1.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-binary-path": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -3897,6 +4674,64 @@
                 "node": ">=8"
             }
         },
+        "node_modules/is-boolean-object": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
+            "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "has-tostringtag": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-callable": {
+            "version": "1.2.7",
+            "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+            "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-data-view": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
+            "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+            "dev": true,
+            "dependencies": {
+                "is-typed-array": "^1.1.13"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-date-object": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
+            "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+            "dev": true,
+            "dependencies": {
+                "has-tostringtag": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-docker": {
             "version": "2.2.1",
             "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
@@ -3948,6 +4783,18 @@
                 "node": ">=8"
             }
         },
+        "node_modules/is-negative-zero": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
+            "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-number": {
             "version": "7.0.0",
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -3957,6 +4804,21 @@
                 "node": ">=0.12.0"
             }
         },
+        "node_modules/is-number-object": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
+            "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+            "dev": true,
+            "dependencies": {
+                "has-tostringtag": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-obj": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
@@ -3974,6 +4836,37 @@
                 "node": ">=8"
             }
         },
+        "node_modules/is-regex": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
+            "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "has-tostringtag": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-shared-array-buffer": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
+            "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-stream": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
@@ -3985,6 +4878,58 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/is-string": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
+            "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+            "dev": true,
+            "dependencies": {
+                "has-tostringtag": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-subset": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
+            "integrity": "sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==",
+            "dev": true,
+            "peer": true
+        },
+        "node_modules/is-symbol": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
+            "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+            "dev": true,
+            "dependencies": {
+                "has-symbols": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/is-typed-array": {
+            "version": "1.1.13",
+            "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
+            "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+            "dev": true,
+            "dependencies": {
+                "which-typed-array": "^1.1.14"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-unicode-supported": {
             "version": "0.1.0",
             "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
@@ -3996,6 +4941,18 @@
                 "url": "https://github.com/sponsors/sindresorhus"
             }
         },
+        "node_modules/is-weakref": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
+            "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.2"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/is-wsl": {
             "version": "2.2.0",
             "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@@ -4238,6 +5195,20 @@
             "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
             "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
         },
+        "node_modules/lodash.escape": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-4.0.1.tgz",
+            "integrity": "sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==",
+            "dev": true,
+            "peer": true
+        },
+        "node_modules/lodash.flattendeep": {
+            "version": "4.4.0",
+            "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+            "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==",
+            "dev": true,
+            "peer": true
+        },
         "node_modules/lodash.includes": {
             "version": "4.3.0",
             "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
@@ -4491,9 +5462,9 @@
             }
         },
         "node_modules/mobx": {
-            "version": "6.12.3",
-            "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.12.3.tgz",
-            "integrity": "sha512-c8NKkO4R2lShkSXZ2Ongj1ycjugjzFFo/UswHBnS62y07DMcTc9Rvo03/3nRyszIvwPNljlkd4S828zIBv/piw==",
+            "version": "6.13.0",
+            "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.13.0.tgz",
+            "integrity": "sha512-1laWODrBWmB7mDJ8EClCjUQTyLwJ0ydJgE4FtK7t9r3JnjXgc9OhmYs2P4RtHrY1co5+4T6cKP2UswX2SU29mA==",
             "dev": true,
             "funding": {
                 "type": "opencollective",
@@ -4501,19 +5472,19 @@
             }
         },
         "node_modules/mobx-react": {
-            "version": "7.6.0",
-            "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-7.6.0.tgz",
-            "integrity": "sha512-+HQUNuh7AoQ9ZnU6c4rvbiVVl+wEkb9WqYsVDzGLng+Dqj1XntHu79PvEWKtSMoMj67vFp/ZPXcElosuJO8ckA==",
+            "version": "9.1.1",
+            "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.1.1.tgz",
+            "integrity": "sha512-gVV7AdSrAAxqXOJ2bAbGa5TkPqvITSzaPiiEkzpW4rRsMhSec7C2NBCJYILADHKp2tzOAIETGRsIY0UaCV5aEw==",
             "dev": true,
             "dependencies": {
-                "mobx-react-lite": "^3.4.0"
+                "mobx-react-lite": "^4.0.7"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/mobx"
             },
             "peerDependencies": {
-                "mobx": "^6.1.0",
+                "mobx": "^6.9.0",
                 "react": "^16.8.0 || ^17 || ^18"
             },
             "peerDependenciesMeta": {
@@ -4526,16 +5497,19 @@
             }
         },
         "node_modules/mobx-react-lite": {
-            "version": "3.4.3",
-            "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-3.4.3.tgz",
-            "integrity": "sha512-NkJREyFTSUXR772Qaai51BnE1voWx56LOL80xG7qkZr6vo8vEaLF3sz1JNUVh+rxmUzxYaqOhfuxTfqUh0FXUg==",
+            "version": "4.0.7",
+            "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz",
+            "integrity": "sha512-RjwdseshK9Mg8On5tyJZHtGD+J78ZnCnRaxeQDSiciKVQDUbfZcXhmld0VMxAwvcTnPEHZySGGewm467Fcpreg==",
             "dev": true,
+            "dependencies": {
+                "use-sync-external-store": "^1.2.0"
+            },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/mobx"
             },
             "peerDependencies": {
-                "mobx": "^6.1.0",
+                "mobx": "^6.9.0",
                 "react": "^16.8.0 || ^17 || ^18"
             },
             "peerDependenciesMeta": {
@@ -4547,6 +5521,13 @@
                 }
             }
         },
+        "node_modules/moo": {
+            "version": "0.5.2",
+            "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
+            "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
+            "dev": true,
+            "peer": true
+        },
         "node_modules/morgan": {
             "version": "1.10.0",
             "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz",
@@ -4655,6 +5636,36 @@
             "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
             "dev": true
         },
+        "node_modules/nearley": {
+            "version": "2.20.1",
+            "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz",
+            "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "commander": "^2.19.0",
+                "moo": "^0.5.0",
+                "railroad-diagrams": "^1.0.0",
+                "randexp": "0.4.6"
+            },
+            "bin": {
+                "nearley-railroad": "bin/nearley-railroad.js",
+                "nearley-test": "bin/nearley-test.js",
+                "nearley-unparse": "bin/nearley-unparse.js",
+                "nearleyc": "bin/nearleyc.js"
+            },
+            "funding": {
+                "type": "individual",
+                "url": "https://nearley.js.org/#give-to-nearley"
+            }
+        },
+        "node_modules/nearley/node_modules/commander": {
+            "version": "2.20.3",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+            "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+            "dev": true,
+            "peer": true
+        },
         "node_modules/negotiator": {
             "version": "0.6.3",
             "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@@ -4670,9 +5681,9 @@
             "dev": true
         },
         "node_modules/node": {
-            "version": "20.12.0",
-            "resolved": "https://registry.npmjs.org/node/-/node-20.12.0.tgz",
-            "integrity": "sha512-2Mk6hEMKBXh6KdiG1DHqI68EU7fEvF6icNJ0/ormVXTv1SXii3tLaIObhUEmCBv15qob23n0yoFPmB6CEos5/Q==",
+            "version": "20.15.0",
+            "resolved": "https://registry.npmjs.org/node/-/node-20.15.0.tgz",
+            "integrity": "sha512-zsJ9aOJAKhnR9rJ4BBfGmgiBmG3ZlLXLZ4jBjshPib+S8qKSY+ggBvphceT5gHF1X7KB4UP1ImU/A4EYr31Y2g==",
             "hasInstallScript": true,
             "dependencies": {
                 "node-bin-setup": "^1.0.0"
@@ -4731,9 +5742,9 @@
             }
         },
         "node_modules/nodemon": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.1.tgz",
-            "integrity": "sha512-k43xGaDtaDIcufn0Fc6fTtsdKSkV/hQzoQFigNH//GaKta28yoKVYXCnV+KXRqfT/YzsFaQU9VdeEG+HEyxr6A==",
+            "version": "3.1.4",
+            "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.4.tgz",
+            "integrity": "sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==",
             "dev": true,
             "dependencies": {
                 "chokidar": "^3.5.2",
@@ -4849,9 +5860,9 @@
             }
         },
         "node_modules/npm": {
-            "version": "10.8.0",
-            "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.0.tgz",
-            "integrity": "sha512-wh93uRczgp7HDnPMiLXcCkv2hagdJS0zJ9KT/31d0FoXP02+qgN2AOwpaW85fxRWkinl2rELfPw+CjBXW48/jQ==",
+            "version": "10.8.1",
+            "resolved": "https://registry.npmjs.org/npm/-/npm-10.8.1.tgz",
+            "integrity": "sha512-Dp1C6SvSMYQI7YHq/y2l94uvI+59Eqbu1EpuKQHQ8p16txXRuRit5gH3Lnaagk2aXDIjg/Iru9pd05bnneKgdw==",
             "bundleDependencies": [
                 "@isaacs/string-locale-compare",
                 "@npmcli/arborist",
@@ -4932,15 +5943,15 @@
             ],
             "dependencies": {
                 "@isaacs/string-locale-compare": "^1.1.0",
-                "@npmcli/arborist": "^7.5.2",
-                "@npmcli/config": "^8.3.2",
+                "@npmcli/arborist": "^7.5.3",
+                "@npmcli/config": "^8.3.3",
                 "@npmcli/fs": "^3.1.1",
                 "@npmcli/map-workspaces": "^3.0.6",
-                "@npmcli/package-json": "^5.1.0",
+                "@npmcli/package-json": "^5.1.1",
                 "@npmcli/promise-spawn": "^7.0.2",
                 "@npmcli/redact": "^2.0.0",
                 "@npmcli/run-script": "^8.1.0",
-                "@sigstore/tuf": "^2.3.3",
+                "@sigstore/tuf": "^2.3.4",
                 "abbrev": "^2.0.0",
                 "archy": "~1.0.0",
                 "cacache": "^18.0.3",
@@ -4949,24 +5960,24 @@
                 "cli-columns": "^4.0.0",
                 "fastest-levenshtein": "^1.0.16",
                 "fs-minipass": "^3.0.3",
-                "glob": "^10.3.15",
+                "glob": "^10.4.1",
                 "graceful-fs": "^4.2.11",
                 "hosted-git-info": "^7.0.2",
-                "ini": "^4.1.2",
+                "ini": "^4.1.3",
                 "init-package-json": "^6.0.3",
-                "is-cidr": "^5.0.5",
+                "is-cidr": "^5.1.0",
                 "json-parse-even-better-errors": "^3.0.2",
                 "libnpmaccess": "^8.0.6",
-                "libnpmdiff": "^6.1.2",
-                "libnpmexec": "^8.1.1",
-                "libnpmfund": "^5.0.10",
+                "libnpmdiff": "^6.1.3",
+                "libnpmexec": "^8.1.2",
+                "libnpmfund": "^5.0.11",
                 "libnpmhook": "^10.0.5",
                 "libnpmorg": "^6.0.6",
-                "libnpmpack": "^7.0.2",
-                "libnpmpublish": "^9.0.8",
-                "libnpmsearch": "^7.0.5",
+                "libnpmpack": "^7.0.3",
+                "libnpmpublish": "^9.0.9",
+                "libnpmsearch": "^7.0.6",
                 "libnpmteam": "^6.0.5",
-                "libnpmversion": "^6.0.2",
+                "libnpmversion": "^6.0.3",
                 "make-fetch-happen": "^13.0.1",
                 "minimatch": "^9.0.4",
                 "minipass": "^7.1.1",
@@ -5109,7 +6120,7 @@
             }
         },
         "node_modules/npm/node_modules/@npmcli/arborist": {
-            "version": "7.5.2",
+            "version": "7.5.3",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -5158,7 +6169,7 @@
             }
         },
         "node_modules/npm/node_modules/@npmcli/config": {
-            "version": "8.3.2",
+            "version": "8.3.3",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -5273,7 +6284,7 @@
             }
         },
         "node_modules/npm/node_modules/@npmcli/package-json": {
-            "version": "5.1.0",
+            "version": "5.1.1",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -5351,12 +6362,12 @@
             }
         },
         "node_modules/npm/node_modules/@sigstore/bundle": {
-            "version": "2.3.1",
+            "version": "2.3.2",
             "dev": true,
             "inBundle": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@sigstore/protobuf-specs": "^0.3.1"
+                "@sigstore/protobuf-specs": "^0.3.2"
             },
             "engines": {
                 "node": "^16.14.0 || >=18.0.0"
@@ -5381,14 +6392,14 @@
             }
         },
         "node_modules/npm/node_modules/@sigstore/sign": {
-            "version": "2.3.1",
+            "version": "2.3.2",
             "dev": true,
             "inBundle": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@sigstore/bundle": "^2.3.0",
+                "@sigstore/bundle": "^2.3.2",
                 "@sigstore/core": "^1.0.0",
-                "@sigstore/protobuf-specs": "^0.3.1",
+                "@sigstore/protobuf-specs": "^0.3.2",
                 "make-fetch-happen": "^13.0.1",
                 "proc-log": "^4.2.0",
                 "promise-retry": "^2.0.1"
@@ -5398,12 +6409,12 @@
             }
         },
         "node_modules/npm/node_modules/@sigstore/tuf": {
-            "version": "2.3.3",
+            "version": "2.3.4",
             "dev": true,
             "inBundle": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@sigstore/protobuf-specs": "^0.3.0",
+                "@sigstore/protobuf-specs": "^0.3.2",
                 "tuf-js": "^2.2.1"
             },
             "engines": {
@@ -5411,14 +6422,14 @@
             }
         },
         "node_modules/npm/node_modules/@sigstore/verify": {
-            "version": "1.2.0",
+            "version": "1.2.1",
             "dev": true,
             "inBundle": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@sigstore/bundle": "^2.3.1",
+                "@sigstore/bundle": "^2.3.2",
                 "@sigstore/core": "^1.1.0",
-                "@sigstore/protobuf-specs": "^0.3.1"
+                "@sigstore/protobuf-specs": "^0.3.2"
             },
             "engines": {
                 "node": "^16.14.0 || >=18.0.0"
@@ -5615,7 +6626,7 @@
             }
         },
         "node_modules/npm/node_modules/cidr-regex": {
-            "version": "4.0.5",
+            "version": "4.1.1",
             "dev": true,
             "inBundle": true,
             "license": "BSD-2-Clause",
@@ -5844,16 +6855,16 @@
             }
         },
         "node_modules/npm/node_modules/glob": {
-            "version": "10.3.15",
+            "version": "10.4.1",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
             "dependencies": {
                 "foreground-child": "^3.1.0",
-                "jackspeak": "^2.3.6",
-                "minimatch": "^9.0.1",
-                "minipass": "^7.0.4",
-                "path-scurry": "^1.11.0"
+                "jackspeak": "^3.1.2",
+                "minimatch": "^9.0.4",
+                "minipass": "^7.1.2",
+                "path-scurry": "^1.11.1"
             },
             "bin": {
                 "glob": "dist/esm/bin.mjs"
@@ -5971,7 +6982,7 @@
             }
         },
         "node_modules/npm/node_modules/ini": {
-            "version": "4.1.2",
+            "version": "4.1.3",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -6023,12 +7034,12 @@
             }
         },
         "node_modules/npm/node_modules/is-cidr": {
-            "version": "5.0.5",
+            "version": "5.1.0",
             "dev": true,
             "inBundle": true,
             "license": "BSD-2-Clause",
             "dependencies": {
-                "cidr-regex": "^4.0.4"
+                "cidr-regex": "^4.1.1"
             },
             "engines": {
                 "node": ">=14"
@@ -6068,7 +7079,7 @@
             "license": "ISC"
         },
         "node_modules/npm/node_modules/jackspeak": {
-            "version": "2.3.6",
+            "version": "3.1.2",
             "dev": true,
             "inBundle": true,
             "license": "BlueOak-1.0.0",
@@ -6144,12 +7155,12 @@
             }
         },
         "node_modules/npm/node_modules/libnpmdiff": {
-            "version": "6.1.2",
+            "version": "6.1.3",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
             "dependencies": {
-                "@npmcli/arborist": "^7.5.2",
+                "@npmcli/arborist": "^7.5.3",
                 "@npmcli/installed-package-contents": "^2.1.0",
                 "binary-extensions": "^2.3.0",
                 "diff": "^5.1.0",
@@ -6163,12 +7174,12 @@
             }
         },
         "node_modules/npm/node_modules/libnpmexec": {
-            "version": "8.1.1",
+            "version": "8.1.2",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
             "dependencies": {
-                "@npmcli/arborist": "^7.5.2",
+                "@npmcli/arborist": "^7.5.3",
                 "@npmcli/run-script": "^8.1.0",
                 "ci-info": "^4.0.0",
                 "npm-package-arg": "^11.0.2",
@@ -6184,12 +7195,12 @@
             }
         },
         "node_modules/npm/node_modules/libnpmfund": {
-            "version": "5.0.10",
+            "version": "5.0.11",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
             "dependencies": {
-                "@npmcli/arborist": "^7.5.2"
+                "@npmcli/arborist": "^7.5.3"
             },
             "engines": {
                 "node": "^16.14.0 || >=18.0.0"
@@ -6222,12 +7233,12 @@
             }
         },
         "node_modules/npm/node_modules/libnpmpack": {
-            "version": "7.0.2",
+            "version": "7.0.3",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
             "dependencies": {
-                "@npmcli/arborist": "^7.5.2",
+                "@npmcli/arborist": "^7.5.3",
                 "@npmcli/run-script": "^8.1.0",
                 "npm-package-arg": "^11.0.2",
                 "pacote": "^18.0.6"
@@ -6237,7 +7248,7 @@
             }
         },
         "node_modules/npm/node_modules/libnpmpublish": {
-            "version": "9.0.8",
+            "version": "9.0.9",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -6256,7 +7267,7 @@
             }
         },
         "node_modules/npm/node_modules/libnpmsearch": {
-            "version": "7.0.5",
+            "version": "7.0.6",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -6281,7 +7292,7 @@
             }
         },
         "node_modules/npm/node_modules/libnpmversion": {
-            "version": "6.0.2",
+            "version": "6.0.3",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -6344,7 +7355,7 @@
             }
         },
         "node_modules/npm/node_modules/minipass": {
-            "version": "7.1.1",
+            "version": "7.1.2",
             "dev": true,
             "inBundle": true,
             "license": "ISC",
@@ -6810,7 +7821,7 @@
             }
         },
         "node_modules/npm/node_modules/postcss-selector-parser": {
-            "version": "6.0.16",
+            "version": "6.1.0",
             "dev": true,
             "inBundle": true,
             "license": "MIT",
@@ -6993,17 +8004,17 @@
             }
         },
         "node_modules/npm/node_modules/sigstore": {
-            "version": "2.3.0",
+            "version": "2.3.1",
             "dev": true,
             "inBundle": true,
             "license": "Apache-2.0",
             "dependencies": {
-                "@sigstore/bundle": "^2.3.1",
+                "@sigstore/bundle": "^2.3.2",
                 "@sigstore/core": "^1.0.0",
-                "@sigstore/protobuf-specs": "^0.3.1",
-                "@sigstore/sign": "^2.3.0",
-                "@sigstore/tuf": "^2.3.1",
-                "@sigstore/verify": "^1.2.0"
+                "@sigstore/protobuf-specs": "^0.3.2",
+                "@sigstore/sign": "^2.3.2",
+                "@sigstore/tuf": "^2.3.4",
+                "@sigstore/verify": "^1.2.1"
             },
             "engines": {
                 "node": "^16.14.0 || >=18.0.0"
@@ -7084,7 +8095,7 @@
             }
         },
         "node_modules/npm/node_modules/spdx-license-ids": {
-            "version": "3.0.17",
+            "version": "3.0.18",
             "dev": true,
             "inBundle": true,
             "license": "CC0-1.0"
@@ -7466,6 +8477,19 @@
             "inBundle": true,
             "license": "ISC"
         },
+        "node_modules/nth-check": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+            "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "boolbase": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/nth-check?sponsor=1"
+            }
+        },
         "node_modules/oas-kit-common": {
             "version": "1.0.8",
             "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz",
@@ -7552,12 +8576,88 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
-        "node_modules/object-treeify": {
-            "version": "1.1.33",
-            "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz",
-            "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==",
+        "node_modules/object-is": {
+            "version": "1.1.6",
+            "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
+            "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "define-properties": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/object-keys": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+            "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/object-treeify": {
+            "version": "1.1.33",
+            "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz",
+            "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==",
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/object.assign": {
+            "version": "4.1.5",
+            "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
+            "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.5",
+                "define-properties": "^1.2.1",
+                "has-symbols": "^1.0.3",
+                "object-keys": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/object.entries": {
+            "version": "1.1.8",
+            "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz",
+            "integrity": "sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "define-properties": "^1.2.1",
+                "es-object-atoms": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/object.values": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
+            "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "define-properties": "^1.2.1",
+                "es-object-atoms": "^1.0.0"
+            },
             "engines": {
-                "node": ">= 10"
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
             }
         },
         "node_modules/on-finished": {
@@ -7635,9 +8735,9 @@
             }
         },
         "node_modules/openapi-sampler": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.4.0.tgz",
-            "integrity": "sha512-3FKJQCHAMG9T7RsRy9u5Ft4ERPq1QQmn77C8T3OSofYL9uur59AqychvQ0YQKijrqRwIkAbzkh+nQnAE3gjMVA==",
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.5.1.tgz",
+            "integrity": "sha512-tIWIrZUKNAsbqf3bd9U1oH6JEXo8LNYuDlXw26By67EygpjT+ArFnsxxyTMjFWRfbqo5ozkvgSQDK69Gd8CddA==",
             "dev": true,
             "dependencies": {
                 "@types/json-schema": "^7.0.7",
@@ -7750,6 +8850,33 @@
                 "xtend": "~4.0.1"
             }
         },
+        "node_modules/parse5": {
+            "version": "7.1.2",
+            "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+            "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "entities": "^4.4.0"
+            },
+            "funding": {
+                "url": "https://github.com/inikulin/parse5?sponsor=1"
+            }
+        },
+        "node_modules/parse5-htmlparser2-tree-adapter": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+            "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "domhandler": "^5.0.2",
+                "parse5": "^7.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/inikulin/parse5?sponsor=1"
+            }
+        },
         "node_modules/parseurl": {
             "version": "1.3.3",
             "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -7834,10 +8961,17 @@
             "integrity": "sha512-dzalfutyP3e/FOpdlhVryN4AJ5XDVauVWxybSkLZmakFE2sS3y3pc4JnSprw8tGmHvkaG5Edr5T7LBTZ+WWU2g==",
             "dev": true
         },
+        "node_modules/performance-now": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+            "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
+            "dev": true,
+            "peer": true
+        },
         "node_modules/picocolors": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-            "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+            "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
             "dev": true
         },
         "node_modules/picomatch": {
@@ -7951,10 +9085,19 @@
                 "node": ">=10"
             }
         },
+        "node_modules/possible-typed-array-names": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
+            "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/postcss": {
-            "version": "8.4.31",
-            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
-            "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==",
+            "version": "8.4.38",
+            "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
+            "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
             "dev": true,
             "funding": [
                 {
@@ -7971,9 +9114,9 @@
                 }
             ],
             "dependencies": {
-                "nanoid": "^3.3.6",
+                "nanoid": "^3.3.7",
                 "picocolors": "^1.0.0",
-                "source-map-js": "^1.0.2"
+                "source-map-js": "^1.2.0"
             },
             "engines": {
                 "node": "^10 || ^12 || >=14"
@@ -7995,13 +9138,13 @@
             }
         },
         "node_modules/prisma": {
-            "version": "5.14.0",
-            "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.14.0.tgz",
-            "integrity": "sha512-gCNZco7y5XtjrnQYeDJTiVZmT/ncqCr5RY1/Cf8X2wgLRmyh9ayPAGBNziI4qEE4S6SxCH5omQLVo9lmURaJ/Q==",
+            "version": "5.16.1",
+            "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.16.1.tgz",
+            "integrity": "sha512-Z1Uqodk44diztImxALgJJfNl2Uisl9xDRvqybMKEBYJLNKNhDfAHf+ZIJbZyYiBhLMbKU9cYGdDVG5IIXEnL2Q==",
             "devOptional": true,
             "hasInstallScript": true,
             "dependencies": {
-                "@prisma/engines": "5.14.0"
+                "@prisma/engines": "5.16.1"
             },
             "bin": {
                 "prisma": "build/index.js"
@@ -8035,6 +9178,12 @@
                 "react-is": "^16.13.1"
             }
         },
+        "node_modules/prop-types/node_modules/react-is": {
+            "version": "16.13.1",
+            "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+            "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+            "dev": true
+        },
         "node_modules/proxy-addr": {
             "version": "2.0.7",
             "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -8105,6 +9254,37 @@
             "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
             "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
         },
+        "node_modules/raf": {
+            "version": "3.4.1",
+            "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
+            "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "performance-now": "^2.1.0"
+            }
+        },
+        "node_modules/railroad-diagrams": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz",
+            "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==",
+            "dev": true,
+            "peer": true
+        },
+        "node_modules/randexp": {
+            "version": "0.4.6",
+            "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz",
+            "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "discontinuous-range": "1.0.0",
+                "ret": "~0.1.10"
+            },
+            "engines": {
+                "node": ">=0.12"
+            }
+        },
         "node_modules/randombytes": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -8150,9 +9330,9 @@
             }
         },
         "node_modules/react": {
-            "version": "18.2.0",
-            "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
-            "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+            "version": "18.3.1",
+            "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
+            "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
             "dev": true,
             "dependencies": {
                 "loose-envify": "^1.1.0"
@@ -8162,35 +9342,48 @@
             }
         },
         "node_modules/react-dom": {
-            "version": "18.2.0",
-            "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
-            "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+            "version": "18.3.1",
+            "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
+            "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
             "dev": true,
             "dependencies": {
                 "loose-envify": "^1.1.0",
-                "scheduler": "^0.23.0"
+                "scheduler": "^0.23.2"
             },
             "peerDependencies": {
-                "react": "^18.2.0"
+                "react": "^18.3.1"
             }
         },
         "node_modules/react-is": {
-            "version": "16.13.1",
-            "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
-            "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+            "version": "18.3.1",
+            "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+            "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
             "dev": true
         },
+        "node_modules/react-shallow-renderer": {
+            "version": "16.15.0",
+            "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
+            "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==",
+            "dev": true,
+            "dependencies": {
+                "object-assign": "^4.1.1",
+                "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0"
+            },
+            "peerDependencies": {
+                "react": "^16.0.0 || ^17.0.0 || ^18.0.0"
+            }
+        },
         "node_modules/react-tabs": {
-            "version": "4.3.0",
-            "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-4.3.0.tgz",
-            "integrity": "sha512-2GfoG+f41kiBIIyd3gF+/GRCCYtamC8/2zlAcD8cqQmqI9Q+YVz7fJLHMmU9pXDVYYHpJeCgUSBJju85vu5q8Q==",
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.0.2.tgz",
+            "integrity": "sha512-aQXTKolnM28k3KguGDBSAbJvcowOQr23A+CUJdzJtOSDOtTwzEaJA+1U4KwhNL9+Obe+jFS7geuvA7ICQPXOnQ==",
             "dev": true,
             "dependencies": {
-                "clsx": "^1.1.0",
+                "clsx": "^2.0.0",
                 "prop-types": "^15.5.0"
             },
             "peerDependencies": {
-                "react": "^16.8.0 || ^17.0.0-0 || ^18.0.0"
+                "react": "^18.0.0"
             }
         },
         "node_modules/readable-stream": {
@@ -8220,31 +9413,32 @@
             }
         },
         "node_modules/redoc": {
-            "version": "2.1.3",
-            "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.1.3.tgz",
-            "integrity": "sha512-d7F9qLLxaiFW4GC03VkwlX9wuRIpx9aiIIf3o6mzMnqPfhxrn2IRKGndrkJeVdItgCfmg9jXZiFEowm60f1meQ==",
+            "version": "2.1.5",
+            "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.1.5.tgz",
+            "integrity": "sha512-POSbVg+7WLf+/5/c6GWLxL7+9t2D+1WlZdLN0a6qaCQc+ih3XYzteRBkXEN5kjrYrRNjdspfxTZkDLN5WV3Tzg==",
             "dev": true,
             "dependencies": {
-                "@redocly/openapi-core": "^1.0.0-rc.2",
-                "classnames": "^2.3.1",
+                "@cfaester/enzyme-adapter-react-18": "^0.8.0",
+                "@redocly/openapi-core": "^1.4.0",
+                "classnames": "^2.3.2",
                 "decko": "^1.2.0",
-                "dompurify": "^2.2.8",
-                "eventemitter3": "^4.0.7",
+                "dompurify": "^3.0.6",
+                "eventemitter3": "^5.0.1",
                 "json-pointer": "^0.6.2",
                 "lunr": "^2.3.9",
                 "mark.js": "^8.11.1",
-                "marked": "^4.0.15",
-                "mobx-react": "^7.2.0",
-                "openapi-sampler": "^1.3.1",
+                "marked": "^4.3.0",
+                "mobx-react": "^9.1.1",
+                "openapi-sampler": "^1.5.0",
                 "path-browserify": "^1.0.1",
                 "perfect-scrollbar": "^1.5.5",
-                "polished": "^4.1.3",
-                "prismjs": "^1.27.0",
-                "prop-types": "^15.7.2",
-                "react-tabs": "^4.3.0",
+                "polished": "^4.2.2",
+                "prismjs": "^1.29.0",
+                "prop-types": "^15.8.1",
+                "react-tabs": "^6.0.2",
                 "slugify": "~1.4.7",
                 "stickyfill": "^1.1.1",
-                "swagger2openapi": "^7.0.6",
+                "swagger2openapi": "^7.0.8",
                 "url-template": "^2.0.8"
             },
             "engines": {
@@ -8274,6 +9468,24 @@
             "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
             "dev": true
         },
+        "node_modules/regexp.prototype.flags": {
+            "version": "1.5.2",
+            "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
+            "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.6",
+                "define-properties": "^1.2.1",
+                "es-errors": "^1.3.0",
+                "set-function-name": "^2.0.1"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/require-directory": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -8326,6 +9538,16 @@
             "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
             "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
         },
+        "node_modules/ret": {
+            "version": "0.1.15",
+            "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+            "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+            "dev": true,
+            "peer": true,
+            "engines": {
+                "node": ">=0.12"
+            }
+        },
         "node_modules/reusify": {
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
@@ -8393,6 +9615,17 @@
                 "node": "*"
             }
         },
+        "node_modules/rst-selector-parser": {
+            "version": "2.2.3",
+            "resolved": "https://registry.npmjs.org/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz",
+            "integrity": "sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==",
+            "dev": true,
+            "peer": true,
+            "dependencies": {
+                "lodash.flattendeep": "^4.4.0",
+                "nearley": "^2.7.10"
+            }
+        },
         "node_modules/run-async": {
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz",
@@ -8424,11 +9657,52 @@
                 "queue-microtask": "^1.2.2"
             }
         },
+        "node_modules/safe-array-concat": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
+            "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "get-intrinsic": "^1.2.4",
+                "has-symbols": "^1.0.3",
+                "isarray": "^2.0.5"
+            },
+            "engines": {
+                "node": ">=0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/safe-array-concat/node_modules/isarray": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+            "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+            "dev": true
+        },
         "node_modules/safe-buffer": {
             "version": "5.1.2",
             "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
             "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
         },
+        "node_modules/safe-regex-test": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
+            "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.6",
+                "es-errors": "^1.3.0",
+                "is-regex": "^1.1.4"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/safe-stable-stringify": {
             "version": "2.4.3",
             "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
@@ -8443,9 +9717,9 @@
             "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
         },
         "node_modules/scheduler": {
-            "version": "0.23.0",
-            "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
-            "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+            "version": "0.23.2",
+            "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
+            "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
             "dev": true,
             "dependencies": {
                 "loose-envify": "^1.1.0"
@@ -8520,6 +9794,21 @@
                 "node": ">= 0.4"
             }
         },
+        "node_modules/set-function-name": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
+            "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+            "dev": true,
+            "dependencies": {
+                "define-data-property": "^1.1.4",
+                "es-errors": "^1.3.0",
+                "functions-have-names": "^1.2.3",
+                "has-property-descriptors": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/setprototypeof": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
@@ -8837,6 +10126,55 @@
                 "node": ">=8"
             }
         },
+        "node_modules/string.prototype.trim": {
+            "version": "1.2.9",
+            "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
+            "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "define-properties": "^1.2.1",
+                "es-abstract": "^1.23.0",
+                "es-object-atoms": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/string.prototype.trimend": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
+            "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "define-properties": "^1.2.1",
+                "es-object-atoms": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/string.prototype.trimstart": {
+            "version": "1.0.8",
+            "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
+            "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "define-properties": "^1.2.1",
+                "es-object-atoms": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/strip-ansi": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
@@ -8881,20 +10219,20 @@
             }
         },
         "node_modules/styled-components": {
-            "version": "6.1.8",
-            "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.8.tgz",
-            "integrity": "sha512-PQ6Dn+QxlWyEGCKDS71NGsXoVLKfE1c3vApkvDYS5KAK+V8fNWGhbSUEo9Gg2iaID2tjLXegEW3bZDUGpofRWw==",
+            "version": "6.1.11",
+            "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.11.tgz",
+            "integrity": "sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==",
             "dev": true,
             "dependencies": {
-                "@emotion/is-prop-valid": "1.2.1",
-                "@emotion/unitless": "0.8.0",
-                "@types/stylis": "4.2.0",
+                "@emotion/is-prop-valid": "1.2.2",
+                "@emotion/unitless": "0.8.1",
+                "@types/stylis": "4.2.5",
                 "css-to-react-native": "3.2.0",
-                "csstype": "3.1.2",
-                "postcss": "8.4.31",
+                "csstype": "3.1.3",
+                "postcss": "8.4.38",
                 "shallowequal": "1.1.0",
-                "stylis": "4.3.1",
-                "tslib": "2.5.0"
+                "stylis": "4.3.2",
+                "tslib": "2.6.2"
             },
             "engines": {
                 "node": ">= 16"
@@ -8909,9 +10247,9 @@
             }
         },
         "node_modules/stylis": {
-            "version": "4.3.1",
-            "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz",
-            "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==",
+            "version": "4.3.2",
+            "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
+            "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==",
             "dev": true
         },
         "node_modules/supports-color": {
@@ -8931,9 +10269,9 @@
             "integrity": "sha512-UAFxQSzxVkY/yfmipeMLj4LwH6I/ZGcfezwSquPm2U9CqOiHp8L6fD7TcyPDYfCZuHFaPw5y4io+fny37Ov9NQ=="
         },
         "node_modules/swagger-ui-express": {
-            "version": "5.0.0",
-            "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.0.tgz",
-            "integrity": "sha512-tsU9tODVvhyfkNSvf03E6FAk+z+5cU3lXAzMy6Pv4av2Gt2xA0++fogwC4qo19XuFf6hdxevPuVCSKFuMHJhFA==",
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/swagger-ui-express/-/swagger-ui-express-5.0.1.tgz",
+            "integrity": "sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==",
             "dependencies": {
                 "swagger-ui-dist": ">=5.0.0"
             },
@@ -9051,18 +10389,18 @@
             }
         },
         "node_modules/tslib": {
-            "version": "2.5.0",
-            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
-            "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
+            "version": "2.6.2",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+            "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
             "dev": true
         },
         "node_modules/tsx": {
-            "version": "4.11.0",
-            "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.11.0.tgz",
-            "integrity": "sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==",
+            "version": "4.16.2",
+            "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.16.2.tgz",
+            "integrity": "sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==",
             "dev": true,
             "dependencies": {
-                "esbuild": "~0.20.2",
+                "esbuild": "~0.21.5",
                 "get-tsconfig": "^4.7.5"
             },
             "bin": {
@@ -9110,15 +10448,88 @@
                 "node": ">= 0.6"
             }
         },
+        "node_modules/typed-array-buffer": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
+            "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "es-errors": "^1.3.0",
+                "is-typed-array": "^1.1.13"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/typed-array-byte-length": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
+            "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "for-each": "^0.3.3",
+                "gopd": "^1.0.1",
+                "has-proto": "^1.0.3",
+                "is-typed-array": "^1.1.13"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/typed-array-byte-offset": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
+            "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
+            "dev": true,
+            "dependencies": {
+                "available-typed-arrays": "^1.0.7",
+                "call-bind": "^1.0.7",
+                "for-each": "^0.3.3",
+                "gopd": "^1.0.1",
+                "has-proto": "^1.0.3",
+                "is-typed-array": "^1.1.13"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/typed-array-length": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
+            "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.7",
+                "for-each": "^0.3.3",
+                "gopd": "^1.0.1",
+                "has-proto": "^1.0.3",
+                "is-typed-array": "^1.1.13",
+                "possible-typed-array-names": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/typedarray": {
             "version": "0.0.6",
             "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
             "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
         },
         "node_modules/typescript": {
-            "version": "5.4.5",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
-            "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
+            "version": "5.5.3",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
+            "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
             "dev": true,
             "bin": {
                 "tsc": "bin/tsc",
@@ -9129,14 +10540,14 @@
             }
         },
         "node_modules/typescript-eslint": {
-            "version": "7.11.0",
-            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.11.0.tgz",
-            "integrity": "sha512-ZKe3yHF/IS/kCUE4CGE3UgtK+Q7yRk1e9kwEI0rqm9XxMTd9P1eHe0LVVtrZ3oFuIQ2unJ9Xn0vTsLApzJ3aPw==",
+            "version": "7.15.0",
+            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.15.0.tgz",
+            "integrity": "sha512-Ta40FhMXBCwHura4X4fncaCVkVcnJ9jnOq5+Lp4lN8F4DzHZtOwZdRvVBiNUGznUDHPwdGnrnwxmUOU2fFQqFA==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/eslint-plugin": "7.11.0",
-                "@typescript-eslint/parser": "7.11.0",
-                "@typescript-eslint/utils": "7.11.0"
+                "@typescript-eslint/eslint-plugin": "7.15.0",
+                "@typescript-eslint/parser": "7.15.0",
+                "@typescript-eslint/utils": "7.15.0"
             },
             "engines": {
                 "node": "^18.18.0 || >=20.0.0"
@@ -9167,6 +10578,21 @@
                 "node": ">=0.8.0"
             }
         },
+        "node_modules/unbox-primitive": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
+            "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.2",
+                "has-bigints": "^1.0.2",
+                "has-symbols": "^1.0.3",
+                "which-boxed-primitive": "^1.0.2"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/undefsafe": {
             "version": "2.0.5",
             "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
@@ -9211,6 +10637,15 @@
             "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==",
             "dev": true
         },
+        "node_modules/use-sync-external-store": {
+            "version": "1.2.2",
+            "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz",
+            "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==",
+            "dev": true,
+            "peerDependencies": {
+                "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+            }
+        },
         "node_modules/util-deprecate": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -9225,9 +10660,9 @@
             }
         },
         "node_modules/uuid": {
-            "version": "9.0.1",
-            "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
-            "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+            "version": "10.0.0",
+            "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz",
+            "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
             "funding": [
                 "https://github.com/sponsors/broofa",
                 "https://github.com/sponsors/ctavan"
@@ -9290,6 +10725,41 @@
                 "node": "^16.13.0 || >=18.0.0"
             }
         },
+        "node_modules/which-boxed-primitive": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
+            "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+            "dev": true,
+            "dependencies": {
+                "is-bigint": "^1.0.1",
+                "is-boolean-object": "^1.1.0",
+                "is-number-object": "^1.0.4",
+                "is-string": "^1.0.5",
+                "is-symbol": "^1.0.3"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/which-typed-array": {
+            "version": "1.1.15",
+            "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
+            "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
+            "dev": true,
+            "dependencies": {
+                "available-typed-arrays": "^1.0.7",
+                "call-bind": "^1.0.7",
+                "for-each": "^0.3.3",
+                "gopd": "^1.0.1",
+                "has-tostringtag": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
         "node_modules/winston": {
             "version": "3.13.0",
             "resolved": "https://registry.npmjs.org/winston/-/winston-3.13.0.tgz",
diff --git a/ExpressAPI/package.json b/ExpressAPI/package.json
index 89dc5f3285609f5f22b54ec5f37fa4a9a93dd319..f94f1bbf30859785fa63366b9f62f84b8536a9f4 100644
--- a/ExpressAPI/package.json
+++ b/ExpressAPI/package.json
@@ -1,7 +1,7 @@
 {
     "name"           : "dojo_backend_api",
     "description"    : "Backend API of the Dojo project",
-    "version"        : "4.1.0",
+    "version"        : "4.2.0",
     "license"        : "AGPLv3",
     "author"         : "Michaël Minelli <dojo@minelli.me>",
     "main"           : "dist/src/app.js",
@@ -28,9 +28,9 @@
         "seed": "node dist/prisma/seed"
     },
     "dependencies"   : {
-        "@dotenvx/dotenvx"    : "^0.44.1",
+        "@dotenvx/dotenvx"    : "^0.45.0",
         "@gitbeaker/rest"     : "^40.0.3",
-        "@prisma/client"      : "^5.14.0",
+        "@prisma/client"      : "^5.16.1",
         "axios"               : "^1.7.2",
         "compression"         : "^1.7.4",
         "cors"                : "^2.8.5",
@@ -44,37 +44,38 @@
         "morgan"              : "^1.10.0",
         "multer"              : "^1.4.5-lts.1",
         "mysql"               : "^2.18.1",
-        "node"                : "^20.11.0",
+        "node"                : "^20.15.0",
         "parse-link-header"   : "^2.0.0",
         "semver"              : "^7.6.2",
-        "swagger-ui-express"  : "^5.0.0",
+        "swagger-ui-express"  : "^5.0.1",
         "tar-stream"          : "^3.1.7",
-        "uuid"                : "^9.0.1",
+        "uuid"                : "^10.0.0",
         "winston"             : "^3.13.0",
         "zod"                 : "^3.23.8",
         "zod-validation-error": "^3.3.0"
     },
     "devDependencies": {
-        "@redocly/cli"             : "^1.13.0",
+        "@redocly/cli"             : "^1.17.0",
         "@types/compression"       : "^1.7.5",
         "@types/cors"              : "^2.8.17",
         "@types/express"           : "^4.17.21",
         "@types/jsonwebtoken"      : "^9.0.6",
         "@types/morgan"            : "^1.9.9",
         "@types/multer"            : "^1.4.11",
-        "@types/node"              : "^20.12.12",
+        "@types/node"              : "^20.14.9",
         "@types/parse-link-header" : "^2.0.3",
         "@types/semver"            : "^7.5.8",
         "@types/swagger-ui-express": "^4.1.6",
         "@types/tar-stream"        : "^3.1.3",
-        "@types/uuid"              : "^9.0.8",
+        "@types/uuid"              : "^10.0.0",
+        "dotenv-cli"               : "^7.4.2",
         "eslint"                   : "^8.57.0",
         "genversion"               : "^3.2.0",
-        "nodemon"                  : "^3.1.1",
-        "npm"                      : "^10.8.0",
-        "prisma"                   : "^5.14.0",
-        "tsx"                      : "^4.11.0",
-        "typescript"               : "^5.4.5",
-        "typescript-eslint"        : "^7.11.0"
+        "nodemon"                  : "^3.1.4",
+        "npm"                      : "^10.8.1",
+        "prisma"                   : "^5.16.1",
+        "tsx"                      : "^4.16.2",
+        "typescript"               : "^5.5.3",
+        "typescript-eslint"        : "^7.15.0"
     }
 }
diff --git a/ExpressAPI/prisma/migrations/20240212153007_add_tags/migration.sql b/ExpressAPI/prisma/migrations/20240212153007_add_tags/migration.sql
new file mode 100644
index 0000000000000000000000000000000000000000..4760713466e16ff80d81a734fe2f3c31837eadcc
--- /dev/null
+++ b/ExpressAPI/prisma/migrations/20240212153007_add_tags/migration.sql
@@ -0,0 +1,46 @@
+-- CreateTable
+CREATE TABLE `Tag` (
+    `name` CHAR(36) NOT NULL,
+    `type` ENUM('LANGUAGE', 'FRAMEWORK', 'THEME', 'USERDEFINED') NOT NULL,
+
+    PRIMARY KEY (`name`)
+) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+-- CreateTable
+CREATE TABLE `_AssignmentToTag` (
+    `A` VARCHAR(191) NOT NULL,
+    `B` CHAR(36) NOT NULL,
+
+    UNIQUE INDEX `_AssignmentToTag_AB_unique`(`A`, `B`),
+    INDEX `_AssignmentToTag_B_index`(`B`)
+) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+-- CreateTable
+CREATE TABLE `_ExerciseToTag` (
+    `A` CHAR(36) NOT NULL,
+    `B` CHAR(36) NOT NULL,
+
+    UNIQUE INDEX `_ExerciseToTag_AB_unique`(`A`, `B`),
+    INDEX `_ExerciseToTag_B_index`(`B`)
+) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
+
+-- AddForeignKey
+ALTER TABLE `_AssignmentToTag` ADD CONSTRAINT `_AssignmentToTag_A_fkey` FOREIGN KEY (`A`) REFERENCES `Assignment`(`name`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE `_AssignmentToTag` ADD CONSTRAINT `_AssignmentToTag_B_fkey` FOREIGN KEY (`B`) REFERENCES `Tag`(`name`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE `_ExerciseToTag` ADD CONSTRAINT `_ExerciseToTag_A_fkey` FOREIGN KEY (`A`) REFERENCES `Exercise`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE `_ExerciseToTag` ADD CONSTRAINT `_ExerciseToTag_B_fkey` FOREIGN KEY (`B`) REFERENCES `Tag`(`name`) ON DELETE CASCADE ON UPDATE CASCADE;
+
+-- CreateTable
+CREATE TABLE `SubmissionTag` (
+    `name` CHAR(36) NOT NULL,
+    `type` ENUM('LANGUAGE', 'FRAMEWORK', 'THEME', 'USERDEFINED') NOT NULL,
+    `state` VARCHAR(191) NOT NULL,
+
+    PRIMARY KEY (`name`)
+) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
diff --git a/ExpressAPI/prisma/migrations/20240523212938_add_deleted_to_exercise/migration.sql b/ExpressAPI/prisma/migrations/20240523212938_add_deleted_to_exercise/migration.sql
new file mode 100644
index 0000000000000000000000000000000000000000..4d82e3a5c8054818e93ff3fdece07ad890f4cb64
--- /dev/null
+++ b/ExpressAPI/prisma/migrations/20240523212938_add_deleted_to_exercise/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE `Exercise` ADD COLUMN `deleted` BOOLEAN NOT NULL DEFAULT false;
diff --git a/ExpressAPI/prisma/migrations/20240619160717_rename_tag_proposal_table/migration.sql b/ExpressAPI/prisma/migrations/20240619160717_rename_tag_proposal_table/migration.sql
new file mode 100644
index 0000000000000000000000000000000000000000..5484fa4855165f86579d571d91ec421ee13ab5c9
--- /dev/null
+++ b/ExpressAPI/prisma/migrations/20240619160717_rename_tag_proposal_table/migration.sql
@@ -0,0 +1,17 @@
+/*
+  Warnings:
+
+  - You are about to drop the `SubmissionTag` table. If the table is not empty, all the data it contains will be lost.
+
+*/
+-- DropTable
+DROP TABLE `SubmissionTag`;
+
+-- CreateTable
+CREATE TABLE `TagProposal` (
+    `name` CHAR(36) NOT NULL,
+    `type` ENUM('LANGUAGE', 'FRAMEWORK', 'THEME', 'USERDEFINED') NOT NULL,
+    `state` VARCHAR(191) NOT NULL,
+
+    PRIMARY KEY (`name`)
+) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
diff --git a/ExpressAPI/prisma/migrations/20240619232301_set_tag_proposal_state_default/migration.sql b/ExpressAPI/prisma/migrations/20240619232301_set_tag_proposal_state_default/migration.sql
new file mode 100644
index 0000000000000000000000000000000000000000..f0feb8cccc7b2e7466528d133231457418edd075
--- /dev/null
+++ b/ExpressAPI/prisma/migrations/20240619232301_set_tag_proposal_state_default/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE `TagProposal` MODIFY `state` VARCHAR(191) NOT NULL DEFAULT 'PendingApproval';
diff --git a/ExpressAPI/prisma/migrations/20240619232804_add_tag_proposal_details/migration.sql b/ExpressAPI/prisma/migrations/20240619232804_add_tag_proposal_details/migration.sql
new file mode 100644
index 0000000000000000000000000000000000000000..28577819d43b5e17369af23ae3e9ee4efb43edfc
--- /dev/null
+++ b/ExpressAPI/prisma/migrations/20240619232804_add_tag_proposal_details/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE `TagProposal` ADD COLUMN `details` VARCHAR(191) NULL;
diff --git a/ExpressAPI/prisma/schema.prisma b/ExpressAPI/prisma/schema.prisma
index 8d7143ac874fd4324ce2d1c043f65c2f6e27ba68..b9fc889ad8b8374cc56d80d43e4e775a8f776e77 100644
--- a/ExpressAPI/prisma/schema.prisma
+++ b/ExpressAPI/prisma/schema.prisma
@@ -13,6 +13,13 @@ enum UserRole {
     ADMIN
 }
 
+enum TagType {
+    LANGUAGE
+    FRAMEWORK
+    THEME
+    USERDEFINED
+}
+
 model User {
     id             Int       @id /// The user's id is the same as their gitlab id
     name           String?
@@ -37,6 +44,7 @@ model Assignment {
 
     exercises Exercise[]
     staff     User[]
+    tags      Tag[]
 }
 
 model Exercise {
@@ -49,6 +57,7 @@ model Exercise {
     gitlabCreationInfo Json     @db.Json
     gitlabLastInfo     Json     @db.Json
     gitlabLastInfoDate DateTime
+    deleted            Boolean  @default(false)
 
     correctionCommit      Json?   @db.Json
     correctionDescription String? @db.VarChar(80)
@@ -57,6 +66,7 @@ model Exercise {
 
     members User[]
     results Result[]
+    tags    Tag[]
 }
 
 model Result {
@@ -72,3 +82,18 @@ model Result {
 
     @@id([exerciseId, dateTime])
 }
+
+model Tag {
+    name String  @id @db.Char(36)
+    type TagType
+
+    assignments Assignment[]
+    exercises   Exercise[]
+}
+
+model TagProposal {
+    name    String  @id @db.Char(36)
+    type    TagType
+    state   String  @default("PendingApproval")
+    details String?
+}
diff --git a/ExpressAPI/prisma/seed.ts b/ExpressAPI/prisma/seed.ts
index 93680f6e393563ebb3adee65bdfe48e5918797a0..6ac1a5d060fb2009293ea630763ec747a2790beb 100644
--- a/ExpressAPI/prisma/seed.ts
+++ b/ExpressAPI/prisma/seed.ts
@@ -6,13 +6,15 @@ import SharedConfig from '../src/shared/config/SharedConfig.js';
 import { UserRole } from '@prisma/client';
 import logger       from '../src/shared/logging/WinstonLogger.js';
 import db           from '../src/helpers/DatabaseHelper.js';
-
+import TagManager  from '../src/managers/TagManager';
+import { TagType }  from '@prisma/client';
 
 async function main() {
     await users();
     await assignments();
     await exercises();
     await results();
+    await tag();
 }
 
 main().then(async () => {
@@ -1580,4 +1582,383 @@ async function results() {
                                    }
                                });
     }
-}
\ No newline at end of file
+}
+
+async function tag() {
+    await db.tag.upsert({
+        where : { name: 'C' },
+        update: {},
+        create: {
+            name          : 'C',
+            type          : TagType.LANGUAGE
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Java' },
+        update: {},
+        create: {
+            name          : 'Java',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Scala' },
+        update: {},
+        create: {
+            name            : 'Scala',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Kotlin' },
+        update: {},
+        create: {
+            name            : 'Kotlin',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Rust' },
+        update: {},
+        create: {
+            name            : 'Rust',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'JavaScript' },
+        update: {},
+        create: {
+            name            : 'JavaScript',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'TypeScript' },
+        update: {},
+        create: {
+            name            : 'TypeScript',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Python' },
+        update: {},
+        create: {
+            name            : 'Python',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'HTML' },
+        update: {},
+        create: {
+            name            : 'HTML',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'CSS' },
+        update: {},
+        create: {
+            name            : 'CSS',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'C++' },
+        update: {},
+        create: {
+            name            : 'C++',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Go' },
+        update: {},
+        create: {
+            name            : 'Go',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'PHP' },
+        update: {},
+        create: {
+            name            : 'PHP',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'C#' },
+        update: {},
+        create: {
+            name            : 'C#',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Swift' },
+        update: {},
+        create: {
+            name            : 'Swift',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Matlab' },
+        update: {},
+        create: {
+            name            : 'Matlab',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'SQL' },
+        update: {},
+        create: {
+            name            : 'SQL',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Assembly' },
+        update: {},
+        create: {
+            name            : 'Assembly',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Ruby' },
+        update: {},
+        create: {
+            name            : 'Ruby',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Fortran' },
+        update: {},
+        create: {
+            name            : 'Fortran',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Pascal' },
+        update: {},
+        create: {
+            name            : 'Pascal',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Visual Basic' },
+        update: {},
+        create: {
+            name            : 'Visual Basic',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'R' },
+        update: {},
+        create: {
+            name            : 'R',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Objective-C' },
+        update: {},
+        create: {
+            name            : 'Objective-C',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Lua' },
+        update: {},
+        create: {
+            name            : 'Lua',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Ada' },
+        update: {},
+        create: {
+            name            : 'Ada',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Haskell' },
+        update: {},
+        create: {
+            name            : 'Haskell',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Shell/PowerShell' },
+        update: {},
+        create: {
+            name            : 'Shell/PowerShell',
+            type          : TagType.LANGUAGE,
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Express' },
+        update: {},
+        create: {
+            name            : 'Express',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Django' },
+        update: {},
+        create: {
+            name            : 'Django',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Ruby on Rails' },
+        update: {},
+        create: {
+            name            : 'Ruby on Rails',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Angular' },
+        update: {},
+        create: {
+            name            : 'Angular',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'React' },
+        update: {},
+        create: {
+            name            : 'React',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Flutter' },
+        update: {},
+        create: {
+            name            : 'Flutter',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Ionic' },
+        update: {},
+        create: {
+            name            : 'Ionic',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Flask' },
+        update: {},
+        create: {
+            name            : 'Flask',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'React Native' },
+        update: {},
+        create: {
+            name            : 'React Native',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Xamarin' },
+        update: {},
+        create: {
+            name            : 'Xamarin',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Laravel' },
+        update: {},
+        create: {
+            name            : 'Laravel',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Spring' },
+        update: {},
+        create: {
+            name            : 'Spring',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Play' },
+        update: {},
+        create: {
+            name            : 'Play',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Symfony' },
+        update: {},
+        create: {
+            name            : 'Symfony',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'ASP.NET' },
+        update: {},
+        create: {
+            name            : 'ASP.NET',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Meteor' },
+        update: {},
+        create: {
+            name            : 'Meteor',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Vue.js' },
+        update: {},
+        create: {
+            name            : 'Vue.js',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Svelte' },
+        update: {},
+        create: {
+            name            : 'Svelte',
+            type          : TagType.FRAMEWORK
+        }
+    });
+    await db.tag.upsert({
+        where : { name: 'Express.js' },
+        update: {},
+        create: {
+            name            : 'Express.js',
+            type          : TagType.FRAMEWORK
+        }
+    });
+}
diff --git a/ExpressAPI/src/config/Config.ts b/ExpressAPI/src/config/Config.ts
index 9d5766cae888d80ac7d705cece888ea8124170d4..29301c0cc30fca094b4d1b3b7ba59de1c4c99085 100644
--- a/ExpressAPI/src/config/Config.ts
+++ b/ExpressAPI/src/config/Config.ts
@@ -44,7 +44,7 @@ class Config {
         }; account: {
             id: number; username: string; token: string;
         }; group: {
-            root: number; templates: number; assignments: number; exercises: number;
+            root: number; templates: number; assignments: number; exercises: number; deletedAssignments: number; deletedExercises: number;
         }, badges: {
             pipeline: ConfigGitlabBadge
         }
@@ -98,10 +98,12 @@ class Config {
                 timeoutAfterCreation: Number(process.env.GITLAB_REPOSITORY_CREATION_TIMEOUT || 5000)
             },
             group     : {
-                root       : Number(process.env.GITLAB_GROUP_ROOT_ID || 0),
-                templates  : Number(process.env.GITLAB_GROUP_TEMPLATES_ID || 0),
-                assignments: Number(process.env.GITLAB_GROUP_ASSIGNMENTS_ID || 0),
-                exercises  : Number(process.env.GITLAB_GROUP_EXERCISES_ID || 0)
+                root              : Number(process.env.GITLAB_GROUP_ROOT_ID || 0),
+                templates         : Number(process.env.GITLAB_GROUP_TEMPLATES_ID || 0),
+                assignments       : Number(process.env.GITLAB_GROUP_ASSIGNMENTS_ID || 0),
+                exercises         : Number(process.env.GITLAB_GROUP_EXERCISES_ID || 0),
+                deletedAssignments: Number(process.env.GITLAB_GROUP_DELETED_ASSIGNMENTS_ID || 0),
+                deletedExercises  : Number(process.env.GITLAB_GROUP_DELETED_EXERCISES_ID || 0)
             },
             badges    : {
                 pipeline: {
diff --git a/ExpressAPI/src/managers/ExerciseManager.ts b/ExpressAPI/src/managers/ExerciseManager.ts
index 258f96379bfe4528e8b59fed8f7be3e78097aeea..bc64be63d2f0e3ec5970ea1400113d421aed8278 100644
--- a/ExpressAPI/src/managers/ExerciseManager.ts
+++ b/ExpressAPI/src/managers/ExerciseManager.ts
@@ -1,6 +1,6 @@
-import { Prisma }   from '@prisma/client';
-import { Exercise } from '../types/DatabaseTypes.js';
-import db           from '../helpers/DatabaseHelper.js';
+import { Prisma }         from '@prisma/client';
+import { Exercise, User } from '../types/DatabaseTypes.js';
+import db                 from '../helpers/DatabaseHelper.js';
 
 
 class ExerciseManager {
@@ -23,6 +23,24 @@ class ExerciseManager {
                                         include: include
                                     }) as Promise<Array<Exercise>>;
     }
+
+    async isUserAllowedToAccessExercise(exercise: Exercise, user: User): Promise<boolean> {
+        if ( !exercise.members ) {
+            exercise.members = await db.exercise.findUnique({
+                                                                where: {
+                                                                    id: exercise.id
+                                                                }
+                                                            }).members() ?? [];
+        }
+
+        const assignmentStaff = (await db.assignment.findUnique({
+                                                                    where: {
+                                                                        name: exercise.assignmentName
+                                                                    }
+                                                                }).staff()) ?? [];
+
+        return exercise.members.findIndex(member => member.id === user.id) !== -1 || assignmentStaff.findIndex(staff => staff.id === user.id) !== -1;
+    }
 }
 
 
diff --git a/ExpressAPI/src/managers/GitlabManager.ts b/ExpressAPI/src/managers/GitlabManager.ts
index bd2746ab4323f39d16b3ab7cee410c463b42ddfe..5ad9dca9dd1bad96492bdb4dd32040c040442aaa 100644
--- a/ExpressAPI/src/managers/GitlabManager.ts
+++ b/ExpressAPI/src/managers/GitlabManager.ts
@@ -29,9 +29,9 @@ class GitlabManager extends SharedGitlabManager {
         }
     }
 
-    async getRepositoryMembers(idOrNamespace: string): Promise<Array<MemberSchema>> {
+    async getRepositoryMembers(idOrNamespace: string, includeInherited: boolean = true): Promise<Array<MemberSchema>> {
         try {
-            return await this.api.ProjectMembers.all(idOrNamespace, { includeInherited: true });
+            return await this.api.ProjectMembers.all(idOrNamespace, { includeInherited: includeInherited });
         } catch ( e ) {
             logger.error(JSON.stringify(e));
             return Promise.reject(e);
@@ -122,6 +122,27 @@ class GitlabManager extends SharedGitlabManager {
         }
     }
 
+    async deleteRepositoryMember(repoId: number, userId: number, skipSubresources: boolean = false, unassignIssuables: boolean = false): Promise<void> {
+        try {
+            return await this.api.ProjectMembers.remove(repoId, userId, {
+                skipSubresourceS: skipSubresources,
+                unassignIssuables
+            });
+        } catch ( e ) {
+            logger.error(JSON.stringify(e));
+            return Promise.reject(e);
+        }
+    }
+
+    async moveRepository(repoId: number, newRepoId: number): Promise<ProjectSchema> {
+        try {
+            return await this.api.Projects.transfer(repoId, newRepoId);
+        } catch ( e ) {
+            logger.error(JSON.stringify(e));
+            return Promise.reject(e);
+        }
+    }
+
     changeRepositoryVisibility(repoId: number, visibility: GitlabVisibility): Promise<ProjectSchema> {
         return this.editRepository(repoId, { visibility: visibility });
     }
diff --git a/ExpressAPI/src/managers/TagManager.ts b/ExpressAPI/src/managers/TagManager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..936b3bcb04d3aea3c205215d6d283337ae62f0b9
--- /dev/null
+++ b/ExpressAPI/src/managers/TagManager.ts
@@ -0,0 +1,16 @@
+import { Prisma, Tag }           from '@prisma/client';
+import db                   from '../helpers/DatabaseHelper';
+
+class TagManager {
+	async get(name: string, include: Prisma.TagInclude | undefined = undefined): Promise<Tag | undefined> {
+        return await db.tag.findUnique({
+                                                where  : {
+                                                    name: name
+                                                },
+                                                include: include
+                                            }) as unknown as Tag ?? undefined;
+    }
+}
+
+export default new TagManager();
+
diff --git a/ExpressAPI/src/managers/TagProposalManager.ts b/ExpressAPI/src/managers/TagProposalManager.ts
new file mode 100644
index 0000000000000000000000000000000000000000..89607e24c566a377b3abc0b1e5ac66c5b1129874
--- /dev/null
+++ b/ExpressAPI/src/managers/TagProposalManager.ts
@@ -0,0 +1,17 @@
+import { TagProposal } from '@prisma/client';
+import db              from '../helpers/DatabaseHelper';
+
+
+class TagProposalManager {
+    async get(name: string | undefined = undefined): Promise<TagProposal | undefined> {
+        return await db.tagProposal.findUnique({
+                                                   where: {
+                                                       name: name
+                                                   }
+                                               }) as unknown as TagProposal ?? undefined;
+    }
+}
+
+
+export default new TagProposalManager();
+
diff --git a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
index a1836d10d7349c935920061299226a7eb825568c..1dffaef8a782bb06c01e485705afc830e563f441 100644
--- a/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
+++ b/ExpressAPI/src/middlewares/ParamsCallbackManager.ts
@@ -1,8 +1,10 @@
-import { Express }       from 'express-serve-static-core';
-import express           from 'express';
-import { StatusCodes }   from 'http-status-codes';
-import ExerciseManager   from '../managers/ExerciseManager.js';
-import AssignmentManager from '../managers/AssignmentManager.js';
+import { Express }        from 'express-serve-static-core';
+import express            from 'express';
+import { StatusCodes }    from 'http-status-codes';
+import ExerciseManager    from '../managers/ExerciseManager';
+import AssignmentManager  from '../managers/AssignmentManager';
+import TagManager         from '../managers/TagManager';
+import TagProposalManager from '../managers/TagProposalManager';
 
 
 type GetFunction = (id: string | number, ...args: Array<unknown>) => Promise<unknown>
@@ -27,8 +29,10 @@ class ParamsCallbackManager {
     initBoundParams(req: express.Request) {
         if ( !req.boundParams ) {
             req.boundParams = {
-                assignment: undefined,
-                exercise  : undefined
+                assignment : undefined,
+                exercise   : undefined,
+                tag        : undefined,
+                tagProposal: undefined
             };
         }
     }
@@ -44,6 +48,12 @@ class ParamsCallbackManager {
             members   : true,
             results   : true
         } ], 'exercise');
+
+        this.listenParam('tagName', backend, (TagManager.get as GetFunction).bind(TagManager), [ {
+            assignments: true
+        } ], 'tag');
+
+        this.listenParam('tagProposalName', backend, (TagProposalManager.get as GetFunction).bind(TagProposalManager), [ {} ], 'tagProposal');
     }
 }
 
diff --git a/ExpressAPI/src/middlewares/SecurityMiddleware.ts b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
index 02c54c16b151e259a45b8ff47fda8f9f50b17bf6..bfe307ecf2adf5b1cbc774565add672d5022df09 100644
--- a/ExpressAPI/src/middlewares/SecurityMiddleware.ts
+++ b/ExpressAPI/src/middlewares/SecurityMiddleware.ts
@@ -3,6 +3,7 @@ import { StatusCodes }   from 'http-status-codes';
 import SecurityCheckType from '../types/SecurityCheckType.js';
 import logger            from '../shared/logging/WinstonLogger.js';
 import AssignmentManager from '../managers/AssignmentManager.js';
+import ExerciseManager   from '../managers/ExerciseManager';
 
 
 class SecurityMiddleware {
@@ -13,8 +14,12 @@ class SecurityMiddleware {
     private async checkType(checkType: SecurityCheckType, req: express.Request): Promise<boolean> {
         try {
             switch ( String(checkType) ) {
+                case SecurityCheckType.ADMIN.valueOf():
+                    return req.session.profile.isAdmin;
                 case SecurityCheckType.TEACHING_STAFF.valueOf():
                     return req.session.profile.isTeachingStaff;
+                case SecurityCheckType.EXERCISE_MEMBERS.valueOf():
+                    return await ExerciseManager.isUserAllowedToAccessExercise(req.boundParams.exercise!, req.session.profile);
                 case SecurityCheckType.ASSIGNMENT_STAFF.valueOf():
                     return await AssignmentManager.isUserAllowedToAccessAssignment(req.boundParams.assignment!, req.session.profile);
                 case SecurityCheckType.ASSIGNMENT_IS_PUBLISHED.valueOf():
diff --git a/ExpressAPI/src/routes/ApiRoutesManager.ts b/ExpressAPI/src/routes/ApiRoutesManager.ts
index 57a418842eb2003e5cab56d24344877837f90691..1508de4124baa104b7aac892da229685ecb9b998 100644
--- a/ExpressAPI/src/routes/ApiRoutesManager.ts
+++ b/ExpressAPI/src/routes/ApiRoutesManager.ts
@@ -5,6 +5,7 @@ import SessionRoutes    from './SessionRoutes.js';
 import AssignmentRoutes from './AssignmentRoutes.js';
 import GitlabRoutes     from './GitlabRoutes.js';
 import ExerciseRoutes   from './ExerciseRoutes.js';
+import TagsRoutes       from './TagRoutes';
 
 
 class AdminRoutesManager implements RoutesManager {
@@ -14,6 +15,7 @@ class AdminRoutesManager implements RoutesManager {
         GitlabRoutes.registerOnBackend(backend);
         AssignmentRoutes.registerOnBackend(backend);
         ExerciseRoutes.registerOnBackend(backend);
+        TagsRoutes.registerOnBackend(backend);
     }
 }
 
diff --git a/ExpressAPI/src/routes/AssignmentRoutes.ts b/ExpressAPI/src/routes/AssignmentRoutes.ts
index 5f46129df7cf916d4b7a94f17bb108f32289ee4c..0f06d74728a684153763d8b7d710809ff6f6e9f4 100644
--- a/ExpressAPI/src/routes/AssignmentRoutes.ts
+++ b/ExpressAPI/src/routes/AssignmentRoutes.ts
@@ -112,7 +112,8 @@ class AssignmentRoutes implements RoutesManager {
                                                            include: {
                                                                assignment: false,
                                                                members   : true,
-                                                               results   : true
+                                                               results   : true,
+                                                               tags      : true
                                                            }
                                                        });
             }
diff --git a/ExpressAPI/src/routes/ExerciseRoutes.ts b/ExpressAPI/src/routes/ExerciseRoutes.ts
index b32ab8b22983feed2cef9d06768bedfc0b70b2c6..463f353a4e47c9cb2ace3b91be3f3fad2018d3ab 100644
--- a/ExpressAPI/src/routes/ExerciseRoutes.ts
+++ b/ExpressAPI/src/routes/ExerciseRoutes.ts
@@ -67,7 +67,12 @@ class ExerciseRoutes implements RoutesManager {
     registerOnBackend(backend: Express) {
         backend.post('/assignments/:assignmentNameOrUrl/exercises', SecurityMiddleware.check(true, SecurityCheckType.ASSIGNMENT_IS_PUBLISHED), ParamsValidatorMiddleware.validate(this.exerciseValidator), this.createExercise.bind(this) as RequestHandler);
 
+        backend.get('/exercises', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), this.getAllExercises.bind(this) as RequestHandler);
         backend.get('/exercises/:exerciseIdOrUrl/assignment', SecurityMiddleware.check(false, SecurityCheckType.EXERCISE_SECRET), this.getAssignment.bind(this) as RequestHandler);
+        backend.get('/exercises/:exerciseIdOrUrl/members', SecurityMiddleware.check(true, SecurityCheckType.ADMIN, SecurityCheckType.EXERCISE_MEMBERS), this.getExerciseMembers.bind(this) as RequestHandler);
+        backend.get('/exercises/:exerciseIdOrUrl/results', SecurityMiddleware.check(true, SecurityCheckType.ADMIN, SecurityCheckType.EXERCISE_MEMBERS), this.getExerciseResults.bind(this) as RequestHandler);
+
+        backend.delete('/exercises/:exerciseIdOrUrl', SecurityMiddleware.check(true, SecurityCheckType.ADMIN, SecurityCheckType.EXERCISE_MEMBERS), this.deleteExercise.bind(this) as RequestHandler);
 
         backend.post('/exercises/:exerciseIdOrUrl/results', SecurityMiddleware.check(false, SecurityCheckType.EXERCISE_SECRET), ParamsValidatorMiddleware.validate(this.resultValidator), this.createResult.bind(this) as RequestHandler);
     }
@@ -78,10 +83,55 @@ class ExerciseRoutes implements RoutesManager {
         return `DojoEx - ${ assignment.name } - ${ memberNames }${ suffixString }`;
     }
 
+    private async getExerciseMembers(req: express.Request, res: express.Response) {
+        const repoId = req.boundParams.exercise!.gitlabId;
+
+        const members = await GitlabManager.getRepositoryMembers(String(repoId));
+
+        return req.session.sendResponse(res, StatusCodes.OK, members);
+    }
+
+    private async getExerciseResults(req: express.Request, res: express.Response) {
+        const results = await db.result.findMany({
+                                                     where  : { exerciseId: req.boundParams.exercise!.id },
+                                                     orderBy: { dateTime: 'desc' }
+                                                 });
+
+        return req.session.sendResponse(res, StatusCodes.OK, results);
+    }
+
+    private async deleteExercise(req: express.Request, res: express.Response) {
+        const repoId = req.boundParams.exercise!.gitlabId;
+
+        const members = await GitlabManager.getRepositoryMembers(String(repoId), false);
+        for ( const member of members ) {
+            if ( member.id !== Config.gitlab.account.id ) {
+                await GitlabManager.deleteRepositoryMember(repoId, member.id);
+            }
+        }
+
+        await GitlabManager.moveRepository(repoId, Config.gitlab.group.deletedExercises);
+
+        await db.exercise.update({
+                                     where: { id: req.boundParams.exercise!.id },
+                                     data : { deleted: true }
+                                 });
+
+        return req.session.sendResponse(res, StatusCodes.OK);
+    }
+
     private getExercisePath(assignment: Assignment, exerciseId: string): string {
         return `dojo-ex_${ (assignment.gitlabLastInfo as unknown as Gitlab.ProjectSchema).path }_${ exerciseId }`;
     }
 
+    // Get all exercise
+    private async getAllExercises(req: express.Request, res: express.Response) {
+        const exos = await db.exercise.findMany();
+
+        return req.session.sendResponse(res, StatusCodes.OK, exos);
+    }
+
+
     private async checkExerciseLimit(assignment: Assignment, members: Array<Gitlab.UserSchema>): Promise<Array<Gitlab.UserSchema>> {
         const exercises: Array<Exercise> | undefined = await ExerciseManager.getFromAssignment(assignment.name, { members: true });
         const reachedLimitUsers: Array<Gitlab.UserSchema> = [];
@@ -259,3 +309,5 @@ class ExerciseRoutes implements RoutesManager {
 
 
 export default new ExerciseRoutes();
+
+
diff --git a/ExpressAPI/src/routes/TagRoutes.ts b/ExpressAPI/src/routes/TagRoutes.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e7e673403fe94dc209d53a91616c7140bc0ea1ec
--- /dev/null
+++ b/ExpressAPI/src/routes/TagRoutes.ts
@@ -0,0 +1,132 @@
+import express, { RequestHandler } from 'express';
+import { TagType }                 from '@prisma/client';
+import * as ExpressValidator       from 'express-validator';
+import { StatusCodes }             from 'http-status-codes';
+import RoutesManager               from '../express/RoutesManager';
+import { Express }                 from 'express-serve-static-core';
+import db                          from '../helpers/DatabaseHelper';
+import SecurityCheckType           from '../types/SecurityCheckType';
+import SecurityMiddleware          from '../middlewares/SecurityMiddleware';
+import ParamsValidatorMiddleware   from '../middlewares/ParamsValidatorMiddleware';
+import DojoStatusCode              from '../shared/types/Dojo/DojoStatusCode';
+
+
+class TagRoutes implements RoutesManager {
+    private readonly tagValidator: ExpressValidator.Schema = {
+        name: {
+            trim    : true,
+            notEmpty: true
+        },
+        type: {
+            trim    : true,
+            notEmpty: true
+        }
+    };
+
+    private readonly tagProposalAnswerValidator: ExpressValidator.Schema = {
+        state  : {
+            trim    : true,
+            notEmpty: true
+        },
+        details: {
+            trim    : true,
+            optional: true
+        }
+    };
+
+    registerOnBackend(backend: Express) {
+        backend.post('/tags', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagValidator), this.createTag.bind(this) as RequestHandler);
+        backend.delete('/tags/:tagName', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), this.deleteTag.bind(this) as RequestHandler);
+        backend.get('/tags/proposals', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), this.getTagProposals.bind(this) as RequestHandler);
+        backend.post('/tags/proposals', SecurityMiddleware.check(true, SecurityCheckType.TEACHING_STAFF), ParamsValidatorMiddleware.validate(this.tagValidator), this.createTagProposal.bind(this) as RequestHandler);
+        backend.patch('/tags/proposals/:tagProposalName', SecurityMiddleware.check(true, SecurityCheckType.ADMIN), ParamsValidatorMiddleware.validate(this.tagProposalAnswerValidator), this.validateTag.bind(this) as RequestHandler);
+    }
+
+    private async createTag(req: express.Request, res: express.Response) {
+        const tagName = req.body.name;
+        const tagType = (req.body.type as string).toUpperCase() as TagType;
+
+        if ( tagType !== TagType.USERDEFINED && !req.session.profile.isAdmin ) {
+            return req.session.sendResponse(res, StatusCodes.FORBIDDEN, {}, 'Only admins can create non userDefined tags', DojoStatusCode.TAG_ONLY_ADMIN_CREATION);
+        }
+
+        await db.tag.create({
+                                data: {
+                                    name: tagName,
+                                    type: tagType
+                                }
+                            });
+
+        return req.session.sendResponse(res, StatusCodes.OK);
+    }
+
+    private async deleteTag(req: express.Request, res: express.Response) {
+        if ( req.boundParams.tag!.assignments.length > 0 ) {
+            return req.session.sendResponse(res, StatusCodes.LOCKED, {}, 'Tag is used in assignments', DojoStatusCode.TAG_WITH_ACTIVE_LINK_DELETION);
+        }
+
+        await db.tag.delete({
+                                where: { name: req.boundParams.tag!.name }
+                            });
+
+        return req.session.sendResponse(res, StatusCodes.OK);
+    }
+
+    private async getTagProposals(req: express.Request, res: express.Response) {
+        const state = req.query.stateFilter as string;
+
+        const tagProposals = await db.tagProposal.findMany(state ? {
+            where: { state: state }
+        } : {});
+
+        return req.session.sendResponse(res, StatusCodes.OK, tagProposals);
+    }
+
+    private async createTagProposal(req: express.Request, res: express.Response) {
+        const tagName = req.body.name;
+        const tagType = (req.body.type as string).toUpperCase() as TagType;
+
+        await db.tagProposal.create({
+                                        data: {
+                                            name: tagName,
+                                            type: tagType
+                                        }
+                                    });
+
+        return req.session.sendResponse(res, StatusCodes.OK);
+    }
+
+    private async validateTag(req: express.Request, res: express.Response) {
+        if ( req.boundParams.tagProposal!.state === 'PendingApproval' ) {
+            const state: string = req.body.state;
+
+            if ( state === 'Approved' ) {
+                try {
+                    await db.tag.create({
+                                            data: {
+                                                name: req.boundParams.tagProposal!.name,
+                                                type: req.boundParams.tagProposal!.type
+                                            }
+                                        });
+                } catch ( error ) {
+                    // empty
+                }
+            }
+
+            await db.tagProposal.update({
+                                            where: { name: req.boundParams.tagProposal?.name },
+                                            data : {
+                                                state  : state,
+                                                details: req.body.details ?? ''
+                                            }
+                                        });
+
+            return req.session.sendResponse(res, StatusCodes.OK);
+        } else {
+            return req.session.sendResponse(res, StatusCodes.BAD_REQUEST, {}, 'Tag proposal is not pending', DojoStatusCode.TAG_PROPOSAL_ANSWER_NOT_PENDING);
+        }
+    }
+}
+
+
+export default new TagRoutes();
diff --git a/ExpressAPI/src/shared b/ExpressAPI/src/shared
index c2afa861bf6306ddec79ffd465a4c7b0edcd3453..bf75a99ba472386daa111c2fefbe69a4272ef48c 160000
--- a/ExpressAPI/src/shared
+++ b/ExpressAPI/src/shared
@@ -1 +1 @@
-Subproject commit c2afa861bf6306ddec79ffd465a4c7b0edcd3453
+Subproject commit bf75a99ba472386daa111c2fefbe69a4272ef48c
diff --git a/ExpressAPI/src/types/DatabaseTypes.ts b/ExpressAPI/src/types/DatabaseTypes.ts
index 011d2efc5643f66cefb4da435b26e4579accfc32..2a7109c532b14733f5f32328757d922a404821b7 100644
--- a/ExpressAPI/src/types/DatabaseTypes.ts
+++ b/ExpressAPI/src/types/DatabaseTypes.ts
@@ -9,14 +9,16 @@ const userBase = Prisma.validator<Prisma.UserDefaultArgs>()({
 const assignmentBase = Prisma.validator<Prisma.AssignmentDefaultArgs>()({
                                                                             include: {
                                                                                 exercises: true,
-                                                                                staff    : true
+                                                                                staff    : true,
+                                                                                tags     : true
                                                                             }
                                                                         });
 const exerciseBase = Prisma.validator<Prisma.ExerciseDefaultArgs>()({
                                                                         include: {
                                                                             assignment: true,
                                                                             members   : true,
-                                                                            results   : true
+                                                                            results   : true,
+                                                                            tags      : true
                                                                         }
                                                                     });
 const resultBase = Prisma.validator<Prisma.ResultDefaultArgs>()({
@@ -24,6 +26,12 @@ const resultBase = Prisma.validator<Prisma.ResultDefaultArgs>()({
                                                                         exercise: true
                                                                     }
                                                                 });
+const tagBase = Prisma.validator<Prisma.TagDefaultArgs>()({
+                                                              include: {
+                                                                  exercises  : true,
+                                                                  assignments: true
+                                                              }
+                                                          });
 
 
 export type User = Prisma.UserGetPayload<typeof userBase> & {
@@ -37,4 +45,5 @@ export type Exercise = Prisma.ExerciseGetPayload<typeof exerciseBase> & {
 export type Assignment = Prisma.AssignmentGetPayload<typeof assignmentBase> & {
     corrections: LazyVal<Array<Exercise>>
 }
-export type Result = Prisma.ResultGetPayload<typeof resultBase>
\ No newline at end of file
+export type Result = Prisma.ResultGetPayload<typeof resultBase>
+export type Tag = Prisma.TagGetPayload<typeof tagBase>
\ No newline at end of file
diff --git a/ExpressAPI/src/types/SecurityCheckType.ts b/ExpressAPI/src/types/SecurityCheckType.ts
index 3a0b733103af4604e10f917ec3edc4c7f56b3b66..e6f122b576e49776c4c398a124ae7fcabc9c6367 100644
--- a/ExpressAPI/src/types/SecurityCheckType.ts
+++ b/ExpressAPI/src/types/SecurityCheckType.ts
@@ -1,5 +1,7 @@
 enum SecurityCheckType {
     TEACHING_STAFF          = 'teachingStaff',
+    ADMIN                   = 'admin',
+    EXERCISE_MEMBERS        = 'exerciseMembers',
     ASSIGNMENT_STAFF        = 'assignmentStaff',
     ASSIGNMENT_IS_PUBLISHED = 'assignmentIsPublished',
     EXERCISE_SECRET         = 'exerciseSecret',
diff --git a/ExpressAPI/src/types/express/index.d.ts b/ExpressAPI/src/types/express/index.d.ts
index 744609f9823e62e1348d63df9252a48ccfa3b64b..59a5e0056b7d85185e11d49a66d82153cab01192 100644
--- a/ExpressAPI/src/types/express/index.d.ts
+++ b/ExpressAPI/src/types/express/index.d.ts
@@ -1,5 +1,6 @@
-import Session                  from '../../controllers/Session.js';
-import { Assignment, Exercise } from '../DatabaseTypes.js';
+import Session                       from '../../controllers/Session.js';
+import { Assignment, Exercise, Tag } from '../DatabaseTypes';
+import { TagProposal }               from '@prisma/client';
 
 // to make the file a module and avoid the TypeScript error
 export {};
@@ -9,7 +10,7 @@ declare global {
         export interface Request {
             session: Session,
             boundParams: {
-                assignment: Assignment | undefined, exercise: Exercise | undefined
+                assignment: Assignment | undefined, exercise: Exercise | undefined, tag: Tag | undefined, tagProposal: TagProposal | undefined
             }
         }
     }