diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..103bd2c647aba772a54dd4140f55da75da9f20f9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+### Own ###
+taller
+*.pdf
\ No newline at end of file
diff --git a/angular/RestClient/angular.json b/angular/RestClient/angular.json
index 0813b43c89578f44e3ff8ee8af010e6ed102fa83..b9017eb47cbc0d902128a7211d7d8f08c6d1f48a 100644
--- a/angular/RestClient/angular.json
+++ b/angular/RestClient/angular.json
@@ -16,9 +16,7 @@
             "outputPath": "dist/rest-client",
             "index": "src/index.html",
             "browser": "src/main.ts",
-            "polyfills": [
-              "zone.js"
-            ],
+            "polyfills": ["zone.js", "@angular/localize/init"],
             "tsConfig": "tsconfig.app.json",
             "assets": [
               {
@@ -27,9 +25,14 @@
               }
             ],
             "styles": [
+              "node_modules/bootstrap/dist/css/bootstrap.min.css",
+              "@angular/material/prebuilt-themes/azure-blue.css",
               "src/styles.css"
             ],
-            "scripts": [],
+            "scripts": [
+              "node_modules/jquery/dist/jquery.min.js",
+              "node_modules/bootstrap/dist/js/bootstrap.min.js"
+            ],
             "server": "src/main.server.ts",
             "prerender": true,
             "ssr": {
@@ -80,7 +83,8 @@
           "options": {
             "polyfills": [
               "zone.js",
-              "zone.js/testing"
+              "zone.js/testing",
+              "@angular/localize/init"
             ],
             "tsConfig": "tsconfig.spec.json",
             "assets": [
@@ -90,6 +94,7 @@
               }
             ],
             "styles": [
+              "@angular/material/prebuilt-themes/azure-blue.css",
               "src/styles.css"
             ],
             "scripts": []
@@ -97,5 +102,8 @@
         }
       }
     }
+  },
+  "cli": {
+    "analytics": false
   }
 }
diff --git a/angular/RestClient/package-lock.json b/angular/RestClient/package-lock.json
index 1382fdaae994c0849bfe75d77ac9a06be0152a2d..a5d201bf11869266cc967b0e328660d5d8870bc7 100644
--- a/angular/RestClient/package-lock.json
+++ b/angular/RestClient/package-lock.json
@@ -9,16 +9,22 @@
       "version": "0.0.0",
       "dependencies": {
         "@angular/animations": "^18.2.0",
+        "@angular/cdk": "^18.2.9",
         "@angular/common": "^18.2.0",
         "@angular/compiler": "^18.2.0",
         "@angular/core": "^18.2.0",
         "@angular/forms": "^18.2.0",
+        "@angular/material": "^18.2.9",
         "@angular/platform-browser": "^18.2.0",
         "@angular/platform-browser-dynamic": "^18.2.0",
         "@angular/platform-server": "^18.2.0",
         "@angular/router": "^18.2.0",
         "@angular/ssr": "^18.2.7",
+        "@ng-bootstrap/ng-bootstrap": "^17.0.1",
+        "@popperjs/core": "^2.11.8",
+        "bootstrap": "^3.4.0",
         "express": "^4.18.2",
+        "jquery": "^3.4.1",
         "rxjs": "~7.8.0",
         "tslib": "^2.3.0",
         "zone.js": "~0.14.10"
@@ -27,23 +33,39 @@
         "@angular-devkit/build-angular": "^18.2.7",
         "@angular/cli": "^18.2.7",
         "@angular/compiler-cli": "^18.2.0",
+        "@angular/localize": "^18.2.0",
         "@types/express": "^4.17.17",
         "@types/jasmine": "~5.1.0",
         "@types/node": "^18.18.0",
+        "autoprefixer": "^10.4.20",
         "jasmine-core": "~5.2.0",
         "karma": "~6.4.0",
         "karma-chrome-launcher": "~3.2.0",
         "karma-coverage": "~2.2.0",
         "karma-jasmine": "~5.1.0",
         "karma-jasmine-html-reporter": "~2.1.0",
+        "postcss": "^8.4.47",
+        "tailwindcss": "^3.4.14",
         "typescript": "~5.5.2"
       }
     },
+    "node_modules/@alloc/quick-lru": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
+      "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/@ampproject/remapping": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
       "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
-      "dev": true,
       "license": "Apache-2.0",
       "dependencies": {
         "@jridgewell/gen-mapping": "^0.3.5",
@@ -54,13 +76,13 @@
       }
     },
     "node_modules/@angular-devkit/architect": {
-      "version": "0.1802.8",
-      "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.8.tgz",
-      "integrity": "sha512-/rtFQEKgS7LlB9oHr4NCBSdKnvP5kr8L5Hbd3Vl8hZOYK9QWjxKPEXnryA2d5+PCE98bBzZswCNXqELZCPTgIQ==",
+      "version": "0.1802.11",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1802.11.tgz",
+      "integrity": "sha512-p+XIc/j51aI83ExNdeZwvkm1F4wkuKMGUUoj0MVUUi5E6NoiMlXYm6uU8+HbRvPBzGy5+3KOiGp3Fks0UmDSAA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@angular-devkit/core": "18.2.8",
+        "@angular-devkit/core": "18.2.11",
         "rxjs": "7.8.1"
       },
       "engines": {
@@ -70,17 +92,17 @@
       }
     },
     "node_modules/@angular-devkit/build-angular": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.8.tgz",
-      "integrity": "sha512-qK/iLk7A8vQp1CyiJV4DpwfLjPKoiOlTtFqoO5vD8Tyxmc+R06FQp6GJTsZ7JtrTLYSiH+QAWiY6NgF/Rj/hHg==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-18.2.11.tgz",
+      "integrity": "sha512-09Ln3NAdlMw/wMLgnwYU5VgWV5TPBEHolZUIvE9D8b6SFWBCowk3B3RWeAMgg7Peuf9SKwqQHBz2b1C7RTP/8g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@ampproject/remapping": "2.3.0",
-        "@angular-devkit/architect": "0.1802.8",
-        "@angular-devkit/build-webpack": "0.1802.8",
-        "@angular-devkit/core": "18.2.8",
-        "@angular/build": "18.2.8",
+        "@angular-devkit/architect": "0.1802.11",
+        "@angular-devkit/build-webpack": "0.1802.11",
+        "@angular-devkit/core": "18.2.11",
+        "@angular/build": "18.2.11",
         "@babel/core": "7.25.2",
         "@babel/generator": "7.25.0",
         "@babel/helper-annotate-as-pure": "7.24.7",
@@ -91,7 +113,7 @@
         "@babel/preset-env": "7.25.3",
         "@babel/runtime": "7.25.0",
         "@discoveryjs/json-ext": "0.6.1",
-        "@ngtools/webpack": "18.2.8",
+        "@ngtools/webpack": "18.2.11",
         "@vitejs/plugin-basic-ssl": "1.1.0",
         "ansi-colors": "4.1.3",
         "autoprefixer": "10.4.20",
@@ -102,7 +124,7 @@
         "css-loader": "7.1.2",
         "esbuild-wasm": "0.23.0",
         "fast-glob": "3.3.2",
-        "http-proxy-middleware": "3.0.0",
+        "http-proxy-middleware": "3.0.3",
         "https-proxy-agent": "7.0.5",
         "istanbul-lib-instrument": "6.0.3",
         "jsonc-parser": "3.3.1",
@@ -198,6 +220,35 @@
         }
       }
     },
+    "node_modules/@angular-devkit/build-angular/node_modules/postcss": {
+      "version": "8.4.41",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
+      "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.7",
+        "picocolors": "^1.0.1",
+        "source-map-js": "^1.2.0"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
     "node_modules/@angular-devkit/build-angular/node_modules/tslib": {
       "version": "2.6.3",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
@@ -206,13 +257,13 @@
       "license": "0BSD"
     },
     "node_modules/@angular-devkit/build-webpack": {
-      "version": "0.1802.8",
-      "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.8.tgz",
-      "integrity": "sha512-uPpopkXkO66SSdjtVr7xCyQCPs/x6KUC76xkDc4j0b8EEHifTbi/fNpbkcZ6wBmoAfjKLWXfKvtkh0TqKK5Hkw==",
+      "version": "0.1802.11",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1802.11.tgz",
+      "integrity": "sha512-G76rNsyn1iQk7qjyr+K4rnDzfalmEswmwXQorypSDGaHYzIDY1SZXMoP4225WMq5fJNBOJrk82FA0PSfnPE+zQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@angular-devkit/architect": "0.1802.8",
+        "@angular-devkit/architect": "0.1802.11",
         "rxjs": "7.8.1"
       },
       "engines": {
@@ -226,9 +277,9 @@
       }
     },
     "node_modules/@angular-devkit/core": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.8.tgz",
-      "integrity": "sha512-4o2T6wsmXGE/v53+F8L7kGoN2+qzt03C9rtjLVQpOljzpJVttQ8bhvfWxyYLWwcl04RWqRa+82fpIZtBkOlZJw==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-18.2.11.tgz",
+      "integrity": "sha512-H9P1shRGigORWJHUY2BRa2YurT+DVminrhuaYHsbhXBRsPmgB2Dx/30YLTnC1s5XmR9QIRUCsg/d3kyT1wd5Zg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -254,13 +305,13 @@
       }
     },
     "node_modules/@angular-devkit/schematics": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.8.tgz",
-      "integrity": "sha512-i/h2Oji5FhJMC7wDSnIl5XUe/qym+C1ZwScaATJwDyRLCUIynZkj5rLgdG/uK6l+H0PgvxigkF+akWpokkwW6w==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-18.2.11.tgz",
+      "integrity": "sha512-efRK3FotTFp4KD5u42jWfXpHUALXB9kJNsWiB4wEImKFH6CN+vjBspJQuLqk2oeBFh/7D2qRMc5P+2tZHM5hdw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@angular-devkit/core": "18.2.8",
+        "@angular-devkit/core": "18.2.11",
         "jsonc-parser": "3.3.1",
         "magic-string": "0.30.11",
         "ora": "5.4.1",
@@ -273,9 +324,9 @@
       }
     },
     "node_modules/@angular/animations": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.8.tgz",
-      "integrity": "sha512-dMSn2hg70siv3lhP+vqhMbgc923xw6XBUvnpCPEzhZqFHvPXfh/LubmsD5RtqHmjWebXtgVcgS+zg3Gq3jB2lg==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-18.2.10.tgz",
+      "integrity": "sha512-LT5+CocFZJ4t5jXsXLx5w/sBuWSxOEjmNTYga13usRcLOblrAB902pjUdFCHEZyrCUgm4MH8vov9fMS+Ks2GCw==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -284,18 +335,18 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/core": "18.2.8"
+        "@angular/core": "18.2.10"
       }
     },
     "node_modules/@angular/build": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.8.tgz",
-      "integrity": "sha512-ufuA4vHJSrL9SQW7bKV61DOoN1mm0t0ILTHaxSoCG3YF70cZJOX7+HNp3cK2uoldRMwbTOKSvCWBw54KKDRd5Q==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/build/-/build-18.2.11.tgz",
+      "integrity": "sha512-AgirvSCmqUKiDE3C0rl3JA68OkOqQWDKUvjqRHXCkhxldLVOVoeIl87+jBYK/v9gcmk+K+ju+5wbGEfu1FjhiQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "@ampproject/remapping": "2.3.0",
-        "@angular-devkit/architect": "0.1802.8",
+        "@angular-devkit/architect": "0.1802.11",
         "@babel/core": "7.25.2",
         "@babel/helper-annotate-as-pure": "7.24.7",
         "@babel/helper-split-export-declaration": "7.24.7",
@@ -356,19 +407,36 @@
         }
       }
     },
+    "node_modules/@angular/cdk": {
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-18.2.11.tgz",
+      "integrity": "sha512-FuvfhrSz2ch0gyOVHrkWq2C/I2PnOzKYSXlG/VEG+ize/WNrvlYy//5WVrTh/hv+HD9sdoWPr9ULXsfFfgbo7w==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "optionalDependencies": {
+        "parse5": "^7.1.2"
+      },
+      "peerDependencies": {
+        "@angular/common": "^18.0.0 || ^19.0.0",
+        "@angular/core": "^18.0.0 || ^19.0.0",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
     "node_modules/@angular/cli": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.8.tgz",
-      "integrity": "sha512-GKXG7F7z5rxwZ8/bnW/Bp8/zsfE/BpHmIP/icLfUIOwv2kaY5OD2tfQssWXPEuqZzYq2AYz+wjVSbWjxGoja8A==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-18.2.11.tgz",
+      "integrity": "sha512-0JI1xjOLRemBPjdT/yVlabxc3Zkjqa/lhvVxxVC1XhKoW7yGxIGwNrQ4pka4CcQtCuktO6KPMmTGIu8YgC3cpw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@angular-devkit/architect": "0.1802.8",
-        "@angular-devkit/core": "18.2.8",
-        "@angular-devkit/schematics": "18.2.8",
+        "@angular-devkit/architect": "0.1802.11",
+        "@angular-devkit/core": "18.2.11",
+        "@angular-devkit/schematics": "18.2.11",
         "@inquirer/prompts": "5.3.8",
         "@listr2/prompt-adapter-inquirer": "2.0.15",
-        "@schematics/angular": "18.2.8",
+        "@schematics/angular": "18.2.11",
         "@yarnpkg/lockfile": "1.1.0",
         "ini": "4.1.3",
         "jsonc-parser": "3.3.1",
@@ -391,9 +459,9 @@
       }
     },
     "node_modules/@angular/common": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.8.tgz",
-      "integrity": "sha512-TYsKtE5nVaIScWSLGSO34Skc+s3hB/BujSddnfQHoNFvPT/WR0dfmdlpVCTeLj+f50htFoMhW11tW99PbK+whQ==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/common/-/common-18.2.10.tgz",
+      "integrity": "sha512-YzTCmuqLiOuT+Yv07vuKymDWiebOVZ8BuXakJiz4EM7FMoOw5gICHJ04jepZSjDNWpA16e7kJSdt5ucnmvCFDQ==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -402,14 +470,14 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/core": "18.2.8",
+        "@angular/core": "18.2.10",
         "rxjs": "^6.5.3 || ^7.4.0"
       }
     },
     "node_modules/@angular/compiler": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.8.tgz",
-      "integrity": "sha512-JRedHNfK1CCPVyeGQB5w3WBYqMA6X8Q240CkvjlGfn0pVXihf9DWk3nkSQJVgYxpvpHfxdgjaYZ5IpMzlkmkhw==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-18.2.10.tgz",
+      "integrity": "sha512-cu+Uq1nnyl00Glg0+2uvm+Xpaq5b4YvWpaLGGtit7uGETAJ4L/frlBVeaTRhEoaIAGBI+RRlyuFLae+etQDA0w==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -418,7 +486,7 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/core": "18.2.8"
+        "@angular/core": "18.2.10"
       },
       "peerDependenciesMeta": {
         "@angular/core": {
@@ -427,10 +495,9 @@
       }
     },
     "node_modules/@angular/compiler-cli": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.8.tgz",
-      "integrity": "sha512-OksDE4LWQUCcIvMjtZF7eiDCdIMrcMMpC1+Q0PIYi7KmnqXFGs4/Y0NdJvtn/LrQznzz5WaKM3ZDVNZTRX4wmw==",
-      "dev": true,
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-18.2.10.tgz",
+      "integrity": "sha512-CNFStKWMB89MFKAZZFUOhoQi+fHqRLgNOOrI73LjizXixvngEh3BDZJRtK9hbSGG+giujBrummEA60CWAw69MA==",
       "license": "MIT",
       "dependencies": {
         "@babel/core": "7.25.2",
@@ -451,14 +518,42 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/compiler": "18.2.8",
+        "@angular/compiler": "18.2.10",
         "typescript": ">=5.4 <5.6"
       }
     },
+    "node_modules/@angular/compiler-cli/node_modules/chokidar": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
+      "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
+      "license": "MIT",
+      "dependencies": {
+        "readdirp": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
+    "node_modules/@angular/compiler-cli/node_modules/readdirp": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
+      "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 14.16.0"
+      },
+      "funding": {
+        "type": "individual",
+        "url": "https://paulmillr.com/funding/"
+      }
+    },
     "node_modules/@angular/core": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.8.tgz",
-      "integrity": "sha512-NwIuX/Iby1jT6Iv1/s6S3wOFf8xfuQR3MPGvKhGgNtjXLbHG+TXceK9+QPZC0s9/Z8JR/hz+li34B79GrIKgUg==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.10.tgz",
+      "integrity": "sha512-EfxVz0pLaxnOppOYkdhnaUkk8HZT+uxaAGpJD3ppAa7YAWTE9xIGoNJmtS33cZNNOnvriMkdv7yn6pDtV4ct+Q==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -472,9 +567,9 @@
       }
     },
     "node_modules/@angular/forms": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.8.tgz",
-      "integrity": "sha512-JCLki7KC6D5vF6dE6yGlBmW33khIgpHs8N9SzuiJtkQqNDTIQA8cPsGV6qpLpxflxASynQOX5lDkWYdQyfm77Q==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-18.2.10.tgz",
+      "integrity": "sha512-2VprGB+enJIeqfz2oALmP/G/UiFzpZW6PHgyZXhk/0J/UMsa26JoYxwDFvfdm/WGTrB+VaQEG7in5xwiFPAFtQ==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -483,16 +578,58 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/common": "18.2.8",
-        "@angular/core": "18.2.8",
-        "@angular/platform-browser": "18.2.8",
+        "@angular/common": "18.2.10",
+        "@angular/core": "18.2.10",
+        "@angular/platform-browser": "18.2.10",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
+    "node_modules/@angular/localize": {
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-18.2.10.tgz",
+      "integrity": "sha512-AOdQn4B/yqei/k0qpd4fVX/WXOzYfLWnp0KtG5q3hyWwMy2MfJ5rfCX0WiwNICzzIRBCjLsYmm8/qxNizK6ORg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/core": "7.25.2",
+        "@types/babel__core": "7.20.5",
+        "fast-glob": "3.3.2",
+        "yargs": "^17.2.1"
+      },
+      "bin": {
+        "localize-extract": "tools/bundles/src/extract/cli.js",
+        "localize-migrate": "tools/bundles/src/migrate/cli.js",
+        "localize-translate": "tools/bundles/src/translate/cli.js"
+      },
+      "engines": {
+        "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
+      },
+      "peerDependencies": {
+        "@angular/compiler": "18.2.10",
+        "@angular/compiler-cli": "18.2.10"
+      }
+    },
+    "node_modules/@angular/material": {
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/material/-/material-18.2.11.tgz",
+      "integrity": "sha512-VPfnpwmg6p5DsH1UMfOXjKA+qAbUx6nyinGWpx4+ntr/T1oEhRk5CnoOtVS0Xk0rnRSbEF6ayjDBH2YPR9ol3A==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@angular/animations": "^18.0.0 || ^19.0.0",
+        "@angular/cdk": "18.2.11",
+        "@angular/common": "^18.0.0 || ^19.0.0",
+        "@angular/core": "^18.0.0 || ^19.0.0",
+        "@angular/forms": "^18.0.0 || ^19.0.0",
+        "@angular/platform-browser": "^18.0.0 || ^19.0.0",
         "rxjs": "^6.5.3 || ^7.4.0"
       }
     },
     "node_modules/@angular/platform-browser": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.8.tgz",
-      "integrity": "sha512-EPai4ZPqSq3ilLJUC85kPi9wo5j5suQovwtgRyjM/75D9Qy4TV19g8hkVM5Co/zrltO8a2G6vDscCNI5BeGw2A==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-18.2.10.tgz",
+      "integrity": "sha512-zKyRKFr3AaEA4SE/DEeb5FWHJutT26avHZog6ZGDkMeMN12zMtSqjPuTSgmDXCWleoOkzbb+nhAQ+fK/EyGyPA==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -501,9 +638,9 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/animations": "18.2.8",
-        "@angular/common": "18.2.8",
-        "@angular/core": "18.2.8"
+        "@angular/animations": "18.2.10",
+        "@angular/common": "18.2.10",
+        "@angular/core": "18.2.10"
       },
       "peerDependenciesMeta": {
         "@angular/animations": {
@@ -512,9 +649,9 @@
       }
     },
     "node_modules/@angular/platform-browser-dynamic": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.8.tgz",
-      "integrity": "sha512-poZoapDqyN/rxGKQ3C6esdPiPLMkSpP2v12hoEa12KHgfPk7T1e+a+NMyJjV8HeOY3WyvL7tGRhW0NPTajTkhw==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-18.2.10.tgz",
+      "integrity": "sha512-syKyOTgfQnMxfpDRP1khTSPZ5dsMgA8YQwNF6KsB3eZQl15CKSka7bzjMOUWeZ8M3WShOp1AzTf0MfwNeh0UBA==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -523,16 +660,16 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/common": "18.2.8",
-        "@angular/compiler": "18.2.8",
-        "@angular/core": "18.2.8",
-        "@angular/platform-browser": "18.2.8"
+        "@angular/common": "18.2.10",
+        "@angular/compiler": "18.2.10",
+        "@angular/core": "18.2.10",
+        "@angular/platform-browser": "18.2.10"
       }
     },
     "node_modules/@angular/platform-server": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-18.2.8.tgz",
-      "integrity": "sha512-gt+UKnDhnsDgpiXTQmkMsTzBMh0+FVkihGHHvjoL/HQ1lBz5od9QIj6EB6+aco5XkPoXaSqkfJ5hi/bnnEJDcg==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-18.2.10.tgz",
+      "integrity": "sha512-vewG3K03uLmxmHyjQivzIxvCBQ334hO33vC1rFZpbe3TX+rpVg7FYmz9ArdTgwbuxMSvImrcBWIYs8m/ZpKs9Q==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0",
@@ -542,17 +679,17 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/animations": "18.2.8",
-        "@angular/common": "18.2.8",
-        "@angular/compiler": "18.2.8",
-        "@angular/core": "18.2.8",
-        "@angular/platform-browser": "18.2.8"
+        "@angular/animations": "18.2.10",
+        "@angular/common": "18.2.10",
+        "@angular/compiler": "18.2.10",
+        "@angular/core": "18.2.10",
+        "@angular/platform-browser": "18.2.10"
       }
     },
     "node_modules/@angular/router": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.8.tgz",
-      "integrity": "sha512-L+olYgxIiBq+tbfayVI0cv1yOuymsw33msnGC2l/vpc9sSVfqGzESFnB4yMVU3vHtE9v6v2Y6O+iV44/b79W/g==",
+      "version": "18.2.10",
+      "resolved": "https://registry.npmjs.org/@angular/router/-/router-18.2.10.tgz",
+      "integrity": "sha512-ZqJgOGOfvW0epsc7pIo7DffZqYHo3O9aUCVepZAhOxqtjF/sfhX2fy+A0xopTIiR0eM3LrT823V+2hjlBHj+CA==",
       "license": "MIT",
       "dependencies": {
         "tslib": "^2.3.0"
@@ -561,16 +698,16 @@
         "node": "^18.19.1 || ^20.11.1 || >=22.0.0"
       },
       "peerDependencies": {
-        "@angular/common": "18.2.8",
-        "@angular/core": "18.2.8",
-        "@angular/platform-browser": "18.2.8",
+        "@angular/common": "18.2.10",
+        "@angular/core": "18.2.10",
+        "@angular/platform-browser": "18.2.10",
         "rxjs": "^6.5.3 || ^7.4.0"
       }
     },
     "node_modules/@angular/ssr": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-18.2.8.tgz",
-      "integrity": "sha512-ShQFI5bFPiLIg1+exYTthh53pGH0Guf+5CoKwGlZpV5sHGnGDO2VvlDyVkKYQfN/ZOxZbwzQ8GFggW1i5Bs18g==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@angular/ssr/-/ssr-18.2.11.tgz",
+      "integrity": "sha512-JO9PCSt3NIHcEkXSS3WkIyNOlbcgZh1IE5u/AVPeDEkKRhmu2vW3mf5X3YJ+m+UMbUG4gQst27sK4EK57GExOg==",
       "license": "MIT",
       "dependencies": {
         "critters": "0.0.24",
@@ -582,13 +719,13 @@
       }
     },
     "node_modules/@babel/code-frame": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz",
-      "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==",
-      "dev": true,
+      "version": "7.26.2",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+      "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
       "license": "MIT",
       "dependencies": {
-        "@babel/highlight": "^7.25.7",
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "js-tokens": "^4.0.0",
         "picocolors": "^1.0.0"
       },
       "engines": {
@@ -596,10 +733,9 @@
       }
     },
     "node_modules/@babel/compat-data": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz",
-      "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==",
-      "dev": true,
+      "version": "7.26.2",
+      "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz",
+      "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==",
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -609,7 +745,6 @@
       "version": "7.25.2",
       "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz",
       "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
@@ -640,14 +775,12 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
       "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@babel/core/node_modules/semver": {
       "version": "6.3.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
       "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
-      "dev": true,
       "license": "ISC",
       "bin": {
         "semver": "bin/semver.js"
@@ -657,7 +790,6 @@
       "version": "7.25.0",
       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz",
       "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/types": "^7.25.0",
@@ -683,28 +815,27 @@
       }
     },
     "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.7.tgz",
-      "integrity": "sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.9.tgz",
+      "integrity": "sha512-C47lC7LIDCnz0h4vai/tpNOI95tCd5ZT3iBt/DBH5lXKHZsyNQv18yf1wIIg2ntiQNgmAvA+DgZ82iW8Qdym8g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/traverse": "^7.25.7",
-        "@babel/types": "^7.25.7"
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-compilation-targets": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz",
-      "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==",
-      "dev": true,
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
+      "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==",
       "license": "MIT",
       "dependencies": {
-        "@babel/compat-data": "^7.25.7",
-        "@babel/helper-validator-option": "^7.25.7",
+        "@babel/compat-data": "^7.25.9",
+        "@babel/helper-validator-option": "^7.25.9",
         "browserslist": "^4.24.0",
         "lru-cache": "^5.1.1",
         "semver": "^6.3.1"
@@ -717,25 +848,24 @@
       "version": "6.3.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
       "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
-      "dev": true,
       "license": "ISC",
       "bin": {
         "semver": "bin/semver.js"
       }
     },
     "node_modules/@babel/helper-create-class-features-plugin": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.7.tgz",
-      "integrity": "sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz",
+      "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-annotate-as-pure": "^7.25.7",
-        "@babel/helper-member-expression-to-functions": "^7.25.7",
-        "@babel/helper-optimise-call-expression": "^7.25.7",
-        "@babel/helper-replace-supers": "^7.25.7",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7",
-        "@babel/traverse": "^7.25.7",
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-member-expression-to-functions": "^7.25.9",
+        "@babel/helper-optimise-call-expression": "^7.25.9",
+        "@babel/helper-replace-supers": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
         "semver": "^6.3.1"
       },
       "engines": {
@@ -746,13 +876,13 @@
       }
     },
     "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz",
-      "integrity": "sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.7"
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -769,13 +899,13 @@
       }
     },
     "node_modules/@babel/helper-create-regexp-features-plugin": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.7.tgz",
-      "integrity": "sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.9.tgz",
+      "integrity": "sha512-ORPNZ3h6ZRkOyAa/SaHU+XsLZr0UQzRwuDQ0cczIA17nAzZ+85G5cVkOJIj7QavLZGSe8QXUmNFxSZzjcZF9bw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-annotate-as-pure": "^7.25.7",
+        "@babel/helper-annotate-as-pure": "^7.25.9",
         "regexpu-core": "^6.1.1",
         "semver": "^6.3.1"
       },
@@ -787,13 +917,13 @@
       }
     },
     "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz",
-      "integrity": "sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.7"
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -827,44 +957,41 @@
       }
     },
     "node_modules/@babel/helper-member-expression-to-functions": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.7.tgz",
-      "integrity": "sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz",
+      "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/traverse": "^7.25.7",
-        "@babel/types": "^7.25.7"
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-imports": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz",
-      "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==",
-      "dev": true,
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+      "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/traverse": "^7.25.7",
-        "@babel/types": "^7.25.7"
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-module-transforms": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz",
-      "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==",
-      "dev": true,
+      "version": "7.26.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+      "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-module-imports": "^7.25.7",
-        "@babel/helper-simple-access": "^7.25.7",
-        "@babel/helper-validator-identifier": "^7.25.7",
-        "@babel/traverse": "^7.25.7"
+        "@babel/helper-module-imports": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -874,22 +1001,22 @@
       }
     },
     "node_modules/@babel/helper-optimise-call-expression": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.7.tgz",
-      "integrity": "sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz",
+      "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.7"
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-plugin-utils": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz",
-      "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz",
+      "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -897,15 +1024,15 @@
       }
     },
     "node_modules/@babel/helper-remap-async-to-generator": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.7.tgz",
-      "integrity": "sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz",
+      "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-annotate-as-pure": "^7.25.7",
-        "@babel/helper-wrap-function": "^7.25.7",
-        "@babel/traverse": "^7.25.7"
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-wrap-function": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -915,28 +1042,28 @@
       }
     },
     "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz",
-      "integrity": "sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.7"
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-replace-supers": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.7.tgz",
-      "integrity": "sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz",
+      "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-member-expression-to-functions": "^7.25.7",
-        "@babel/helper-optimise-call-expression": "^7.25.7",
-        "@babel/traverse": "^7.25.7"
+        "@babel/helper-member-expression-to-functions": "^7.25.9",
+        "@babel/helper-optimise-call-expression": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -946,28 +1073,28 @@
       }
     },
     "node_modules/@babel/helper-simple-access": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz",
-      "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.9.tgz",
+      "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/traverse": "^7.25.7",
-        "@babel/types": "^7.25.7"
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.7.tgz",
-      "integrity": "sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz",
+      "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/traverse": "^7.25.7",
-        "@babel/types": "^7.25.7"
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -987,88 +1114,67 @@
       }
     },
     "node_modules/@babel/helper-string-parser": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz",
-      "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==",
-      "dev": true,
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+      "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-identifier": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz",
-      "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==",
-      "dev": true,
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+      "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-validator-option": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz",
-      "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==",
-      "dev": true,
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+      "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helper-wrap-function": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.7.tgz",
-      "integrity": "sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz",
+      "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/template": "^7.25.7",
-        "@babel/traverse": "^7.25.7",
-        "@babel/types": "^7.25.7"
+        "@babel/template": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/helpers": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz",
-      "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "@babel/template": "^7.25.7",
-        "@babel/types": "^7.25.7"
-      },
-      "engines": {
-        "node": ">=6.9.0"
-      }
-    },
-    "node_modules/@babel/highlight": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz",
-      "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==",
-      "dev": true,
+      "version": "7.26.0",
+      "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
+      "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-validator-identifier": "^7.25.7",
-        "chalk": "^2.4.2",
-        "js-tokens": "^4.0.0",
-        "picocolors": "^1.0.0"
+        "@babel/template": "^7.25.9",
+        "@babel/types": "^7.26.0"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz",
-      "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==",
-      "dev": true,
+      "version": "7.26.2",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
+      "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.8"
+        "@babel/types": "^7.26.0"
       },
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -1078,14 +1184,14 @@
       }
     },
     "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.7.tgz",
-      "integrity": "sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz",
+      "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/traverse": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1095,13 +1201,13 @@
       }
     },
     "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.7.tgz",
-      "integrity": "sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz",
+      "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1111,13 +1217,13 @@
       }
     },
     "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.7.tgz",
-      "integrity": "sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz",
+      "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1127,15 +1233,15 @@
       }
     },
     "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.7.tgz",
-      "integrity": "sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz",
+      "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7",
-        "@babel/plugin-transform-optional-chaining": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9",
+        "@babel/plugin-transform-optional-chaining": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1145,14 +1251,14 @@
       }
     },
     "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.7.tgz",
-      "integrity": "sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz",
+      "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/traverse": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1243,13 +1349,13 @@
       }
     },
     "node_modules/@babel/plugin-syntax-import-assertions": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz",
-      "integrity": "sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ==",
+      "version": "7.26.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz",
+      "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1428,13 +1534,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-arrow-functions": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.7.tgz",
-      "integrity": "sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz",
+      "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1481,13 +1587,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-block-scoped-functions": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.7.tgz",
-      "integrity": "sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz",
+      "integrity": "sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1497,13 +1603,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-block-scoping": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.7.tgz",
-      "integrity": "sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz",
+      "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1513,14 +1619,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-class-properties": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.7.tgz",
-      "integrity": "sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz",
+      "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-class-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1530,14 +1636,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-class-static-block": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz",
-      "integrity": "sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ==",
+      "version": "7.26.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz",
+      "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-class-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1547,17 +1653,17 @@
       }
     },
     "node_modules/@babel/plugin-transform-classes": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.7.tgz",
-      "integrity": "sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz",
+      "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-annotate-as-pure": "^7.25.7",
-        "@babel/helper-compilation-targets": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-replace-supers": "^7.25.7",
-        "@babel/traverse": "^7.25.7",
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-replace-supers": "^7.25.9",
+        "@babel/traverse": "^7.25.9",
         "globals": "^11.1.0"
       },
       "engines": {
@@ -1568,27 +1674,27 @@
       }
     },
     "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz",
-      "integrity": "sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.7"
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/plugin-transform-computed-properties": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.7.tgz",
-      "integrity": "sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz",
+      "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/template": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/template": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1598,13 +1704,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-destructuring": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.7.tgz",
-      "integrity": "sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz",
+      "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1614,14 +1720,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-dotall-regex": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.7.tgz",
-      "integrity": "sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz",
+      "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1631,13 +1737,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-duplicate-keys": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.7.tgz",
-      "integrity": "sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz",
+      "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1647,14 +1753,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.7.tgz",
-      "integrity": "sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz",
+      "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1664,13 +1770,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-dynamic-import": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz",
-      "integrity": "sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz",
+      "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1680,14 +1786,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-exponentiation-operator": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.7.tgz",
-      "integrity": "sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.9.tgz",
+      "integrity": "sha512-KRhdhlVk2nObA5AYa7QMgTMTVJdfHprfpAk4DjZVtllqRg9qarilstTKEhpVjyt+Npi8ThRyiV8176Am3CodPA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-builder-binary-assignment-operator-visitor": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1697,13 +1803,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-export-namespace-from": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz",
-      "integrity": "sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz",
+      "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1713,14 +1819,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-for-of": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.7.tgz",
-      "integrity": "sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz",
+      "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1730,15 +1836,15 @@
       }
     },
     "node_modules/@babel/plugin-transform-function-name": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.7.tgz",
-      "integrity": "sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz",
+      "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-compilation-targets": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/traverse": "^7.25.7"
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1748,13 +1854,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-json-strings": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz",
-      "integrity": "sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz",
+      "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1764,13 +1870,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-literals": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.7.tgz",
-      "integrity": "sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz",
+      "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1780,13 +1886,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-logical-assignment-operators": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz",
-      "integrity": "sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz",
+      "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1796,13 +1902,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-member-expression-literals": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.7.tgz",
-      "integrity": "sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz",
+      "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1812,14 +1918,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-amd": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.7.tgz",
-      "integrity": "sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz",
+      "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1829,15 +1935,15 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-commonjs": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.7.tgz",
-      "integrity": "sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.9.tgz",
+      "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-simple-access": "^7.25.7"
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-simple-access": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1847,16 +1953,16 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-systemjs": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.7.tgz",
-      "integrity": "sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz",
+      "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-validator-identifier": "^7.25.7",
-        "@babel/traverse": "^7.25.7"
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9",
+        "@babel/traverse": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1866,14 +1972,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-modules-umd": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.7.tgz",
-      "integrity": "sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz",
+      "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-module-transforms": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-module-transforms": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1883,14 +1989,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-named-capturing-groups-regex": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.7.tgz",
-      "integrity": "sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz",
+      "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1900,13 +2006,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-new-target": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.7.tgz",
-      "integrity": "sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz",
+      "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1916,13 +2022,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-nullish-coalescing-operator": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz",
-      "integrity": "sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz",
+      "integrity": "sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1932,13 +2038,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-numeric-separator": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz",
-      "integrity": "sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz",
+      "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1948,15 +2054,15 @@
       }
     },
     "node_modules/@babel/plugin-transform-object-rest-spread": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz",
-      "integrity": "sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz",
+      "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-compilation-targets": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/plugin-transform-parameters": "^7.25.7"
+        "@babel/helper-compilation-targets": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/plugin-transform-parameters": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1966,14 +2072,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-object-super": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.7.tgz",
-      "integrity": "sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz",
+      "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-replace-supers": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-replace-supers": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1983,13 +2089,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-optional-catch-binding": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz",
-      "integrity": "sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz",
+      "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1999,14 +2105,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-optional-chaining": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz",
-      "integrity": "sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz",
+      "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2016,13 +2122,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-parameters": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.7.tgz",
-      "integrity": "sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz",
+      "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2032,14 +2138,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-private-methods": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz",
-      "integrity": "sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz",
+      "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-class-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2049,15 +2155,15 @@
       }
     },
     "node_modules/@babel/plugin-transform-private-property-in-object": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz",
-      "integrity": "sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz",
+      "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-annotate-as-pure": "^7.25.7",
-        "@babel/helper-create-class-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-annotate-as-pure": "^7.25.9",
+        "@babel/helper-create-class-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2067,26 +2173,26 @@
       }
     },
     "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz",
-      "integrity": "sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz",
+      "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.7"
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/plugin-transform-property-literals": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.7.tgz",
-      "integrity": "sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz",
+      "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2096,13 +2202,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-regenerator": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.7.tgz",
-      "integrity": "sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz",
+      "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
+        "@babel/helper-plugin-utils": "^7.25.9",
         "regenerator-transform": "^0.15.2"
       },
       "engines": {
@@ -2113,13 +2219,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-reserved-words": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.7.tgz",
-      "integrity": "sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz",
+      "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2160,13 +2266,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-shorthand-properties": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.7.tgz",
-      "integrity": "sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz",
+      "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2176,14 +2282,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-spread": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.7.tgz",
-      "integrity": "sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz",
+      "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7",
-        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9",
+        "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2193,13 +2299,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-sticky-regex": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.7.tgz",
-      "integrity": "sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz",
+      "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2209,13 +2315,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-template-literals": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.7.tgz",
-      "integrity": "sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz",
+      "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2225,13 +2331,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-typeof-symbol": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.7.tgz",
-      "integrity": "sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz",
+      "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2241,13 +2347,13 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-escapes": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.7.tgz",
-      "integrity": "sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz",
+      "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2257,14 +2363,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-property-regex": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.7.tgz",
-      "integrity": "sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz",
+      "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2274,14 +2380,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-regex": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.7.tgz",
-      "integrity": "sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz",
+      "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2291,14 +2397,14 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-sets-regex": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.7.tgz",
-      "integrity": "sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw==",
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz",
+      "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-create-regexp-features-plugin": "^7.25.7",
-        "@babel/helper-plugin-utils": "^7.25.7"
+        "@babel/helper-create-regexp-features-plugin": "^7.25.9",
+        "@babel/helper-plugin-utils": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -2444,32 +2550,30 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz",
-      "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==",
-      "dev": true,
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
+      "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
       "license": "MIT",
       "dependencies": {
-        "@babel/code-frame": "^7.25.7",
-        "@babel/parser": "^7.25.7",
-        "@babel/types": "^7.25.7"
+        "@babel/code-frame": "^7.25.9",
+        "@babel/parser": "^7.25.9",
+        "@babel/types": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz",
-      "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==",
-      "dev": true,
+      "version": "7.25.9",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
+      "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/code-frame": "^7.25.7",
-        "@babel/generator": "^7.25.7",
-        "@babel/parser": "^7.25.7",
-        "@babel/template": "^7.25.7",
-        "@babel/types": "^7.25.7",
+        "@babel/code-frame": "^7.25.9",
+        "@babel/generator": "^7.25.9",
+        "@babel/parser": "^7.25.9",
+        "@babel/template": "^7.25.9",
+        "@babel/types": "^7.25.9",
         "debug": "^4.3.1",
         "globals": "^11.1.0"
       },
@@ -2478,13 +2582,13 @@
       }
     },
     "node_modules/@babel/traverse/node_modules/@babel/generator": {
-      "version": "7.25.7",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz",
-      "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==",
-      "dev": true,
+      "version": "7.26.2",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz",
+      "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
       "license": "MIT",
       "dependencies": {
-        "@babel/types": "^7.25.7",
+        "@babel/parser": "^7.26.2",
+        "@babel/types": "^7.26.0",
         "@jridgewell/gen-mapping": "^0.3.5",
         "@jridgewell/trace-mapping": "^0.3.25",
         "jsesc": "^3.0.2"
@@ -2497,7 +2601,6 @@
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
       "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
-      "dev": true,
       "license": "MIT",
       "bin": {
         "jsesc": "bin/jsesc"
@@ -2507,15 +2610,13 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.25.8",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz",
-      "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==",
-      "dev": true,
+      "version": "7.26.0",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
+      "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
       "license": "MIT",
       "dependencies": {
-        "@babel/helper-string-parser": "^7.25.7",
-        "@babel/helper-validator-identifier": "^7.25.7",
-        "to-fast-properties": "^2.0.0"
+        "@babel/helper-string-parser": "^7.25.9",
+        "@babel/helper-validator-identifier": "^7.25.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -3018,13 +3119,13 @@
       }
     },
     "node_modules/@inquirer/core/node_modules/@types/node": {
-      "version": "22.7.5",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
-      "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
+      "version": "22.8.6",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.6.tgz",
+      "integrity": "sha512-tosuJYKrIqjQIlVCM4PEGxOmyg3FCPa/fViuJChnGeEIhjA46oy8FMVoF9su1/v8PNs2a8Q0iFNyOx0uOF91nw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "undici-types": "~6.19.2"
+        "undici-types": "~6.19.8"
       }
     },
     "node_modules/@inquirer/core/node_modules/undici-types": {
@@ -3317,7 +3418,6 @@
       "version": "0.3.5",
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
       "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@jridgewell/set-array": "^1.2.1",
@@ -3332,7 +3432,6 @@
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
       "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.0.0"
@@ -3342,7 +3441,6 @@
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
       "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.0.0"
@@ -3363,14 +3461,12 @@
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
       "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/@jridgewell/trace-mapping": {
       "version": "0.3.25",
       "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
       "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@jridgewell/resolve-uri": "^3.1.0",
@@ -3625,10 +3721,27 @@
         "win32"
       ]
     },
+    "node_modules/@ng-bootstrap/ng-bootstrap": {
+      "version": "17.0.1",
+      "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-17.0.1.tgz",
+      "integrity": "sha512-utbm8OXIoqVVYGVzQkOS773ymbjc+UMkXv8lyi7hTqLhCQs0rZ0yA74peqVZRuOGXLHgcSTA7fnJhA80iQOblw==",
+      "license": "MIT",
+      "dependencies": {
+        "tslib": "^2.3.0"
+      },
+      "peerDependencies": {
+        "@angular/common": "^18.0.0",
+        "@angular/core": "^18.0.0",
+        "@angular/forms": "^18.0.0",
+        "@angular/localize": "^18.0.0",
+        "@popperjs/core": "^2.11.8",
+        "rxjs": "^6.5.3 || ^7.4.0"
+      }
+    },
     "node_modules/@ngtools/webpack": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.8.tgz",
-      "integrity": "sha512-sq0kI8gEen4QlM6X8XqOYy7j4B8iLCYNo+iKxatV36ts4AXH0MuVkP56+oMaoH5oZNoSqd0RlfnotEHfvJAr8A==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-18.2.11.tgz",
+      "integrity": "sha512-iTdUGJ5O7yMm1DyCzyoMDMxBJ68emUSSXPWbQzEEdcqmtifRebn+VAq4vHN8OmtGM1mtuKeLEsbiZP8ywrw7Ug==",
       "dev": true,
       "license": "MIT",
       "engines": {
@@ -3646,7 +3759,6 @@
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
       "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@nodelib/fs.stat": "2.0.5",
@@ -3660,7 +3772,6 @@
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
       "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 8"
@@ -3670,7 +3781,6 @@
       "version": "1.2.8",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
       "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@nodelib/fs.scandir": "2.1.5",
@@ -3968,6 +4078,16 @@
         "node": ">=14"
       }
     },
+    "node_modules/@popperjs/core": {
+      "version": "2.11.8",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+      "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+      "license": "MIT",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
     "node_modules/@rollup/rollup-android-arm-eabi": {
       "version": "4.22.4",
       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz",
@@ -4193,14 +4313,14 @@
       ]
     },
     "node_modules/@schematics/angular": {
-      "version": "18.2.8",
-      "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.8.tgz",
-      "integrity": "sha512-62Sr7/j/dlhZorxH4GzQgpJy0s162BVts0Q7knZuEacP4VL+IWOUE1NS9OFkh/cbomoyXBdoewkZ5Zd1dVX78w==",
+      "version": "18.2.11",
+      "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-18.2.11.tgz",
+      "integrity": "sha512-jT54mc9+hPOwie9bji/g2krVuK1kkNh2PNFGwfgCg3Ofmt3hcyOBai1DKuot5uLTX4VCCbvfwiVR/hJniQl2SA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@angular-devkit/core": "18.2.8",
-        "@angular-devkit/schematics": "18.2.8",
+        "@angular-devkit/core": "18.2.11",
+        "@angular-devkit/schematics": "18.2.11",
         "jsonc-parser": "3.3.1"
       },
       "engines": {
@@ -4359,6 +4479,47 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/@types/babel__core": {
+      "version": "7.20.5",
+      "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+      "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.20.7",
+        "@babel/types": "^7.20.7",
+        "@types/babel__generator": "*",
+        "@types/babel__template": "*",
+        "@types/babel__traverse": "*"
+      }
+    },
+    "node_modules/@types/babel__generator": {
+      "version": "7.6.8",
+      "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+      "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__template": {
+      "version": "7.4.4",
+      "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+      "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.1.0",
+        "@babel/types": "^7.0.0"
+      }
+    },
+    "node_modules/@types/babel__traverse": {
+      "version": "7.20.6",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+      "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/types": "^7.20.7"
+      }
+    },
     "node_modules/@types/body-parser": {
       "version": "1.19.5",
       "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
@@ -4500,9 +4661,9 @@
       }
     },
     "node_modules/@types/node": {
-      "version": "18.19.55",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.55.tgz",
-      "integrity": "sha512-zzw5Vw52205Zr/nmErSEkN5FLqXPuKX/k5d1D7RKHATGqU7y6YfX9QxZraUzUrFGqH6XzOzG196BC35ltJC4Cw==",
+      "version": "18.19.63",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.63.tgz",
+      "integrity": "sha512-hcUB7THvrGmaEcPcvUZCZtQ2Z3C+UR/aOcraBLCvTsFMh916Gc1kCCYcfcMuB76HM2pSerxl1PoP3KnmHzd9Lw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -4591,9 +4752,9 @@
       "license": "MIT"
     },
     "node_modules/@types/ws": {
-      "version": "8.5.12",
-      "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz",
-      "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==",
+      "version": "8.5.13",
+      "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz",
+      "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -4819,9 +4980,9 @@
       }
     },
     "node_modules/acorn": {
-      "version": "8.12.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
-      "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==",
+      "version": "8.14.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+      "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
       "dev": true,
       "license": "MIT",
       "bin": {
@@ -4988,25 +5149,33 @@
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
     "node_modules/ansi-styles": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
-      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-      "dev": true,
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "license": "MIT",
       "dependencies": {
-        "color-convert": "^1.9.0"
+        "color-convert": "^2.0.1"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/any-promise": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+      "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/anymatch": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
@@ -5034,6 +5203,13 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/arg": {
+      "version": "5.0.2",
+      "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz",
+      "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/argparse": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
@@ -5291,6 +5467,15 @@
       "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
       "license": "ISC"
     },
+    "node_modules/bootstrap": {
+      "version": "3.4.0",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.0.tgz",
+      "integrity": "sha512-F1yTDO9OHKH0xjl03DsOe8Nu1OWBIeAugGMhy3UTIYDdbbIPesQIhCEbj+HEr6wqlwweGAlP8F3OBC6kEuhFuw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -5306,7 +5491,6 @@
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
       "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "fill-range": "^7.1.1"
@@ -5316,10 +5500,9 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.24.0",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz",
-      "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==",
-      "dev": true,
+      "version": "4.24.2",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz",
+      "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==",
       "funding": [
         {
           "type": "opencollective",
@@ -5336,10 +5519,10 @@
       ],
       "license": "MIT",
       "dependencies": {
-        "caniuse-lite": "^1.0.30001663",
-        "electron-to-chromium": "^1.5.28",
+        "caniuse-lite": "^1.0.30001669",
+        "electron-to-chromium": "^1.5.41",
         "node-releases": "^2.0.18",
-        "update-browserslist-db": "^1.1.0"
+        "update-browserslist-db": "^1.1.1"
       },
       "bin": {
         "browserslist": "cli.js"
@@ -5512,11 +5695,20 @@
         "node": ">=6"
       }
     },
-    "node_modules/caniuse-lite": {
-      "version": "1.0.30001668",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz",
-      "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==",
+    "node_modules/camelcase-css": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
+      "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
       "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/caniuse-lite": {
+      "version": "1.0.30001676",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001676.tgz",
+      "integrity": "sha512-Qz6zwGCiPghQXGJvgQAem79esjitvJ+CxSbSQkW9H/UX5hg8XM88d4lp2W+MEQ81j+Hip58Il+jGVdazk1z9cw==",
       "funding": [
         {
           "type": "opencollective",
@@ -5534,18 +5726,19 @@
       "license": "CC-BY-4.0"
     },
     "node_modules/chalk": {
-      "version": "2.4.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
-      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-      "dev": true,
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "license": "MIT",
       "dependencies": {
-        "ansi-styles": "^3.2.1",
-        "escape-string-regexp": "^1.0.5",
-        "supports-color": "^5.3.0"
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
       }
     },
     "node_modules/chardet": {
@@ -5556,19 +5749,41 @@
       "license": "MIT"
     },
     "node_modules/chokidar": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz",
-      "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "readdirp": "^4.0.1"
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
       },
       "engines": {
-        "node": ">= 14.16.0"
+        "node": ">= 8.10.0"
       },
       "funding": {
         "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/chokidar/node_modules/glob-parent": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+      "dev": true,
+      "license": "ISC",
+      "dependencies": {
+        "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
     "node_modules/chownr": {
@@ -5661,7 +5876,6 @@
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
       "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
-      "dev": true,
       "license": "ISC",
       "dependencies": {
         "string-width": "^4.2.0",
@@ -5672,54 +5886,16 @@
         "node": ">=12"
       }
     },
-    "node_modules/cliui/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/cliui/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/cliui/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/cliui/node_modules/emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/cliui/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8"
@@ -5729,7 +5905,6 @@
       "version": "4.2.3",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
       "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
@@ -5744,7 +5919,6 @@
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
       "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "ansi-styles": "^4.0.0",
@@ -5783,21 +5957,35 @@
         "node": ">=6"
       }
     },
-    "node_modules/color-convert": {
-      "version": "1.9.3",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
-      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+    "node_modules/clone-deep/node_modules/is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "color-name": "1.1.3"
+        "isobject": "^3.0.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "license": "MIT",
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
       }
     },
     "node_modules/color-name": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
-      "dev": true,
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "license": "MIT"
     },
     "node_modules/colorette": {
@@ -5835,34 +6023,24 @@
       }
     },
     "node_modules/compression": {
-      "version": "1.7.4",
-      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
-      "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+      "version": "1.7.5",
+      "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.5.tgz",
+      "integrity": "sha512-bQJ0YRck5ak3LgtnpKkiabX5pNF7tMUh1BSy2ZBOTh0Dim0BUu6aPPwByIns6/A5Prh8PufSPerMDUklpzes2Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "accepts": "~1.3.5",
-        "bytes": "3.0.0",
-        "compressible": "~2.0.16",
+        "bytes": "3.1.2",
+        "compressible": "~2.0.18",
         "debug": "2.6.9",
+        "negotiator": "~0.6.4",
         "on-headers": "~1.0.2",
-        "safe-buffer": "5.1.2",
+        "safe-buffer": "5.2.1",
         "vary": "~1.1.2"
       },
       "engines": {
         "node": ">= 0.8.0"
       }
     },
-    "node_modules/compression/node_modules/bytes": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
-      "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
     "node_modules/compression/node_modules/debug": {
       "version": "2.6.9",
       "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -5880,12 +6058,15 @@
       "dev": true,
       "license": "MIT"
     },
-    "node_modules/compression/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/compression/node_modules/negotiator": {
+      "version": "0.6.4",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
+      "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
       "dev": true,
-      "license": "MIT"
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
     },
     "node_modules/concat-map": {
       "version": "0.0.1",
@@ -6014,7 +6195,6 @@
       "version": "1.9.0",
       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
       "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/cookie": {
@@ -6071,13 +6251,13 @@
       }
     },
     "node_modules/core-js-compat": {
-      "version": "3.38.1",
-      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.38.1.tgz",
-      "integrity": "sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw==",
+      "version": "3.39.0",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.39.0.tgz",
+      "integrity": "sha512-VgEUx3VwlExr5no0tXlBt+silBvhTryPwCXRI2Id1PN8WTKu7MreethvddqOubrYxkFdv/RnYrqlv1sFNAUelw==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "browserslist": "^4.23.3"
+        "browserslist": "^4.24.2"
       },
       "funding": {
         "type": "opencollective",
@@ -6136,6 +6316,7 @@
       "version": "0.0.24",
       "resolved": "https://registry.npmjs.org/critters/-/critters-0.0.24.tgz",
       "integrity": "sha512-Oyqew0FGM0wYUSNqR0L6AteO5MpMoUU0rhKRieXeiKs+PmRTxiJMyaunYB2KF6fQ3dzChXKCpbFOEJx3OQ1v/Q==",
+      "deprecated": "Ownership of Critters has moved to the Nuxt team, who will be maintaining the project going forward. If you'd like to keep using Critters, please switch to the actively-maintained fork at https://github.com/danielroe/beasties",
       "license": "Apache-2.0",
       "dependencies": {
         "chalk": "^4.1.0",
@@ -6147,76 +6328,6 @@
         "postcss-media-query-parser": "^0.2.3"
       }
     },
-    "node_modules/critters/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/critters/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/critters/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/critters/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "license": "MIT"
-    },
-    "node_modules/critters/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/critters/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -6346,7 +6457,6 @@
       "version": "4.3.7",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
       "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "ms": "^2.1.3"
@@ -6489,6 +6599,20 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/didyoumean": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
+      "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
+      "dev": true,
+      "license": "Apache-2.0"
+    },
+    "node_modules/dlv": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
+      "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/dns-packet": {
       "version": "5.6.1",
       "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
@@ -6584,10 +6708,9 @@
       "license": "MIT"
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.5.38",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.38.tgz",
-      "integrity": "sha512-VbeVexmZ1IFh+5EfrYz1I0HTzHVIlJa112UEWhciPyeOcKJGeTv6N8WnG4wsQB81DGCaVEGhpSb6o6a8WYFXXg==",
-      "dev": true,
+      "version": "1.5.50",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz",
+      "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==",
       "license": "ISC"
     },
     "node_modules/emoji-regex": {
@@ -6861,7 +6984,6 @@
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
       "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6"
@@ -6873,16 +6995,6 @@
       "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
       "license": "MIT"
     },
-    "node_modules/escape-string-regexp": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
     "node_modules/eslint-scope": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -7110,7 +7222,6 @@
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
       "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@nodelib/fs.stat": "^2.0.2",
@@ -7127,7 +7238,6 @@
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
       "license": "ISC",
       "dependencies": {
         "is-glob": "^4.0.1"
@@ -7144,17 +7254,16 @@
       "license": "MIT"
     },
     "node_modules/fast-uri": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.2.tgz",
-      "integrity": "sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
+      "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
       "dev": true,
-      "license": "MIT"
+      "license": "BSD-3-Clause"
     },
     "node_modules/fastq": {
       "version": "1.17.1",
       "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
       "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
-      "dev": true,
       "license": "ISC",
       "dependencies": {
         "reusify": "^1.0.4"
@@ -7177,7 +7286,6 @@
       "version": "7.1.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
       "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "to-regex-range": "^5.0.1"
@@ -7403,7 +7511,6 @@
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
       "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6.9.0"
@@ -7413,7 +7520,6 @@
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true,
       "license": "ISC",
       "engines": {
         "node": "6.* || 8.* || >= 10.*"
@@ -7510,7 +7616,6 @@
       "version": "11.12.0",
       "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
       "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=4"
@@ -7564,13 +7669,12 @@
       "license": "MIT"
     },
     "node_modules/has-flag": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-      "dev": true,
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
       "license": "MIT",
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/has-property-descriptors": {
@@ -7797,18 +7901,18 @@
       }
     },
     "node_modules/http-proxy-middleware": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.0.tgz",
-      "integrity": "sha512-36AV1fIaI2cWRzHo+rbcxhe3M3jUDCNzc4D5zRl57sEWRAxdXYtw7FSQKYY6PDKssiAKjLYypbssHk+xs/kMXw==",
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.3.tgz",
+      "integrity": "sha512-usY0HG5nyDUwtqpiZdETNbmKtw3QQ1jwYFZ9wi5iHzX2BcILwQKtYDJPo7XHTsu5Z0B2Hj3W9NNnbd+AjFWjqg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@types/http-proxy": "^1.17.10",
-        "debug": "^4.3.4",
+        "@types/http-proxy": "^1.17.15",
+        "debug": "^4.3.6",
         "http-proxy": "^1.18.1",
-        "is-glob": "^4.0.1",
-        "is-plain-obj": "^3.0.0",
-        "micromatch": "^4.0.5"
+        "is-glob": "^4.0.3",
+        "is-plain-object": "^5.0.0",
+        "micromatch": "^4.0.8"
       },
       "engines": {
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -8108,7 +8212,6 @@
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=0.10.0"
@@ -8131,7 +8234,6 @@
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "is-extglob": "^2.1.1"
@@ -8193,7 +8295,6 @@
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=0.12.0"
@@ -8213,14 +8314,11 @@
       }
     },
     "node_modules/is-plain-object": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
-      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+      "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
       "dev": true,
       "license": "MIT",
-      "dependencies": {
-        "isobject": "^3.0.1"
-      },
       "engines": {
         "node": ">=0.10.0"
       }
@@ -8353,29 +8451,6 @@
         "node": ">=10"
       }
     },
-    "node_modules/istanbul-lib-report/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/istanbul-lib-report/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/istanbul-lib-source-maps": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
@@ -8453,16 +8528,6 @@
         "node": ">= 10.13.0"
       }
     },
-    "node_modules/jest-worker/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/jest-worker/node_modules/supports-color": {
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
@@ -8489,11 +8554,16 @@
         "jiti": "bin/jiti.js"
       }
     },
+    "node_modules/jquery": {
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
+      "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==",
+      "license": "MIT"
+    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
       "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/js-yaml": {
@@ -8520,7 +8590,6 @@
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
       "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
-      "dev": true,
       "license": "MIT",
       "bin": {
         "jsesc": "bin/jsesc"
@@ -8550,7 +8619,6 @@
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
       "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
-      "dev": true,
       "license": "MIT",
       "bin": {
         "json5": "lib/cli.js"
@@ -8725,135 +8793,35 @@
         "source-map-support": "^0.5.5"
       }
     },
-    "node_modules/karma/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+    "node_modules/karma/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
       "dev": true,
-      "license": "MIT",
+      "license": "ISC",
       "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
       }
     },
-    "node_modules/karma/node_modules/chokidar": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/karma/node_modules/cliui": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.0",
-        "wrap-ansi": "^7.0.0"
-      }
-    },
-    "node_modules/karma/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/karma/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/karma/node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/karma/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/karma/node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+    "node_modules/karma/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true,
+      "license": "MIT"
+    },
+    "node_modules/karma/node_modules/is-fullwidth-code-point": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
       "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8"
       }
     },
-    "node_modules/karma/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/karma/node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
     "node_modules/karma/node_modules/source-map": {
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -9080,6 +9048,16 @@
         }
       }
     },
+    "node_modules/lilconfig": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
+      "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/lines-and-columns": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
@@ -9265,82 +9243,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/log-symbols/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/log-symbols/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/log-symbols/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/log-symbols/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/log-symbols/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/log-symbols/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/log-update": {
       "version": "6.1.0",
       "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
@@ -9491,7 +9393,6 @@
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
       "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
-      "dev": true,
       "license": "ISC",
       "dependencies": {
         "yallist": "^3.0.2"
@@ -9596,7 +9497,6 @@
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
       "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 8"
@@ -9615,7 +9515,6 @@
       "version": "4.0.8",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
       "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "braces": "^3.0.3",
@@ -9629,7 +9528,6 @@
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8.6"
@@ -9950,9 +9848,9 @@
       "license": "MIT"
     },
     "node_modules/msgpackr": {
-      "version": "1.11.0",
-      "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.0.tgz",
-      "integrity": "sha512-I8qXuuALqJe5laEBYoFykChhSXLikZmUhccjGsPuSJ/7uPip2TJ7lwdIQwWSAi0jGZDXv4WOP8Qg65QZRuXxXw==",
+      "version": "1.11.2",
+      "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.2.tgz",
+      "integrity": "sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==",
       "dev": true,
       "license": "MIT",
       "optionalDependencies": {
@@ -10006,6 +9904,18 @@
         "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
       }
     },
+    "node_modules/mz": {
+      "version": "2.7.0",
+      "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+      "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "any-promise": "^1.0.0",
+        "object-assign": "^4.0.1",
+        "thenify-all": "^1.0.0"
+      }
+    },
     "node_modules/nanoid": {
       "version": "3.3.7",
       "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -10243,7 +10153,6 @@
       "version": "2.0.18",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
       "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/nopt": {
@@ -10433,6 +10342,16 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/object-hash": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+      "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/object-inspect": {
       "version": "1.13.2",
       "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
@@ -10543,39 +10462,6 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/ora/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/ora/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
     "node_modules/ora/node_modules/cli-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -10589,36 +10475,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/ora/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/ora/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
-    "node_modules/ora/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/ora/node_modules/onetime": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -10656,19 +10512,6 @@
       "dev": true,
       "license": "ISC"
     },
-    "node_modules/ora/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/ordered-binary": {
       "version": "1.5.2",
       "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.5.2.tgz",
@@ -10851,10 +10694,10 @@
       }
     },
     "node_modules/parse5": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz",
-      "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==",
-      "dev": true,
+      "version": "7.2.1",
+      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
+      "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
+      "devOptional": true,
       "license": "MIT",
       "dependencies": {
         "entities": "^4.5.0"
@@ -10981,9 +10824,9 @@
       }
     },
     "node_modules/picocolors": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
-      "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
       "license": "ISC"
     },
     "node_modules/picomatch": {
@@ -11010,6 +10853,16 @@
         "node": ">=6"
       }
     },
+    "node_modules/pirates": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+      "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/piscina": {
       "version": "4.6.1",
       "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.6.1.tgz",
@@ -11037,9 +10890,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.41",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
-      "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==",
+      "version": "8.4.47",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+      "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
       "funding": [
         {
           "type": "opencollective",
@@ -11057,13 +10910,100 @@
       "license": "MIT",
       "dependencies": {
         "nanoid": "^3.3.7",
-        "picocolors": "^1.0.1",
-        "source-map-js": "^1.2.0"
+        "picocolors": "^1.1.0",
+        "source-map-js": "^1.2.1"
       },
       "engines": {
         "node": "^10 || ^12 || >=14"
       }
     },
+    "node_modules/postcss-import": {
+      "version": "15.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz",
+      "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "postcss-value-parser": "^4.0.0",
+        "read-cache": "^1.0.0",
+        "resolve": "^1.1.7"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.0.0"
+      }
+    },
+    "node_modules/postcss-js": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz",
+      "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "camelcase-css": "^2.0.1"
+      },
+      "engines": {
+        "node": "^12 || ^14 || >= 16"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/postcss/"
+      },
+      "peerDependencies": {
+        "postcss": "^8.4.21"
+      }
+    },
+    "node_modules/postcss-load-config": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
+      "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "lilconfig": "^3.0.0",
+        "yaml": "^2.3.4"
+      },
+      "engines": {
+        "node": ">= 14"
+      },
+      "peerDependencies": {
+        "postcss": ">=8.0.9",
+        "ts-node": ">=9.0.0"
+      },
+      "peerDependenciesMeta": {
+        "postcss": {
+          "optional": true
+        },
+        "ts-node": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/postcss-load-config/node_modules/lilconfig": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
+      "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/antonk52"
+      }
+    },
     "node_modules/postcss-loader": {
       "version": "8.1.1",
       "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz",
@@ -11165,6 +11105,32 @@
         "postcss": "^8.1.0"
       }
     },
+    "node_modules/postcss-nested": {
+      "version": "6.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+      "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "postcss-selector-parser": "^6.1.1"
+      },
+      "engines": {
+        "node": ">=12.0"
+      },
+      "peerDependencies": {
+        "postcss": "^8.2.14"
+      }
+    },
     "node_modules/postcss-selector-parser": {
       "version": "6.1.2",
       "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
@@ -11281,7 +11247,6 @@
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -11332,6 +11297,26 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/read-cache": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+      "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "pify": "^2.3.0"
+      }
+    },
+    "node_modules/read-cache/node_modules/pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
     "node_modules/readable-stream": {
       "version": "3.6.2",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
@@ -11348,24 +11333,35 @@
       }
     },
     "node_modules/readdirp": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz",
-      "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
       "dev": true,
       "license": "MIT",
+      "dependencies": {
+        "picomatch": "^2.2.1"
+      },
       "engines": {
-        "node": ">= 14.16.0"
+        "node": ">=8.10.0"
+      }
+    },
+    "node_modules/readdirp/node_modules/picomatch": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=8.6"
       },
       "funding": {
-        "type": "individual",
-        "url": "https://paulmillr.com/funding/"
+        "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
     "node_modules/reflect-metadata": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
       "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
-      "dev": true,
       "license": "Apache-2.0"
     },
     "node_modules/regenerate": {
@@ -11438,9 +11434,9 @@
       "license": "MIT"
     },
     "node_modules/regjsparser": {
-      "version": "0.11.1",
-      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.1.tgz",
-      "integrity": "sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ==",
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.11.2.tgz",
+      "integrity": "sha512-3OGZZ4HoLJkkAZx/48mTXJNlmqTGOzc0o9OWQPuWpkOlXXPbyN6OafCcoXUnBqE2D3f/T5L+pWc1kdEmnfnRsA==",
       "dev": true,
       "license": "BSD-2-Clause",
       "dependencies": {
@@ -11467,7 +11463,6 @@
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
       "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=0.10.0"
@@ -11591,7 +11586,6 @@
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
       "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "iojs": ">=1.0.0",
@@ -11675,7 +11669,6 @@
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
       "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -11789,70 +11782,6 @@
         }
       }
     },
-    "node_modules/sass/node_modules/chokidar": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
-    "node_modules/sass/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/sass/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/sass/node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
     "node_modules/sax": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
@@ -11924,7 +11853,6 @@
       "version": "7.6.3",
       "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
       "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
-      "dev": true,
       "license": "ISC",
       "bin": {
         "semver": "bin/semver.js"
@@ -12277,9 +12205,9 @@
       }
     },
     "node_modules/socket.io": {
-      "version": "4.8.0",
-      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz",
-      "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==",
+      "version": "4.8.1",
+      "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz",
+      "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -12642,7 +12570,6 @@
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "ansi-regex": "^5.0.1"
@@ -12657,35 +12584,114 @@
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "license": "MIT",
+      "license": "MIT",
+      "dependencies": {
+        "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/strip-final-newline": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/sucrase": {
+      "version": "3.35.0",
+      "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",
+      "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@jridgewell/gen-mapping": "^0.3.2",
+        "commander": "^4.0.0",
+        "glob": "^10.3.10",
+        "lines-and-columns": "^1.1.6",
+        "mz": "^2.7.0",
+        "pirates": "^4.0.1",
+        "ts-interface-checker": "^0.1.9"
+      },
+      "bin": {
+        "sucrase": "bin/sucrase",
+        "sucrase-node": "bin/sucrase-node"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
+    },
+    "node_modules/sucrase/node_modules/brace-expansion": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "balanced-match": "^1.0.0"
+      }
+    },
+    "node_modules/sucrase/node_modules/commander": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
+      "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/sucrase/node_modules/glob": {
+      "version": "10.4.5",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+      "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+      "dev": true,
+      "license": "ISC",
       "dependencies": {
-        "ansi-regex": "^5.0.1"
+        "foreground-child": "^3.1.0",
+        "jackspeak": "^3.1.2",
+        "minimatch": "^9.0.4",
+        "minipass": "^7.1.2",
+        "package-json-from-dist": "^1.0.0",
+        "path-scurry": "^1.11.1"
       },
-      "engines": {
-        "node": ">=8"
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/strip-final-newline": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
-      "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+    "node_modules/sucrase/node_modules/minimatch": {
+      "version": "9.0.5",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+      "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
       "dev": true,
-      "license": "MIT",
+      "license": "ISC",
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
       "engines": {
-        "node": ">=6"
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
     "node_modules/supports-color": {
-      "version": "5.5.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-      "dev": true,
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
       "license": "MIT",
       "dependencies": {
-        "has-flag": "^3.0.0"
+        "has-flag": "^4.0.0"
       },
       "engines": {
-        "node": ">=4"
+        "node": ">=8"
       }
     },
     "node_modules/supports-preserve-symlinks-flag": {
@@ -12711,6 +12717,44 @@
         "node": ">=0.10"
       }
     },
+    "node_modules/tailwindcss": {
+      "version": "3.4.14",
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz",
+      "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@alloc/quick-lru": "^5.2.0",
+        "arg": "^5.0.2",
+        "chokidar": "^3.5.3",
+        "didyoumean": "^1.2.2",
+        "dlv": "^1.1.3",
+        "fast-glob": "^3.3.0",
+        "glob-parent": "^6.0.2",
+        "is-glob": "^4.0.3",
+        "jiti": "^1.21.0",
+        "lilconfig": "^2.1.0",
+        "micromatch": "^4.0.5",
+        "normalize-path": "^3.0.0",
+        "object-hash": "^3.0.0",
+        "picocolors": "^1.0.0",
+        "postcss": "^8.4.23",
+        "postcss-import": "^15.1.0",
+        "postcss-js": "^4.0.1",
+        "postcss-load-config": "^4.0.1",
+        "postcss-nested": "^6.0.1",
+        "postcss-selector-parser": "^6.0.11",
+        "resolve": "^1.22.2",
+        "sucrase": "^3.32.0"
+      },
+      "bin": {
+        "tailwind": "lib/cli.js",
+        "tailwindcss": "lib/cli.js"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
     "node_modules/tapable": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -12902,6 +12946,29 @@
         "url": "https://opencollective.com/webpack"
       }
     },
+    "node_modules/thenify": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+      "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "any-promise": "^1.0.0"
+      }
+    },
+    "node_modules/thenify-all": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+      "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "thenify": ">= 3.1.0 < 4"
+      },
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
     "node_modules/thingies": {
       "version": "1.21.0",
       "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz",
@@ -12935,21 +13002,10 @@
         "node": ">=0.6.0"
       }
     },
-    "node_modules/to-fast-properties": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
-      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=4"
-      }
-    },
     "node_modules/to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "is-number": "^7.0.0"
@@ -12994,10 +13050,17 @@
         "tree-kill": "cli.js"
       }
     },
+    "node_modules/ts-interface-checker": {
+      "version": "0.1.13",
+      "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
+      "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
+      "dev": true,
+      "license": "Apache-2.0"
+    },
     "node_modules/tslib": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
-      "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
       "license": "0BSD"
     },
     "node_modules/tuf-js": {
@@ -13052,7 +13115,6 @@
       "version": "5.5.4",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
       "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
-      "dev": true,
       "license": "Apache-2.0",
       "bin": {
         "tsc": "bin/tsc",
@@ -13202,7 +13264,6 @@
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
       "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
-      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -13795,35 +13856,6 @@
         "@esbuild/win32-x64": "0.21.5"
       }
     },
-    "node_modules/vite/node_modules/postcss": {
-      "version": "8.4.47",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
-      "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
-      "dev": true,
-      "funding": [
-        {
-          "type": "opencollective",
-          "url": "https://opencollective.com/postcss/"
-        },
-        {
-          "type": "tidelift",
-          "url": "https://tidelift.com/funding/github/npm/postcss"
-        },
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/ai"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "nanoid": "^3.3.7",
-        "picocolors": "^1.1.0",
-        "source-map-js": "^1.2.1"
-      },
-      "engines": {
-        "node": "^10 || ^12 || >=14"
-      }
-    },
     "node_modules/void-elements": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
@@ -14022,31 +14054,6 @@
         "balanced-match": "^1.0.0"
       }
     },
-    "node_modules/webpack-dev-server/node_modules/chokidar": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
-      "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "anymatch": "~3.1.2",
-        "braces": "~3.0.2",
-        "glob-parent": "~5.1.2",
-        "is-binary-path": "~2.1.0",
-        "is-glob": "~4.0.1",
-        "normalize-path": "~3.0.0",
-        "readdirp": "~3.6.0"
-      },
-      "engines": {
-        "node": ">= 8.10.0"
-      },
-      "funding": {
-        "url": "https://paulmillr.com/funding/"
-      },
-      "optionalDependencies": {
-        "fsevents": "~2.3.2"
-      }
-    },
     "node_modules/webpack-dev-server/node_modules/glob": {
       "version": "10.4.5",
       "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
@@ -14068,19 +14075,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/webpack-dev-server/node_modules/glob-parent": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
-      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
-      "license": "ISC",
-      "dependencies": {
-        "is-glob": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
     "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": {
       "version": "2.0.7",
       "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz",
@@ -14132,32 +14126,6 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "node_modules/webpack-dev-server/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/jonschlinkert"
-      }
-    },
-    "node_modules/webpack-dev-server/node_modules/readdirp": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
-      "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "picomatch": "^2.2.1"
-      },
-      "engines": {
-        "node": ">=8.10.0"
-      }
-    },
     "node_modules/webpack-dev-server/node_modules/rimraf": {
       "version": "5.0.10",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
@@ -14360,42 +14328,6 @@
         "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
-    "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/wrap-ansi-cjs/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -14428,42 +14360,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/wrap-ansi/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/wrap-ansi/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/wrap-ansi/node_modules/emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -14538,7 +14434,6 @@
       "version": "5.0.8",
       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
       "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "dev": true,
       "license": "ISC",
       "engines": {
         "node": ">=10"
@@ -14548,14 +14443,25 @@
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
-      "dev": true,
       "license": "ISC"
     },
+    "node_modules/yaml": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz",
+      "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==",
+      "dev": true,
+      "license": "ISC",
+      "bin": {
+        "yaml": "bin.mjs"
+      },
+      "engines": {
+        "node": ">= 14"
+      }
+    },
     "node_modules/yargs": {
       "version": "17.7.2",
       "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
       "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "cliui": "^8.0.1",
@@ -14574,7 +14480,6 @@
       "version": "21.1.1",
       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
       "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-      "dev": true,
       "license": "ISC",
       "engines": {
         "node": ">=12"
@@ -14584,14 +14489,12 @@
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
       "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/yargs/node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=8"
@@ -14601,7 +14504,6 @@
       "version": "4.2.3",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
       "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "emoji-regex": "^8.0.0",
diff --git a/angular/RestClient/package.json b/angular/RestClient/package.json
index 9b17eb5672e75d2f68fb51b154806ef2ed8f7c3b..262eacd1144f0eaab113dda4aad24eedab9ff958 100644
--- a/angular/RestClient/package.json
+++ b/angular/RestClient/package.json
@@ -12,16 +12,22 @@
   "private": true,
   "dependencies": {
     "@angular/animations": "^18.2.0",
+    "@angular/cdk": "^18.2.9",
     "@angular/common": "^18.2.0",
     "@angular/compiler": "^18.2.0",
     "@angular/core": "^18.2.0",
     "@angular/forms": "^18.2.0",
+    "@angular/material": "^18.2.9",
     "@angular/platform-browser": "^18.2.0",
     "@angular/platform-browser-dynamic": "^18.2.0",
     "@angular/platform-server": "^18.2.0",
     "@angular/router": "^18.2.0",
     "@angular/ssr": "^18.2.7",
+    "@ng-bootstrap/ng-bootstrap": "^17.0.1",
+    "@popperjs/core": "^2.11.8",
+    "bootstrap": "^3.4.0",
     "express": "^4.18.2",
+    "jquery": "^3.4.1",
     "rxjs": "~7.8.0",
     "tslib": "^2.3.0",
     "zone.js": "~0.14.10"
@@ -30,15 +36,19 @@
     "@angular-devkit/build-angular": "^18.2.7",
     "@angular/cli": "^18.2.7",
     "@angular/compiler-cli": "^18.2.0",
+    "@angular/localize": "^18.2.0",
     "@types/express": "^4.17.17",
     "@types/jasmine": "~5.1.0",
     "@types/node": "^18.18.0",
+    "autoprefixer": "^10.4.20",
     "jasmine-core": "~5.2.0",
     "karma": "~6.4.0",
     "karma-chrome-launcher": "~3.2.0",
     "karma-coverage": "~2.2.0",
     "karma-jasmine": "~5.1.0",
     "karma-jasmine-html-reporter": "~2.1.0",
+    "postcss": "^8.4.47",
+    "tailwindcss": "^3.4.14",
     "typescript": "~5.5.2"
   }
-}
\ No newline at end of file
+}
diff --git a/angular/RestClient/public/search.svg b/angular/RestClient/public/search.svg
new file mode 100644
index 0000000000000000000000000000000000000000..5833a246d21d7f3442153559710b642e3fdc179d
--- /dev/null
+++ b/angular/RestClient/public/search.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="50px" height="50px" fill-rule="nonzero"><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.12,5.12)"><path d="M21,3c-9.39844,0 -17,7.60156 -17,17c0,9.39844 7.60156,17 17,17c3.35547,0 6.46094,-0.98437 9.09375,-2.65625l12.28125,12.28125l4.25,-4.25l-12.125,-12.09375c2.17969,-2.85937 3.5,-6.40234 3.5,-10.28125c0,-9.39844 -7.60156,-17 -17,-17zM21,7c7.19922,0 13,5.80078 13,13c0,7.19922 -5.80078,13 -13,13c-7.19922,0 -13,-5.80078 -13,-13c0,-7.19922 5.80078,-13 13,-13z"></path></g></g></svg>
\ No newline at end of file
diff --git a/angular/RestClient/src/app/app.component.html b/angular/RestClient/src/app/app.component.html
index 36093e1879779624f181733152bb55d71a711d3b..94ead7dd6b3d1d18c77eb5ad41ff2a32f4a097ad 100644
--- a/angular/RestClient/src/app/app.component.html
+++ b/angular/RestClient/src/app/app.component.html
@@ -1,336 +1,4 @@
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * The content below * * * * * * * * * * * -->
-<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * -->
-<!-- * * * * * * * * * * and can be replaced.  * * * * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * Delete the template below * * * * * * * * * -->
-<!-- * * * * * * * to get started with your project! * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-
-<style>
-  :host {
-    --bright-blue: oklch(51.01% 0.274 263.83);
-    --electric-violet: oklch(53.18% 0.28 296.97);
-    --french-violet: oklch(47.66% 0.246 305.88);
-    --vivid-pink: oklch(69.02% 0.277 332.77);
-    --hot-red: oklch(61.42% 0.238 15.34);
-    --orange-red: oklch(63.32% 0.24 31.68);
-
-    --gray-900: oklch(19.37% 0.006 300.98);
-    --gray-700: oklch(36.98% 0.014 302.71);
-    --gray-400: oklch(70.9% 0.015 304.04);
-
-    --red-to-pink-to-purple-vertical-gradient: linear-gradient(
-      180deg,
-      var(--orange-red) 0%,
-      var(--vivid-pink) 50%,
-      var(--electric-violet) 100%
-    );
-
-    --red-to-pink-to-purple-horizontal-gradient: linear-gradient(
-      90deg,
-      var(--orange-red) 0%,
-      var(--vivid-pink) 50%,
-      var(--electric-violet) 100%
-    );
-
-    --pill-accent: var(--bright-blue);
-
-    font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-      Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
-      "Segoe UI Symbol";
-    box-sizing: border-box;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale;
-  }
-
-  h1 {
-    font-size: 3.125rem;
-    color: var(--gray-900);
-    font-weight: 500;
-    line-height: 100%;
-    letter-spacing: -0.125rem;
-    margin: 0;
-    font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
-      Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
-      "Segoe UI Symbol";
-  }
-
-  p {
-    margin: 0;
-    color: var(--gray-700);
-  }
-
-  main {
-    width: 100%;
-    min-height: 100%;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    padding: 1rem;
-    box-sizing: inherit;
-    position: relative;
-  }
-
-  .angular-logo {
-    max-width: 9.2rem;
-  }
-
-  .content {
-    display: flex;
-    justify-content: space-around;
-    width: 100%;
-    max-width: 700px;
-    margin-bottom: 3rem;
-  }
-
-  .content h1 {
-    margin-top: 1.75rem;
-  }
-
-  .content p {
-    margin-top: 1.5rem;
-  }
-
-  .divider {
-    width: 1px;
-    background: var(--red-to-pink-to-purple-vertical-gradient);
-    margin-inline: 0.5rem;
-  }
-
-  .pill-group {
-    display: flex;
-    flex-direction: column;
-    align-items: start;
-    flex-wrap: wrap;
-    gap: 1.25rem;
-  }
-
-  .pill {
-    display: flex;
-    align-items: center;
-    --pill-accent: var(--bright-blue);
-    background: color-mix(in srgb, var(--pill-accent) 5%, transparent);
-    color: var(--pill-accent);
-    padding-inline: 0.75rem;
-    padding-block: 0.375rem;
-    border-radius: 2.75rem;
-    border: 0;
-    transition: background 0.3s ease;
-    font-family: var(--inter-font);
-    font-size: 0.875rem;
-    font-style: normal;
-    font-weight: 500;
-    line-height: 1.4rem;
-    letter-spacing: -0.00875rem;
-    text-decoration: none;
-  }
-
-  .pill:hover {
-    background: color-mix(in srgb, var(--pill-accent) 15%, transparent);
-  }
-
-  .pill-group .pill:nth-child(6n + 1) {
-    --pill-accent: var(--bright-blue);
-  }
-  .pill-group .pill:nth-child(6n + 2) {
-    --pill-accent: var(--french-violet);
-  }
-  .pill-group .pill:nth-child(6n + 3),
-  .pill-group .pill:nth-child(6n + 4),
-  .pill-group .pill:nth-child(6n + 5) {
-    --pill-accent: var(--hot-red);
-  }
-
-  .pill-group svg {
-    margin-inline-start: 0.25rem;
-  }
-
-  .social-links {
-    display: flex;
-    align-items: center;
-    gap: 0.73rem;
-    margin-top: 1.5rem;
-  }
-
-  .social-links path {
-    transition: fill 0.3s ease;
-    fill: var(--gray-400);
-  }
-
-  .social-links a:hover svg path {
-    fill: var(--gray-900);
-  }
-
-  @media screen and (max-width: 650px) {
-    .content {
-      flex-direction: column;
-      width: max-content;
-    }
-
-    .divider {
-      height: 1px;
-      width: 100%;
-      background: var(--red-to-pink-to-purple-horizontal-gradient);
-      margin-block: 1.5rem;
-    }
-  }
-</style>
-
-<main class="main">
-  <div class="content">
-    <div class="left-side">
-      <svg
-        xmlns="http://www.w3.org/2000/svg"
-        viewBox="0 0 982 239"
-        fill="none"
-        class="angular-logo"
-      >
-        <g clip-path="url(#a)">
-          <path
-            fill="url(#b)"
-            d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
-          />
-          <path
-            fill="url(#c)"
-            d="M388.676 191.625h30.849L363.31 31.828h-35.758l-56.215 159.797h30.848l13.174-39.356h60.061l13.256 39.356Zm-65.461-62.675 21.602-64.311h1.227l21.602 64.311h-44.431Zm126.831-7.527v70.202h-28.23V71.839h27.002v20.374h1.392c2.782-6.71 7.2-12.028 13.255-15.956 6.056-3.927 13.584-5.89 22.503-5.89 8.264 0 15.465 1.8 21.684 5.318 6.137 3.518 10.964 8.673 14.319 15.382 3.437 6.71 5.074 14.81 4.992 24.383v76.175h-28.23v-71.92c0-8.019-2.046-14.237-6.219-18.819-4.173-4.5-9.819-6.791-17.102-6.791-4.91 0-9.328 1.063-13.174 3.272-3.846 2.128-6.792 5.237-9.001 9.328-2.046 4.009-3.191 8.918-3.191 14.728ZM589.233 239c-10.147 0-18.82-1.391-26.103-4.091-7.282-2.7-13.092-6.382-17.511-10.964-4.418-4.582-7.528-9.655-9.164-15.219l25.448-6.136c1.145 2.372 2.782 4.663 4.991 6.954 2.209 2.291 5.155 4.255 8.837 5.81 3.683 1.554 8.428 2.291 14.074 2.291 8.019 0 14.647-1.964 19.884-5.81 5.237-3.845 7.856-10.227 7.856-19.064v-22.665h-1.391c-1.473 2.946-3.601 5.892-6.383 9.001-2.782 3.109-6.464 5.645-10.965 7.691-4.582 2.046-10.228 3.109-17.101 3.109-9.165 0-17.511-2.209-25.039-6.545-7.446-4.337-13.42-10.883-17.757-19.474-4.418-8.673-6.628-19.473-6.628-32.565 0-13.091 2.21-24.301 6.628-33.383 4.419-9.082 10.311-15.955 17.839-20.7 7.528-4.746 15.874-7.037 25.039-7.037 7.037 0 12.846 1.145 17.347 3.518 4.582 2.373 8.182 5.236 10.883 8.51 2.7 3.272 4.746 6.382 6.137 9.327h1.554v-19.8h27.821v121.749c0 10.228-2.454 18.737-7.364 25.447-4.91 6.709-11.538 11.7-20.048 15.055-8.509 3.355-18.165 4.991-28.884 4.991Zm.245-71.266c5.974 0 11.047-1.473 15.302-4.337 4.173-2.945 7.446-7.118 9.573-12.519 2.21-5.482 3.274-12.027 3.274-19.637 0-7.609-1.064-14.155-3.274-19.8-2.127-5.646-5.318-10.064-9.491-13.255-4.174-3.11-9.329-4.746-15.384-4.746s-11.537 1.636-15.792 4.91c-4.173 3.272-7.365 7.772-9.492 13.418-2.128 5.727-3.191 12.191-3.191 19.392 0 7.2 1.063 13.745 3.273 19.228 2.127 5.482 5.318 9.736 9.573 12.764 4.174 3.027 9.41 4.582 15.629 4.582Zm141.56-26.51V71.839h28.23v119.786h-27.412v-21.273h-1.227c-2.7 6.709-7.119 12.191-13.338 16.446-6.137 4.255-13.747 6.382-22.748 6.382-7.855 0-14.81-1.718-20.783-5.237-5.974-3.518-10.72-8.591-14.075-15.382-3.355-6.709-5.073-14.891-5.073-24.464V71.839h28.312v71.921c0 7.609 2.046 13.664 6.219 18.083 4.173 4.5 9.655 6.709 16.365 6.709 4.173 0 8.183-.982 12.111-3.028 3.927-2.045 7.118-5.072 9.655-9.082 2.537-4.091 3.764-9.164 3.764-15.218Zm65.707-109.395v159.796h-28.23V31.828h28.23Zm44.841 162.169c-7.61 0-14.402-1.391-20.457-4.091-6.055-2.7-10.883-6.791-14.32-12.109-3.518-5.319-5.237-11.946-5.237-19.801 0-6.791 1.228-12.355 3.765-16.773 2.536-4.419 5.891-7.937 10.228-10.637 4.337-2.618 9.164-4.664 14.647-6.055 5.4-1.391 11.046-2.373 16.856-3.027 7.037-.737 12.683-1.391 17.102-1.964 4.337-.573 7.528-1.555 9.574-2.782 1.963-1.309 3.027-3.273 3.027-5.973v-.491c0-5.891-1.718-10.391-5.237-13.664-3.518-3.191-8.51-4.828-15.056-4.828-6.955 0-12.356 1.473-16.447 4.5-4.009 3.028-6.71 6.546-8.183 10.719l-26.348-3.764c2.046-7.282 5.483-13.336 10.31-18.328 4.746-4.909 10.638-8.59 17.511-11.045 6.955-2.455 14.565-3.682 22.912-3.682 5.809 0 11.537.654 17.265 2.045s10.965 3.6 15.711 6.71c4.746 3.109 8.51 7.282 11.455 12.6 2.864 5.318 4.337 11.946 4.337 19.883v80.184h-27.166v-16.446h-.9c-1.719 3.355-4.092 6.464-7.201 9.328-3.109 2.864-6.955 5.237-11.619 6.955-4.828 1.718-10.229 2.536-16.529 2.536Zm7.364-20.701c5.646 0 10.556-1.145 14.729-3.354 4.173-2.291 7.364-5.237 9.655-9.001 2.292-3.763 3.355-7.854 3.355-12.273v-14.155c-.9.737-2.373 1.391-4.5 2.046-2.128.654-4.419 1.145-7.037 1.636-2.619.491-5.155.9-7.692 1.227-2.537.328-4.746.655-6.628.901-4.173.572-8.019 1.472-11.292 2.781-3.355 1.31-5.973 3.11-7.855 5.401-1.964 2.291-2.864 5.318-2.864 8.918 0 5.237 1.882 9.164 5.728 11.782 3.682 2.782 8.51 4.091 14.401 4.091Zm64.643 18.328V71.839h27.412v19.965h1.227c2.21-6.955 5.974-12.274 11.292-16.038 5.319-3.763 11.456-5.645 18.329-5.645 1.555 0 3.355.082 5.237.163 1.964.164 3.601.328 4.91.573v25.938c-1.227-.41-3.109-.819-5.646-1.146a58.814 58.814 0 0 0-7.446-.49c-5.155 0-9.738 1.145-13.829 3.354-4.091 2.209-7.282 5.236-9.655 9.164-2.373 3.927-3.519 8.427-3.519 13.5v70.448h-28.312ZM222.077 39.192l-8.019 125.923L137.387 0l84.69 39.192Zm-53.105 162.825-57.933 33.056-57.934-33.056 11.783-28.556h92.301l11.783 28.556ZM111.039 62.675l30.357 73.803H80.681l30.358-73.803ZM7.937 165.115 0 39.192 84.69 0 7.937 165.115Z"
-          />
-        </g>
-        <defs>
-          <radialGradient
-            id="c"
-            cx="0"
-            cy="0"
-            r="1"
-            gradientTransform="rotate(118.122 171.182 60.81) scale(205.794)"
-            gradientUnits="userSpaceOnUse"
-          >
-            <stop stop-color="#FF41F8" />
-            <stop offset=".707" stop-color="#FF41F8" stop-opacity=".5" />
-            <stop offset="1" stop-color="#FF41F8" stop-opacity="0" />
-          </radialGradient>
-          <linearGradient
-            id="b"
-            x1="0"
-            x2="982"
-            y1="192"
-            y2="192"
-            gradientUnits="userSpaceOnUse"
-          >
-            <stop stop-color="#F0060B" />
-            <stop offset="0" stop-color="#F0070C" />
-            <stop offset=".526" stop-color="#CC26D5" />
-            <stop offset="1" stop-color="#7702FF" />
-          </linearGradient>
-          <clipPath id="a"><path fill="#fff" d="M0 0h982v239H0z" /></clipPath>
-        </defs>
-      </svg>
-      <h1>Hello, {{ title }}</h1>
-      <p>Congratulations! Your app is running. 🎉</p>
-    </div>
-    <div class="divider" role="separator" aria-label="Divider"></div>
-    <div class="right-side">
-      <div class="pill-group">
-        @for (item of [
-          { title: 'Explore the Docs', link: 'https://angular.dev' },
-          { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' },
-          { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' },
-          { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' },
-          { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' },
-        ]; track item.title) {
-          <a
-            class="pill"
-            [href]="item.link"
-            target="_blank"
-            rel="noopener"
-          >
-            <span>{{ item.title }}</span>
-            <svg
-              xmlns="http://www.w3.org/2000/svg"
-              height="14"
-              viewBox="0 -960 960 960"
-              width="14"
-              fill="currentColor"
-            >
-              <path
-                d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"
-              />
-            </svg>
-          </a>
-        }
-      </div>
-      <div class="social-links">
-        <a
-          href="https://github.com/angular/angular"
-          aria-label="Github"
-          target="_blank"
-          rel="noopener"
-        >
-          <svg
-            width="25"
-            height="24"
-            viewBox="0 0 25 24"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
-            alt="Github"
-          >
-            <path
-              d="M12.3047 0C5.50634 0 0 5.50942 0 12.3047C0 17.7423 3.52529 22.3535 8.41332 23.9787C9.02856 24.0946 9.25414 23.7142 9.25414 23.3871C9.25414 23.0949 9.24389 22.3207 9.23876 21.2953C5.81601 22.0377 5.09414 19.6444 5.09414 19.6444C4.53427 18.2243 3.72524 17.8449 3.72524 17.8449C2.61064 17.082 3.81137 17.0973 3.81137 17.0973C5.04697 17.1835 5.69604 18.3647 5.69604 18.3647C6.79321 20.2463 8.57636 19.7029 9.27978 19.3881C9.39052 18.5924 9.70736 18.0499 10.0591 17.7423C7.32641 17.4347 4.45429 16.3765 4.45429 11.6618C4.45429 10.3185 4.9311 9.22133 5.72065 8.36C5.58222 8.04931 5.16694 6.79833 5.82831 5.10337C5.82831 5.10337 6.85883 4.77319 9.2121 6.36459C10.1965 6.09082 11.2424 5.95546 12.2883 5.94931C13.3342 5.95546 14.3801 6.09082 15.3644 6.36459C17.7023 4.77319 18.7328 5.10337 18.7328 5.10337C19.3942 6.79833 18.9789 8.04931 18.8559 8.36C19.6403 9.22133 20.1171 10.3185 20.1171 11.6618C20.1171 16.3888 17.2409 17.4296 14.5031 17.7321C14.9338 18.1012 15.3337 18.8559 15.3337 20.0084C15.3337 21.6552 15.3183 22.978 15.3183 23.3779C15.3183 23.7009 15.5336 24.0854 16.1642 23.9623C21.0871 22.3484 24.6094 17.7341 24.6094 12.3047C24.6094 5.50942 19.0999 0 12.3047 0Z"
-            />
-          </svg>
-        </a>
-        <a
-          href="https://twitter.com/angular"
-          aria-label="Twitter"
-          target="_blank"
-          rel="noopener"
-        >
-          <svg
-            width="24"
-            height="24"
-            viewBox="0 0 24 24"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
-            alt="Twitter"
-          >
-            <path
-              d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"
-            />
-          </svg>
-        </a>
-        <a
-          href="https://www.youtube.com/channel/UCbn1OgGei-DV7aSRo_HaAiw"
-          aria-label="Youtube"
-          target="_blank"
-          rel="noopener"
-        >
-          <svg
-            width="29"
-            height="20"
-            viewBox="0 0 29 20"
-            fill="none"
-            xmlns="http://www.w3.org/2000/svg"
-            alt="Youtube"
-          >
-            <path
-              fill-rule="evenodd"
-              clip-rule="evenodd"
-              d="M27.4896 1.52422C27.9301 1.96749 28.2463 2.51866 28.4068 3.12258C29.0004 5.35161 29.0004 10 29.0004 10C29.0004 10 29.0004 14.6484 28.4068 16.8774C28.2463 17.4813 27.9301 18.0325 27.4896 18.4758C27.0492 18.9191 26.5 19.2389 25.8972 19.4032C23.6778 20 14.8068 20 14.8068 20C14.8068 20 5.93586 20 3.71651 19.4032C3.11363 19.2389 2.56449 18.9191 2.12405 18.4758C1.68361 18.0325 1.36732 17.4813 1.20683 16.8774C0.613281 14.6484 0.613281 10 0.613281 10C0.613281 10 0.613281 5.35161 1.20683 3.12258C1.36732 2.51866 1.68361 1.96749 2.12405 1.52422C2.56449 1.08095 3.11363 0.76113 3.71651 0.596774C5.93586 0 14.8068 0 14.8068 0C14.8068 0 23.6778 0 25.8972 0.596774C26.5 0.76113 27.0492 1.08095 27.4896 1.52422ZM19.3229 10L11.9036 5.77905V14.221L19.3229 10Z"
-            />
-          </svg>
-        </a>
-      </div>
-    </div>
-  </div>
-</main>
-
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * The content above * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * is only a placeholder * * * * * * * * * * * -->
-<!-- * * * * * * * * * * and can be replaced.  * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * End of Placeholder  * * * * * * * * * * * * -->
-<!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * -->
-
-
-<router-outlet />
+<div class="container">
+  <app-navigation />
+  <router-outlet></router-outlet>
+</div>
diff --git a/angular/RestClient/src/app/app.component.spec.ts b/angular/RestClient/src/app/app.component.spec.ts
index ab77de0d1b761c50efffa4c4fcbc31e301eb01a0..360bd69b802b5865ce5bb94b3a5ed758dbc09b26 100644
--- a/angular/RestClient/src/app/app.component.spec.ts
+++ b/angular/RestClient/src/app/app.component.spec.ts
@@ -1,10 +1,11 @@
 import { TestBed } from '@angular/core/testing';
 import { AppComponent } from './app.component';
+import { ReactiveFormsModule } from '@angular/forms';
 
 describe('AppComponent', () => {
   beforeEach(async () => {
     await TestBed.configureTestingModule({
-      imports: [AppComponent],
+      imports: [AppComponent, ReactiveFormsModule],
     }).compileComponents();
   });
 
diff --git a/angular/RestClient/src/app/app.component.ts b/angular/RestClient/src/app/app.component.ts
index 0d3b21a781b1019a1f82594eb2d3e0b6cbcce844..f6060eca2fe714c3b89bb6ee62c3e02b26f37a94 100644
--- a/angular/RestClient/src/app/app.component.ts
+++ b/angular/RestClient/src/app/app.component.ts
@@ -1,12 +1,13 @@
 import { Component } from '@angular/core';
 import { RouterOutlet } from '@angular/router';
+import { NavigationComponent } from './core/navigation/navigation.component';
 
 @Component({
   selector: 'app-root',
   standalone: true,
-  imports: [RouterOutlet],
+  imports: [RouterOutlet, NavigationComponent],
   templateUrl: './app.component.html',
-  styleUrl: './app.component.css'
+  styleUrl: './app.component.css',
 })
 export class AppComponent {
   title = 'RestClient';
diff --git a/angular/RestClient/src/app/app.config.ts b/angular/RestClient/src/app/app.config.ts
index 52cd710c6c090668c4ee8282b3bc68f5870f7476..1f668ea1741efbdb605f6d418a9a93f53f1327fa 100644
--- a/angular/RestClient/src/app/app.config.ts
+++ b/angular/RestClient/src/app/app.config.ts
@@ -1,9 +1,20 @@
 import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
 import { provideRouter } from '@angular/router';
-
 import { routes } from './app.routes';
+import { provideHttpClient, withFetch } from '@angular/common/http';
+import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
+import { ReactiveFormsModule } from '@angular/forms'; // Added import for ReactiveFormsModule
+import { provideNativeDateAdapter } from '@angular/material/core';
 import { provideClientHydration } from '@angular/platform-browser';
 
 export const appConfig: ApplicationConfig = {
-  providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideClientHydration()]
+  providers: [
+    provideNativeDateAdapter(),
+    provideZoneChangeDetection({ eventCoalescing: true }),
+    provideRouter(routes),
+    provideClientHydration(),
+    provideHttpClient(withFetch()),
+    provideAnimationsAsync(),
+    ReactiveFormsModule,
+  ],
 };
diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts
index dc39edb5f23a35f788cba146dd7337127ba6c5ab..b8ee77b36e9b121a4cf804746bde023134978c1c 100644
--- a/angular/RestClient/src/app/app.routes.ts
+++ b/angular/RestClient/src/app/app.routes.ts
@@ -1,3 +1,43 @@
 import { Routes } from '@angular/router';
+import { HotelListComponent } from './core/features/hotel/hotel-list/hotel-list.component';
+import { BookingComponent } from './core/features/bookings/booking/booking.component';
+import { HotelRegisterComponent } from './core/features/hotel/hotel-register/hotel-register.component';
+import { MainPageComponent } from './core/features/user/main-page/main-page.component';
+import { BookingListComponent } from './core/features/bookings/booking-list/booking-list.component';
+import { UserBookingListComponent } from './core/features/user/user-booking-list/user-booking-list.component';
 
-export const routes: Routes = [];
+export const routes: Routes = [
+  {
+    path: '', // Ruta principal
+    component: MainPageComponent, // Componente de la página principal
+  },
+  {
+    path: 'bookings/search',
+    component: BookingListComponent,
+  },
+  {
+    path: 'bookings/new',
+    component: BookingComponent,
+  },
+  {
+    path: 'users/:id/bookings',
+    component: UserBookingListComponent,
+  },
+  {
+    path: 'hotels',
+    component: HotelListComponent,
+  },
+  {
+    path: 'hotels/new',
+    component: HotelRegisterComponent,
+  },
+  {
+    path: 'hotels/:id',
+    component: HotelRegisterComponent,
+  },
+  {
+    path: '**',
+    redirectTo: '',
+    pathMatch: 'full',
+  },
+];
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.css b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..fcbb63ff2da3990e7eb2bffbfedcd84cadac8004
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.css
@@ -0,0 +1,8 @@
+.container {
+  max-width: 1000px;
+  margin-top: 2rem;
+  padding: 20px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  background-color: #f9f9f9;
+}
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.html b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..231f1d8fd1b898e90529cf994a333cb986cb8377
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.html
@@ -0,0 +1,96 @@
+<div class="container">
+  <mat-card>
+    <mat-card-title class="flex text-center p-4">
+      <strong class="text-5xl">Registro de Hotel</strong>
+    </mat-card-title>
+
+    <mat-card-content>
+      <div class="form-group text-xl flex justify-center gap-20">
+        <mat-form-field>
+          <mat-label class="text-2xl">Enter a date range</mat-label>
+          <mat-date-range-input [rangePicker]="picker">
+            <input
+              matStartDate
+              placeholder="Start date"
+              (dateInput)="updateStart($event)"
+              (dateChange)="updateStart($event)"
+            />
+            <input
+              matEndDate
+              placeholder="End date"
+              (dateInput)="updateEnd($event)"
+              (dateChange)="updateEnd($event)"
+            />
+          </mat-date-range-input>
+          <mat-datepicker-toggle
+            matIconSuffix
+            [for]="picker"
+          ></mat-datepicker-toggle>
+          <mat-date-range-picker #picker></mat-date-range-picker>
+        </mat-form-field>
+        <mat-form-field>
+          <mat-label class="text-2xl">Hotel</mat-label>
+          <mat-select [(value)]="hotelSelected" class="text-2xl">
+            @for (hotel of hotels; track hotel.id) {
+            <mat-option [value]="hotel" class="text-3xl">{{
+              hotel.name
+            }}</mat-option>
+            }
+          </mat-select>
+        </mat-form-field>
+        <button
+          [disabled]="!this.start || !this.end || !this.hotelSelected"
+          mat-raised-button
+          class="bg-blue-500 rounded-full p-2"
+          (click)="search()"
+        >
+          <img class="w-3/4" src="/search.svg" />
+        </button>
+        <mat-form-field>
+          <mat-label>Filter by Room Type</mat-label>
+          <mat-select
+            [(value)]="roomTypeSelected"
+            (selectionChange)="updateRooms()"
+          >
+            @for (type of roomTypes; track type) {
+            <mat-option [value]="type">{{ type }}</mat-option>
+            }
+          </mat-select>
+        </mat-form-field>
+      </div>
+      <!-- Lista de Habitaciones -->
+      @if (trateRooms.length > 0) {
+      <div class="grid gap-4 text-lg mb-8">
+        <h2 class="text-2xl font-semibold mb-4">Habitaciones Disponibles</h2>
+        <div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
+          @for(room of trateRooms; track room.id) {
+          <mat-card class="example-card" appearance="outlined">
+            <mat-card-header class="flex justify-center">
+              <mat-card-title>
+                <strong
+                  >(#{{ $index + 1 }}) Habitación {{ room.roomNumber }}
+                </strong>
+                <span class="italic">({{ room.type }})</span>
+              </mat-card-title>
+            </mat-card-header>
+            <mat-card-content class="mt-4">
+              <button
+                mat-raised-button
+                class="w-full text-center py-3 rounded-lg shadow-md hover:shadow-lg text-3xl bg-sky-600 text-slate-200 font-bold"
+                (click)="bookingRoom(room.id)"
+              >
+                Reservar
+              </button>
+            </mat-card-content>
+          </mat-card>
+          }
+        </div>
+      </div>
+      } @else if (searched) {
+      <div class="text-center text-lg">
+        <p>No hay habitaciones disponibles</p>
+      </div>
+      }
+    </mat-card-content>
+  </mat-card>
+</div>
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.spec.ts b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f6b1910a567d3ff00efa491436359519ee52632d
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { BookingListComponent } from './booking-list.component';
+
+describe('BookingListComponent', () => {
+  let component: BookingListComponent;
+  let fixture: ComponentFixture<BookingListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [BookingListComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(BookingListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..06aab259dd9efcd5efaccb4defdacf03a55f3518
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking-list/booking-list.component.ts
@@ -0,0 +1,108 @@
+import { Component } from '@angular/core';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import {
+  MatDatepickerInputEvent,
+  MatDatepickerModule,
+} from '@angular/material/datepicker';
+import { FormsModule } from '@angular/forms';
+import { MatInputModule } from '@angular/material/input';
+import { MatSelectModule } from '@angular/material/select';
+import { Hotel, Room, RoomType, roomTypeArray } from '../../../../../types';
+
+import { Router } from '@angular/router';
+import { MatCardModule } from '@angular/material/card';
+import { MatChipsModule } from '@angular/material/chips';
+import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
+
+type SelectableRoomType = 'All' | RoomType;
+const selectableRoomTypeArray: SelectableRoomType[] = ['All', ...roomTypeArray];
+
+@Component({
+  selector: 'app-booking-list',
+  standalone: true,
+  imports: [
+    MatCardModule,
+    MatChipsModule,
+    MatFormFieldModule,
+    MatDatepickerModule,
+    MatCardModule,
+    MatFormFieldModule,
+    MatSelectModule,
+    MatInputModule,
+    FormsModule,
+  ],
+  templateUrl: './booking-list.component.html',
+  styleUrl: './booking-list.component.css',
+})
+export class BookingListComponent {
+  searched: boolean = false;
+  start?: Date;
+  end?: Date;
+  hotels!: Hotel[];
+  hotelSelected?: Hotel;
+  roomTypeSelected?: SelectableRoomType;
+  roomTypes = selectableRoomTypeArray;
+  rooms: Room[] = [];
+  trateRooms: Room[] = [];
+
+  constructor(private router: Router, private client: ClienteApiRestService) {}
+
+  ngOnInit() {
+    this.getHotels();
+  }
+
+  getHotels() {
+    this.client.getAllHotels().subscribe({
+      next: (resp) => {
+        if (resp != null) this.hotels = [...resp];
+      },
+      error(err) {
+        console.log('Error al traer la lista: ' + err.message);
+        throw err;
+      },
+    });
+  }
+
+  updateStart(event: MatDatepickerInputEvent<Date>) {
+    this.start = event.value!;
+  }
+
+  updateEnd(event: MatDatepickerInputEvent<Date>) {
+    this.end = event.value!;
+  }
+
+  search() {
+    this.client
+      .getRoomsAvailableInDateRange(
+        this.hotelSelected!.id,
+        this.start!,
+        this.end!
+      )
+      .subscribe({
+        next: (resp) => {
+          this.rooms = resp;
+          this.updateRooms();
+        },
+      });
+  }
+
+  updateRooms() {
+    this.searched = true;
+    this.trateRooms =
+      this.roomTypeSelected && this.roomTypeSelected !== 'All'
+        ? this.rooms.filter((room) => room.type === this.roomTypeSelected)
+        : this.rooms;
+  }
+
+  bookingRoom(roomId: number) {
+    localStorage.setItem(
+      'booking-data',
+      JSON.stringify({
+        roomId,
+        startDate: this.start,
+        endDate: this.end,
+      })
+    );
+    this.router.navigate(['/bookings', 'new'], { queryParams: { roomId } });
+  }
+}
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.css b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..34f19bda870b7fe9ab1df89627e400529a8b543f
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.css
@@ -0,0 +1,26 @@
+.container {
+    max-width: 600px;
+    margin: auto;
+    padding: 20px;
+    border: 1px solid #ccc;
+    border-radius: 5px;
+    background-color: #f9f9f9;
+  }
+  
+  h2 {
+    text-align: center;
+    margin-bottom: 20px;
+  }
+  
+  .form-group {
+    margin-bottom: 15px;
+  }
+  
+  label {
+    font-weight: bold;
+  }
+  
+  .btn {
+    width: 100%;
+  }
+  
\ No newline at end of file
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.html b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..4b09b386e32b53641cb4c00d522958fabcb21e07
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.html
@@ -0,0 +1,52 @@
+<div class="container">
+  <h2>Crear Reserva</h2>
+  <form [formGroup]="bookingForm" (ngSubmit)="submitBooking()">
+    <div class="form-group">
+      <label for="userId">ID del Usuario:</label>
+      <select
+        type="number"
+        id="userId"
+        formControlName="userId"
+        class="form-control"
+      >
+        @for(user of users; track user.id) {
+        <option value="{{ user.id }}">{{ user.name }}</option>
+        }
+      </select>
+    </div>
+
+    <div class="form-group">
+      <label for="roomId">ID del Habitación:</label>
+      <input
+        type="number"
+        id="roomId"
+        formControlName="roomId"
+        class="form-control"
+      />
+    </div>
+
+    <div class="form-group">
+      <label for="startDate">Fecha de Inicio:</label>
+      <input
+        type="date"
+        id="startDate"
+        formControlName="startDate"
+        class="form-control"
+      />
+    </div>
+
+    <div class="form-group">
+      <label for="endDate">Fecha de Fin:</label>
+      <input
+        type="date"
+        id="endDate"
+        formControlName="endDate"
+        class="form-control"
+      />
+    </div>
+
+    <button [disabled]="!isUserSelected" type="submit" class="btn btn-primary">
+      Reservar
+    </button>
+  </form>
+</div>
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.spec.ts b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5cfaef60aecb9a8a1c93f2b210c55e336ba27684
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.spec.ts
@@ -0,0 +1,56 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
+import { BookingComponent } from './booking.component';
+import { BookingService } from '../../../../shared/booking.service';
+import { of } from 'rxjs';
+
+class MockBookingService {
+  createBooking() {
+    return of({}); // Simula una respuesta exitosa
+  }
+}
+
+describe('BookingComponent', () => {
+  let component: BookingComponent;
+  let fixture: ComponentFixture<BookingComponent>;
+  let bookingService: BookingService;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [BookingComponent],
+      imports: [ReactiveFormsModule],
+      providers: [{ provide: BookingService, useClass: MockBookingService }],
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(BookingComponent);
+    component = fixture.componentInstance;
+    bookingService = TestBed.inject(BookingService);
+    fixture.detectChanges();
+  });
+
+  it('should create the component', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should have a valid form when all fields are filled', () => {
+    component.bookingForm.controls['userId'].setValue(1);
+    component.bookingForm.controls['hotelId'].setValue(1);
+    component.bookingForm.controls['roomType'].setValue('single');
+    component.bookingForm.controls['startDate'].setValue('2024-10-01');
+    component.bookingForm.controls['endDate'].setValue('2024-10-05');
+
+    expect(component.bookingForm.valid).toBeTrue();
+  });
+
+  it('should submit booking when form is valid', () => {
+    spyOn(bookingService, 'createBooking').and.callThrough();
+    component.bookingForm.controls['userId'].setValue(1);
+    component.bookingForm.controls['hotelId'].setValue(1);
+    component.bookingForm.controls['roomType'].setValue('single');
+    component.bookingForm.controls['startDate'].setValue('2024-10-01');
+    component.bookingForm.controls['endDate'].setValue('2024-10-05');
+
+    component.submitBooking();
+    expect(bookingService.createBooking).toHaveBeenCalled();
+  });
+});
diff --git a/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cd63902449b286409ab2ae045a9b273a7033a1f8
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/bookings/booking/booking.component.ts
@@ -0,0 +1,128 @@
+import { Component, OnInit } from '@angular/core';
+import {
+  ReactiveFormsModule,
+  FormGroup,
+  FormBuilder,
+  Validators,
+} from '@angular/forms';
+
+import { BookingService } from '../../../../shared/booking.service'; // Asegúrate de que el servicio exista
+import { ActivatedRoute, Router } from '@angular/router';
+import { Booking, User } from '../../../../../types';
+import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
+
+@Component({
+  standalone: true,
+  imports: [ReactiveFormsModule],
+  selector: 'app-booking',
+  templateUrl: './booking.component.html',
+  styleUrls: ['./booking.component.css'],
+})
+export class BookingComponent implements OnInit {
+  users: User[] = [];
+  bookingForm: FormGroup;
+  bookingLocal: { roomId: number; startDate: Date; endDate: Date };
+  roomId: number = 0;
+
+  constructor(
+    private router: Router,
+    private route: ActivatedRoute,
+    private fb: FormBuilder,
+    private bookingService: BookingService,
+    private client: ClienteApiRestService
+  ) {
+    // Inicialización del formulario con validaciones
+    this.bookingForm = this.fb.group({
+      userId: ['', Validators.required],
+      roomId: ['', Validators.required],
+      startDate: ['', Validators.required],
+      endDate: ['', Validators.required],
+    });
+    const localBookingStr = localStorage.getItem('booking-data');
+    if (localBookingStr === null) {
+      this.router.navigate(['/booking', 'search']);
+    }
+    const localBooking = JSON.parse(localBookingStr!);
+    this.bookingLocal = localBooking;
+    this.route.queryParams.subscribe((params) => {
+      const roomId = Number(params['roomId']);
+      this.roomId = roomId;
+      if (localBooking.roomId !== roomId) {
+        this.router.navigate(['/bookings', 'search']);
+        this.loadBooking(localBooking);
+      }
+    });
+    this.client.getAllUsers().subscribe({
+      next: (resp) => {
+        this.users = resp;
+      },
+    });
+  }
+
+  get userId() {
+    return this.bookingForm.get('userId')!.value;
+  }
+  get isUserSelected() {
+    return !isNaN(this.userId);
+  }
+
+  ngOnInit() {
+    this.loadBooking(this.bookingLocal);
+  }
+
+  loadBooking(booking: { roomId: number; startDate: Date; endDate: Date }) {
+    const start = new Date(booking.startDate).toISOString().split('T')[0];
+    const end = new Date(booking.endDate).toISOString().split('T')[0];
+    this.bookingForm = this.fb.group({
+      userId: [Validators.required],
+      roomId: [booking.roomId, Validators.required],
+      startDate: [start, Validators.required],
+      endDate: [end, Validators.required],
+    });
+    this.bookingForm.get('roomId')?.disable();
+    this.bookingForm.get('startDate')?.disable();
+    this.bookingForm.get('endDate')?.disable();
+  }
+
+  submitBooking() {
+    if (this.bookingForm.valid) {
+      const formValue = this.bookingForm.value;
+      const userId = Number(formValue.userId);
+      const bookingRequest: any = {
+        ...this.bookingLocal,
+        userId: { id: userId },
+        roomId: { id: this.roomId },
+      };
+
+      // Llama al servicio para crear una nueva reserva
+      this.bookingService.createBooking(bookingRequest).subscribe({
+        next: (response) => {
+          console.log('Reserva creada con éxito', response);
+          // Llama al servicio para actualizar el estado del usuario
+          this.client
+            .alterUserStatus(userId, 'WITH_ACTIVE_BOOKINGS')
+            .subscribe({
+              next: (response) => {
+                console.log(
+                  'Estado de usuario actualizado con exito',
+                  response
+                );
+                localStorage.removeItem('booking-data');
+                this.router.navigate(['/user', userId, 'bookings']);
+              },
+              error: (error) => {
+                console.error('Error al cambiar el estado del usuario', error);
+              },
+            });
+        },
+        error: (error) => {
+          console.error('Error al crear la reserva', error);
+          // Manejo de errores
+        },
+      });
+    } else {
+      console.warn('El formulario no es válido');
+      // Puedes mostrar un mensaje al usuario sobre la validez del formulario
+    }
+  }
+}
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.css b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..fcbb63ff2da3990e7eb2bffbfedcd84cadac8004
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.css
@@ -0,0 +1,8 @@
+.container {
+  max-width: 1000px;
+  margin-top: 2rem;
+  padding: 20px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  background-color: #f9f9f9;
+}
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.html b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..a97254ba286fcb168c472d0f717d7bff62409a50
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.html
@@ -0,0 +1,93 @@
+<div class="container">
+  <h2 class="text-center text-5xl font-bold mb-4">Hotel List</h2>
+  <mat-accordion>
+    <mat-expansion-panel disabled class="cursor-default">
+      <mat-expansion-panel-header>
+        <mat-panel-title class="text-3xl font-bold">Hotel</mat-panel-title>
+        <mat-panel-description class="text-3xl font-bold"
+          >Location</mat-panel-description
+        >
+      </mat-expansion-panel-header>
+    </mat-expansion-panel>
+    @for(hotel of hotels; track hotel.id) {
+    <mat-expansion-panel>
+      <mat-expansion-panel-header>
+        <mat-panel-title class="text-3xl">
+          {{ $index + 1 }}. {{ hotel.name }}
+        </mat-panel-title>
+        <mat-panel-description class="text-3xl">
+          {{ hotel.address.streetKind }} {{ hotel.address.streetName }} No.
+          {{ hotel.address.number }}, {{ hotel.address.postCode }}
+          {{ hotel.address.otherInfo }}
+        </mat-panel-description>
+      </mat-expansion-panel-header>
+
+      <div class="text-end mb-4">
+        <button
+          mat-raised-button
+          (click)="goToHotelDetails(hotel.id)"
+          style="
+            font-size: medium;
+            background-color: rgb(28, 197, 248);
+            color: rgb(250, 250, 250);
+          "
+        >
+          View hotel
+        </button>
+        <button
+          mat-raised-button
+          (click)="deleteHotel(hotel.id)"
+          style="
+            margin-left: 2rem;
+            font-size: medium;
+            background-color: rgb(223, 36, 36);
+            color: rgb(250, 250, 250);
+          "
+        >
+          <strong> Delete Hotel </strong>
+        </button>
+      </div>
+      <table mat-table [dataSource]="hotel.rooms" class="mat-elevation-z8">
+        <ng-container matColumnDef="roomNumber">
+          <th class="text-3xl" mat-header-cell *matHeaderCellDef>
+            Room Number
+          </th>
+          <td class="text-2xl" mat-cell *matCellDef="let room">
+            {{ room.roomNumber }}
+          </td>
+        </ng-container>
+
+        <ng-container matColumnDef="type">
+          <th class="text-3xl" mat-header-cell *matHeaderCellDef>Type</th>
+          <td class="text-2xl" ce mat-cell *matCellDef="let room">
+            {{ room.type }}
+          </td>
+        </ng-container>
+
+        <ng-container matColumnDef="available">
+          <th class="text-3xl text-center" mat-header-cell *matHeaderCellDef>
+            Available
+          </th>
+          <td class="text-2xl" mat-cell *matCellDef="let room">
+            <mat-slide-toggle
+              [checked]="room.available"
+              (change)="
+                toggleRoomAvailability(hotel.id!, room.id, !room.available)
+              "
+            ></mat-slide-toggle>
+          </td>
+        </ng-container>
+
+        <tr
+          mat-header-row
+          *matHeaderRowDef="['roomNumber', 'type', 'available']"
+        ></tr>
+        <tr
+          mat-row
+          *matRowDef="let row; columns: ['roomNumber', 'type', 'available']"
+        ></tr>
+      </table>
+    </mat-expansion-panel>
+    }
+  </mat-accordion>
+</div>
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.spec.ts b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ecc47151bf323959f0871b28bf1a09980e6b6702
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HotelListComponent } from './hotel-list.component';
+
+describe('HotelListComponent', () => {
+  let component: HotelListComponent;
+  let fixture: ComponentFixture<HotelListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [HotelListComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(HotelListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bdd87d3d36ce178cbb994508955b05bec3474803
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-list/hotel-list.component.ts
@@ -0,0 +1,107 @@
+import { Component } from '@angular/core';
+import { RouterModule, Router } from '@angular/router';
+import { Hotel } from '../../../../../types';
+import {
+  MatAccordion,
+  MatExpansionPanel,
+  MatExpansionPanelDescription,
+  MatExpansionPanelHeader,
+  MatExpansionPanelTitle,
+} from '@angular/material/expansion';
+import { MatSlideToggle } from '@angular/material/slide-toggle';
+import { MatTable, MatTableModule } from '@angular/material/table';
+import { MatButton } from '@angular/material/button';
+import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
+import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
+
+@Component({
+  selector: 'app-hotel-list',
+  standalone: true,
+  imports: [
+    RouterModule,
+    MatAccordion,
+    MatSlideToggle,
+    MatButton,
+    MatTable,
+    MatTableModule,
+    MatExpansionPanel,
+    MatExpansionPanelHeader,
+    MatExpansionPanelTitle,
+    MatExpansionPanelDescription,
+    NgbAccordionModule,
+  ],
+  templateUrl: './hotel-list.component.html',
+  styleUrl: './hotel-list.component.css',
+})
+export class HotelListComponent {
+  hotels!: Hotel[];
+  mostrarMensaje!: boolean;
+  mensaje!: string;
+
+  constructor(private router: Router, private client: ClienteApiRestService) {}
+
+  ngOnInit() {
+    this.getHotels();
+  }
+
+  getHotels() {
+    this.client.getAllHotels().subscribe({
+      next: (resp) => {
+        if (!!resp || (resp as never[]).length != 0) this.hotels = [...resp];
+      },
+      error(err) {
+        console.log('Error al traer la lista: ' + err.message);
+        throw err;
+      },
+    });
+  }
+
+  deleteHotel(id: number) {
+    if (!confirm(`Borrar hotel con id ${id}. Continuar?`)) return;
+
+    this.client.deleteHotel(id).subscribe({
+      next: (resp) => {
+        if (resp.status < 400) {
+          this.mostrarMensaje = true;
+          this.mensaje = resp.body as string;
+          this.getHotels();
+        } else {
+          this.mostrarMensaje = true;
+          this.mensaje = 'Error al eliminar registro';
+        }
+      },
+      error: (err) => {
+        console.log('Error al borrar: ' + err.message);
+        throw err;
+      },
+    });
+  }
+
+  toggleRoomAvailability(
+    hotelId: number,
+    roomId: number,
+    availability: boolean
+  ) {
+    this.client.alterRoomAvailability(hotelId, roomId, availability).subscribe({
+      next: (resp) => {
+        if (resp.status < 400) {
+          this.mostrarMensaje = true;
+          this.mensaje = resp.body as string;
+          this.getHotels();
+        } else {
+          this.mostrarMensaje = true;
+          this.mensaje = 'Error al cambiar disponibilidad';
+          console.error(this.mensaje);
+        }
+      },
+      error: (error) => {
+        console.log('Error al cambiar disponibilidad: ' + error.message);
+        throw error;
+      },
+    });
+  }
+
+  goToHotelDetails(hotelId: number): void {
+    this.router.navigate(['/hotels', hotelId]);
+  }
+}
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.css b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..79b4834ee543b62f19df182154eeb62fa0911db1
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.css
@@ -0,0 +1,21 @@
+.container {
+  max-width: 600px;
+  margin-top: 2rem;
+  padding: 20px;
+  border: 1px solid #ccc;
+  border-radius: 5px;
+  background-color: #f9f9f9;
+}
+
+h2 {
+  text-align: center;
+  margin-bottom: 20px;
+}
+
+.form-group {
+  margin-bottom: 15px;
+}
+
+label {
+  font-weight: bold;
+}
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.html b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..490aa3aacc1d222405ff173335b79b1aa6b844e2
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.html
@@ -0,0 +1,133 @@
+<div class="container">
+  <form [formGroup]="hotelForm">
+    <mat-card>
+      <mat-card-title class="flex text-center p-4">
+        <strong class="text-5xl">Registro de Hotel</strong>
+      </mat-card-title>
+      <mat-card-content>
+        <div class="form-group">
+          <label for="name" class="text-3xl">Nombre del Hotel</label>
+          <input
+            id="name"
+            class="form-control"
+            formControlName="name"
+            placeholder="Nombre del hotel"
+          />
+        </div>
+
+        <div class="form-group text-3xl">
+          <label class="">Dirección</label>
+          <div formGroupName="address">
+            <input
+              class="form-control mb-2"
+              formControlName="streetKind"
+              placeholder="Tipo de calle"
+            />
+            <input
+              class="form-control mb-2"
+              formControlName="streetName"
+              placeholder="Nombre de la calle"
+            />
+            <input
+              class="form-control mb-2"
+              formControlName="number"
+              type="number"
+              min="1"
+              placeholder="Número"
+            />
+            <input
+              class="form-control mb-2"
+              formControlName="postCode"
+              placeholder="Código Postal"
+            />
+            <input
+              class="form-control mb-2"
+              formControlName="otherInfo"
+              placeholder="Otra información (opcional)"
+            />
+          </div>
+        </div>
+
+        <!-- Lista de habitaciones -->
+        <div formArrayName="rooms">
+          <div class="flex gap-4 items-center mb-3">
+            <label class="text-3xl">Habitaciones</label>
+            <button
+              class="btn btn-primary rounded-full"
+              (click)="addRoom()"
+              [hidden]="editMode"
+              [disabled]="editMode"
+            >
+              <strong class="text-3xl">+</strong>
+            </button>
+          </div>
+
+          <div
+            *ngFor="let room of rooms.controls; let i = index"
+            [formGroupName]="i"
+            class="form-row row align-items-center mb-3"
+          >
+            <div class="col-md-12 flex justify-between align-items-center mb-3">
+              <span class="flex gap-4 items-center pa fs-3">
+                <label>Habitación {{ i + 1 }}</label>
+                <!-- Disponibilidad de habitación -->
+                <mat-slide-toggle formControlName="available"
+                  >Disponible</mat-slide-toggle
+                >
+              </span>
+              <button
+                class="btn btn-danger"
+                (click)="removeRoom(i)"
+                [disabled]="editMode || rooms.length <= 1"
+                [hidden]="editMode"
+              >
+                Eliminar
+              </button>
+            </div>
+
+            <!-- Número de habitación -->
+            <div class="col-md-6">
+              <mat-form-field appearance="fill" class="w-full">
+                <mat-label class="text-2xl">Número de habitación</mat-label>
+                <input
+                  matInput
+                  formControlName="roomNumber"
+                  placeholder="104A"
+                  class="text-2xl"
+                />
+              </mat-form-field>
+            </div>
+
+            <!-- Tipo de habitación -->
+            <div class="col-md-6">
+              <mat-form-field appearance="fill" class="w-full">
+                <mat-label class="text-2xl">Tipo de habitación</mat-label>
+                <mat-select formControlName="type">
+                  <mat-option class="text-2xl" value="SINGLE"
+                    >Single</mat-option
+                  >
+                  <mat-option class="text-2xl" value="DOUBLE"
+                    >Double</mat-option
+                  >
+                  <mat-option class="text-2xl" value="SUITE">Suite</mat-option>
+                </mat-select>
+              </mat-form-field>
+            </div>
+          </div>
+        </div>
+      </mat-card-content>
+      @if (!editMode) {
+      <mat-card-actions class="flex justify-center mb-5">
+        <button
+          type="submit"
+          class="btn btn-success text-5xl"
+          (click)="onSubmit()"
+          [disabled]="!hotelForm.valid"
+        >
+          Guardar Hotel
+        </button>
+      </mat-card-actions>
+      }
+    </mat-card>
+  </form>
+</div>
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.spec.ts b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7c085a3a8e7f1451e531f12d96d0049bb6b8a319
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { HotelRegisterComponent } from './hotel-register.component';
+
+describe('HotelRegisterComponent', () => {
+  let component: HotelRegisterComponent;
+  let fixture: ComponentFixture<HotelRegisterComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [HotelRegisterComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(HotelRegisterComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fd09a256f2380ae5c144b373f0406228079dcd73
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/hotel/hotel-register/hotel-register.component.ts
@@ -0,0 +1,155 @@
+import { Component } from '@angular/core';
+import {
+  FormArray,
+  FormBuilder,
+  FormGroup,
+  ReactiveFormsModule,
+  Validators,
+} from '@angular/forms';
+
+import { MatCardModule } from '@angular/material/card';
+import { MatInputModule } from '@angular/material/input';
+import { MatFormFieldModule } from '@angular/material/form-field';
+import { MatSelectModule } from '@angular/material/select';
+import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { CommonModule } from '@angular/common';
+import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
+import { Address, Hotel, Room } from '../../../../../types';
+import { ActivatedRoute, Router } from '@angular/router';
+
+const emptyRoom: Room = {
+  id: 0,
+  roomNumber: '',
+  type: 'SINGLE',
+  available: false,
+};
+const emptyHotel: Hotel = {
+  id: 0,
+  name: '',
+  rooms: [emptyRoom],
+  address: {
+    id: 0,
+    number: 0,
+    streetKind: '',
+    postCode: '',
+    streetName: '',
+  },
+};
+
+@Component({
+  selector: 'app-hotel-register',
+  standalone: true,
+  imports: [
+    CommonModule,
+    ReactiveFormsModule,
+    MatCardModule,
+    MatInputModule,
+    MatFormFieldModule,
+    MatSelectModule,
+    MatSlideToggleModule,
+  ],
+  templateUrl: './hotel-register.component.html',
+  styleUrl: './hotel-register.component.css',
+})
+export class HotelRegisterComponent {
+  editMode: boolean;
+  hotelForm: FormGroup;
+
+  constructor(
+    private router: Router,
+    private route: ActivatedRoute,
+    private fb: FormBuilder,
+    private client: ClienteApiRestService
+  ) {
+    this.hotelForm = this.setHotelForm();
+    this.editMode = false;
+    this.route.paramMap.subscribe({
+      next: (params) => {
+        const id = Number(params.get('id'));
+        this.editMode = id !== 0;
+        if (this.editMode) {
+          this.client.getHotel(id).subscribe({
+            next: (h) => this.setHotelForm(h),
+            error: (error) => {
+              this.router.navigate(['/hotels/new']);
+            },
+          });
+        }
+      },
+    });
+  }
+
+  get rooms(): FormArray {
+    return this.hotelForm.get('rooms') as FormArray;
+  }
+
+  // Agregar una nueva habitación
+  addRoom(): void {
+    const roomForm = this.fb.group({
+      roomNumber: [emptyRoom.roomNumber, Validators.required],
+      type: [emptyRoom.type, Validators.required],
+      available: [emptyRoom.available],
+    });
+    this.rooms.push(roomForm);
+  }
+
+  // Eliminar habitación
+  removeRoom(index: number): void {
+    this.rooms.removeAt(index);
+  }
+
+  // Método de envío del formulario
+  onSubmit(): void {
+    if (this.hotelForm.valid) {
+      const hotel = this.hotelForm.value as Hotel;
+      this.client.addHotel(hotel).subscribe({
+        next: (resp) => {
+          if (resp.status < 400) {
+            alert('Hotel guardado correctamente');
+            this.router.navigate(['/hotels']);
+          } else {
+          }
+        },
+        error: (err) => {
+          console.log('Error al borrar: ' + err.message);
+          throw err;
+        },
+      });
+    }
+  }
+
+  setHotelForm({
+    name,
+    address,
+    rooms,
+  }: {
+    name: String;
+    address: Address;
+    rooms: Room[];
+  } = emptyHotel) {
+    const form = this.fb.group({
+      name: [name, Validators.required],
+      address: this.fb.group({
+        streetKind: [address.streetKind, Validators.required],
+        streetName: [address.streetName, Validators.required],
+        number: [address.number, [Validators.required, Validators.min(1)]],
+        postCode: [address.postCode, Validators.required],
+        otherInfo: address.otherInfo,
+      }),
+      rooms: this.fb.array(
+        rooms.map(
+          (room) =>
+            this.fb.group({
+              roomNumber: [room.roomNumber, Validators.required],
+              type: [room.type, Validators.required],
+              available: [room.available],
+            }),
+          Validators.required
+        )
+      ),
+    });
+    if (this.editMode) form.disable();
+    this.hotelForm = form;
+    return form;
+  }
+}
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.css b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..f3f3318a77b3200dc595486e2d703bec99a0811c
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.css
@@ -0,0 +1,112 @@
+/* Contenedor principal con esquinas redondeadas y sombra sutil */
+.user-container {
+  max-width: 900px;
+  margin: 30px auto;
+  padding: 25px;
+  background-color: #1f1f1f;
+  border-radius: 12px;
+  box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.6);
+}
+
+/* Título centralizado y con un estilo moderno */
+h1 {
+  text-align: center;
+  font-size: 2em;
+  margin-bottom: 25px;
+  color: #ffffff;
+  letter-spacing: 1px;
+}
+
+/* Contenedor de filtro centrado y limpio */
+.filter-container {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 20px;
+}
+
+label {
+  font-weight: 600;
+  margin-right: 10px;
+  color: #a1a1a1;
+}
+
+/* Select estilizado con borde suave y sombras */
+select {
+  padding: 10px;
+  font-size: 1em;
+  border: none;
+  outline: none;
+  background-color: #292929;
+  color: #e0e0e0;
+  border-radius: 6px;
+  box-shadow: inset 0px 3px 8px rgba(0, 0, 0, 0.5);
+  transition: all 0.3s ease;
+}
+
+select:hover {
+  background-color: #3a3a3a;
+}
+
+/* Lista de usuarios sin puntos y con bordes modernos */
+.user-list {
+  list-style-type: none;
+  padding: 0;
+  margin: 0;
+}
+
+/* Elementos de la lista con espaciado y efecto hover futurista */
+.user-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px 20px;
+  margin-bottom: 8px;
+  background-color: #2c2c2c;
+  border-radius: 8px;
+  transition: transform 0.3s ease, background-color 0.3s ease;
+}
+
+.user-item:hover {
+  background-color: #333333;
+  transform: translateY(-2px);
+  box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.3);
+}
+
+/* Estilos de usuario con tipografía clara y futurista */
+.user-name {
+  flex: 0.5;
+  font-weight: 700;
+  color: #ffffff;
+}
+
+.user-email {
+  flex: 1.5;
+  color: #b0b0b0;
+  font-style: italic;
+  text-align: center;
+  padding-left: 15px;
+}
+
+.user-status {
+  flex: 1;
+  font-weight: 500;
+  color: #76c7c0;
+  text-transform: uppercase;
+  text-align: center;
+}
+
+.user-bookings {
+  flex: 1;
+  font-weight: 500;
+  color: #76c7c0;
+  text-transform: uppercase;
+  text-align: center;
+}
+
+.user-bookings button {
+  padding: 0.5rem 1rem;
+  background-color: #3d6b74;
+  color: white;
+  border-radius: 20px;
+}
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.html b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..9c34f26569237817882140eb2960e3fc98cc0fcf
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.html
@@ -0,0 +1,34 @@
+<div class="user-container">
+  <h1>Listado de Usuarios</h1>
+
+  <div class="filter-container">
+    <label for="filter">Filtrar por estado:</label>
+    <select id="filter" [(ngModel)]="selectedStatus" (change)="filterUsers()">
+      <option value="All">Todos</option>
+      <option value="NO_BOOKINGS">Sin reservas</option>
+      <option value="WITH_ACTIVE_BOOKINGS">Con reservas activas</option>
+      <option value="WITH_INACTIVE_BOOKINGS">Con reservas inactivas</option>
+    </select>
+  </div>
+
+  <ul class="user-list">
+    <li class="user-item">
+      <span class="user-name">Nombre</span>
+      <span class="user-email">Dirección de correo electronica</span>
+      <span class="user-status">Estado de usuario</span>
+      <span class="user-bookings">Reservas</span>
+    </li>
+    @for (user of filteredUsers; track user.id) {
+    <li class="user-item">
+      <span class="user-name">{{ user.name }}</span>
+      <span class="user-email">{{ user.email }}</span>
+      <span class="user-status">{{ getState(user) }}</span>
+      <span class="user-bookings">
+        <a [routerLink]="['/users', user.id, 'bookings']">
+          <button>Reservas</button>
+        </a>
+      </span>
+    </li>
+    }
+  </ul>
+</div>
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.spec.ts b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..40d589a21205dbd8b271cf4f441e0dfd44ed37ca
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.spec.ts
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MainPageComponent } from './main-page.component';
+
+describe('MainPageComponent', () => {
+  let component: MainPageComponent;
+  let fixture: ComponentFixture<MainPageComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [MainPageComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(MainPageComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..55760b59690b884457e25d55f8410a50c81cc0bd
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/main-page/main-page.component.ts
@@ -0,0 +1,51 @@
+// main-page.component.ts
+import { Component, OnInit } from '@angular/core';
+import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
+import { User, UserStateFilter } from '../../../../../types';
+import { FormsModule } from '@angular/forms';
+import { CommonModule } from '@angular/common';
+import users from '../../../../../mocks/users.json';
+import { RouterModule } from '@angular/router';
+@Component({
+  standalone: true,
+  imports: [FormsModule, CommonModule, RouterModule],
+  selector: 'app-main-page',
+  templateUrl: './main-page.component.html',
+  styleUrls: ['./main-page.component.css'],
+})
+export class MainPageComponent implements OnInit {
+  users: User[] = [];
+  filteredUsers: User[] = [];
+  selectedStatus: UserStateFilter = 'All';
+
+  constructor(private ClienteApiRestService: ClienteApiRestService) {}
+
+  ngOnInit(): void {
+    this.users = users as unknown as User[];
+    this.ClienteApiRestService.getAllUsers().subscribe((data: User[]) => {
+      this.users = data;
+      this.filteredUsers = data; // Inicialmente, muestra todos los usuarios
+    });
+  }
+
+  filterUsers(): void {
+    if (this.selectedStatus === 'All') {
+      this.filteredUsers = this.users;
+    } else {
+      this.filteredUsers = this.users.filter(
+        (user) => user.status === this.selectedStatus
+      );
+    }
+  }
+
+  getState(user: User) {
+    switch (user.status) {
+      case 'NO_BOOKINGS':
+        return 'SIN RESERVAS';
+      case 'WITH_ACTIVE_BOOKINGS':
+        return 'CON RESERVAS ACTIVAS';
+      case 'WITH_INACTIVE_BOOKINGS':
+        return 'CON RESERVAS INACTIVAS';
+    }
+  }
+}
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.css b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..dd9f0254a734af4e5e692facbd3f81ae64e04734
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.css
@@ -0,0 +1,118 @@
+body {
+  background-color: #121212;
+  color: #e0e0e0;
+  font-family: "Roboto", sans-serif;
+}
+
+.booking-container {
+  max-width: 900px;
+  margin: 30px auto;
+  padding: 25px;
+  background-color: #1f1f1f;
+  border-radius: 12px;
+  box-shadow: 0px 8px 20px rgba(0, 0, 0, 0.6);
+}
+
+.booking-list {
+  list-style-type: none;
+  padding: 0;
+  margin: 0;
+}
+
+.booking-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 15px 20px;
+  margin-bottom: 8px;
+  background-color: #2c2c2c;
+  border-radius: 8px;
+  transition: transform 0.3s ease, background-color 0.3s ease;
+}
+.booking-item:hover {
+  background-color: #333333;
+  transform: translateY(-2px);
+  box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.3);
+}
+.booking-id {
+  flex: 0.5;
+  font-weight: 700;
+  color: #ffffff;
+}
+
+.booking-start,
+.booking-end {
+  flex: 1;
+  color: #b0b0b0;
+  font-style: italic;
+  text-align: center;
+  padding-left: 15px;
+}
+
+.booking-status {
+  flex: 1;
+  font-weight: 500;
+  color: #76c7c0;
+  text-transform: uppercase;
+  text-align: center;
+}
+
+.booking-delete {
+  flex: 1;
+  font-weight: 500;
+  color: #76c7c0;
+  text-transform: uppercase;
+  text-align: center;
+}
+
+.booking-delete button {
+  padding: 0.5rem 1rem;
+  background-color: #3d6b74;
+  color: white;
+  border-radius: 20px;
+}
+
+h1 {
+  font-size: 2em;
+}
+h3 {
+  font-size: 1.25em;
+}
+
+h1,
+h3 {
+  text-align: center;
+  margin-bottom: 25px;
+  color: #ffffff;
+  letter-spacing: 1px;
+}
+
+.filter-container {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 20px;
+}
+
+label {
+  font-weight: 600;
+  margin-right: 10px;
+  color: #a1a1a1;
+}
+
+/* Select estilizado con borde suave y sombras */
+select {
+  padding: 10px;
+  font-size: 1em;
+  border: none;
+  outline: none;
+  background-color: #292929;
+  color: #e0e0e0;
+  border-radius: 6px;
+  box-shadow: inset 0px 3px 8px rgba(0, 0, 0, 0.5);
+  transition: all 0.3s ease;
+}
+
+select:hover {
+  background-color: #3a3a3a;
+}
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.html b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..88e7c25943f832f6984cd1ee0c5bcf34729f5ced
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.html
@@ -0,0 +1,46 @@
+<div class="booking-container">
+  <h1>Listado de Reservas</h1>
+  <h3>para el usuario {{ user?.name }} (ID: {{ userId }})</h3>
+
+  <div class="filter-container">
+    <label for="filter">Filtrar por estado:</label>
+    <select id="filter" [(ngModel)]="selectedState" (change)="updateBookings()">
+      <option value="all">Todas</option>
+      <option value="active">Reservas activas</option>
+      <option value="inactive">Reservas inactivas</option>
+    </select>
+  </div>
+
+  @if (bookings.length > 0) {
+  <ul class="booking-list">
+    <li class="booking-item">
+      <span class="booking-id">Reservas</span>
+      <span class="booking-start">Comienzo de reserva</span>
+      <span class="booking-end">Fin de reserva</span>
+      <span class="booking-status">Estado de la reserva</span>
+      <span class="booking-delete">Eliminar</span>
+    </li>
+    @for (booking of bookings; track booking.id) {
+    <ng-container>
+      <li class="booking-item">
+        <span class="booking-id">Reserva #{{ booking.id }}</span>
+
+        <span class="booking-start">{{ booking.startDate }}</span>
+        <span class="booking-end">{{ booking.endDate }}</span>
+        <span class="booking-status">{{ genBookingState(booking) }}</span>
+        <span class="booking-delete">
+          <button (click)="deleteBooking(booking.id)">Eliminar</button>
+        </span>
+      </li>
+    </ng-container>
+    }
+  </ul>
+  } @else if (search) {
+  <div class="no-bookings-found">
+    <h3>
+      No se encontraron reservas @if (selectedState !== 'all') { con estado @if
+      (selectedState === 'active') { activo } @else {inactivo} } para el usuario
+    </h3>
+  </div>
+  }
+</div>
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.spec.ts b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aae5d913c76b3f160908b0f5302bd80e29e94082
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { UserBookingListComponent } from './user-booking-list.component';
+
+describe('UserBookingListComponent', () => {
+  let component: UserBookingListComponent;
+  let fixture: ComponentFixture<UserBookingListComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [UserBookingListComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(UserBookingListComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5f1b3f1374342c3f9633486e6ce12027c2ebf7c5
--- /dev/null
+++ b/angular/RestClient/src/app/core/features/user/user-booking-list/user-booking-list.component.ts
@@ -0,0 +1,142 @@
+import { Component } from '@angular/core';
+import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
+import { Booking, User } from '../../../../../types';
+import { ActivatedRoute, RouterModule } from '@angular/router';
+import { MatSelectModule } from '@angular/material/select';
+import { CommonModule } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { BookingService } from '../../../../shared/booking.service';
+
+type state = 'all' | 'active' | 'inactive';
+
+@Component({
+  selector: 'app-user-booking-list',
+  standalone: true,
+  imports: [FormsModule, CommonModule, RouterModule],
+  templateUrl: './user-booking-list.component.html',
+  styleUrl: './user-booking-list.component.css',
+})
+export class UserBookingListComponent {
+  selectedState: state = 'all';
+  search = false;
+  bookings: Booking[] = [];
+  userId: number = 0;
+  user?: User;
+
+  constructor(
+    private client: ClienteApiRestService,
+    private bookingClient: BookingService,
+    private route: ActivatedRoute
+  ) {
+    this.route.paramMap.subscribe({
+      next: (params) => {
+        this.userId = Number(params.get('id'));
+        this.updateBookings();
+      },
+    });
+    this.client
+      .getUser(this.userId)
+      .subscribe({ next: (user) => (this.user = user) });
+  }
+
+  ngOnInit() {
+    this.updateBookings();
+  }
+
+  updateBookings() {
+    this.client.getUserBookings(this.userId).subscribe({
+      next: (bookings) => {
+        this.search = true;
+        switch (this.selectedState) {
+          case 'all':
+            this.bookings = bookings;
+            break;
+          case 'active':
+            this.bookings = bookings.filter(
+              (booking) => this.genBookingState(booking) === 'Reserva activa'
+            );
+            break;
+          case 'inactive':
+            this.bookings = bookings.filter(
+              (booking) => this.genBookingState(booking) === 'Reserva inactiva'
+            );
+            break;
+        }
+      },
+      error: (error) => {
+        console.error(error);
+      },
+    });
+  }
+
+  genBookingState(booking: Booking) {
+    return new Date(booking.endDate).getTime() < Date.now()
+      ? 'Reserva inactiva'
+      : 'Reserva activa';
+  }
+
+  deleteBooking(bookingId: number) {
+    this.bookingClient.deleteBooking(bookingId).subscribe({
+      next: () => {
+        this.updateBookings();
+        this.updateUserStatus();
+      },
+      error: (err) => {
+        console.error('Error al eliminar una reserva', err);
+      },
+    });
+  }
+
+  updateUserStatus() {
+    this.client.getUserBookings(this.userId).subscribe({
+      next: (bookings) => {
+        const withActive = bookings.find(
+          (booking) => this.genBookingState(booking) === 'Reserva activa'
+        );
+        const withInactive = bookings.find(
+          (booking) => this.genBookingState(booking) === 'Reserva inactiva'
+        );
+        if (withActive) {
+          this.client
+            .alterUserStatus(this.userId, 'WITH_ACTIVE_BOOKINGS')
+            .subscribe({
+              next: (response) => {
+                console.log('Cambio de estado en el usuario a activo correcto');
+              },
+              error: (err) => {
+                console.error('Error al cambiar de estado al usuario a activo');
+              },
+            });
+        } else if (withInactive) {
+          this.client
+            .alterUserStatus(this.userId, 'WITH_INACTIVE_BOOKINGS')
+            .subscribe({
+              next: (response) => {
+                console.log(
+                  'Cambio de estado en el usuario a inactivo correcto'
+                );
+              },
+              error: (err) => {
+                console.error(
+                  'Error al cambiar de estado al usuario a inactivo'
+                );
+              },
+            });
+        } else {
+          this.client.alterUserStatus(this.userId, 'NO_BOOKINGS').subscribe({
+            next: (response) => {
+              console.log(
+                'Cambio de estado en el usuario a sin reservas correcto'
+              );
+            },
+            error: (err) => {
+              console.error(
+                'Error al cambiar de estado al usuario sin reservas'
+              );
+            },
+          });
+        }
+      },
+    });
+  }
+}
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.css b/angular/RestClient/src/app/core/navigation/navigation.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..200c21a3a62ba294324b6a77c75d043c2bd5574b
--- /dev/null
+++ b/angular/RestClient/src/app/core/navigation/navigation.component.css
@@ -0,0 +1,44 @@
+nav {
+  background-color: #333;
+  color: white;
+  padding: 1em;
+}
+
+ul {
+  list-style: none;
+  padding: 0;
+  display: flex;
+}
+
+li {
+  margin-right: 20px;
+}
+
+a,
+a:visited {
+  color: white;
+  text-decoration: none;
+  transform: scale(1);
+  transition: transform 0.3s ease;
+}
+
+a:hover {
+  font-weight: bold;
+  text-decoration: underline;
+  color: yellow;
+  transition: transform 0.3s ease;
+  transform: scale(1.5);
+}
+
+.active {
+  font-weight: bold;
+}
+
+@keyframes escalar {
+  0% {
+    transform: scale(1);
+  }
+  100% {
+    transform: scale(1.5);
+  }
+}
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.html b/angular/RestClient/src/app/core/navigation/navigation.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..63615464cbbf7aec69cbd99e5e33ea9d1e5e08d8
--- /dev/null
+++ b/angular/RestClient/src/app/core/navigation/navigation.component.html
@@ -0,0 +1,12 @@
+<nav>
+  <ul>
+    <li><a class="btn" [routerLink]="['/']">Home - Usuarios</a></li>
+    <li>
+      <a class="btn" [routerLink]="['/hotels', 'new']">Registrar Hotel</a>
+    </li>
+    <li><a class="btn" [routerLink]="['/hotels']">Hoteles</a></li>
+    <li>
+      <a class="btn" [routerLink]="['/bookings', 'search']">Nueva Reserva</a>
+    </li>
+  </ul>
+</nav>
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.spec.ts b/angular/RestClient/src/app/core/navigation/navigation.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a161d3121330b48782b4b9f80a5060f1b5ab7c53
--- /dev/null
+++ b/angular/RestClient/src/app/core/navigation/navigation.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { NavigationComponent } from './navigation.component';
+
+describe('NavigationComponent', () => {
+  let component: NavigationComponent;
+  let fixture: ComponentFixture<NavigationComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [NavigationComponent]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(NavigationComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/core/navigation/navigation.component.ts b/angular/RestClient/src/app/core/navigation/navigation.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ccdab77b49379e3ed27abd65ada67e693882939a
--- /dev/null
+++ b/angular/RestClient/src/app/core/navigation/navigation.component.ts
@@ -0,0 +1,10 @@
+import { Component } from '@angular/core';
+import { Router, RouterModule } from '@angular/router';
+@Component({
+  selector: 'app-navigation',
+  standalone: true,
+  imports: [RouterModule],
+  templateUrl: './navigation.component.html',
+  styleUrl: './navigation.component.css',
+})
+export class NavigationComponent {}
diff --git a/angular/RestClient/src/app/shared/booking.service.spec.ts b/angular/RestClient/src/app/shared/booking.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3992ef555abf9021f683a3b7fd42344842c4d6ed
--- /dev/null
+++ b/angular/RestClient/src/app/shared/booking.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { BookingService } from './booking.service';
+
+describe('BookingService', () => {
+  let service: BookingService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(BookingService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/shared/booking.service.ts b/angular/RestClient/src/app/shared/booking.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..535f4d55ae2c7492a18e0bbf8472c0e78ca99392
--- /dev/null
+++ b/angular/RestClient/src/app/shared/booking.service.ts
@@ -0,0 +1,40 @@
+// booking.service.ts
+import { Injectable } from '@angular/core';
+import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { Observable } from 'rxjs';
+
+import { Booking } from '../../types/Booking'; // Ajusta la ruta a tu modelo Booking
+import { User, UserState } from '../../types';
+
+@Injectable({
+  providedIn: 'root', // Esto hace que el servicio esté disponible en toda la aplicación
+})
+export class BookingService {
+  private apiUrl = 'http://localhost:8080/bookings';
+
+  constructor(private http: HttpClient) {}
+
+  // Método para crear una nueva reserva
+  createBooking(bookingRequest: Booking): Observable<Booking> {
+    return this.http.post<Booking>(this.apiUrl, bookingRequest, {
+      headers: new HttpHeaders({
+        'Content-Type': 'application/json',
+      }),
+    });
+  }
+
+  // Método para obtener todas las reservas
+  getAllBookings(): Observable<Booking[]> {
+    return this.http.get<Booking[]>(this.apiUrl);
+  }
+
+  // Método para obtener una reserva por ID
+  getBookingById(id: number): Observable<Booking> {
+    return this.http.get<Booking>(`${this.apiUrl}/${id}`);
+  }
+
+  // Método para eliminar una reserva
+  deleteBooking(id: number) {
+    return this.http.delete(`${this.apiUrl}/${id}`);
+  }
+}
diff --git a/angular/RestClient/src/app/shared/cliente-api-rest.service.spec.ts b/angular/RestClient/src/app/shared/cliente-api-rest.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..737c9449305eb7a05fdbb88e75ef1492b05990b3
--- /dev/null
+++ b/angular/RestClient/src/app/shared/cliente-api-rest.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { ClienteApiRestService } from './cliente-api-rest.service';
+
+describe('ClienteApiRestService', () => {
+  let service: ClienteApiRestService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(ClienteApiRestService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/shared/cliente-api-rest.service.ts b/angular/RestClient/src/app/shared/cliente-api-rest.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cb4326ef52f9ed54bc172aa9fad9406872423815
--- /dev/null
+++ b/angular/RestClient/src/app/shared/cliente-api-rest.service.ts
@@ -0,0 +1,93 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+import { Hotel, Booking, Room, UserState } from '../../types';
+import { User } from '../../types';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class ClienteApiRestService {
+  private static readonly BASE_URI = 'http://localhost:8080';
+  private static readonly HOTEL_URI = `${ClienteApiRestService.BASE_URI}/hotels`;
+  private static readonly USER_URI = `${ClienteApiRestService.BASE_URI}/users`;
+  constructor(private http: HttpClient) {}
+
+  getHotel(id: number) {
+    const url = `${ClienteApiRestService.HOTEL_URI}/${id}`;
+    return this.http.get<Hotel>(url);
+  }
+
+  getAllHotels() {
+    const url = `${ClienteApiRestService.HOTEL_URI}`;
+    return this.http.get<Hotel[]>(url);
+  }
+
+  deleteHotel(id: number) {
+    const url = `${ClienteApiRestService.HOTEL_URI}/${id}`;
+    return this.http.delete(url, { observe: 'response', responseType: 'text' });
+  }
+
+  addHotel(hotel: Hotel) {
+    const url = `${ClienteApiRestService.HOTEL_URI}`;
+    return this.http.post(url, hotel, {
+      observe: 'response',
+      responseType: 'text',
+    });
+  }
+
+  alterRoomAvailability(
+    hotelId: number,
+    roomId: number,
+    availability: boolean
+  ) {
+    const url = `${ClienteApiRestService.HOTEL_URI}/${hotelId}/rooms/${roomId}`;
+    return this.http.patch(
+      url,
+      { available: availability },
+      {
+        observe: 'response',
+        responseType: 'text',
+      }
+    );
+  }
+
+  createBooking(bookingRequest: Booking) {
+    return this.http.post('http://localhost:8080/bookings', bookingRequest);
+  }
+
+  getRoomsAvailableInDateRange(hotelId: number, start: Date, end: Date) {
+    const startStr = start.toISOString().split('T')[0];
+    const endStr = end.toISOString().split('T')[0];
+    const url = `${ClienteApiRestService.HOTEL_URI}/${hotelId}/rooms?start=${startStr}&end=${endStr}`;
+    return this.http.get<Room[]>(url);
+  }
+
+  getUser(userId: number) {
+    return this.http.get<User>(`http://localhost:8080/users/${userId}`);
+  }
+
+  getAllUsers() {
+    return this.http.get<User[]>('http://localhost:8080/users', {
+      observe: 'body',
+    });
+  }
+
+  getUserBookings(userId: number) {
+    return this.http.get<Booking[]>(
+      `${ClienteApiRestService.BASE_URI}/users/${userId}/bookings`
+    );
+  }
+
+  alterUserStatus(userId: number, status: UserState) {
+    return this.http.patch(
+      `${ClienteApiRestService.BASE_URI}/users/${userId}`,
+      {
+        status,
+      },
+      {
+        observe: 'response',
+        responseType: 'text',
+      }
+    );
+  }
+}
diff --git a/angular/RestClient/src/app/shared/data.service.spec.ts b/angular/RestClient/src/app/shared/data.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..38e8d9ec63f1f637f51a18393f66c56d564e49a9
--- /dev/null
+++ b/angular/RestClient/src/app/shared/data.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { DataService } from './data.service';
+
+describe('DataService', () => {
+  let service: DataService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(DataService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/angular/RestClient/src/app/shared/data.service.ts b/angular/RestClient/src/app/shared/data.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f22afaeb6662ab48290b344d645945fc9a1c77b0
--- /dev/null
+++ b/angular/RestClient/src/app/shared/data.service.ts
@@ -0,0 +1,23 @@
+import { Injectable } from '@angular/core';
+import { BehaviorSubject } from 'rxjs';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class DataService {
+  private message = new BehaviorSubject('hotel list');
+  currentMessage = this.message.asObservable();
+
+  private showMessage = new BehaviorSubject<boolean>(false);
+  showCurrentMessage = this.showMessage.asObservable();
+
+  constructor() {}
+
+  setMessage(message: string) {
+    this.message.next(message);
+  }
+
+  setShowCurrentMessage(valor: boolean) {
+    this.showMessage.next(valor);
+  }
+}
diff --git a/angular/RestClient/src/index.html b/angular/RestClient/src/index.html
index 4f031927b575ccad9bed3e42d1c4442589159d3d..55c5530803842faa15de37607c2c916d5bd4f068 100644
--- a/angular/RestClient/src/index.html
+++ b/angular/RestClient/src/index.html
@@ -1,13 +1,29 @@
-<!doctype html>
+<!DOCTYPE html>
 <html lang="en">
-<head>
-  <meta charset="utf-8">
-  <title>RestClient</title>
-  <base href="/">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <link rel="icon" type="image/x-icon" href="favicon.ico">
-</head>
-<body>
-  <app-root></app-root>
-</body>
+  <head>
+    <meta charset="utf-8" />
+    <title>RestClient</title>
+    <base href="/" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <link rel="icon" type="image/x-icon" href="favicon.ico" />
+    <link
+      href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap"
+      rel="stylesheet"
+    />
+    <link
+      href="https://fonts.googleapis.com/icon?family=Material+Icons"
+      rel="stylesheet"
+    />
+    <link
+      rel="stylesheet"
+      href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css"
+    /></head
+  ><!-- compiled and minified CSS -->
+  <!-- jQuery library -->
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
+  <!-- compiled JavaScript -->
+  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
+  <body>
+    <app-root></app-root>
+  </body>
 </html>
diff --git a/angular/RestClient/src/main.ts b/angular/RestClient/src/main.ts
index 35b00f3463311f2afe0fd0d9d5f696dbb992dff5..60fe609f3d03c833222daf111673a1af3aa47d64 100644
--- a/angular/RestClient/src/main.ts
+++ b/angular/RestClient/src/main.ts
@@ -1,6 +1,9 @@
+/// <reference types="@angular/localize" />
+
 import { bootstrapApplication } from '@angular/platform-browser';
 import { appConfig } from './app/app.config';
 import { AppComponent } from './app/app.component';
 
-bootstrapApplication(AppComponent, appConfig)
-  .catch((err) => console.error(err));
+bootstrapApplication(AppComponent, appConfig).catch((err) =>
+  console.error(err)
+);
diff --git a/angular/RestClient/src/mocks/bookings.json b/angular/RestClient/src/mocks/bookings.json
new file mode 100644
index 0000000000000000000000000000000000000000..7db55ff76f1627de21762d95a7732a4f7be1ce34
--- /dev/null
+++ b/angular/RestClient/src/mocks/bookings.json
@@ -0,0 +1,30 @@
+[
+  {
+    "user": {
+      "name": "John Doe",
+      "email": "john.doe@example.com",
+      "status": "NO_BOOKINGS"
+    },
+    "room": {
+      "roomNumber": "101",
+      "type": "SINGLE",
+      "available": true
+    },
+    "startDate": "2024-03-01",
+    "endDate": "2024-03-08"
+  },
+  {
+    "user": {
+      "name": "Pepe",
+      "email": "pepe@example.com",
+      "status": "WITH_ACTIVE_BOOKINGS"
+    },
+    "room": {
+      "roomNumber": "101",
+      "type": "SINGLE",
+      "available": true
+    },
+    "startDate": "2024-03-15",
+    "endDate": "2024-03-22"
+  }
+]
diff --git a/angular/RestClient/src/mocks/hotels.json b/angular/RestClient/src/mocks/hotels.json
new file mode 100644
index 0000000000000000000000000000000000000000..11381112f37ac1123d22f06a2a0526c07825f211
--- /dev/null
+++ b/angular/RestClient/src/mocks/hotels.json
@@ -0,0 +1,46 @@
+[
+  {
+    "id": 1,
+    "name": "Hotel 1",
+    "address": {
+      "id": 1,
+      "streetName": "Aca al lao",
+      "streetKind": "Alargada",
+      "number": 12,
+      "postCode": "12345"
+    },
+    "rooms": [
+      {
+        "id": 1,
+        "roomNumber": "101",
+        "type": "SINGLE",
+        "available": true
+      },
+      {
+        "id": 2,
+        "roomNumber": "102",
+        "type": "DOUBLE",
+        "available": false
+      }
+    ]
+  },
+  {
+    "id": 2,
+    "name": "Hotel 2",
+    "address": {
+      "id": 2,
+      "streetName": "Calle de la plaza",
+      "streetKind": "Alargada",
+      "number": 12,
+      "postCode": "12345"
+    },
+    "rooms": [
+      {
+        "id": 3,
+        "roomNumber": "103",
+        "type": "SUITE",
+        "available": true
+      }
+    ]
+  }
+]
diff --git a/angular/RestClient/src/mocks/users.json b/angular/RestClient/src/mocks/users.json
new file mode 100644
index 0000000000000000000000000000000000000000..2f02d00125b0deaa2a86db47ea26f0c91f2e5fa3
--- /dev/null
+++ b/angular/RestClient/src/mocks/users.json
@@ -0,0 +1,12 @@
+[
+  {
+    "name": "John Doe",
+    "email": "john.doe@example.com",
+    "status": "NO_BOOKINGS"
+  },
+  {
+    "name": "Pepe",
+    "email": "pepe@example.com",
+    "status": "WITH_ACTIVE_BOOKINGS"
+  }
+]
diff --git a/angular/RestClient/src/styles.css b/angular/RestClient/src/styles.css
index 90d4ee0072ce3fc41812f8af910219f9eea3c3de..2b38a785ddb3df9137e3695c83f5841746135ce0 100644
--- a/angular/RestClient/src/styles.css
+++ b/angular/RestClient/src/styles.css
@@ -1 +1,12 @@
 /* You can add global styles to this file, and also import other style files */
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+html,
+body {
+  height: 100%;
+}
+body {
+  margin: 0;
+  font-family: Roboto, "Helvetica Neue", sans-serif;
+}
diff --git a/angular/RestClient/src/types/Address.d.ts b/angular/RestClient/src/types/Address.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..093601b162374201189adc393bca36393761920f
--- /dev/null
+++ b/angular/RestClient/src/types/Address.d.ts
@@ -0,0 +1,8 @@
+export interface Address {
+  id: number;
+  streetKind: string;
+  streetName: string;
+  number: number;
+  postCode: string;
+  otherInfo?: string;
+}
diff --git a/angular/RestClient/src/types/Booking.d.ts b/angular/RestClient/src/types/Booking.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..797c8aafb11b15aff5ac7cb9a3f4b510d7628284
--- /dev/null
+++ b/angular/RestClient/src/types/Booking.d.ts
@@ -0,0 +1,10 @@
+import { Room } from './Room';
+import { User } from './User';
+
+export interface Booking {
+  id: number;
+  startDate: Date;
+  endDate: Date;
+  userId: User;
+  roomId: Room;
+}
diff --git a/angular/RestClient/src/types/Hotel.d.ts b/angular/RestClient/src/types/Hotel.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c4183aa7f7055c24016b6b4325038a16cdaca09c
--- /dev/null
+++ b/angular/RestClient/src/types/Hotel.d.ts
@@ -0,0 +1,9 @@
+import { Address } from './Address';
+import { Room } from './Room';
+
+export interface Hotel {
+  id: number;
+  name: string;
+  address: Address;
+  rooms: Room[];
+}
diff --git a/angular/RestClient/src/types/Room.d.ts b/angular/RestClient/src/types/Room.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0c54fdcbfee2f4da7aa34f3727dd21421acbb048
--- /dev/null
+++ b/angular/RestClient/src/types/Room.d.ts
@@ -0,0 +1,7 @@
+export type RoomType = 'SINGLE' | 'DOUBLE' | 'SUITE';
+export interface Room {
+  id: number;
+  roomNumber: String;
+  type: RoomType;
+  available: boolean;
+}
diff --git a/angular/RestClient/src/types/User.d.ts b/angular/RestClient/src/types/User.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1ecc3d7512e7ff0b644e5555d290c48e88518219
--- /dev/null
+++ b/angular/RestClient/src/types/User.d.ts
@@ -0,0 +1,14 @@
+export interface User {
+  id: number;
+  name: string;
+  email: String;
+  // status: "noBookings" | "withActiveBookings" | "withInactiveBookings";
+  status: UserState;
+}
+
+export type UserStateFilter = 'All' | UserState;
+
+export type UserState =
+  | 'NO_BOOKINGS'
+  | 'WITH_ACTIVE_BOOKINGS'
+  | 'WITH_INACTIVE_BOOKINGS';
diff --git a/angular/RestClient/src/types/index.ts b/angular/RestClient/src/types/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b974a05f55ecc2a2b9a6e953882d7cc526689ab6
--- /dev/null
+++ b/angular/RestClient/src/types/index.ts
@@ -0,0 +1,9 @@
+import { RoomType } from './Room';
+
+export type * from './User';
+export type * from './Address';
+export type * from './Hotel';
+export type * from './Room';
+export const roomTypeArray: RoomType[] = ['SINGLE', 'DOUBLE', 'SUITE'];
+export type * from './Booking';
+export type * from './User';
diff --git a/angular/RestClient/tailwind.config.js b/angular/RestClient/tailwind.config.js
new file mode 100644
index 0000000000000000000000000000000000000000..73f743abf7a52e8820002459d0b0649938d5c78d
--- /dev/null
+++ b/angular/RestClient/tailwind.config.js
@@ -0,0 +1,8 @@
+/** @type {import('tailwindcss').Config} */
+module.exports = {
+  content: ["./src/**/*.{html,ts}"],
+  theme: {
+    extend: {},
+  },
+  plugins: [],
+};
diff --git a/angular/RestClient/tsconfig.app.json b/angular/RestClient/tsconfig.app.json
index cdc0b287f5dcddd808e55e1729efd6742fc621b6..d7319476f8a3febb1722be1542fb6612430f3b68 100644
--- a/angular/RestClient/tsconfig.app.json
+++ b/angular/RestClient/tsconfig.app.json
@@ -5,7 +5,8 @@
   "compilerOptions": {
     "outDir": "./out-tsc/app",
     "types": [
-      "node"
+      "node",
+      "@angular/localize"
     ]
   },
   "files": [
diff --git a/angular/RestClient/tsconfig.spec.json b/angular/RestClient/tsconfig.spec.json
index 5fb748d9207a99686549d6ef1415527dc544dd0f..b4c6282d524b2b574de3bf8be46db79ff231ccfa 100644
--- a/angular/RestClient/tsconfig.spec.json
+++ b/angular/RestClient/tsconfig.spec.json
@@ -5,7 +5,8 @@
   "compilerOptions": {
     "outDir": "./out-tsc/spec",
     "types": [
-      "jasmine"
+      "jasmine",
+      "@angular/localize"
     ]
   },
   "include": [
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java
new file mode 100644
index 0000000000000000000000000000000000000000..c52866c2ca28e056ad9551b42e007c0f2f487a80
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/BookingController.java
@@ -0,0 +1,80 @@
+// BookingController.java
+package com.uva.roomBooking.Controllers;
+
+import com.uva.roomBooking.Models.Booking;
+import com.uva.roomBooking.Models.Room;
+import com.uva.roomBooking.Models.User;
+import com.uva.roomBooking.Repositories.BookingRepository;
+import com.uva.roomBooking.Repositories.RoomRepository;
+import com.uva.roomBooking.Repositories.UserRepository;
+
+import jakarta.transaction.Transactional;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.HttpStatusCode;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/bookings")
+@CrossOrigin(origins = "http://localhost:4200")
+public class BookingController {
+
+    private final BookingRepository bookingRepository;
+    private final UserRepository userRepository;
+    private final RoomRepository roomRepository;
+
+    public BookingController(BookingRepository bookingRepository, UserRepository userRepository,
+            RoomRepository roomRepository) {
+        this.bookingRepository = bookingRepository;
+        this.userRepository = userRepository;
+        this.roomRepository = roomRepository;
+    }
+
+    @GetMapping
+    public List<Booking> getAllBookings() {
+        return bookingRepository.findAll();
+    }
+
+    @PostMapping
+    public Booking createBooking(@RequestBody Booking booking) {
+        User user = userRepository.findById(booking.getUserId().getId())
+                .orElseThrow(() -> new RuntimeException("User not found"));
+        Room room = roomRepository.findById(booking.getRoomId().getId())
+                .orElseThrow(() -> new RuntimeException("Room not found"));
+
+        // Verificar disponibilidad
+        List<Booking> existingBookings = bookingRepository.findByRoomIdAndDateRange(
+                room.getId(), booking.getStartDate(), booking.getEndDate());
+
+        if (!existingBookings.isEmpty()) {
+            throw new RuntimeException("Room is not available for the selected dates");
+        }
+
+        booking.setUserId(user);
+        booking.setRoomId(room);
+        return bookingRepository.save(booking);
+    }
+
+    @GetMapping("/{id}")
+    public Booking getBookingById(@PathVariable Integer id) {
+        return bookingRepository.findById(id)
+                .orElseThrow(() -> new RuntimeException("Booking not found"));
+    }
+
+    @DeleteMapping("/{id}")
+    @Transactional
+    public ResponseEntity<Void> deleteBooking(@PathVariable Integer id) {
+        try {
+            if (!bookingRepository.existsById(id))
+                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+
+            bookingRepository.deleteBookingById(id);
+            return new ResponseEntity<>(HttpStatus.ACCEPTED);
+        } catch (Exception e) {
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java
new file mode 100644
index 0000000000000000000000000000000000000000..587c57014ea64272b3be49cbed0706800bef484b
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/HotelController.java
@@ -0,0 +1,106 @@
+package com.uva.roomBooking.Controllers;
+
+import java.util.List;
+import java.util.Map;
+import java.time.LocalDate;
+
+import com.uva.roomBooking.Exceptions.HotelNotFoundException;
+import com.uva.roomBooking.Exceptions.InvalidDateRangeException;
+import com.uva.roomBooking.Exceptions.InvalidRequestException;
+import com.uva.roomBooking.Models.Hotel;
+import com.uva.roomBooking.Models.Room;
+import com.uva.roomBooking.Repositories.HotelRepository;
+import com.uva.roomBooking.Repositories.RoomRepository;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("hotels")
+@CrossOrigin(origins = "*")
+public class HotelController {
+    private final HotelRepository hotelRepository;
+    private final RoomRepository roomRepository;
+
+    public HotelController(HotelRepository hotelRepository, RoomRepository roomRepository) {
+        this.hotelRepository = hotelRepository;
+        this.roomRepository = roomRepository;
+    }
+
+    // Obtener todos los hoteles
+    @GetMapping
+    public List<Hotel> getAllHotels() {
+        return hotelRepository.findAll();
+    }
+
+    // Añadir un hotel con sus habitaciones
+    @PostMapping
+    public ResponseEntity<Hotel> addHotel(@RequestBody Hotel hotel) {
+        Hotel savedHotel = hotelRepository.save(hotel);
+        return new ResponseEntity<>(savedHotel, HttpStatus.CREATED);
+    }
+
+    // Obtener un hotel por su ID
+    @GetMapping("/{id}")
+    public Hotel getHotelById(@PathVariable int id) {
+        return hotelRepository.findById(id)
+                .orElseThrow(() -> new HotelNotFoundException(id));
+    }
+
+    // Borrar un hotel junto con sus habitaciones (borrado en cascada)
+    @DeleteMapping("/{id}")
+    public ResponseEntity<Void> deleteHotel(@PathVariable Integer id) {
+        Hotel target = hotelRepository.findById(id)
+                .orElseThrow(() -> new HotelNotFoundException(id));
+        hotelRepository.delete(target);
+        return new ResponseEntity<>(HttpStatus.NO_CONTENT);
+    }
+
+    // Obtener habitaciones de un hotel según disponibilidad y fechas
+    @GetMapping("/{hotelId}/rooms")
+    public ResponseEntity<List<Room>> getRoomsFromHotel(
+            @PathVariable int hotelId,
+            @RequestParam(required = false) LocalDate start,
+            @RequestParam(required = false) LocalDate end) {
+
+        List<Room> rooms;
+        if (start != null && end != null) {
+            if (!start.isBefore(end)) {
+                throw new InvalidDateRangeException("La fecha de inicio debe ser anterior a la fecha de fin");
+            }
+            rooms = roomRepository.findAvailableRoomsByHotelAndDates(hotelId, start, end);
+        } else {
+            rooms = roomRepository.findAllByHotelId(hotelId);
+        }
+        return new ResponseEntity<>(rooms, HttpStatus.OK);
+    }
+
+    // Actualizar disponibilidad de una habitación específica en un hotel
+    @PatchMapping("/{hotelId}/rooms/{roomId}")
+    public ResponseEntity<Room> updateRoomAvailability(
+            @PathVariable int hotelId,
+            @PathVariable int roomId,
+            @RequestBody Map<String, Boolean> body) {
+
+        if (!body.containsKey("available")) {
+            throw new InvalidRequestException("El campo 'available' es obligatorio");
+        }
+
+        Room targetRoom = roomRepository.findByIdAndHotelId(roomId, hotelId)
+                .orElseThrow(() -> new IllegalArgumentException("Habitación no encontrada"));
+
+        targetRoom.setAvailable(body.get("available"));
+        roomRepository.save(targetRoom);
+
+        return new ResponseEntity<>(targetRoom, HttpStatus.OK);
+    }
+
+    // Obtener los detalles de una habitación específica en un hotel
+    @GetMapping("/{hotelId}/rooms/{roomId}")
+    public Room getRoomByIdFromHotel(
+            @PathVariable int hotelId, @PathVariable int roomId) {
+        return roomRepository.findByIdAndHotelId(roomId, hotelId)
+                .orElseThrow(() -> new HotelNotFoundException(hotelId));
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/UserController.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/UserController.java
new file mode 100644
index 0000000000000000000000000000000000000000..a0e6397b9cabc191f7d5d24ecde162e8da6b2f14
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Controllers/UserController.java
@@ -0,0 +1,117 @@
+package com.uva.roomBooking.Controllers;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.uva.roomBooking.Models.UserStatus;
+import com.uva.roomBooking.Models.Booking;
+import com.uva.roomBooking.Models.User;
+import com.uva.roomBooking.Repositories.UserRepository;
+
+@RestController
+@RequestMapping("users")
+@CrossOrigin(origins = "*")
+public class UserController {
+  private final UserRepository userRepository;
+
+  public UserController(UserRepository userRepository) {
+    this.userRepository = userRepository;
+  }
+
+  @GetMapping
+  public List<User> getAllUsers() {
+    return userRepository.findAll();
+  }
+
+  @PostMapping
+  public User addUser(@RequestBody User user) {
+    // TODO revisar como se desea manejar estado por defecto
+    user.setStatus(UserStatus.NO_BOOKINGS);
+    // Aunque se asegure a lo mejor no es la forma de manejo esperada
+    return userRepository.save(user);
+  }
+
+  @GetMapping("/{id}")
+  public User getUserById(@PathVariable int id) {
+    return userRepository.findById(id).orElseThrow();
+  }
+
+  @PutMapping("/{id}")
+  public User updateUserData(@PathVariable int id, @RequestBody Map<String, String> json) {
+    User target = userRepository.findById(id).orElseThrow();
+    if (!json.containsKey("name") || !json.containsKey("email")) {
+      // TODO cambiar manejo
+      throw new RuntimeException("Missing required fields");
+    }
+    target.setName(json.get("name"));
+    target.setEmail(json.get("email"));
+    return userRepository.save(target);
+  }
+
+  @PatchMapping("/{id}")
+  public User updateUserState(@PathVariable int id, @RequestBody Map<String, String> json) {
+    User target = userRepository.findById(id).orElseThrow();
+    String strStatus = json.get("status");
+    if (strStatus == null) {
+      // TODO cambiar manejo
+      throw new RuntimeException("Missing required fields");
+    }
+    UserStatus userStatus = UserStatus.valueOf(strStatus);
+
+    boolean activeBookings = target.getBookings().stream()
+        .anyMatch(booking -> !booking.getEndDate().isBefore(LocalDate.now())); // reserva >= ahora
+    boolean inactiveBookings = target.getBookings().stream()
+        .anyMatch(booking -> booking.getStartDate().isBefore(LocalDate.now())); // reserva < ahora
+
+    switch (userStatus) {
+      // TODO Buscar como validar las (in)active bookings
+      case NO_BOOKINGS:
+        if (!target.getBookings().isEmpty())
+          throw new IllegalArgumentException("Invalid State: The user has at least one booking");
+        break;
+      case WITH_ACTIVE_BOOKINGS:
+        if (target.getBookings().isEmpty())
+          throw new IllegalArgumentException("Invalid State: The user don't has bookings");
+        if (!activeBookings)
+          throw new IllegalArgumentException("Invalid State: The user don't has active bookings");
+        break;
+      case WITH_INACTIVE_BOOKINGS:
+        if (target.getBookings().isEmpty())
+          throw new IllegalArgumentException("Invalid State: The user don't has bookings");
+        if (!inactiveBookings)
+          throw new IllegalArgumentException("Invalid State: The user don't has inactive bookings");
+        break;
+      default:
+        break;
+    }
+    target.setStatus(userStatus);
+    return userRepository.save(target);
+  }
+
+  @DeleteMapping("/{id}")
+  public User deleteUser(@PathVariable Integer id) {
+    User target;
+    if ((target = userRepository.findById(id).orElseThrow()) != null) {
+      userRepository.deleteById(id);
+    }
+    return target;
+  }
+
+  @GetMapping("/{id}/bookings")
+  public List<Booking> getUserBookingsById(@PathVariable int id) {
+    User user = userRepository.findById(id).orElseThrow();
+    return user.getBookings();
+  }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..03b21e27ffa7e4e921cc9801187911d9f1be6a52
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/GlobalExceptionHandler.java
@@ -0,0 +1,50 @@
+package com.uva.roomBooking.Exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+
+@ControllerAdvice
+public class GlobalExceptionHandler {
+
+    @ExceptionHandler(HotelNotFoundException.class)
+    public ResponseEntity<Map<String, Object>> handleHotelNotFound(HotelNotFoundException ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
+    }
+
+    @ExceptionHandler(InvalidRequestException.class)
+    public ResponseEntity<Map<String, Object>> handleInvalidRequest(InvalidRequestException ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
+    }
+
+    @ExceptionHandler(InvalidDateRangeException.class)
+    public ResponseEntity<Map<String, Object>> handleInvalidDateRange(InvalidDateRangeException ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
+    }
+
+    @ExceptionHandler(Exception.class)
+    public ResponseEntity<Map<String, Object>> handleGeneralException(Exception ex) {
+        Map<String, Object> body = new HashMap<>();
+        body.put("timestamp", LocalDateTime.now());
+        body.put("message", "An unexpected error occurred: " + ex.getMessage());
+
+        return new ResponseEntity<>(body, HttpStatus.INTERNAL_SERVER_ERROR);
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d47f5efad71b6fbf3b3f5912493c9c0af1ca412
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/HotelNotFoundException.java
@@ -0,0 +1,11 @@
+package com.uva.roomBooking.Exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)  // Devuelve un 404 cuando se lanza la excepción
+public class HotelNotFoundException extends RuntimeException {
+    public HotelNotFoundException(int id) {
+        super("Hotel not found with id: " + id);
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java
new file mode 100644
index 0000000000000000000000000000000000000000..17a8420453ef402411b61b965d001560a4dd51ce
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidDateRangeException.java
@@ -0,0 +1,8 @@
+package com.uva.roomBooking.Exceptions;
+
+public class InvalidDateRangeException extends RuntimeException {
+    public InvalidDateRangeException(String message) {
+        super(message);
+    }
+}
+
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8433b6f620da742dab87dae96a2e0f0193709ff
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Exceptions/InvalidRequestException.java
@@ -0,0 +1,11 @@
+package com.uva.roomBooking.Exceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.BAD_REQUEST)
+public class InvalidRequestException extends RuntimeException {
+    public InvalidRequestException(String message) {
+        super(message);
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Address.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Address.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e51f55e710c68ac38d4cb1c5769e574b06654bf
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Address.java
@@ -0,0 +1,115 @@
+package com.uva.roomBooking.Models;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToOne;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "addresses")
+public class Address {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Basic(optional = false)
+  private int id;
+
+  @Basic(optional = false)
+  @Column(name = "street_kind")
+  private String streetKind;
+
+  @Basic(optional = false)
+  @Column(name = "street_name")
+  private String streetName;
+
+  @Basic(optional = false)
+  private int number;
+
+  @Basic(optional = false)
+  @Column(name = "post_code")
+  private String postCode;
+
+  @Basic(optional = true)
+  @Column(name = "other_info")
+  private String otherInfo;
+
+  @JsonIgnore
+  @OneToOne(mappedBy = "address", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+  private Hotel hotel;
+
+  public Address() {
+  }
+
+  public Address(String streetKind, String streetName, int number, String postCode, String otherInfo, Hotel hotel) {
+    setStreetKind(streetKind);
+    setStreetName(streetName);
+    setNumber(number);
+    setPostCode(postCode);
+    setOtherInfo(otherInfo);
+    setHotel(hotel);
+  }
+
+  public int getId() {
+    return this.id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getStreetKind() {
+    return this.streetKind;
+  }
+
+  public void setStreetKind(String streetKind) {
+    this.streetKind = streetKind;
+  }
+
+  public String getStreetName() {
+    return this.streetName;
+  }
+
+  public void setStreetName(String streetName) {
+    this.streetName = streetName;
+  }
+
+  public int getNumber() {
+    return this.number;
+  }
+
+  public void setNumber(int number) {
+    this.number = number;
+  }
+
+  public String getPostCode() {
+    return this.postCode;
+  }
+
+  public void setPostCode(String postCode) {
+    this.postCode = postCode;
+  }
+
+  public String getOtherInfo() {
+    return this.otherInfo;
+  }
+
+  public void setOtherInfo(String otherInfo) {
+    this.otherInfo = otherInfo;
+  }
+
+  public Hotel getHotel() {
+    return this.hotel;
+  }
+
+  public void setHotel(Hotel hotel) {
+    this.hotel = hotel;
+  }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java
new file mode 100644
index 0000000000000000000000000000000000000000..c546d1916b1c29a10f95c97f03db34e64ffbe7d2
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Booking.java
@@ -0,0 +1,85 @@
+package com.uva.roomBooking.Models;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
+import java.time.LocalDate;
+
+@Entity
+@Table(name = "bookings")
+public class Booking {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Basic(optional = false)
+    private int id;
+    @JoinColumn(name = "user_id", referencedColumnName = "id")
+    @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
+    private User userId;
+    @JoinColumn(name = "room_id", referencedColumnName = "id")
+    @ManyToOne(optional = false, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
+    private Room roomId;
+    @Column(name = "start_date", nullable = false)
+    private LocalDate startDate;
+    @Column(name = "end_date", nullable = false)
+    private LocalDate endDate;
+
+    public Booking() {
+    }
+
+    public Booking(int id, User userId, Room roomID, LocalDate startDate, LocalDate endDate) {
+        this.id = id;
+        this.userId = userId;
+        this.roomId = roomID;
+        this.startDate = startDate;
+        this.endDate = endDate;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return this.id;
+    }
+
+    public void setUserId(User userId) {
+        this.userId = userId;
+    }
+
+    public User getUserId() {
+        return this.userId;
+    }
+
+    public void setRoomId(Room roomID) {
+        this.roomId = roomID;
+    }
+
+    public Room getRoomId() {
+        return this.roomId;
+    }
+
+    public void setStartDate(LocalDate startDate) {
+        this.startDate = startDate;
+    }
+
+    public LocalDate getStartDate() {
+        return this.startDate;
+    }
+
+    public void setEndDate(LocalDate endDate) {
+        this.endDate = endDate;
+    }
+
+    public LocalDate getEndDate() {
+        return this.endDate;
+    }
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java
new file mode 100644
index 0000000000000000000000000000000000000000..5a23005de99c022b5fff9570e2c515fcfc75e07e
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Hotel.java
@@ -0,0 +1,84 @@
+package com.uva.roomBooking.Models;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.OneToOne;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "hotels")
+// @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
+// property = "id")
+public class Hotel {
+
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Basic(optional = false)
+  private int id;
+
+  @Basic(optional = false)
+  private String name;
+
+  @JoinColumn(name = "address_id", referencedColumnName = "id")
+  @OneToOne(optional = false, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
+  private Address address;
+
+  @OneToMany(mappedBy = "hotel", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+  private List<Room> rooms;
+
+  public Hotel() {
+  }
+
+  public Hotel(int id, String name, Address address, List<Room> rooms) {
+    setId(id);
+    setName(name);
+    setAddress(address);
+    setRooms(rooms);
+  }
+
+  public int getId() {
+    return this.id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public Address getAddress() {
+    return this.address;
+  }
+
+  public void setAddress(Address address) {
+    this.address = address;
+  }
+
+  public List<Room> getRooms() {
+    return this.rooms;
+  }
+
+  public void setRooms(List<Room> rooms) {
+    this.rooms = rooms;
+    rooms.forEach(room -> room.setHotel(this));
+  }
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java
new file mode 100644
index 0000000000000000000000000000000000000000..639dfdb0bd3be629b16c719373fa51c9a7584898
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Room.java
@@ -0,0 +1,105 @@
+package com.uva.roomBooking.Models;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIdentityInfo;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.ObjectIdGenerators;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "rooms")
+// @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
+// property = "id")
+public class Room {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    @Basic(optional = false)
+    private int id;
+
+    @ManyToOne
+    @JoinColumn(name = "hotel_id", referencedColumnName = "id")
+    @JsonIgnore
+    private Hotel hotel;
+    @Column(name = "room_number", nullable = false)
+    private String roomNumber;
+    @Column(name = "type", nullable = false)
+    private Tipo type;
+    @Column(name = "available", nullable = false)
+    private boolean available;
+    @JsonIgnore
+    @OneToMany(mappedBy = "roomId", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+    private List<Booking> bookings;
+
+    public Room() {
+    }
+
+    public Room(int id, Hotel hotelId, String roomNumber, Tipo type, boolean available, List<Booking> bookings) {
+        this.id = id;
+        this.hotel = hotelId;
+        this.roomNumber = roomNumber;
+        this.type = type;
+        this.available = available;
+        this.bookings = bookings;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getId() {
+        return this.id;
+    }
+
+    public void setHotel(Hotel hotelId) {
+        this.hotel = hotelId;
+    }
+
+    public Hotel getHotel() {
+        return this.hotel;
+    }
+
+    public void setRoomNumber(String roomNumber) {
+        this.roomNumber = roomNumber;
+    }
+
+    public String getRoomNumber() {
+        return this.roomNumber;
+    }
+
+    public void setType(Tipo type) {
+        this.type = type;
+    }
+
+    public Tipo getType() {
+        return this.type;
+    }
+
+    public void setAvailable(boolean available) {
+        this.available = available;
+    }
+
+    public boolean isAvailable() {
+        return this.available;
+    }
+
+    public List<Booking> getBookings() {
+        return this.bookings;
+    }
+
+    public void setBookings(List<Booking> bookings) {
+        this.bookings = bookings;
+    }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Tipo.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Tipo.java
new file mode 100644
index 0000000000000000000000000000000000000000..e1a48b53450e1f87ae070b1bf70bd6a9afc1ea34
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/Tipo.java
@@ -0,0 +1,7 @@
+package com.uva.roomBooking.Models;
+
+public enum Tipo {
+    SINGLE, 
+    DOUBLE, 
+    SUITE
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java
new file mode 100644
index 0000000000000000000000000000000000000000..c5373df6edc5e936d9c94f794ae36d3289d173d5
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/User.java
@@ -0,0 +1,90 @@
+package com.uva.roomBooking.Models;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+
+import jakarta.persistence.Basic;
+import jakarta.persistence.CascadeType;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.FetchType;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "users")
+public class User {
+  @Id
+  @GeneratedValue(strategy = GenerationType.IDENTITY)
+  @Basic(optional = false)
+  private int id;
+
+  @Basic(optional = false)
+  private String name;
+
+  @Basic(optional = false)
+  private String email;
+
+  @Basic(optional = false)
+  @Enumerated(EnumType.STRING)
+  private UserStatus status = UserStatus.NO_BOOKINGS;
+
+  @JsonIgnore
+  @OneToMany(mappedBy = "userId", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
+  private List<Booking> bookings;
+
+  public User() {
+  }
+
+  public User(int id, String name, String email, UserStatus status, List<Booking> bookings) {
+    setId(id);
+    setEmail(email);
+    setStatus(status);
+    setBookings(bookings);
+  }
+
+  public int getId() {
+    return this.id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getName() {
+    return this.name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+  public String getEmail() {
+    return this.email;
+  }
+
+  public void setEmail(String email) {
+    this.email = email;
+  }
+
+  public UserStatus getStatus() {
+    return this.status;
+  }
+
+  public void setStatus(UserStatus status) {
+    this.status = status;
+  }
+
+  public List<Booking> getBookings() {
+    return this.bookings;
+  }
+
+  public void setBookings(List<Booking> bookings) {
+    this.bookings = bookings;
+  }
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Models/UserStatus.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/UserStatus.java
new file mode 100644
index 0000000000000000000000000000000000000000..41adce4ba6df6332286f0971b7f8e43b9126e401
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Models/UserStatus.java
@@ -0,0 +1,5 @@
+package com.uva.roomBooking.Models;
+
+public enum UserStatus {
+  NO_BOOKINGS, WITH_ACTIVE_BOOKINGS, WITH_INACTIVE_BOOKINGS;
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/BookingRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/BookingRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..b926175f84ff2d8748e4250e0bd8f574151ab25a
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/BookingRepository.java
@@ -0,0 +1,24 @@
+// BookingRepository.java
+package com.uva.roomBooking.Repositories;
+
+import com.uva.roomBooking.Models.Booking;
+
+import java.time.LocalDate;
+import java.util.List;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+public interface BookingRepository extends JpaRepository<Booking, Integer> {
+
+    @Query("SELECT b FROM Booking b WHERE b.roomId.id = ?1 AND b.startDate < ?2 AND b.endDate > ?3")
+    List<Booking> findByRoomIdAndDateRange(@Param("roomId") int roomId, @Param("startDate") LocalDate startDate,
+            @Param("endDate") LocalDate endDate);
+
+    @Modifying
+    @Query("DELETE FROM Booking b WHERE b.id = ?1")
+    void deleteBookingById(@Param("id") Integer id);
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/HotelRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/HotelRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..290f129a7be376279300062d4bf3d7a614abefcc
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/HotelRepository.java
@@ -0,0 +1,8 @@
+package com.uva.roomBooking.Repositories;
+
+import com.uva.roomBooking.Models.Hotel;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface HotelRepository extends JpaRepository<Hotel, Integer> {
+
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..3df9937f1ba7dc7c8bc0aa839a7a93ffd0baa8de
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/RoomRepository.java
@@ -0,0 +1,35 @@
+package com.uva.roomBooking.Repositories;
+
+import com.uva.roomBooking.Models.Room;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Optional;
+
+public interface RoomRepository extends JpaRepository<Room, Integer> {
+
+    Optional<Room> findByIdAndHotelId(int id, int hotelId);
+
+    // Encontrar todas las habitaciones de un hotel
+    List<Room> findAllByHotelId(int hotelId);
+
+    // Encontrar habitaciones disponibles de un hotel en un rango de fechas
+    @Query("""
+                SELECT r FROM Room r
+                WHERE r.hotel.id = ?1
+                AND r.available = true
+                AND NOT EXISTS (
+                    SELECT b FROM Booking b
+                    WHERE b.roomId.id = r.id
+                    AND (
+                        b.endDate > ?2
+                        OR
+                        b.startDate > ?3
+                    )
+                )
+            """)
+    List<Room> findAvailableRoomsByHotelAndDates(
+            int hotelId, LocalDate startDate, LocalDate endDate);
+}
diff --git a/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/UserRepository.java b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/UserRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f02f6d4a3b2147d181b8db36736d85ccfd884b5
--- /dev/null
+++ b/java/roomBooking/src/main/java/com/uva/roomBooking/Repositories/UserRepository.java
@@ -0,0 +1,9 @@
+package com.uva.roomBooking.Repositories;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import com.uva.roomBooking.Models.User;
+
+public interface UserRepository extends JpaRepository<User, Integer> {
+
+}
diff --git a/java/roomBooking/src/main/resources/application.properties b/java/roomBooking/src/main/resources/application.properties
index 714e8d5ce0a0b002fc02c3c982854ed28bbe3dd8..563d4ad07ad10e7fb52bb3defcc3b736d889447b 100644
--- a/java/roomBooking/src/main/resources/application.properties
+++ b/java/roomBooking/src/main/resources/application.properties
@@ -1 +1,10 @@
 spring.application.name=roomBooking
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
+spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/RoomsBooking?createDatabaseIfNotExist=true
+spring.datasource.username=user
+spring.datasource.password=password
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+# Usar esto para alternar entre las exposición del room repository ya que no es necesario su uso pero por defecto, al no cubrir su ruta, se expone
+# spring.data.rest.base-path=false
\ No newline at end of file