test: migrate ocpp server to poetry to ease usage main
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 10 Jun 2024 18:37:18 +0000 (20:37 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 10 Jun 2024 18:37:18 +0000 (20:37 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
69 files changed:
.eslintignore
.github/workflows/ci.yml
CHANGELOG.md
build-requirements.js
package.json
pnpm-lock.yaml
skip-preinstall.js
sonar-project.properties
src/assets/ui-protocol/Insomnia-CSSimulatorUIHTTPProtocol.json
src/assets/ui-protocol/Insomnia-CSSimulatorUIWSProtocol.json
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/Bootstrap.ts
src/charging-station/ChargingStation.ts
src/charging-station/Helpers.ts
src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts
src/charging-station/index.ts
src/charging-station/ocpp/1.6/OCPP16Constants.ts
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/1.6/OCPP16RequestService.ts
src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
src/charging-station/ocpp/2.0/OCPP20Constants.ts
src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts
src/charging-station/ocpp/2.0/OCPP20RequestService.ts
src/charging-station/ocpp/2.0/OCPP20ResponseService.ts
src/charging-station/ocpp/OCPPConstants.ts
src/charging-station/ocpp/OCPPIncomingRequestService.ts
src/charging-station/ocpp/OCPPRequestService.ts
src/charging-station/ocpp/OCPPResponseService.ts
src/charging-station/ocpp/OCPPServiceUtils.ts
src/charging-station/ui-server/AbstractUIServer.ts
src/charging-station/ui-server/UIServerFactory.ts
src/performance/PerformanceStatistics.ts
src/performance/storage/MikroOrmStorage.ts
src/performance/storage/MongoDBStorage.ts
src/performance/storage/Storage.ts
src/scripts/deleteChargingStations.cjs
src/scripts/setCSPublicFlag.cjs
src/types/ChargingStationEvents.ts
src/types/Statistics.ts
src/types/index.ts
src/types/ocpp/1.6/Requests.ts
src/types/ocpp/ChargingProfile.ts
src/utils/ChargingStationConfigurationUtils.ts
src/utils/CircularArray.ts [deleted file]
src/utils/Configuration.ts
src/utils/Constants.ts
src/utils/ErrorUtils.ts
src/utils/MessageChannelUtils.ts
src/utils/StatisticUtils.ts
src/utils/Utils.ts
src/utils/index.ts
src/worker/WorkerSet.ts
tests/exception/OCPPError.test.ts [new file with mode: 0644]
tests/ocpp-server/README.md [new file with mode: 0644]
tests/ocpp-server/__init__.py [new file with mode: 0644]
tests/ocpp-server/poetry.lock [new file with mode: 0644]
tests/ocpp-server/pyproject.toml [new file with mode: 0644]
tests/ocpp-server/server.py [new file with mode: 0644]
tests/utils/CircularArray.test.ts [deleted file]
tests/utils/ConfigurationUtils.test.ts [new file with mode: 0644]
tests/utils/ErrorUtils.test.ts [new file with mode: 0644]
tests/utils/StatisticUtils.test.ts
tests/utils/Utils.test.ts
ui/web/package.json
ui/web/src/composables/UIClient.ts
ui/web/src/composables/Utils.ts
ui/web/src/shims-vue.d.ts
ui/web/src/views/ChargingStationsView.vue
ui/web/start.js

index b14ff364d2da00bda0dcbb1ee90666d1329a1ad9..537479312061fdfbef0da43ff4d6cb9e62d3870d 100644 (file)
@@ -1,4 +1,2 @@
 dist/
 ui/web/
 dist/
 ui/web/
-# FIXME: ESM import parse error
-build-requirements.js
index 9d6b5f136f7c53f951149bc3a27af5d9b7760976..f48baf21a7062ffe14da4386fb2bf7c42c316b5c 100644 (file)
@@ -65,7 +65,7 @@ jobs:
         run: pnpm coverage
       - name: SonarCloud Scan
         if: ${{ needs.check-secrets.outputs.sonar-token-exists == 'true' && github.repository == 'sap/e-mobility-charging-stations-simulator' && matrix.os == 'ubuntu-latest' && matrix.node == '20.x' }}
         run: pnpm coverage
       - name: SonarCloud Scan
         if: ${{ needs.check-secrets.outputs.sonar-token-exists == 'true' && github.repository == 'sap/e-mobility-charging-stations-simulator' && matrix.os == 'ubuntu-latest' && matrix.node == '20.x' }}
-        uses: sonarsource/sonarcloud-github-action@v2.1.1
+        uses: sonarsource/sonarcloud-github-action@v2.2.0
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
           SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
@@ -116,7 +116,7 @@ jobs:
         run: pnpm coverage
       - name: SonarCloud Scan
         if: ${{ needs.check-secrets.outputs.sonar-token-exists == 'true' && github.repository == 'sap/e-mobility-charging-stations-simulator' && matrix.os == 'ubuntu-latest' && matrix.node == '20.x' }}
         run: pnpm coverage
       - name: SonarCloud Scan
         if: ${{ needs.check-secrets.outputs.sonar-token-exists == 'true' && github.repository == 'sap/e-mobility-charging-stations-simulator' && matrix.os == 'ubuntu-latest' && matrix.node == '20.x' }}
-        uses: sonarsource/sonarcloud-github-action@v2.1.1
+        uses: sonarsource/sonarcloud-github-action@v2.2.0
         with:
           projectBaseDir: ui/web
         env:
         with:
           projectBaseDir: ui/web
         env:
index e3a03ebf77991da0573fc6d2cbde496f465c8e03..832d877b7fa9a09e2de75de2bd62604e95a13d8e 100644 (file)
@@ -1,6 +1,129 @@
 # Changelog
 
 # Changelog
 
-## [v1.3.3](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.3.2...v1.3.3)
+## [v1.3.6](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.3.5...v1.3.6)
+
+- build(deps-dev): apply updates [`01ffb6d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/01ffb6d3583ab4da138dad815803121f3cc6d336)
+- feat: handle CHARGE_POINT_MAX_PROFILE charging profiles at power [`3579910`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/357991053f9d8910cdfaebde426eca58f813c05f)
+- build(deps-dev): apply updates [`7b0a334`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7b0a334d2c0e42768b246cbc962718d605ca7464)
+- refactor: cleanup power limitation code [`21f68e2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/21f68e222da0b9ac5d43a70b96beaf3f13ff3926)
+- refactor: cleanup charging profiles handling code [`c76d9c8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c76d9c83dba681eeccd78dcfae661b085d7ccf2b)
+- fix: ensure no charging profile purpose TxProfile is loaded at startup [`3edfdf5`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/3edfdf53dc3c75bf26b4737bb014e6e98239ef38)
+- build(deps-dev): apply updates [`1056f1b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1056f1b4cf5e305c45351093cb062d05468c83e8)
+- build: apply volta pnpm update [`c9a92ed`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c9a92ed7a2ef6d5258f075620b7f4878ba12c454)
+- fix: fix TxProfile removal with transaction id defined at Tx stop [`d020e24`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d020e249e5206699107d6e63d3d585a7e72e7830)
+
+## [v1.3.5](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.3.4...v1.3.5) (2024-06-09)
+
+- test: add ErrorUtils test [`d05b53c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d05b53c7a03b8fad2e106caee68d5871cc6aac6e)
+- test: improve ErrorUtils coverage [`2d4928a`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/2d4928a7237a906158f2e9652e08f0392eeabdcd)
+- build(deps-dev): apply updates [`c4387ed`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c4387ed4b3d2021034f452deeb35276fabe022e2)
+- feat: handle charging profile purpose TxProfile [`7abb61b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7abb61bb4a4e1de238c6bdb31b1a017bcf56d7b6)
+- build(deps-dev): apply updates [`65b608f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/65b608f0259f6f59138406ea327d22ecd6a19361)
+- test: add tests [`b49550e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/b49550e256d11c7a30fb19cd672e5e3611d01553)
+- test: improve coverage on existing tests [`ff40d2c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ff40d2cc466140d6f18bc15b742100dd4f060d0f)
+- chore: version 1.3.5 [`cc04ce3`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/cc04ce3549100de93505abdd6ff43fd3d968998d)
+- fix: restart metervalues interval if MeterValueSampleInterval is changed [`b8e3363`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/b8e3363a179fcf79d8bb66f47724b377d4d38a75)
+- refactor: rename Storage.handleDBError -&gt; Storage.handleDBStorageError [`a03b18c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a03b18c4731bfd1173ff67b74a75684d3f6bb470)
+- fix: allow to set charging profile with TxProfile purpose [`65099c1`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/65099c1e7297b252523172096a8d6ded22daa702)
+- fix: avoid to modify stored charging profiles [`a629e6f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a629e6fcfeb952d77da280e69d645b17d94b2e4c)
+- test: add ConfigurationUtils test [`2a9305b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/2a9305b5ace7b5a49b5862c4282c1a88e3087da5)
+- perf: compute power limitation only once [`5b1bd2d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5b1bd2d2c3c606aeef58cb1098def9a20c50dc4e)
+- fix: refine default configuration [`a9babd5`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a9babd5006e9b70f281d4bd654923fc3d63cd733)
+- test: improve ConfigurationUtils coverage [`8598b56`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/8598b5618e5acf6b9e2538faa5225ba51aa68d10)
+- test: add Utils insertAt() test [`055d4c4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/055d4c4c39c9c1fcce050019c61caf305ec1a83e)
+- test: trivial refinements [`0acbf5e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/0acbf5e6ab020dda7ddc6785347c05c144de3bd9)
+- fix: ensure ATG status is refreshed in the UI at stop [`c004d5e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c004d5e2e7d277ab99b3ee1b8ce363736529db9e)
+- test: improve ConfigurationUtils coverage [`329f14c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/329f14c004f74241c7cae1400e81740f3333eeee)
+- fix: add sanity check in ATG on connector id [`a4d9680`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a4d9680730c77debfb3b9455e4bd5b63e61ce664)
+- perf: add fastpath in array sorting helper [`8bfa4d2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/8bfa4d2be3f3817654791f166f4aab1b02485005)
+- fix: fix start transaction response handling with authorize [`ae8fb16`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ae8fb16df7c98a9238e61b1b358f8fbe2aee7a74)
+- fix: fix condition at ATG configuration handling [`274f9b3`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/274f9b3662d8cf5e5fb0a361a1ae9fac86309e40)
+
+## [v1.3.4](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.3.3...v1.3.4) (2024-06-06)
+
+- build(deps): bump sonarsource/sonarcloud-github-action from 2.1.1 to 2.2.0 [`#1038`](https://github.com/sap/e-mobility-charging-stations-simulator/pull/1038)
+- build(deps): bump pnpm/action-setup from 3 to 4 [`#1037`](https://github.com/sap/e-mobility-charging-stations-simulator/pull/1037)
+- fix: ensure message sequence is fired at boot notification response [`#1039`](https://github.com/sap/e-mobility-charging-stations-simulator/issues/1039)
+- refactor: code formatting [`48847bc`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/48847bc0d5e594c3e4c0b81c580ac6df48052668)
+- build(deps-dev): apply updates [`7445d18`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7445d18b9b9ac750b9dc3dc3638d4fd0e8aff818)
+- build(deps-dev): apply updates [`268173c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/268173c99a4ff81e1416909244ec58a6eb56dae6)
+- build(deps-dev): apply updates [`4f146c7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4f146c7c528d96cbe53ffeb9e578dc0c7e633af2)
+- build(deps): apply updates [`1dfc15d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1dfc15d22b7ac2363a32540d43540b7a93277a67)
+- build(deps-dev): apply updates [`c8d7098`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c8d709814d13d9e4ea88a6c3a6701b37bfa858a4)
+- build(deps-dev): apply updates [`5218eec`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5218eec27c72bade7112c6b029d7d1eb1f42f871)
+- build(deps-dev): apply updates [`18f25d9`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/18f25d958f1a57c34ed9d6e1de32ba9160c49dc2)
+- perf: use mnemonist CirculerBuffer [`840ca85`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/840ca85d7c40a6ee6f3a85a50e68dbea2f90acb8)
+- build(deps-dev): apply updates [`4bbeb8a`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4bbeb8ad766752ba5da88513d9e77cba136ae85f)
+- build(deps-dev): apply updates [`4ed43d2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4ed43d280ab39b9beaadfa90875c71bf3b2a9507)
+- build(deps-dev): apply updates [`2f2e044`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/2f2e04446bb16844a71e8752ae29bff584267029)
+- build(deps): apply updates [`b1b7103`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/b1b7103d2089ea75bff0a15125422adf69683fc1)
+- build(deps): apply updates [`78ffd68`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/78ffd6863ea25544c4933303281c4bc7a81496f0)
+- build(deps-dev): apply updates [`a112428`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a11242837ef77110c4d4b7a6ab0fa6f9a644a253)
+- build(deps): apply updates [`f26697b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/f26697b4c9dcdf791e48e8f15160e90f6855c995)
+- build(deps-dev): apply updates [`cd01b1d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/cd01b1d8f00898e27f78f4795650a78a179f0d14)
+- build(deps): apply updates [`576c4a4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/576c4a496a355c5d995325406ec2cc37416f8a8e)
+- build(deps-dev): apply updates [`8788b81`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/8788b81a3dd4add12ca01b1fe989b5c7c8927d54)
+- build(deps): apply updates [`21d5c4c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/21d5c4cdd0ccc30526f290a0be994990d5feac3f)
+- fix: fix performance statistics storage [`1c818bd`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1c818bd3b021c8e660d64f9054e02d06424a3c59)
+- build(deps): apply updates [`24a0327`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/24a032720668044fc8439da3165715bab8474b26)
+- build(deps): apply updates [`47f846b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/47f846b2a74439a610321356604f2f4184cb5c0b)
+- build(deps): apply updates [`cc99095`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/cc99095fab6d038ffff7ef3a2a8d33e762368670)
+- build(deps): apply updates [`73a88b8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/73a88b832be6eedd83e7b277032c8d7ba7d06a97)
+- build(deps): apply updates [`0972694`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/0972694d006542648c971026f43e5f4c8498f459)
+- build(deps-dev): apply updates [`36158bb`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/36158bb7c539757a8b4a898dd6093d6805376921)
+- build(deps): apply updates [`1f851da`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1f851da6440e4e4a31e959fcb8802b6c7f30beef)
+- chore: version 1.3.4 [`13a6494`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/13a6494f3542b9ed8773311302fa85258a1edec7)
+- refactor: cleanup OCPP utils [`01b82de`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/01b82de5b532cd149eccab7b82fe86a741289581)
+- build(deps-dev): apply updates [`55e006e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/55e006e1af126c62f26f39cd4a1f91ebd44b865d)
+- fix: ensure only circular buffer is converted to array [`312d325`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/312d3254e6581f6bc939497d610048b6c6226d6d)
+- fix: fix date handling connectorsStatus configuration file section [`1fa9df8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1fa9df8ce0e186387ecaa80efb9f40180fc36a7d)
+- fix: start heartbeat once [`d627f8e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d627f8ef31d97da80f4de5ed0cb9386472f51bbe)
+- fix: ensure boot notification response is assigned before querying [`0320e2b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/0320e2bb72ca522c3932850cce0601ab0a895ad3)
+- build(deps-dev): apply updates [`aa345d0`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/aa345d0154ff9700d8c9467c04c215ef5d07bbbf)
+- build: cleanup pnpm lock file [`fccc8f6`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/fccc8f66dfabe8e91f67311f3182e26aece20293)
+- refactor: cleanup boot notification response assignation [`ab29e68`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ab29e6820d6a6d48d8ccc091ec8adae575398c3d)
+- build(deps): apply updates [`29fe6fd`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/29fe6fd834029f21b22a23a3342f86b43c277c56)
+- build(deps-dev): apply updates [`fc10596`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/fc105961dd56e041fc6de1df3fd51c74723ba419)
+- refactor: refine OCPP message sending error handling [`436569b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/436569b1470c8e6187c63d974304bd1b99f35ba3)
+- fix: fix clear charging profiles with no connector in payload [`ec6dd88`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ec6dd88b156eac9a14afd0d349ed58bb02fa920e)
+- fix: start web socket ping interval at successful connection [`99100f9`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/99100f9c8709a7ead56c1e2745db80a75e8f6f79)
+- build(deps-dev): apply updates [`3ebab70`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/3ebab7003594d1c243bcca4ef90007dc63680a52)
+- build(deps-dev): apply updates [`e4006e4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e4006e4283d9150be5bd2f1050ff78c979a203c1)
+- fix: ensure charging profiles not related to the current transaction are [`626d3ce`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/626d3ce5e6dfdc848cb2bb5833044fe6fbe68324)
+- fix: ensure inflight requests id cannot be duplicated [`3024d5b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/3024d5b2497e97bdd355243a5d236fa3f7a4d874)
+- build(deps-dev): apply updates [`69d995b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/69d995b2c8683703e7d9ce42fdd73ec02209482f)
+- fix: avoid endless loop at remote start transaction [`d0b7173`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d0b71736d6fced71a50c67e1f1e7ca842068e43e)
+- build(deps-dev): apply updates [`a6f03d2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a6f03d2ddc8e28752b94cb0a43687d70c16683a6)
+- build(deps-dev): apply updates [`fa394dc`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/fa394dc9dd5f30d5121c2ce6ed11ba5d7c30bcd3)
+- fix: reset authorize fields connector status after reservation [`239194e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/239194e9867eaea7d34fc3c8d3bff3360113d8dc)
+- build(deps-dev): apply updates [`df3e0f8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/df3e0f8da05b9680213ccd3e3beee6686f296cd1)
+- refactor: cleanup Infinity usage [`cffc32b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/cffc32b7bc5a6569525e92b562af8a93760bc339)
+- build(deps-dev): apply updates [`fa30db1`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/fa30db101a2d11774bd9b29ca806597865ea06bf)
+- build: fix pnpm lockfile [`5e1bf42`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5e1bf4295e75408830ff46bb704a5139572a4120)
+- fix: properly handle undefined connector id at remote start transaction [`c0bbb3e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c0bbb3eaf0c5dc704ea92820a2666a68ffdc27ff)
+- fix: fix error handling default options definition [`30695dc`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/30695dcf67470f149e349d196b3d016482d11a17)
+- build(deps-dev): apply updates [`9e66896`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/9e668960f040bf5da86a6d6e7c477d4ad39dfd04)
+- build: bump volta node version [`494983d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/494983d465621a426f5dc92fd7cccc62821616f9)
+- build(deps-dev): apply updates [`bb57ea0`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/bb57ea07805938bec42dbee3da6bfda569a1b9bb)
+- refactor: convert npx to pnpm exec [`e1486a4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e1486a4c8ce0142f2efc57c87fc8e8e05745a13f)
+- refactor: cleanup boot notification response handling [`52f1dd5`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/52f1dd569da1eac66de821796cdfbcef09b48c87)
+- refactor: cleanup connection retries logic [`aa5f2ea`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/aa5f2ea2958ef34e8d34e20edbe8486b8911d82b)
+- fix: pickup not reserved connector at remote start transaction [`8946ba9`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/8946ba9db13e225292a62b8f4bdcd1419792697a)
+- refactor: cleanup eslint usage [`c69ae13`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c69ae13bb71df8f2017e21d919979b73dc6184f9)
+- fix: fix firmware update in progress detection [`382b62c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/382b62c45d665e66d4a2f3ad5ac7ecc6396859c7)
+- fix: fix log files path resolution at GetDiagnostics [`e56bbec`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e56bbec564af27559aade33d375dc890e882858e)
+- docs: refine code comments [`1d85f41`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1d85f415a46d0d3355ee013e449ad99d3aee9418)
+- build(deps): bump sonarsource/sonarcloud-github-action [`e48376c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e48376cebb2f0e5d6c670b432e1b524e21702d3a)
+- build(ci): rely on packageManager field to setup pnpm [`7bba320`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7bba3209fa975827c841aeab8fa20b4837ca64b1)
+- refactor: cleanup boot notification handling internal handling [`d9c13bc`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d9c13bcac891b8686dbba36ae5c10f87948e3614)
+- fix: fix remote transaction start debug log [`7b08e7f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7b08e7f332d1146fa5990cf29e08e328343819f1)
+- fix: ensure registration status is deleted if invalid boot notification [`18c6df2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/18c6df2b1102c307cbe8eb0c04d85c82045abf15)
+- refactor: cleanup string literal variables handling [`4c6f356`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4c6f35659fb67d395adc035ef80c566eb6eef79e)
+- perf: resize circular array to sensible default [`9b5cf75`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/9b5cf75581e0338885b8e2ea408ea5a3f391d0ec)
+- fix(ci): silence linter [`4293e51`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4293e5179eabbc8f42a1c06064d15c0ec7d1ca3f)
+- refactor: helper cleanup [`f69ca7c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/f69ca7ca5f551a427e3181d38bc893cb68b2b542)
+
+## [v1.3.3](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.3.2...v1.3.3) (2024-04-30)
 
 - fix: avoid duplicated slash in connection url [`#1034`](https://github.com/sap/e-mobility-charging-stations-simulator/issues/1034)
 - chore: switch to pnpm 9.x.x [`6eddb71`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6eddb71902ac0d0552f705190aaf62525f07c476)
 
 - fix: avoid duplicated slash in connection url [`#1034`](https://github.com/sap/e-mobility-charging-stations-simulator/issues/1034)
 - chore: switch to pnpm 9.x.x [`6eddb71`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6eddb71902ac0d0552f705190aaf62525f07c476)
 - build(deps-dev): apply updates [`a637f99`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a637f99f1d9a63bed1338809a5dbfab26925babe)
 - build(deps): apply updates [`de073a7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/de073a748bcd60308615b81c3f6da817639461a1)
 - build(deps-dev): apply updates [`5b7bbdb`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5b7bbdba3612e2f5748a4c21b46ba7bee89ddaba)
 - build(deps-dev): apply updates [`a637f99`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a637f99f1d9a63bed1338809a5dbfab26925babe)
 - build(deps): apply updates [`de073a7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/de073a748bcd60308615b81c3f6da817639461a1)
 - build(deps-dev): apply updates [`5b7bbdb`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5b7bbdba3612e2f5748a4c21b46ba7bee89ddaba)
+- chore: version 1.3.3 [`6deeebd`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6deeebd11133a5c4b47452d9d9ab8cf5759e7c8a)
 - build(deps-dev): apply updates [`98d6958`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/98d6958a6225cecc92e2f8b676c91be9fffd857b)
 - refactor: silence typing errors [`314793a`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/314793aaf25bf1a99deb3f8209c09421235942ba)
 - build: bump volta pnpm version [`8fb8f42`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/8fb8f42ace8b9295865adebaeb7845e064c05e71)
 - build(deps-dev): apply updates [`98d6958`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/98d6958a6225cecc92e2f8b676c91be9fffd857b)
 - refactor: silence typing errors [`314793a`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/314793aaf25bf1a99deb3f8209c09421235942ba)
 - build: bump volta pnpm version [`8fb8f42`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/8fb8f42ace8b9295865adebaeb7845e064c05e71)
index c92b20953402121217bb38ed224222498cac1852..501933c4fa5ae659809f3ab8f96f13f710d4caa4 100644 (file)
@@ -1,7 +1,9 @@
+import { readFileSync } from 'node:fs'
+import { exit, version } from 'node:process'
+
 import chalk from 'chalk'
 import chalk from 'chalk'
+// eslint-disable-next-line n/no-unpublished-import
 import { satisfies } from 'semver'
 import { satisfies } from 'semver'
-import { version, exit } from 'node:process'
-import { readFileSync } from 'node:fs'
 
 const packageJson = JSON.parse(readFileSync('./package.json', 'utf8'))
 
 
 const packageJson = JSON.parse(readFileSync('./package.json', 'utf8'))
 
index d3a7d256942445f5d7ff01f2d96f09573e633594..db7a052699cbf7b1e0389fc720e8b097ad241f8e 100644 (file)
@@ -1,16 +1,16 @@
 {
   "$schema": "https://json.schemastore.org/package",
   "name": "e-mobility-charging-stations-simulator",
 {
   "$schema": "https://json.schemastore.org/package",
   "name": "e-mobility-charging-stations-simulator",
-  "version": "1.3.3",
+  "version": "1.3.6",
   "engines": {
     "node": ">=18.18.0",
     "pnpm": ">=9.0.0"
   },
   "volta": {
   "engines": {
     "node": ">=18.18.0",
     "pnpm": ">=9.0.0"
   },
   "volta": {
-    "node": "22.1.0",
-    "pnpm": "9.1.0"
+    "node": "22.2.0",
+    "pnpm": "9.3.0"
   },
   },
-  "packageManager": "pnpm@9.1.0",
+  "packageManager": "pnpm@9.3.0",
   "repository": {
     "type": "git",
     "url": "https://github.com/sap/e-mobility-charging-stations-simulator.git"
   "repository": {
     "type": "git",
     "url": "https://github.com/sap/e-mobility-charging-stations-simulator.git"
@@ -70,9 +70,9 @@
     "build:entities": "tsc -p tsconfig-mikro-orm.json",
     "clean:dist": "pnpm exec rimraf dist",
     "clean:node_modules": "pnpm exec rimraf node_modules",
     "build:entities": "tsc -p tsconfig-mikro-orm.json",
     "clean:dist": "pnpm exec rimraf dist",
     "clean:node_modules": "pnpm exec rimraf node_modules",
-    "lint": "cross-env TIMING=1 eslint --cache src tests .eslintrc.cjs bundle.js mikro-orm.config-template.ts",
-    "lint:fix": "cross-env TIMING=1 eslint --cache --fix src tests .eslintrc.cjs bundle.js mikro-orm.config-template.ts",
-    "format": "prettier --cache --write .; eslint --cache --fix src .eslintrc.cjs tests bundle.js mikro-orm.config-template.ts",
+    "lint": "cross-env TIMING=1 eslint --cache src tests ./*.cjs ./*.js ./*.ts",
+    "lint:fix": "cross-env TIMING=1 eslint --cache --fix src tests ./*.cjs ./*.js ./*.ts",
+    "format": "prettier --cache --write .; eslint --cache --fix src tests ./*.cjs ./*.js ./*.ts",
     "test": "glob -c \"c8 node --import tsx --test\" \"tests/**/*.test.ts\"",
     "test:debug": "glob -c \"node --import tsx --test --inspect\" \"tests/**/*.test.ts\"",
     "coverage": "c8 report --reporter=lcov",
     "test": "glob -c \"c8 node --import tsx --test\" \"tests/**/*.test.ts\"",
     "test:debug": "glob -c \"node --import tsx --test --inspect\" \"tests/**/*.test.ts\"",
     "coverage": "c8 report --reporter=lcov",
     }
   },
   "dependencies": {
     }
   },
   "dependencies": {
-    "@mikro-orm/core": "^6.2.5",
-    "@mikro-orm/mariadb": "^6.2.5",
-    "@mikro-orm/reflection": "^6.2.5",
-    "@mikro-orm/sqlite": "^6.2.5",
-    "ajv": "^8.13.0",
+    "@mikro-orm/core": "^6.2.9",
+    "@mikro-orm/mariadb": "^6.2.9",
+    "@mikro-orm/reflection": "^6.2.9",
+    "@mikro-orm/sqlite": "^6.2.9",
+    "ajv": "^8.16.0",
     "ajv-formats": "^3.0.1",
     "basic-ftp": "^5.0.5",
     "chalk": "^5.3.0",
     "ajv-formats": "^3.0.1",
     "basic-ftp": "^5.0.5",
     "chalk": "^5.3.0",
     "http-status-codes": "^2.3.0",
     "logform": "^2.6.0",
     "mnemonist": "0.40.0-rc1",
     "http-status-codes": "^2.3.0",
     "logform": "^2.6.0",
     "mnemonist": "0.40.0-rc1",
-    "mongodb": "^6.6.1",
-    "poolifier": "^4.0.2",
+    "mongodb": "^6.7.0",
+    "poolifier": "^4.0.13",
     "rambda": "^9.2.0",
     "rambda": "^9.2.0",
-    "tar": "^7.1.0",
+    "tar": "^7.2.0",
     "winston": "^3.13.0",
     "winston-daily-rotate-file": "^5.0.0",
     "ws": "^8.17.0"
   },
   "optionalDependencies": {
     "bufferutil": "^4.0.8",
     "winston": "^3.13.0",
     "winston-daily-rotate-file": "^5.0.0",
     "ws": "^8.17.0"
   },
   "optionalDependencies": {
     "bufferutil": "^4.0.8",
-    "utf-8-validate": "^6.0.3"
+    "utf-8-validate": "^6.0.4"
   },
   "devDependencies": {
     "@commitlint/cli": "^19.3.0",
     "@commitlint/config-conventional": "^19.2.2",
   },
   "devDependencies": {
     "@commitlint/cli": "^19.3.0",
     "@commitlint/config-conventional": "^19.2.2",
-    "@mikro-orm/cli": "^6.2.5",
+    "@mikro-orm/cli": "^6.2.9",
     "@release-it/bumper": "^6.0.1",
     "@release-it/bumper": "^6.0.1",
-    "@types/node": "^20.12.10",
+    "@types/node": "^20.14.2",
     "@types/semver": "^7.5.8",
     "@types/ws": "^8.5.10",
     "@types/semver": "^7.5.8",
     "@types/ws": "^8.5.10",
-    "@typescript-eslint/eslint-plugin": "^7.8.0",
-    "@typescript-eslint/parser": "^7.8.0",
+    "@typescript-eslint/eslint-plugin": "^7.12.0",
+    "@typescript-eslint/parser": "^7.12.0",
     "auto-changelog": "^2.4.0",
     "auto-changelog": "^2.4.0",
-    "c8": "^9.1.0",
+    "c8": "^10.0.0",
     "clinic": "^13.0.0",
     "cross-env": "^7.0.3",
     "clinic": "^13.0.0",
     "cross-env": "^7.0.3",
-    "esbuild": "^0.21.0",
+    "esbuild": "^0.21.5",
     "esbuild-plugin-clean": "^1.0.1",
     "esbuild-plugin-copy": "^2.1.1",
     "eslint": "^8.57.0",
     "esbuild-plugin-clean": "^1.0.1",
     "esbuild-plugin-copy": "^2.1.1",
     "eslint": "^8.57.0",
     "eslint-define-config": "^2.1.0",
     "eslint-import-resolver-typescript": "^3.6.1",
     "eslint-plugin-import": "^2.29.1",
     "eslint-define-config": "^2.1.0",
     "eslint-import-resolver-typescript": "^3.6.1",
     "eslint-plugin-import": "^2.29.1",
-    "eslint-plugin-jsdoc": "^48.2.3",
-    "eslint-plugin-n": "^17.5.0",
+    "eslint-plugin-jsdoc": "^48.2.9",
+    "eslint-plugin-n": "^17.8.1",
     "eslint-plugin-simple-import-sort": "^12.1.0",
     "eslint-plugin-simple-import-sort": "^12.1.0",
-    "eslint-plugin-tsdoc": "^0.2.17",
+    "eslint-plugin-tsdoc": "^0.3.0",
     "expect": "^29.7.0",
     "expect": "^29.7.0",
-    "glob": "^10.3.12",
+    "glob": "^10.4.1",
     "husky": "^9.0.11",
     "husky": "^9.0.11",
-    "lint-staged": "^15.2.2",
-    "prettier": "^3.2.5",
-    "release-it": "^17.2.1",
-    "rimraf": "^5.0.5",
-    "semver": "^7.6.0",
+    "lint-staged": "^15.2.5",
+    "prettier": "^3.3.1",
+    "release-it": "^17.3.0",
+    "rimraf": "^5.0.7",
+    "semver": "^7.6.2",
     "ts-node": "^10.9.2",
     "ts-node": "^10.9.2",
-    "tsx": "^4.9.3",
+    "tsx": "^4.15.1",
     "typescript": "~5.4.5"
   }
 }
     "typescript": "~5.4.5"
   }
 }
index b1cd64c7f567dec9b97b53fb1735672f3fc1ec5c..8fdf1d9be2b4c4e291c127971bf7133372827a1f 100644 (file)
@@ -18,23 +18,23 @@ importers:
   .:
     dependencies:
       '@mikro-orm/core':
   .:
     dependencies:
       '@mikro-orm/core':
-        specifier: ^6.2.5
-        version: 6.2.5
+        specifier: ^6.2.9
+        version: 6.2.9
       '@mikro-orm/mariadb':
       '@mikro-orm/mariadb':
-        specifier: ^6.2.5
-        version: 6.2.5(@mikro-orm/core@6.2.5)
+        specifier: ^6.2.9
+        version: 6.2.9(@mikro-orm/core@6.2.9)
       '@mikro-orm/reflection':
       '@mikro-orm/reflection':
-        specifier: ^6.2.5
-        version: 6.2.5(@mikro-orm/core@6.2.5)
+        specifier: ^6.2.9
+        version: 6.2.9(@mikro-orm/core@6.2.9)
       '@mikro-orm/sqlite':
       '@mikro-orm/sqlite':
-        specifier: ^6.2.5
-        version: 6.2.5(@mikro-orm/core@6.2.5)
+        specifier: ^6.2.9
+        version: 6.2.9(@mikro-orm/core@6.2.9)(mariadb@3.3.0)
       ajv:
       ajv:
-        specifier: ^8.13.0
-        version: 8.13.0
+        specifier: ^8.16.0
+        version: 8.16.0
       ajv-formats:
         specifier: ^3.0.1
       ajv-formats:
         specifier: ^3.0.1
-        version: 3.0.1(ajv@8.13.0)
+        version: 3.0.1(ajv@8.16.0)
       basic-ftp:
         specifier: ^5.0.5
         version: 5.0.5
       basic-ftp:
         specifier: ^5.0.5
         version: 5.0.5
@@ -54,17 +54,17 @@ importers:
         specifier: 0.40.0-rc1
         version: 0.40.0-rc1
       mongodb:
         specifier: 0.40.0-rc1
         version: 0.40.0-rc1
       mongodb:
-        specifier: ^6.6.1
-        version: 6.6.1(socks@2.8.3)
+        specifier: ^6.7.0
+        version: 6.7.0(socks@2.8.3)
       poolifier:
       poolifier:
-        specifier: ^4.0.2
-        version: 4.0.2
+        specifier: ^4.0.13
+        version: 4.0.13
       rambda:
         specifier: ^9.2.0
         version: 9.2.0
       tar:
       rambda:
         specifier: ^9.2.0
         version: 9.2.0
       tar:
-        specifier: ^7.1.0
-        version: 7.1.0
+        specifier: ^7.2.0
+        version: 7.2.0
       winston:
         specifier: ^3.13.0
         version: 3.13.0
       winston:
         specifier: ^3.13.0
         version: 3.13.0
@@ -73,30 +73,30 @@ importers:
         version: 5.0.0(winston@3.13.0)
       ws:
         specifier: ^8.17.0
         version: 5.0.0(winston@3.13.0)
       ws:
         specifier: ^8.17.0
-        version: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
+        version: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
     optionalDependencies:
       bufferutil:
         specifier: ^4.0.8
         version: 4.0.8
       utf-8-validate:
     optionalDependencies:
       bufferutil:
         specifier: ^4.0.8
         version: 4.0.8
       utf-8-validate:
-        specifier: ^6.0.3
-        version: 6.0.3
+        specifier: ^6.0.4
+        version: 6.0.4
     devDependencies:
       '@commitlint/cli':
         specifier: ^19.3.0
     devDependencies:
       '@commitlint/cli':
         specifier: ^19.3.0
-        version: 19.3.0(@types/node@20.12.10)(typescript@5.4.5)
+        version: 19.3.0(@types/node@20.14.2)(typescript@5.4.5)
       '@commitlint/config-conventional':
         specifier: ^19.2.2
         version: 19.2.2
       '@mikro-orm/cli':
       '@commitlint/config-conventional':
         specifier: ^19.2.2
         version: 19.2.2
       '@mikro-orm/cli':
-        specifier: ^6.2.5
-        version: 6.2.5
+        specifier: ^6.2.9
+        version: 6.2.9(mariadb@3.3.0)
       '@release-it/bumper':
         specifier: ^6.0.1
       '@release-it/bumper':
         specifier: ^6.0.1
-        version: 6.0.1(release-it@17.2.1(typescript@5.4.5))
+        version: 6.0.1(release-it@17.3.0(typescript@5.4.5))
       '@types/node':
       '@types/node':
-        specifier: ^20.12.10
-        version: 20.12.10
+        specifier: ^20.14.2
+        version: 20.14.2
       '@types/semver':
         specifier: ^7.5.8
         version: 7.5.8
       '@types/semver':
         specifier: ^7.5.8
         version: 7.5.8
@@ -104,17 +104,17 @@ importers:
         specifier: ^8.5.10
         version: 8.5.10
       '@typescript-eslint/eslint-plugin':
         specifier: ^8.5.10
         version: 8.5.10
       '@typescript-eslint/eslint-plugin':
-        specifier: ^7.8.0
-        version: 7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
+        specifier: ^7.12.0
+        version: 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
       '@typescript-eslint/parser':
       '@typescript-eslint/parser':
-        specifier: ^7.8.0
-        version: 7.8.0(eslint@8.57.0)(typescript@5.4.5)
+        specifier: ^7.12.0
+        version: 7.12.0(eslint@8.57.0)(typescript@5.4.5)
       auto-changelog:
         specifier: ^2.4.0
         version: 2.4.0(encoding@0.1.13)
       c8:
       auto-changelog:
         specifier: ^2.4.0
         version: 2.4.0(encoding@0.1.13)
       c8:
-        specifier: ^9.1.0
-        version: 9.1.0
+        specifier: ^10.0.0
+        version: 10.0.0
       clinic:
         specifier: ^13.0.0
         version: 13.0.0(encoding@0.1.13)
       clinic:
         specifier: ^13.0.0
         version: 13.0.0(encoding@0.1.13)
@@ -122,74 +122,74 @@ importers:
         specifier: ^7.0.3
         version: 7.0.3
       esbuild:
         specifier: ^7.0.3
         version: 7.0.3
       esbuild:
-        specifier: ^0.21.0
-        version: 0.21.0
+        specifier: ^0.21.5
+        version: 0.21.5
       esbuild-plugin-clean:
         specifier: ^1.0.1
       esbuild-plugin-clean:
         specifier: ^1.0.1
-        version: 1.0.1(esbuild@0.21.0)
+        version: 1.0.1(esbuild@0.21.5)
       esbuild-plugin-copy:
         specifier: ^2.1.1
       esbuild-plugin-copy:
         specifier: ^2.1.1
-        version: 2.1.1(esbuild@0.21.0)
+        version: 2.1.1(esbuild@0.21.5)
       eslint:
         specifier: ^8.57.0
         version: 8.57.0
       eslint-config-love:
         specifier: ^47.0.0
       eslint:
         specifier: ^8.57.0
         version: 8.57.0
       eslint-config-love:
         specifier: ^47.0.0
-        version: 47.0.0(@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.5.0(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5)
+        version: 47.0.0(@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.8.1(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5)
       eslint-config-standard:
         specifier: ^17.1.0
       eslint-config-standard:
         specifier: ^17.1.0
-        version: 17.1.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.5.0(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0)
+        version: 17.1.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.8.1(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0)
       eslint-define-config:
         specifier: ^2.1.0
         version: 2.1.0
       eslint-import-resolver-typescript:
         specifier: ^3.6.1
       eslint-define-config:
         specifier: ^2.1.0
         version: 2.1.0
       eslint-import-resolver-typescript:
         specifier: ^3.6.1
-        version: 3.6.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+        version: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
       eslint-plugin-import:
         specifier: ^2.29.1
       eslint-plugin-import:
         specifier: ^2.29.1
-        version: 2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+        version: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
       eslint-plugin-jsdoc:
       eslint-plugin-jsdoc:
-        specifier: ^48.2.3
-        version: 48.2.3(eslint@8.57.0)
+        specifier: ^48.2.9
+        version: 48.2.9(eslint@8.57.0)
       eslint-plugin-n:
       eslint-plugin-n:
-        specifier: ^17.5.0
-        version: 17.5.0(eslint@8.57.0)
+        specifier: ^17.8.1
+        version: 17.8.1(eslint@8.57.0)
       eslint-plugin-simple-import-sort:
         specifier: ^12.1.0
         version: 12.1.0(eslint@8.57.0)
       eslint-plugin-tsdoc:
       eslint-plugin-simple-import-sort:
         specifier: ^12.1.0
         version: 12.1.0(eslint@8.57.0)
       eslint-plugin-tsdoc:
-        specifier: ^0.2.17
-        version: 0.2.17
+        specifier: ^0.3.0
+        version: 0.3.0
       expect:
         specifier: ^29.7.0
         version: 29.7.0
       glob:
       expect:
         specifier: ^29.7.0
         version: 29.7.0
       glob:
-        specifier: ^10.3.12
-        version: 10.3.12
+        specifier: ^10.4.1
+        version: 10.4.1
       husky:
         specifier: ^9.0.11
         version: 9.0.11
       lint-staged:
       husky:
         specifier: ^9.0.11
         version: 9.0.11
       lint-staged:
-        specifier: ^15.2.2
-        version: 15.2.2
+        specifier: ^15.2.5
+        version: 15.2.5
       prettier:
       prettier:
-        specifier: ^3.2.5
-        version: 3.2.5
+        specifier: ^3.3.1
+        version: 3.3.1
       release-it:
       release-it:
-        specifier: ^17.2.1
-        version: 17.2.1(typescript@5.4.5)
+        specifier: ^17.3.0
+        version: 17.3.0(typescript@5.4.5)
       rimraf:
       rimraf:
-        specifier: ^5.0.5
-        version: 5.0.5
+        specifier: ^5.0.7
+        version: 5.0.7
       semver:
         specifier: ^7.5.3
       semver:
         specifier: ^7.5.3
-        version: 7.6.0
+        version: 7.6.2
       ts-node:
         specifier: ^10.9.2
       ts-node:
         specifier: ^10.9.2
-        version: 10.9.2(@types/node@20.12.10)(typescript@5.4.5)
+        version: 10.9.2(@types/node@20.14.2)(typescript@5.4.5)
       tsx:
       tsx:
-        specifier: ^4.9.3
-        version: 4.9.3
+        specifier: ^4.15.1
+        version: 4.15.1
       typescript:
         specifier: ~5.4.5
         version: 5.4.5
       typescript:
         specifier: ~5.4.5
         version: 5.4.5
@@ -206,45 +206,45 @@ importers:
         specifier: ^3.4.27
         version: 3.4.27(typescript@5.4.5)
       vue-router:
         specifier: ^3.4.27
         version: 3.4.27(typescript@5.4.5)
       vue-router:
-        specifier: ^4.3.2
-        version: 4.3.2(vue@3.4.27(typescript@5.4.5))
+        specifier: ^4.3.3
+        version: 4.3.3(vue@3.4.27(typescript@5.4.5))
       vue-toast-notification:
         specifier: ^3.1.2
         version: 3.1.2(vue@3.4.27(typescript@5.4.5))
     devDependencies:
       '@rushstack/eslint-patch':
       vue-toast-notification:
         specifier: ^3.1.2
         version: 3.1.2(vue@3.4.27(typescript@5.4.5))
     devDependencies:
       '@rushstack/eslint-patch':
-        specifier: ^1.10.2
-        version: 1.10.2
+        specifier: ^1.10.3
+        version: 1.10.3
       '@tsconfig/node20':
         specifier: ^20.1.4
         version: 20.1.4
       '@types/jsdom':
       '@tsconfig/node20':
         specifier: ^20.1.4
         version: 20.1.4
       '@types/jsdom':
-        specifier: ^21.1.6
-        version: 21.1.6
+        specifier: ^21.1.7
+        version: 21.1.7
       '@types/node':
       '@types/node':
-        specifier: ^20.12.10
-        version: 20.12.10
+        specifier: ^20.14.2
+        version: 20.14.2
       '@typescript-eslint/eslint-plugin':
       '@typescript-eslint/eslint-plugin':
-        specifier: ^7.8.0
-        version: 7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
+        specifier: ^7.12.0
+        version: 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
       '@typescript-eslint/parser':
       '@typescript-eslint/parser':
-        specifier: ^7.8.0
-        version: 7.8.0(eslint@8.57.0)(typescript@5.4.5)
+        specifier: ^7.12.0
+        version: 7.12.0(eslint@8.57.0)(typescript@5.4.5)
       '@vitejs/plugin-vue':
       '@vitejs/plugin-vue':
-        specifier: ^5.0.4
-        version: 5.0.4(vite@5.2.11(@types/node@20.12.10))(vue@3.4.27(typescript@5.4.5))
+        specifier: ^5.0.5
+        version: 5.0.5(vite@5.2.13(@types/node@20.14.2))(vue@3.4.27(typescript@5.4.5))
       '@vitejs/plugin-vue-jsx':
       '@vitejs/plugin-vue-jsx':
-        specifier: ^3.1.0
-        version: 3.1.0(vite@5.2.11(@types/node@20.12.10))(vue@3.4.27(typescript@5.4.5))
+        specifier: ^4.0.0
+        version: 4.0.0(vite@5.2.13(@types/node@20.14.2))(vue@3.4.27(typescript@5.4.5))
       '@vitest/coverage-v8':
         specifier: ^1.6.0
       '@vitest/coverage-v8':
         specifier: ^1.6.0
-        version: 1.6.0(vitest@1.6.0(@types/node@20.12.10)(jsdom@24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)))
+        version: 1.6.0(vitest@1.6.0(@types/node@20.14.2)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)))
       '@vue/eslint-config-prettier':
         specifier: ^9.0.0
       '@vue/eslint-config-prettier':
         specifier: ^9.0.0
-        version: 9.0.0(eslint@8.57.0)(prettier@3.2.5)
+        version: 9.0.0(@types/eslint@8.56.10)(eslint@8.57.0)(prettier@3.3.1)
       '@vue/eslint-config-typescript':
         specifier: ^13.0.0
       '@vue/eslint-config-typescript':
         specifier: ^13.0.0
-        version: 13.0.0(eslint-plugin-vue@9.25.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5)
+        version: 13.0.0(eslint-plugin-vue@9.26.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5)
       '@vue/test-utils':
         specifier: ^2.4.6
         version: 2.4.6
       '@vue/test-utils':
         specifier: ^2.4.6
         version: 2.4.6
@@ -262,34 +262,34 @@ importers:
         version: 2.1.0
       eslint-import-resolver-typescript:
         specifier: ^3.6.1
         version: 2.1.0
       eslint-import-resolver-typescript:
         specifier: ^3.6.1
-        version: 3.6.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+        version: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
       eslint-plugin-import:
         specifier: ^2.29.1
       eslint-plugin-import:
         specifier: ^2.29.1
-        version: 2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+        version: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
       eslint-plugin-simple-import-sort:
         specifier: ^12.1.0
         version: 12.1.0(eslint@8.57.0)
       eslint-plugin-vue:
       eslint-plugin-simple-import-sort:
         specifier: ^12.1.0
         version: 12.1.0(eslint@8.57.0)
       eslint-plugin-vue:
-        specifier: ^9.25.0
-        version: 9.25.0(eslint@8.57.0)
+        specifier: ^9.26.0
+        version: 9.26.0(eslint@8.57.0)
       jsdom:
       jsdom:
-        specifier: ^24.0.0
-        version: 24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
+        specifier: ^24.1.0
+        version: 24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
       prettier:
       prettier:
-        specifier: ^3.2.5
-        version: 3.2.5
+        specifier: ^3.3.1
+        version: 3.3.1
       rimraf:
       rimraf:
-        specifier: ^5.0.5
-        version: 5.0.5
+        specifier: ^5.0.7
+        version: 5.0.7
       typescript:
         specifier: ~5.4.5
         version: 5.4.5
       vite:
       typescript:
         specifier: ~5.4.5
         version: 5.4.5
       vite:
-        specifier: ^5.2.11
-        version: 5.2.11(@types/node@20.12.10)
+        specifier: ^5.2.13
+        version: 5.2.13(@types/node@20.14.2)
       vitest:
         specifier: ^1.6.0
       vitest:
         specifier: ^1.6.0
-        version: 1.6.0(@types/node@20.12.10)(jsdom@24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3))
+        version: 1.6.0(@types/node@20.14.2)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4))
 
 packages:
 
 
 packages:
 
@@ -305,145 +305,145 @@ packages:
   '@assemblyscript/loader@0.19.23':
     resolution: {integrity: sha512-ulkCYfFbYj01ie1MDOyxv2F6SpRN1TOj7fQxbP07D6HmeR+gr2JLSmINKjga2emB+b1L2KGrFKBTc+e00p54nw==}
 
   '@assemblyscript/loader@0.19.23':
     resolution: {integrity: sha512-ulkCYfFbYj01ie1MDOyxv2F6SpRN1TOj7fQxbP07D6HmeR+gr2JLSmINKjga2emB+b1L2KGrFKBTc+e00p54nw==}
 
-  '@babel/code-frame@7.24.2':
-    resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
+  '@babel/code-frame@7.24.7':
+    resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/compat-data@7.24.4':
-    resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==}
+  '@babel/compat-data@7.24.7':
+    resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/core@7.24.5':
-    resolution: {integrity: sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==}
+  '@babel/core@7.24.7':
+    resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/generator@7.24.5':
-    resolution: {integrity: sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==}
+  '@babel/generator@7.24.7':
+    resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-annotate-as-pure@7.22.5':
-    resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==}
+  '@babel/helper-annotate-as-pure@7.24.7':
+    resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-compilation-targets@7.23.6':
-    resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==}
+  '@babel/helper-compilation-targets@7.24.7':
+    resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-create-class-features-plugin@7.24.5':
-    resolution: {integrity: sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==}
+  '@babel/helper-create-class-features-plugin@7.24.7':
+    resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
 
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
 
-  '@babel/helper-environment-visitor@7.22.20':
-    resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==}
+  '@babel/helper-environment-visitor@7.24.7':
+    resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-function-name@7.23.0':
-    resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
+  '@babel/helper-function-name@7.24.7':
+    resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-hoist-variables@7.22.5':
-    resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==}
+  '@babel/helper-hoist-variables@7.24.7':
+    resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-member-expression-to-functions@7.24.5':
-    resolution: {integrity: sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==}
+  '@babel/helper-member-expression-to-functions@7.24.7':
+    resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==}
     engines: {node: '>=6.9.0'}
 
   '@babel/helper-module-imports@7.22.15':
     resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
   '@babel/helper-module-imports@7.22.15':
     resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-module-imports@7.24.3':
-    resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==}
+  '@babel/helper-module-imports@7.24.7':
+    resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-module-transforms@7.24.5':
-    resolution: {integrity: sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==}
+  '@babel/helper-module-transforms@7.24.7':
+    resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
 
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
 
-  '@babel/helper-optimise-call-expression@7.22.5':
-    resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==}
+  '@babel/helper-optimise-call-expression@7.24.7':
+    resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-plugin-utils@7.24.5':
-    resolution: {integrity: sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==}
+  '@babel/helper-plugin-utils@7.24.7':
+    resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-replace-supers@7.24.1':
-    resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==}
+  '@babel/helper-replace-supers@7.24.7':
+    resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
 
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
 
-  '@babel/helper-simple-access@7.24.5':
-    resolution: {integrity: sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==}
+  '@babel/helper-simple-access@7.24.7':
+    resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-skip-transparent-expression-wrappers@7.22.5':
-    resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==}
+  '@babel/helper-skip-transparent-expression-wrappers@7.24.7':
+    resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-split-export-declaration@7.24.5':
-    resolution: {integrity: sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==}
+  '@babel/helper-split-export-declaration@7.24.7':
+    resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-string-parser@7.24.1':
-    resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==}
+  '@babel/helper-string-parser@7.24.7':
+    resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-validator-identifier@7.24.5':
-    resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==}
+  '@babel/helper-validator-identifier@7.24.7':
+    resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helper-validator-option@7.23.5':
-    resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==}
+  '@babel/helper-validator-option@7.24.7':
+    resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/helpers@7.24.5':
-    resolution: {integrity: sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==}
+  '@babel/helpers@7.24.7':
+    resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/highlight@7.24.5':
-    resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==}
+  '@babel/highlight@7.24.7':
+    resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/parser@7.24.5':
-    resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==}
+  '@babel/parser@7.24.7':
+    resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==}
     engines: {node: '>=6.0.0'}
     hasBin: true
 
     engines: {node: '>=6.0.0'}
     hasBin: true
 
-  '@babel/plugin-syntax-jsx@7.24.1':
-    resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==}
+  '@babel/plugin-syntax-jsx@7.24.7':
+    resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
 
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
 
-  '@babel/plugin-syntax-typescript@7.24.1':
-    resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==}
+  '@babel/plugin-syntax-typescript@7.24.7':
+    resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
 
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
 
-  '@babel/plugin-transform-typescript@7.24.5':
-    resolution: {integrity: sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw==}
+  '@babel/plugin-transform-typescript@7.24.7':
+    resolution: {integrity: sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
 
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
 
-  '@babel/template@7.24.0':
-    resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==}
+  '@babel/template@7.24.7':
+    resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/traverse@7.24.5':
-    resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==}
+  '@babel/traverse@7.24.7':
+    resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==}
     engines: {node: '>=6.9.0'}
 
     engines: {node: '>=6.9.0'}
 
-  '@babel/types@7.24.5':
-    resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==}
+  '@babel/types@7.24.7':
+    resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==}
     engines: {node: '>=6.9.0'}
 
   '@bcoe/v8-coverage@0.2.3':
     engines: {node: '>=6.9.0'}
 
   '@bcoe/v8-coverage@0.2.3':
@@ -556,8 +556,8 @@ packages:
   '@dabh/diagnostics@2.0.3':
     resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
 
   '@dabh/diagnostics@2.0.3':
     resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==}
 
-  '@es-joy/jsdoccomment@0.42.0':
-    resolution: {integrity: sha512-R1w57YlVA6+YE01wch3GPYn6bCsrOV3YW/5oGGE2tmX6JcL9Nr+b5IikrjMPF+v9CV3ay+obImEdsDhovhJrzw==}
+  '@es-joy/jsdoccomment@0.43.1':
+    resolution: {integrity: sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==}
     engines: {node: '>=16'}
 
   '@esbuild/aix-ppc64@0.20.2':
     engines: {node: '>=16'}
 
   '@esbuild/aix-ppc64@0.20.2':
@@ -566,8 +566,8 @@ packages:
     cpu: [ppc64]
     os: [aix]
 
     cpu: [ppc64]
     os: [aix]
 
-  '@esbuild/aix-ppc64@0.21.0':
-    resolution: {integrity: sha512-kB8I77Onff4y6hAREwsjF11ifM+xi8bBIq/viMO5NFZDX2vKlF0/mevHJYb4sNfb55jIREeUztkUfIgOFtSzdw==}
+  '@esbuild/aix-ppc64@0.21.5':
+    resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [aix]
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [aix]
@@ -578,8 +578,8 @@ packages:
     cpu: [arm64]
     os: [android]
 
     cpu: [arm64]
     os: [android]
 
-  '@esbuild/android-arm64@0.21.0':
-    resolution: {integrity: sha512-SDGbrIOL6P6WTIbDcCa2sbFgznp8o6ztjGWrA+js8JZ9HhBXavN3gPrEqUqB4+bV4AdsqlZG1tK2F06BOPNpZg==}
+  '@esbuild/android-arm64@0.21.5':
+    resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [android]
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [android]
@@ -590,8 +590,8 @@ packages:
     cpu: [arm]
     os: [android]
 
     cpu: [arm]
     os: [android]
 
-  '@esbuild/android-arm@0.21.0':
-    resolution: {integrity: sha512-8OvDALSbmoLJ79KCs0hxoki5I3qJA7JQMhJO6aq5O8G+pi7TPnGICdQRQcgdzwZaVc4ptp5SX7Phg6jKzvSEBg==}
+  '@esbuild/android-arm@0.21.5':
+    resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [android]
     engines: {node: '>=12'}
     cpu: [arm]
     os: [android]
@@ -602,8 +602,8 @@ packages:
     cpu: [x64]
     os: [android]
 
     cpu: [x64]
     os: [android]
 
-  '@esbuild/android-x64@0.21.0':
-    resolution: {integrity: sha512-G4fkcHqDtIbiE9b3KFJP+ay+TiCOHmenT5GYVi0fuHxFbX0CJ3lpTQbFuWR5s5AlYZZ1j4yY2hbggSUkaBK0pg==}
+  '@esbuild/android-x64@0.21.5':
+    resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [android]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [android]
@@ -614,8 +614,8 @@ packages:
     cpu: [arm64]
     os: [darwin]
 
     cpu: [arm64]
     os: [darwin]
 
-  '@esbuild/darwin-arm64@0.21.0':
-    resolution: {integrity: sha512-XMcLA6siz67AoEOl8WOot2Y3TOSClT15AqJdQz/sx98Dpv3oTbcv0BoqvHAhpBPgC8iyIKM98vVj6th7lA4DFg==}
+  '@esbuild/darwin-arm64@0.21.5':
+    resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [darwin]
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [darwin]
@@ -626,8 +626,8 @@ packages:
     cpu: [x64]
     os: [darwin]
 
     cpu: [x64]
     os: [darwin]
 
-  '@esbuild/darwin-x64@0.21.0':
-    resolution: {integrity: sha512-+dmvTVqVkAArjJyIbo4Rl2S4I4A/yRuivTPR9Igw0QMBVSJegJqixKxZvKLCh8xi6n8tePdq3EpfbFYH2KNNiw==}
+  '@esbuild/darwin-x64@0.21.5':
+    resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [darwin]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [darwin]
@@ -638,8 +638,8 @@ packages:
     cpu: [arm64]
     os: [freebsd]
 
     cpu: [arm64]
     os: [freebsd]
 
-  '@esbuild/freebsd-arm64@0.21.0':
-    resolution: {integrity: sha512-g8/wBRLbsjryMBo4PGg050I1fn4qrJobkxpT1OekO6I4H2HVQfVfBAvGPhwzc9tr8CUVu0pSGSz9oDPGIjhLNw==}
+  '@esbuild/freebsd-arm64@0.21.5':
+    resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [freebsd]
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [freebsd]
@@ -650,8 +650,8 @@ packages:
     cpu: [x64]
     os: [freebsd]
 
     cpu: [x64]
     os: [freebsd]
 
-  '@esbuild/freebsd-x64@0.21.0':
-    resolution: {integrity: sha512-uwRL7kSN9tfFBpa7o9HQjEgxPsQsSmOz2ALQ30dxMNT22xS49s8nUtFi7bJ+kM/pcTHcnhyJwJPCY7cwlbQbWQ==}
+  '@esbuild/freebsd-x64@0.21.5':
+    resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [freebsd]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [freebsd]
@@ -662,8 +662,8 @@ packages:
     cpu: [arm64]
     os: [linux]
 
     cpu: [arm64]
     os: [linux]
 
-  '@esbuild/linux-arm64@0.21.0':
-    resolution: {integrity: sha512-mgOuJBbV8Uexb3BmeVl1q2preJMu0aDiwiFxIfsQhE2+rqxVAEcIrllb7SulkH9G244O/ZN1VVILdZb2NPSvpw==}
+  '@esbuild/linux-arm64@0.21.5':
+    resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [linux]
@@ -674,8 +674,8 @@ packages:
     cpu: [arm]
     os: [linux]
 
     cpu: [arm]
     os: [linux]
 
-  '@esbuild/linux-arm@0.21.0':
-    resolution: {integrity: sha512-8s/YeLaUV3QTaGzwDqiTpb78Nw/DdIaUdIlRZItGgWf/8UZHsYUIWj9RfsEXVJB5qvtrg835Dgz/gf+GmFGa7w==}
+  '@esbuild/linux-arm@0.21.5':
+    resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
     engines: {node: '>=12'}
     cpu: [arm]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [arm]
     os: [linux]
@@ -686,8 +686,8 @@ packages:
     cpu: [ia32]
     os: [linux]
 
     cpu: [ia32]
     os: [linux]
 
-  '@esbuild/linux-ia32@0.21.0':
-    resolution: {integrity: sha512-7pVhVYBt3/R8x0Um9p4V8eMiQcnk6/IHkOo6tkfLnDqPn+NS6lnbfWysAYeDAqFKt6INQKtVxejh6ccbVYLBwQ==}
+  '@esbuild/linux-ia32@0.21.5':
+    resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [linux]
@@ -698,8 +698,8 @@ packages:
     cpu: [loong64]
     os: [linux]
 
     cpu: [loong64]
     os: [linux]
 
-  '@esbuild/linux-loong64@0.21.0':
-    resolution: {integrity: sha512-P8Lse7CXV83ARWVaq6KwV6w86ABeViyUvw6s++tYsUuqUEZgG5697Un72usafkuD7AfOyBdFX6JqZSvIQAU0yQ==}
+  '@esbuild/linux-loong64@0.21.5':
+    resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
     engines: {node: '>=12'}
     cpu: [loong64]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [loong64]
     os: [linux]
@@ -710,8 +710,8 @@ packages:
     cpu: [mips64el]
     os: [linux]
 
     cpu: [mips64el]
     os: [linux]
 
-  '@esbuild/linux-mips64el@0.21.0':
-    resolution: {integrity: sha512-lUvMkXlUMrx5vnspMWohma6vuWh+Z/mPV6DdbXW07fNgF2Tlg6SLSqqzDXv5XYV4og5awNFYcPXpgqOVsqdx7Q==}
+  '@esbuild/linux-mips64el@0.21.5':
+    resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
     engines: {node: '>=12'}
     cpu: [mips64el]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [mips64el]
     os: [linux]
@@ -722,8 +722,8 @@ packages:
     cpu: [ppc64]
     os: [linux]
 
     cpu: [ppc64]
     os: [linux]
 
-  '@esbuild/linux-ppc64@0.21.0':
-    resolution: {integrity: sha512-wLi9VRnLDRg1Gudic24gcT5aa5LZGBwLi4aYghQ9bVb8z0qYHrZnRTNxulErFvOsSgijUWS5uNLCUaLwj+tvIQ==}
+  '@esbuild/linux-ppc64@0.21.5':
+    resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [ppc64]
     os: [linux]
@@ -734,8 +734,8 @@ packages:
     cpu: [riscv64]
     os: [linux]
 
     cpu: [riscv64]
     os: [linux]
 
-  '@esbuild/linux-riscv64@0.21.0':
-    resolution: {integrity: sha512-MOjonqpNtns0Y32NwvMZiZXw94g8EqeqI+4BQtIHj07xX61vOyqlBsJH3UbjkWvaewie1VP9IoiX2Ja/P2XCJw==}
+  '@esbuild/linux-riscv64@0.21.5':
+    resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
     engines: {node: '>=12'}
     cpu: [riscv64]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [riscv64]
     os: [linux]
@@ -746,8 +746,8 @@ packages:
     cpu: [s390x]
     os: [linux]
 
     cpu: [s390x]
     os: [linux]
 
-  '@esbuild/linux-s390x@0.21.0':
-    resolution: {integrity: sha512-Gz/gafubuM3L1D29LnqaxcGg16aa2XES/uFTFdcvrwsRpMxkLiowaUvIiWJfatf/oCyyZu5CT8SrlMy37dGc7A==}
+  '@esbuild/linux-s390x@0.21.5':
+    resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
     engines: {node: '>=12'}
     cpu: [s390x]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [s390x]
     os: [linux]
@@ -758,8 +758,8 @@ packages:
     cpu: [x64]
     os: [linux]
 
     cpu: [x64]
     os: [linux]
 
-  '@esbuild/linux-x64@0.21.0':
-    resolution: {integrity: sha512-OGorpObKLm8XlhoJlxtdwECfnESXu3kd8mU1yZ5Xk0vmh0d2xoJjEXJi7y7mjFpc3+XfGQRgHq/gqyIkbufnvA==}
+  '@esbuild/linux-x64@0.21.5':
+    resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [linux]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [linux]
@@ -770,8 +770,8 @@ packages:
     cpu: [x64]
     os: [netbsd]
 
     cpu: [x64]
     os: [netbsd]
 
-  '@esbuild/netbsd-x64@0.21.0':
-    resolution: {integrity: sha512-AwkJoff9D5Px7+lHafSSgDK3JreyeyPtwTsOfxhlk5NZ+bMGlvSfHkA6DKv9vD0gmGrBPTMv/uIePkNaVsDq7w==}
+  '@esbuild/netbsd-x64@0.21.5':
+    resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [netbsd]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [netbsd]
@@ -782,8 +782,8 @@ packages:
     cpu: [x64]
     os: [openbsd]
 
     cpu: [x64]
     os: [openbsd]
 
-  '@esbuild/openbsd-x64@0.21.0':
-    resolution: {integrity: sha512-wqv7KSmRA4qf0lFZ2Abjp2boO9tDe7YwNLZ7DNUI5rsluS0/TF78CtPUUAePukgE6b2HcXYZYuL5F2yXdQIqIg==}
+  '@esbuild/openbsd-x64@0.21.5':
+    resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [openbsd]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [openbsd]
@@ -794,8 +794,8 @@ packages:
     cpu: [x64]
     os: [sunos]
 
     cpu: [x64]
     os: [sunos]
 
-  '@esbuild/sunos-x64@0.21.0':
-    resolution: {integrity: sha512-3qAZFC752nZZQOI+OG4KIawvLfdD5yMFCeIFz0OhedMpYgq9AOKygW45Ojy0E5upBqns2fUaMFk1CnNSkvJaYw==}
+  '@esbuild/sunos-x64@0.21.5':
+    resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [sunos]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [sunos]
@@ -806,8 +806,8 @@ packages:
     cpu: [arm64]
     os: [win32]
 
     cpu: [arm64]
     os: [win32]
 
-  '@esbuild/win32-arm64@0.21.0':
-    resolution: {integrity: sha512-06BY4wjQQ2bPjayuvKWXr5X3V+ZGnoTOX1+doLoQBUSyCDb9JZgX7o0N3t3rRNmEiMY/DuxXwu+EE+U32B4ErA==}
+  '@esbuild/win32-arm64@0.21.5':
+    resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [win32]
     engines: {node: '>=12'}
     cpu: [arm64]
     os: [win32]
@@ -818,8 +818,8 @@ packages:
     cpu: [ia32]
     os: [win32]
 
     cpu: [ia32]
     os: [win32]
 
-  '@esbuild/win32-ia32@0.21.0':
-    resolution: {integrity: sha512-uTLz9mPOMkl3bfuGnSQumrUN7U1aPb8MCOdjQJOWPGdXTZhkK6Z2lLHxdTjX6C51jxXWWAo64tcRwiAYOkQhJw==}
+  '@esbuild/win32-ia32@0.21.5':
+    resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [win32]
     engines: {node: '>=12'}
     cpu: [ia32]
     os: [win32]
@@ -830,8 +830,8 @@ packages:
     cpu: [x64]
     os: [win32]
 
     cpu: [x64]
     os: [win32]
 
-  '@esbuild/win32-x64@0.21.0':
-    resolution: {integrity: sha512-XT0oCVNRjmrMTz/Xd+9L2eOI83gUQZg9Viiv3cuT/8VNlXVMn6QsxyBMDNFsYX+wmQRD31VMKNtkZaXvS3/JiA==}
+  '@esbuild/win32-x64@0.21.5':
+    resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
     engines: {node: '>=12'}
     cpu: [x64]
     os: [win32]
     engines: {node: '>=12'}
     cpu: [x64]
     os: [win32]
@@ -842,8 +842,8 @@ packages:
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
 
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
 
-  '@eslint-community/regexpp@4.10.0':
-    resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==}
+  '@eslint-community/regexpp@4.10.1':
+    resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==}
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
 
   '@eslint/eslintrc@2.1.4':
     engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
 
   '@eslint/eslintrc@2.1.4':
@@ -860,6 +860,7 @@ packages:
   '@humanwhocodes/config-array@0.11.14':
     resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
     engines: {node: '>=10.10.0'}
   '@humanwhocodes/config-array@0.11.14':
     resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
     engines: {node: '>=10.10.0'}
+    deprecated: Use @eslint/config-array instead
 
   '@humanwhocodes/module-importer@1.0.1':
     resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
 
   '@humanwhocodes/module-importer@1.0.1':
     resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
@@ -867,12 +868,13 @@ packages:
 
   '@humanwhocodes/object-schema@2.0.3':
     resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
 
   '@humanwhocodes/object-schema@2.0.3':
     resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
+    deprecated: Use @eslint/object-schema instead
 
   '@iarna/toml@2.2.5':
     resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
 
 
   '@iarna/toml@2.2.5':
     resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==}
 
-  '@inquirer/figures@1.0.1':
-    resolution: {integrity: sha512-mtup3wVKia3ZwULPHcbs4Mor8Voi+iIXEWD7wCNbIO6lYR62oPCTQyrddi5OMYVXHzeCSoneZwJuS8sBvlEwDw==}
+  '@inquirer/figures@1.0.3':
+    resolution: {integrity: sha512-ErXXzENMH5pJt5/ssXV0DfWUZqly8nGzf0UcBV9xTnP+KyffE2mqyxIMBrZ8ijQck2nU0TQm40EQB53YreyWHw==}
     engines: {node: '>=18'}
 
   '@isaacs/cliui@8.0.2':
     engines: {node: '>=18'}
 
   '@isaacs/cliui@8.0.2':
@@ -927,47 +929,57 @@ packages:
     resolution: {integrity: sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==}
     engines: {node: '>= 0.4'}
 
     resolution: {integrity: sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==}
     engines: {node: '>= 0.4'}
 
-  '@microsoft/tsdoc-config@0.16.2':
-    resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==}
+  '@microsoft/tsdoc-config@0.17.0':
+    resolution: {integrity: sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg==}
 
 
-  '@microsoft/tsdoc@0.14.2':
-    resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==}
+  '@microsoft/tsdoc@0.15.0':
+    resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==}
 
 
-  '@mikro-orm/cli@6.2.5':
-    resolution: {integrity: sha512-1DKde27pB0EDvJF2srRn8JmaukKh8ea+UI1AkjHNK9+owgx5BrszrYxMl60UTqUfBpt08+Krblnis7mok/OJ6w==}
+  '@mikro-orm/cli@6.2.9':
+    resolution: {integrity: sha512-9eW9ZSzdO03KBkUn5Q0OxWBv/2RrKDwOabW2FKzuWslOY3ZBX+k+e8eP6a/+T8GeGGD/uqj8xVZSgM2DuGGqrw==}
     engines: {node: '>= 18.12.0'}
     hasBin: true
 
     engines: {node: '>= 18.12.0'}
     hasBin: true
 
-  '@mikro-orm/core@6.2.5':
-    resolution: {integrity: sha512-KZvirbAoFNjR/Sx30Jr7j6y5oEofNr13llPvCPUQlWQzHrFXedU1Td5AtVeBkOzp7f5FDBSv/a/wMRXqyqkrcA==}
+  '@mikro-orm/core@6.2.9':
+    resolution: {integrity: sha512-fzeg8qNwNr0f9embDhs0L75EBC8ivIOsK1GGPXe48Ab+P0Vmv1qCskSP7/vNDsz4s1xDu0h0l6fIsv1N7j4jKQ==}
     engines: {node: '>= 18.12.0'}
 
     engines: {node: '>= 18.12.0'}
 
-  '@mikro-orm/knex@6.2.5':
-    resolution: {integrity: sha512-PNKzclHk21Yx4dlfoTttUCOSAqj32WSSdY4G+mxpukTtIgSc/iFd8OpkJ+x/c9tfs27o3ZyBRQRxDoC6fMA4hQ==}
+  '@mikro-orm/knex@6.2.9':
+    resolution: {integrity: sha512-eSHPiS5em+RGv/jx5lP7a1xDVVlnrG+l90/7N7WAgTGcPOzyILVw9EJOZl2KR8dh8EfPI6Wm35Lo4qkO2LoDUg==}
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
+      better-sqlite3: '*'
+      libsql: '*'
+      mariadb: '*'
+    peerDependenciesMeta:
+      better-sqlite3:
+        optional: true
+      libsql:
+        optional: true
+      mariadb:
+        optional: true
 
 
-  '@mikro-orm/mariadb@6.2.5':
-    resolution: {integrity: sha512-Bv7BOp3OsXPFOU/7qDodBOREe6//SQ7EeG8p1KhTINasUR2pQML0TOzfl7C9PgHrldIElYi9k2hIKyvNWRQsHg==}
+  '@mikro-orm/mariadb@6.2.9':
+    resolution: {integrity: sha512-V+wJ0bjX8clO64j0gRcvAZdl5FV2EJElHpn/x779/T5CuAratF68elEkKJNfqCPB6bbAPb6qrzvcI+szgjB23A==}
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
 
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
 
-  '@mikro-orm/reflection@6.2.5':
-    resolution: {integrity: sha512-PHRz0BRX3OGjVxe6YzWGEG3xFF6mkaLrmaV40pfyxy2vNh0P8LQkNIFfRqk4PWbpI8yNbANEeQ9TtrtYAsmQ1g==}
+  '@mikro-orm/reflection@6.2.9':
+    resolution: {integrity: sha512-JkdQnEohwngC1LiNNB+tt0ReDiCMlTAJA4/n5N4+tdSv8aspgrIX8ARgB2a6IjgWwes7xIkJJ1nb5tWdFwPSmA==}
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
 
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
 
-  '@mikro-orm/sqlite@6.2.5':
-    resolution: {integrity: sha512-dZVYm1gBO2Ja77SDk1bLLQRfy96QSvz4GdjN7Ap5bcuM5HcGHneM7adn5Tzq1oW0ihbfSpqXzyoynPaWgmC89A==}
+  '@mikro-orm/sqlite@6.2.9':
+    resolution: {integrity: sha512-+ZdlKEtE8HmqbZWSm44MaZwfeS1AlrhMJrZfRr5tQfvdKi5VuRQ+I87Uxo03Ni5r0JXV1wEfFyWovK5c6h1iCQ==}
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
 
     engines: {node: '>= 18.12.0'}
     peerDependencies:
       '@mikro-orm/core': ^6.0.0
 
-  '@mongodb-js/saslprep@1.1.6':
-    resolution: {integrity: sha512-jqTTXQ46H8cAxmXBu8wm1HTSIMBMrIcoVrsjdQkKdMBj3il/fSCgWyya4P2I1xjPBl69mw+nRphrPlcIqBd20Q==}
+  '@mongodb-js/saslprep@1.1.7':
+    resolution: {integrity: sha512-dCHW/oEX0KJ4NjDULBo3JiOaK5+6axtpBbS+ao2ZInoAL9/YRQLhXzSNAFz7hP4nzLkIqsfYAK/PDE3+XHny0Q==}
 
   '@nearform/heap-profiler@2.0.0':
     resolution: {integrity: sha512-846CWyq3Ky5rzcl8Z3S+VT3z6GQSlYD1G/dqbtANu29NUHoCO+W7tOZRK6eA6FjLHnNX0DvP1Mrt2oFBPnkxLw==}
 
   '@nearform/heap-profiler@2.0.0':
     resolution: {integrity: sha512-846CWyq3Ky5rzcl8Z3S+VT3z6GQSlYD1G/dqbtANu29NUHoCO+W7tOZRK6eA6FjLHnNX0DvP1Mrt2oFBPnkxLw==}
@@ -1009,14 +1021,11 @@ packages:
     resolution: {integrity: sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==}
     engines: {node: '>= 18'}
 
     resolution: {integrity: sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==}
     engines: {node: '>= 18'}
 
-  '@octokit/openapi-types@20.0.0':
-    resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==}
-
   '@octokit/openapi-types@22.2.0':
     resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==}
 
   '@octokit/openapi-types@22.2.0':
     resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==}
 
-  '@octokit/plugin-paginate-rest@9.2.1':
-    resolution: {integrity: sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==}
+  '@octokit/plugin-paginate-rest@11.3.1':
+    resolution: {integrity: sha512-ryqobs26cLtM1kQxqeZui4v8FeznirUsksiA+RYemMPJ7Micju0WSkv50dBksTuZks9O5cg4wp+t8fZ/cLY56g==}
     engines: {node: '>= 18'}
     peerDependencies:
       '@octokit/core': '5'
     engines: {node: '>= 18'}
     peerDependencies:
       '@octokit/core': '5'
@@ -1027,11 +1036,11 @@ packages:
     peerDependencies:
       '@octokit/core': '5'
 
     peerDependencies:
       '@octokit/core': '5'
 
-  '@octokit/plugin-rest-endpoint-methods@10.4.1':
-    resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==}
+  '@octokit/plugin-rest-endpoint-methods@13.2.2':
+    resolution: {integrity: sha512-EI7kXWidkt3Xlok5uN43suK99VWqc8OaIMktY9d9+RNKl69juoTyxmLoWPIZgJYzi41qj/9zU7G/ljnNOJ5AFA==}
     engines: {node: '>= 18'}
     peerDependencies:
     engines: {node: '>= 18'}
     peerDependencies:
-      '@octokit/core': '5'
+      '@octokit/core': ^5
 
   '@octokit/request-error@5.1.0':
     resolution: {integrity: sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==}
 
   '@octokit/request-error@5.1.0':
     resolution: {integrity: sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==}
@@ -1041,13 +1050,10 @@ packages:
     resolution: {integrity: sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==}
     engines: {node: '>= 18'}
 
     resolution: {integrity: sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==}
     engines: {node: '>= 18'}
 
-  '@octokit/rest@20.1.0':
-    resolution: {integrity: sha512-STVO3itHQLrp80lvcYB2UIKoeil5Ctsgd2s1AM+du3HqZIR35ZH7WE9HLwUOLXH0myA0y3AGNPo8gZtcgIbw0g==}
+  '@octokit/rest@20.1.1':
+    resolution: {integrity: sha512-MB4AYDsM5jhIHro/dq4ix1iWTLGToIGk6cWF5L6vanFaMble5jTX/UBQyiv05HsWnwUtY8JrfHy2LWfKwihqMw==}
     engines: {node: '>= 18'}
 
     engines: {node: '>= 18'}
 
-  '@octokit/types@12.6.0':
-    resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==}
-
   '@octokit/types@13.5.0':
     resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==}
 
   '@octokit/types@13.5.0':
     resolution: {integrity: sha512-HdqWTf5Z3qwDVlzCrP8UJquMwunpDiMPt5er+QjGzL4hqr/vBVY/MauQgS1xWxCDT1oMx1EULyqxncdCY/NVSQ==}
 
@@ -1080,88 +1086,88 @@ packages:
     peerDependencies:
       release-it: ^17.0.0
 
     peerDependencies:
       release-it: ^17.0.0
 
-  '@rollup/rollup-android-arm-eabi@4.17.2':
-    resolution: {integrity: sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==}
+  '@rollup/rollup-android-arm-eabi@4.18.0':
+    resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==}
     cpu: [arm]
     os: [android]
 
     cpu: [arm]
     os: [android]
 
-  '@rollup/rollup-android-arm64@4.17.2':
-    resolution: {integrity: sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==}
+  '@rollup/rollup-android-arm64@4.18.0':
+    resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==}
     cpu: [arm64]
     os: [android]
 
     cpu: [arm64]
     os: [android]
 
-  '@rollup/rollup-darwin-arm64@4.17.2':
-    resolution: {integrity: sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==}
+  '@rollup/rollup-darwin-arm64@4.18.0':
+    resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==}
     cpu: [arm64]
     os: [darwin]
 
     cpu: [arm64]
     os: [darwin]
 
-  '@rollup/rollup-darwin-x64@4.17.2':
-    resolution: {integrity: sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==}
+  '@rollup/rollup-darwin-x64@4.18.0':
+    resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==}
     cpu: [x64]
     os: [darwin]
 
     cpu: [x64]
     os: [darwin]
 
-  '@rollup/rollup-linux-arm-gnueabihf@4.17.2':
-    resolution: {integrity: sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==}
+  '@rollup/rollup-linux-arm-gnueabihf@4.18.0':
+    resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==}
     cpu: [arm]
     os: [linux]
 
     cpu: [arm]
     os: [linux]
 
-  '@rollup/rollup-linux-arm-musleabihf@4.17.2':
-    resolution: {integrity: sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==}
+  '@rollup/rollup-linux-arm-musleabihf@4.18.0':
+    resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==}
     cpu: [arm]
     os: [linux]
 
     cpu: [arm]
     os: [linux]
 
-  '@rollup/rollup-linux-arm64-gnu@4.17.2':
-    resolution: {integrity: sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==}
+  '@rollup/rollup-linux-arm64-gnu@4.18.0':
+    resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==}
     cpu: [arm64]
     os: [linux]
 
     cpu: [arm64]
     os: [linux]
 
-  '@rollup/rollup-linux-arm64-musl@4.17.2':
-    resolution: {integrity: sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==}
+  '@rollup/rollup-linux-arm64-musl@4.18.0':
+    resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==}
     cpu: [arm64]
     os: [linux]
 
     cpu: [arm64]
     os: [linux]
 
-  '@rollup/rollup-linux-powerpc64le-gnu@4.17.2':
-    resolution: {integrity: sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==}
+  '@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
+    resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==}
     cpu: [ppc64]
     os: [linux]
 
     cpu: [ppc64]
     os: [linux]
 
-  '@rollup/rollup-linux-riscv64-gnu@4.17.2':
-    resolution: {integrity: sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==}
+  '@rollup/rollup-linux-riscv64-gnu@4.18.0':
+    resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==}
     cpu: [riscv64]
     os: [linux]
 
     cpu: [riscv64]
     os: [linux]
 
-  '@rollup/rollup-linux-s390x-gnu@4.17.2':
-    resolution: {integrity: sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==}
+  '@rollup/rollup-linux-s390x-gnu@4.18.0':
+    resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==}
     cpu: [s390x]
     os: [linux]
 
     cpu: [s390x]
     os: [linux]
 
-  '@rollup/rollup-linux-x64-gnu@4.17.2':
-    resolution: {integrity: sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==}
+  '@rollup/rollup-linux-x64-gnu@4.18.0':
+    resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==}
     cpu: [x64]
     os: [linux]
 
     cpu: [x64]
     os: [linux]
 
-  '@rollup/rollup-linux-x64-musl@4.17.2':
-    resolution: {integrity: sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==}
+  '@rollup/rollup-linux-x64-musl@4.18.0':
+    resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==}
     cpu: [x64]
     os: [linux]
 
     cpu: [x64]
     os: [linux]
 
-  '@rollup/rollup-win32-arm64-msvc@4.17.2':
-    resolution: {integrity: sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==}
+  '@rollup/rollup-win32-arm64-msvc@4.18.0':
+    resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==}
     cpu: [arm64]
     os: [win32]
 
     cpu: [arm64]
     os: [win32]
 
-  '@rollup/rollup-win32-ia32-msvc@4.17.2':
-    resolution: {integrity: sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==}
+  '@rollup/rollup-win32-ia32-msvc@4.18.0':
+    resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==}
     cpu: [ia32]
     os: [win32]
 
     cpu: [ia32]
     os: [win32]
 
-  '@rollup/rollup-win32-x64-msvc@4.17.2':
-    resolution: {integrity: sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==}
+  '@rollup/rollup-win32-x64-msvc@4.18.0':
+    resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==}
     cpu: [x64]
     os: [win32]
 
     cpu: [x64]
     os: [win32]
 
-  '@rushstack/eslint-patch@1.10.2':
-    resolution: {integrity: sha512-hw437iINopmQuxWPSUEvqE56NCPsiU8N4AYtfHmJFckclktzK9YQJieD3XkDCDH4OjL+C7zgPUh73R/nrcHrqw==}
+  '@rushstack/eslint-patch@1.10.3':
+    resolution: {integrity: sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==}
 
   '@sinclair/typebox@0.27.8':
     resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
 
   '@sinclair/typebox@0.27.8':
     resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
@@ -1216,6 +1222,9 @@ packages:
   '@types/conventional-commits-parser@5.0.0':
     resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==}
 
   '@types/conventional-commits-parser@5.0.0':
     resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==}
 
+  '@types/eslint@8.56.10':
+    resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==}
+
   '@types/estree@1.0.5':
     resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
 
   '@types/estree@1.0.5':
     resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
 
@@ -1234,8 +1243,8 @@ packages:
   '@types/istanbul-reports@3.0.4':
     resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
 
   '@types/istanbul-reports@3.0.4':
     resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
 
-  '@types/jsdom@21.1.6':
-    resolution: {integrity: sha512-/7kkMsC+/kMs7gAYmmBR9P0vGTnOoLhQhyhQJSlXGI5bzTHp6xdo0TtKWQAsz6pmSAeVqKSbqeyP6hytqr9FDw==}
+  '@types/jsdom@21.1.7':
+    resolution: {integrity: sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==}
 
   '@types/json-schema@7.0.15':
     resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
 
   '@types/json-schema@7.0.15':
     resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
@@ -1246,8 +1255,8 @@ packages:
   '@types/long@4.0.2':
     resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==}
 
   '@types/long@4.0.2':
     resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==}
 
-  '@types/node@20.12.10':
-    resolution: {integrity: sha512-Eem5pH9pmWBHoGAT8Dr5fdc5rYA+4NAovdM4EktRPVAAiJhmWWfQrA0cFhAbOsQdSfIHjAud6YdkbL69+zSKjw==}
+  '@types/node@20.14.2':
+    resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==}
 
   '@types/offscreencanvas@2019.3.0':
     resolution: {integrity: sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==}
 
   '@types/offscreencanvas@2019.3.0':
     resolution: {integrity: sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q==}
@@ -1273,8 +1282,8 @@ packages:
   '@types/webidl-conversions@7.0.3':
     resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==}
 
   '@types/webidl-conversions@7.0.3':
     resolution: {integrity: sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA==}
 
-  '@types/whatwg-url@11.0.4':
-    resolution: {integrity: sha512-lXCmTWSHJvf0TRSO58nm978b8HJ/EdsSsEKLd3ODHFjo+3VGAyyTp4v50nWvwtzBxSMQrVOK7tcuN0zGPLICMw==}
+  '@types/whatwg-url@11.0.5':
+    resolution: {integrity: sha512-coYR071JRaHa+xoEvvYqvnIHaVqaYrLPbsufM9BF63HkwI5Lgmy2QR8Q5K/lYDYo5AK82wOvSOS0UsLTpTG7uQ==}
 
   '@types/ws@8.5.10':
     resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
 
   '@types/ws@8.5.10':
     resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==}
@@ -1285,8 +1294,8 @@ packages:
   '@types/yargs@17.0.32':
     resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==}
 
   '@types/yargs@17.0.32':
     resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==}
 
-  '@typescript-eslint/eslint-plugin@7.8.0':
-    resolution: {integrity: sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==}
+  '@typescript-eslint/eslint-plugin@7.12.0':
+    resolution: {integrity: sha512-7F91fcbuDf/d3S8o21+r3ZncGIke/+eWk0EpO21LXhDfLahriZF9CGj4fbAetEjlaBdjdSm9a6VeXbpbT6Z40Q==}
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       '@typescript-eslint/parser': ^7.0.0
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       '@typescript-eslint/parser': ^7.0.0
@@ -1296,8 +1305,8 @@ packages:
       typescript:
         optional: true
 
       typescript:
         optional: true
 
-  '@typescript-eslint/parser@7.8.0':
-    resolution: {integrity: sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==}
+  '@typescript-eslint/parser@7.12.0':
+    resolution: {integrity: sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ==}
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
@@ -1306,12 +1315,12 @@ packages:
       typescript:
         optional: true
 
       typescript:
         optional: true
 
-  '@typescript-eslint/scope-manager@7.8.0':
-    resolution: {integrity: sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==}
+  '@typescript-eslint/scope-manager@7.12.0':
+    resolution: {integrity: sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg==}
     engines: {node: ^18.18.0 || >=20.0.0}
 
     engines: {node: ^18.18.0 || >=20.0.0}
 
-  '@typescript-eslint/type-utils@7.8.0':
-    resolution: {integrity: sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==}
+  '@typescript-eslint/type-utils@7.12.0':
+    resolution: {integrity: sha512-lib96tyRtMhLxwauDWUp/uW3FMhLA6D0rJ8T7HmH7x23Gk1Gwwu8UZ94NMXBvOELn6flSPiBrCKlehkiXyaqwA==}
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
@@ -1320,12 +1329,12 @@ packages:
       typescript:
         optional: true
 
       typescript:
         optional: true
 
-  '@typescript-eslint/types@7.8.0':
-    resolution: {integrity: sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==}
+  '@typescript-eslint/types@7.12.0':
+    resolution: {integrity: sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==}
     engines: {node: ^18.18.0 || >=20.0.0}
 
     engines: {node: ^18.18.0 || >=20.0.0}
 
-  '@typescript-eslint/typescript-estree@7.8.0':
-    resolution: {integrity: sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==}
+  '@typescript-eslint/typescript-estree@7.12.0':
+    resolution: {integrity: sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==}
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       typescript: '*'
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       typescript: '*'
@@ -1333,28 +1342,28 @@ packages:
       typescript:
         optional: true
 
       typescript:
         optional: true
 
-  '@typescript-eslint/utils@7.8.0':
-    resolution: {integrity: sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==}
+  '@typescript-eslint/utils@7.12.0':
+    resolution: {integrity: sha512-Y6hhwxwDx41HNpjuYswYp6gDbkiZ8Hin9Bf5aJQn1bpTs3afYY4GX+MPYxma8jtoIV2GRwTM/UJm/2uGCVv+DQ==}
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
 
     engines: {node: ^18.18.0 || >=20.0.0}
     peerDependencies:
       eslint: ^8.56.0
 
-  '@typescript-eslint/visitor-keys@7.8.0':
-    resolution: {integrity: sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==}
+  '@typescript-eslint/visitor-keys@7.12.0':
+    resolution: {integrity: sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==}
     engines: {node: ^18.18.0 || >=20.0.0}
 
   '@ungap/structured-clone@1.2.0':
     resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
 
     engines: {node: ^18.18.0 || >=20.0.0}
 
   '@ungap/structured-clone@1.2.0':
     resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
 
-  '@vitejs/plugin-vue-jsx@3.1.0':
-    resolution: {integrity: sha512-w9M6F3LSEU5kszVb9An2/MmXNxocAnUb3WhRr8bHlimhDrXNt6n6D2nJQR3UXpGlZHh/EsgouOHCsM8V3Ln+WA==}
-    engines: {node: ^14.18.0 || >=16.0.0}
+  '@vitejs/plugin-vue-jsx@4.0.0':
+    resolution: {integrity: sha512-A+6wL2AdQhDsLsDnY+2v4rRDI1HLJGIMc97a8FURO9tqKsH5QvjWrzsa5DH3NlZsM742W2wODl2fF+bfcTWtXw==}
+    engines: {node: ^18.0.0 || >=20.0.0}
     peerDependencies:
     peerDependencies:
-      vite: ^4.0.0 || ^5.0.0
+      vite: ^5.0.0
       vue: ^3.0.0
 
       vue: ^3.0.0
 
-  '@vitejs/plugin-vue@5.0.4':
-    resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==}
+  '@vitejs/plugin-vue@5.0.5':
+    resolution: {integrity: sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==}
     engines: {node: ^18.0.0 || >=20.0.0}
     peerDependencies:
       vite: ^5.0.0
     engines: {node: ^18.0.0 || >=20.0.0}
     peerDependencies:
       vite: ^5.0.0
@@ -1408,8 +1417,8 @@ packages:
   '@vue/compiler-ssr@3.4.27':
     resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==}
 
   '@vue/compiler-ssr@3.4.27':
     resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==}
 
-  '@vue/devtools-api@6.6.1':
-    resolution: {integrity: sha512-LgPscpE3Vs0x96PzSSB4IGVSZXZBZHpfxs+ZA1d+VEPwHdOXowy/Y2CsvCAIFrf+ssVU1pD1jidj505EpUnfbA==}
+  '@vue/devtools-api@6.6.3':
+    resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==}
 
   '@vue/eslint-config-prettier@9.0.0':
     resolution: {integrity: sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==}
 
   '@vue/eslint-config-prettier@9.0.0':
     resolution: {integrity: sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==}
@@ -1530,8 +1539,11 @@ packages:
   ajv@6.12.6:
     resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
 
   ajv@6.12.6:
     resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
 
-  ajv@8.13.0:
-    resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==}
+  ajv@8.12.0:
+    resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==}
+
+  ajv@8.16.0:
+    resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==}
 
   ansi-align@3.0.1:
     resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
 
   ansi-align@3.0.1:
     resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
@@ -1605,6 +1617,7 @@ packages:
   are-we-there-yet@3.0.1:
     resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==}
     engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
   are-we-there-yet@3.0.1:
     resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==}
     engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+    deprecated: This package is no longer supported.
 
   arg@4.1.3:
     resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
 
   arg@4.1.3:
     resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -1709,8 +1722,8 @@ packages:
   aws-sign2@0.7.0:
     resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
 
   aws-sign2@0.7.0:
     resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
 
-  aws4@1.12.0:
-    resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==}
+  aws4@1.13.0:
+    resolution: {integrity: sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==}
 
   b4a@1.6.6:
     resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==}
 
   b4a@1.6.6:
     resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==}
@@ -1767,8 +1780,8 @@ packages:
   brace-expansion@2.0.1:
     resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
 
   brace-expansion@2.0.1:
     resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
 
-  braces@3.0.2:
-    resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
+  braces@3.0.3:
+    resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
     engines: {node: '>=8'}
 
   brfs@2.0.2:
     engines: {node: '>=8'}
 
   brfs@2.0.2:
@@ -1812,8 +1825,8 @@ packages:
     engines: {node: '>= 0.8'}
     hasBin: true
 
     engines: {node: '>= 0.8'}
     hasBin: true
 
-  browserslist@4.23.0:
-    resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==}
+  browserslist@4.23.1:
+    resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==}
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
 
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
 
@@ -1841,10 +1854,6 @@ packages:
     resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==}
     engines: {node: '>=6.14.2'}
 
     resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==}
     engines: {node: '>=6.14.2'}
 
-  builtin-modules@3.3.0:
-    resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
-    engines: {node: '>=6'}
-
   builtin-status-codes@3.0.0:
     resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==}
 
   builtin-status-codes@3.0.0:
     resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==}
 
@@ -1852,9 +1861,9 @@ packages:
     resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
     engines: {node: '>=18'}
 
     resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
     engines: {node: '>=18'}
 
-  c8@9.1.0:
-    resolution: {integrity: sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==}
-    engines: {node: '>=14.14.0'}
+  c8@10.0.0:
+    resolution: {integrity: sha512-rdQecjxw16P8kwgMBjruaQyfF+R2o/mucCCK4VPktwq2HFMWLOHGyUasb46+WlUOVJX94d6dZolcJxzjCzWmXg==}
+    engines: {node: '>=18'}
     hasBin: true
 
   cac@6.7.14:
     hasBin: true
 
   cac@6.7.14:
@@ -1899,8 +1908,8 @@ packages:
     resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
     engines: {node: '>=14.16'}
 
     resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
     engines: {node: '>=14.16'}
 
-  caniuse-lite@1.0.30001616:
-    resolution: {integrity: sha512-RHVYKov7IcdNjVHJFNY/78RdG4oGVjbayxv8u5IO74Wv7Hlq4PnJE6mo/OjFijjVFNy5ijnCt6H3IIo4t+wfEw==}
+  caniuse-lite@1.0.30001632:
+    resolution: {integrity: sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==}
 
   caseless@0.12.0:
     resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
 
   caseless@0.12.0:
     resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
@@ -1990,8 +1999,8 @@ packages:
     resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
     engines: {node: '>=6'}
 
     resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
     engines: {node: '>=6'}
 
-  cli-table3@0.6.4:
-    resolution: {integrity: sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==}
+  cli-table3@0.6.5:
+    resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==}
     engines: {node: 10.* || >= 12.*}
 
   cli-truncate@4.0.0:
     engines: {node: 10.* || >= 12.*}
 
   cli-truncate@4.0.0:
@@ -2073,9 +2082,9 @@ packages:
     resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
     engines: {node: '>=14'}
 
     resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==}
     engines: {node: '>=14'}
 
-  commander@11.1.0:
-    resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==}
-    engines: {node: '>=16'}
+  commander@12.1.0:
+    resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
+    engines: {node: '>=18'}
 
   commander@2.20.3:
     resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
 
   commander@2.20.3:
     resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
@@ -2378,6 +2387,15 @@ packages:
       supports-color:
         optional: true
 
       supports-color:
         optional: true
 
+  debug@4.3.5:
+    resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==}
+    engines: {node: '>=6.0'}
+    peerDependencies:
+      supports-color: '*'
+    peerDependenciesMeta:
+      supports-color:
+        optional: true
+
   decamelize@1.2.0:
     resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
     engines: {node: '>=0.10.0'}
   decamelize@1.2.0:
     resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
     engines: {node: '>=0.10.0'}
@@ -2389,8 +2407,8 @@ packages:
     resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
     engines: {node: '>=10'}
 
     resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
     engines: {node: '>=10'}
 
-  deep-eql@4.1.3:
-    resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==}
+  deep-eql@4.1.4:
+    resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==}
     engines: {node: '>=6'}
 
   deep-extend@0.6.0:
     engines: {node: '>=6'}
 
   deep-extend@0.6.0:
@@ -2545,8 +2563,8 @@ packages:
   ee-first@1.1.1:
     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
 
   ee-first@1.1.1:
     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
 
-  electron-to-chromium@1.4.757:
-    resolution: {integrity: sha512-jftDaCknYSSt/+KKeXzH3LX5E2CvRLm75P3Hj+J/dv3CL0qUYcOt13d5FN1NiL5IJbbhzHrb3BomeG2tkSlZmw==}
+  electron-to-chromium@1.4.796:
+    resolution: {integrity: sha512-NglN/xprcM+SHD2XCli4oC6bWe6kHoytcyLKCWXmRL854F0qhPhaYgUswUsglnPxYaNQIg2uMY4BvaomIf3kLA==}
 
   elliptic@6.5.5:
     resolution: {integrity: sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==}
 
   elliptic@6.5.5:
     resolution: {integrity: sha512-7EjbcmUm17NQFu4Pmgmq2olYMj8nwMnpcddByChSUjArp8F5DQWcIcpriwO4ZToLNAJig0yiyjswfyGNje/ixw==}
@@ -2579,8 +2597,8 @@ packages:
   endpoint@0.4.5:
     resolution: {integrity: sha512-oA2ALUF+d4Y0I8/WMV/0BuAZGHxfIdAygr9ZXP4rfzmp5zpYZmYKHKAbqRQnrE1YGdPhVg4D24CQkyx2qYEoHg==}
 
   endpoint@0.4.5:
     resolution: {integrity: sha512-oA2ALUF+d4Y0I8/WMV/0BuAZGHxfIdAygr9ZXP4rfzmp5zpYZmYKHKAbqRQnrE1YGdPhVg4D24CQkyx2qYEoHg==}
 
-  enhanced-resolve@5.16.0:
-    resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==}
+  enhanced-resolve@5.17.0:
+    resolution: {integrity: sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==}
     engines: {node: '>=10.13.0'}
 
   entities@4.5.0:
     engines: {node: '>=10.13.0'}
 
   entities@4.5.0:
@@ -2666,8 +2684,8 @@ packages:
     engines: {node: '>=12'}
     hasBin: true
 
     engines: {node: '>=12'}
     hasBin: true
 
-  esbuild@0.21.0:
-    resolution: {integrity: sha512-eyK64lASNug3Wo2+bQEBnYngjh9rkXUfOus403+OeVZteMon6moIhcEYbrSvcgBN6RsrRWCMoWcKDDK6UEsTOQ==}
+  esbuild@0.21.5:
+    resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
     engines: {node: '>=12'}
     hasBin: true
 
     engines: {node: '>=12'}
     hasBin: true
 
@@ -2708,8 +2726,8 @@ packages:
     engines: {node: '>=6.0'}
     hasBin: true
 
     engines: {node: '>=6.0'}
     hasBin: true
 
-  eslint-compat-utils@0.5.0:
-    resolution: {integrity: sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==}
+  eslint-compat-utils@0.5.1:
+    resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==}
     engines: {node: '>=12'}
     peerDependencies:
       eslint: '>=6.0.0'
     engines: {node: '>=12'}
     peerDependencies:
       eslint: '>=6.0.0'
@@ -2774,8 +2792,8 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
 
       eslint-import-resolver-webpack:
         optional: true
 
-  eslint-plugin-es-x@7.6.0:
-    resolution: {integrity: sha512-I0AmeNgevgaTR7y2lrVCJmGYF0rjoznpDvqV/kIkZSZbZ8Rw3eu4cGlvBBULScfkSOCzqKbff5LR4CNrV7mZHA==}
+  eslint-plugin-es-x@7.7.0:
+    resolution: {integrity: sha512-aP3qj8BwiEDPttxQkZdI221DLKq9sI/qHolE2YSQL1/9+xk7dTV+tB1Fz8/IaCA+lnLA1bDEnvaS2LKs0k2Uig==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=8'
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=8'
@@ -2790,14 +2808,14 @@ packages:
       '@typescript-eslint/parser':
         optional: true
 
       '@typescript-eslint/parser':
         optional: true
 
-  eslint-plugin-jsdoc@48.2.3:
-    resolution: {integrity: sha512-r9DMAmFs66VNvNqRLLjHejdnJtILrt3xGi+Qx0op0oRfFGVpOR1Hb3BC++MacseHx93d8SKYPhyrC9BS7Os2QA==}
+  eslint-plugin-jsdoc@48.2.9:
+    resolution: {integrity: sha512-ErpKyr2mEUEkcdZ4nwW/cvDjClvAcvJMEXkGGll0wf8sro8h6qeQ3qlZyp1vM1dRk8Ap6rMdke8FnP94QBIaVQ==}
     engines: {node: '>=18'}
     peerDependencies:
       eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
 
     engines: {node: '>=18'}
     peerDependencies:
       eslint: ^7.0.0 || ^8.0.0 || ^9.0.0
 
-  eslint-plugin-n@17.5.0:
-    resolution: {integrity: sha512-r7i+NY+RVXQi4Q7sKCG5H4464saJWddDk7QFQjtj+wU//sf15QCq3M8LwZU2yiE45yhVUT9DXW+8AbXRQKJLPQ==}
+  eslint-plugin-n@17.8.1:
+    resolution: {integrity: sha512-KdG0h0voZms8UhndNu8DeWx1eM4sY+A4iXtsNo6kOfJLYHNeTGPacGalJ9GcvrbmOL3r/7QOMwVZDSw+1SqsrA==}
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       eslint: '>=8.23.0'
     engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
     peerDependencies:
       eslint: '>=8.23.0'
@@ -2827,11 +2845,11 @@ packages:
     peerDependencies:
       eslint: '>=5.0.0'
 
     peerDependencies:
       eslint: '>=5.0.0'
 
-  eslint-plugin-tsdoc@0.2.17:
-    resolution: {integrity: sha512-xRmVi7Zx44lOBuYqG8vzTXuL6IdGOeF9nHX17bjJ8+VE6fsxpdGem0/SBTmAwgYMKYB1WBkqRJVQ+n8GK041pA==}
+  eslint-plugin-tsdoc@0.3.0:
+    resolution: {integrity: sha512-0MuFdBrrJVBjT/gyhkP2BqpD0np1NxNLfQ38xXDlSs/KVVpKI2A6vN7jx2Rve/CyUsvOsMGwp9KKrinv7q9g3A==}
 
 
-  eslint-plugin-vue@9.25.0:
-    resolution: {integrity: sha512-tDWlx14bVe6Bs+Nnh3IGrD+hb11kf2nukfm6jLsmJIhmiRQ1SUaksvwY9U5MvPB0pcrg0QK0xapQkfITs3RKOA==}
+  eslint-plugin-vue@9.26.0:
+    resolution: {integrity: sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
@@ -3004,8 +3022,8 @@ packages:
   file-uri-to-path@1.0.0:
     resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
 
   file-uri-to-path@1.0.0:
     resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
 
-  fill-range@7.0.1:
-    resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
+  fill-range@7.1.1:
+    resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
     engines: {node: '>=8'}
 
   finalhandler@1.2.0:
     engines: {node: '>=8'}
 
   finalhandler@1.2.0:
@@ -3112,6 +3130,7 @@ packages:
   gauge@4.0.4:
     resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
     engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
   gauge@4.0.4:
     resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
     engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+    deprecated: This package is no longer supported.
 
   generate-function@2.3.1:
     resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
 
   generate-function@2.3.1:
     resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
@@ -3161,8 +3180,8 @@ packages:
     resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
     engines: {node: '>= 0.4'}
 
     resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
     engines: {node: '>= 0.4'}
 
-  get-tsconfig@4.7.4:
-    resolution: {integrity: sha512-ofbkKj+0pjXjhejr007J/fLf+sW+8H7K5GCm+msC8q3IpvgjobpyPqSRFemNyIMxklC0zeJpi7VDFna19FacvQ==}
+  get-tsconfig@4.7.5:
+    resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==}
 
   get-uri@6.0.3:
     resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==}
 
   get-uri@6.0.3:
     resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==}
@@ -3196,13 +3215,14 @@ packages:
     resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
     engines: {node: '>=10.13.0'}
 
     resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
     engines: {node: '>=10.13.0'}
 
-  glob@10.3.12:
-    resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==}
-    engines: {node: '>=16 || 14 >=14.17'}
+  glob@10.4.1:
+    resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==}
+    engines: {node: '>=16 || 14 >=14.18'}
     hasBin: true
 
   glob@7.2.3:
     resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
     hasBin: true
 
   glob@7.2.3:
     resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
+    deprecated: Glob versions prior to v9 are no longer supported
 
   global-directory@4.0.1:
     resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==}
 
   global-directory@4.0.1:
     resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==}
@@ -3220,8 +3240,8 @@ packages:
     resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
     engines: {node: '>=8'}
 
     resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==}
     engines: {node: '>=8'}
 
-  globals@15.1.0:
-    resolution: {integrity: sha512-926gJqg+4mkxwYKiFvoomM4J0kWESfk3qfTvRL2/oc/tK/eTDBbrfcKnSa2KtfdxB5onoL7D3A3qIHQFpd4+UA==}
+  globals@15.4.0:
+    resolution: {integrity: sha512-unnwvMZpv0eDUyjNyh9DH/yxUaRYrEjW/qK4QcdrHg3oO11igUQrCSgODHEqxlKg8v2CD2Sd7UkqqEBoz5U7TQ==}
     engines: {node: '>=18'}
 
   globalthis@1.0.4:
     engines: {node: '>=18'}
 
   globalthis@1.0.4:
@@ -3470,6 +3490,7 @@ packages:
 
   inflight@1.0.6:
     resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
 
   inflight@1.0.6:
     resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+    deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
 
   inherits@2.0.3:
     resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==}
 
   inherits@2.0.3:
     resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==}
@@ -3488,8 +3509,8 @@ packages:
     resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
     resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==}
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
-  ini@4.1.2:
-    resolution: {integrity: sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw==}
+  ini@4.1.3:
+    resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==}
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
   inline-source-map@0.6.3:
     engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
 
   inline-source-map@0.6.3:
@@ -3499,8 +3520,8 @@ packages:
     resolution: {integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==}
     engines: {node: '>=6.0.0'}
 
     resolution: {integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==}
     engines: {node: '>=6.0.0'}
 
-  inquirer@9.2.19:
-    resolution: {integrity: sha512-WpxOT71HGsFya6/mj5PUue0sWwbpbiPfAR+332zLj/siB0QA1PZM8v3GepegFV1Op189UxHUCF6y8AySdtOMVA==}
+  inquirer@9.2.22:
+    resolution: {integrity: sha512-SqLLa/Oe5rZUagTR9z+Zd6izyatHglbmbvVofo1KzuVB54YHleWzeHNLoR7FOICGOeQSqeLh1cordb3MzhGcEw==}
     engines: {node: '>=18'}
 
   insert-module-globals@7.2.1:
     engines: {node: '>=18'}
 
   insert-module-globals@7.2.1:
@@ -3571,10 +3592,6 @@ packages:
     resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
     engines: {node: '>=4'}
 
     resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==}
     engines: {node: '>=4'}
 
-  is-builtin-module@3.2.1:
-    resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==}
-    engines: {node: '>=6'}
-
   is-callable@1.2.7:
     resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
     engines: {node: '>= 0.4'}
   is-callable@1.2.7:
     resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
     engines: {node: '>= 0.4'}
@@ -3817,8 +3834,8 @@ packages:
   iterate-value@1.0.2:
     resolution: {integrity: sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==}
 
   iterate-value@1.0.2:
     resolution: {integrity: sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==}
 
-  jackspeak@2.3.6:
-    resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
+  jackspeak@3.4.0:
+    resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==}
     engines: {node: '>=14'}
 
   jest-diff@29.7.0:
     engines: {node: '>=14'}
 
   jest-diff@29.7.0:
@@ -3841,8 +3858,8 @@ packages:
     resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
 
     resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
 
-  jiti@1.21.0:
-    resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==}
+  jiti@1.21.6:
+    resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
     hasBin: true
 
   jju@1.4.0:
     hasBin: true
 
   jju@1.4.0:
@@ -3877,8 +3894,8 @@ packages:
     resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==}
     engines: {node: '>=12.0.0'}
 
     resolution: {integrity: sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==}
     engines: {node: '>=12.0.0'}
 
-  jsdom@24.0.0:
-    resolution: {integrity: sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==}
+  jsdom@24.1.0:
+    resolution: {integrity: sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==}
     engines: {node: '>=18'}
     peerDependencies:
       canvas: ^2.11.2
     engines: {node: '>=18'}
     peerDependencies:
       canvas: ^2.11.2
@@ -3997,20 +4014,20 @@ packages:
     resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
     engines: {node: '>= 0.8.0'}
 
     resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
     engines: {node: '>= 0.8.0'}
 
-  lilconfig@3.0.0:
-    resolution: {integrity: sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==}
+  lilconfig@3.1.2:
+    resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
     engines: {node: '>=14'}
 
   lines-and-columns@1.2.4:
     resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
 
     engines: {node: '>=14'}
 
   lines-and-columns@1.2.4:
     resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
 
-  lint-staged@15.2.2:
-    resolution: {integrity: sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==}
+  lint-staged@15.2.5:
+    resolution: {integrity: sha512-j+DfX7W9YUvdzEZl3Rk47FhDF6xwDBV5wwsCPw6BwWZVPYJemusQmvb9bRsW23Sqsaa+vRloAWogbK4BUuU2zA==}
     engines: {node: '>=18.12.0'}
     hasBin: true
 
     engines: {node: '>=18.12.0'}
     hasBin: true
 
-  listr2@8.0.1:
-    resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==}
+  listr2@8.2.1:
+    resolution: {integrity: sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==}
     engines: {node: '>=18.0.0'}
 
   local-pkg@0.5.0:
     engines: {node: '>=18.0.0'}
 
   local-pkg@0.5.0:
@@ -4199,12 +4216,12 @@ packages:
     resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
     engines: {node: '>= 8'}
 
     resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
     engines: {node: '>= 8'}
 
-  micromatch@4.0.5:
-    resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+  micromatch@4.0.7:
+    resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
     engines: {node: '>=8.6'}
 
     engines: {node: '>=8.6'}
 
-  mikro-orm@6.2.5:
-    resolution: {integrity: sha512-8GJulcYlawnMbXHch4/HTKDg8u0Q6p4l1Jfyn0WmaN4lMz/XXTuLQTZMSdHhISXUjf9/aQdVkmRPxvKog47pVA==}
+  mikro-orm@6.2.9:
+    resolution: {integrity: sha512-zpP8D7Lw8Q2WYwd43iFQI+5e0zPUM+vEAAyJaGE87RzSiQwchqZNPuV/H74STNJYqj8mLSvwZxFvRzrQXsCRRw==}
     engines: {node: '>= 18.12.0'}
 
   miller-rabin@4.0.1:
     engines: {node: '>= 18.12.0'}
 
   miller-rabin@4.0.1:
@@ -4300,8 +4317,8 @@ packages:
     resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
     engines: {node: '>=8'}
 
     resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
     engines: {node: '>=8'}
 
-  minipass@7.1.0:
-    resolution: {integrity: sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==}
+  minipass@7.1.2:
+    resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
     engines: {node: '>=16 || 14 >=14.17'}
 
   minizlib@2.1.2:
     engines: {node: '>=16 || 14 >=14.17'}
 
   minizlib@2.1.2:
@@ -4352,8 +4369,8 @@ packages:
   ml-xsadd@2.0.0:
     resolution: {integrity: sha512-VoAYUqmPRmzKbbqRejjqceGFp3VF81Qe8XXFGU0UXLxB7Mf4GGvyGq5Qn3k4AiQgDEV6WzobqlPOd+j0+m6IrA==}
 
   ml-xsadd@2.0.0:
     resolution: {integrity: sha512-VoAYUqmPRmzKbbqRejjqceGFp3VF81Qe8XXFGU0UXLxB7Mf4GGvyGq5Qn3k4AiQgDEV6WzobqlPOd+j0+m6IrA==}
 
-  mlly@1.7.0:
-    resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==}
+  mlly@1.7.1:
+    resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==}
 
   mnemonist@0.40.0-rc1:
     resolution: {integrity: sha512-38L0xGDezsPweee5i7duiaCRzlkkCJorozW6Rta60iel7ZkT4vF6jDIfr101NxE3rsAsumuOvc8yiTGZD5gG4w==}
 
   mnemonist@0.40.0-rc1:
     resolution: {integrity: sha512-38L0xGDezsPweee5i7duiaCRzlkkCJorozW6Rta60iel7ZkT4vF6jDIfr101NxE3rsAsumuOvc8yiTGZD5gG4w==}
@@ -4366,11 +4383,11 @@ packages:
   moment@2.30.1:
     resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
 
   moment@2.30.1:
     resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
 
-  mongodb-connection-string-url@3.0.0:
-    resolution: {integrity: sha512-t1Vf+m1I5hC2M5RJx/7AtxgABy1cZmIPQRMXw+gEIPn/cZNF3Oiy+l0UIypUwVB5trcWHq3crg2g3uAR9aAwsQ==}
+  mongodb-connection-string-url@3.0.1:
+    resolution: {integrity: sha512-XqMGwRX0Lgn05TDB4PyG2h2kKO/FfWJyCzYQbIhXUxz7ETt0I/FqHjUeqj37irJ+Dl1ZtU82uYyj14u2XsZKfg==}
 
 
-  mongodb@6.6.1:
-    resolution: {integrity: sha512-FvA9ocQzRzzvhin1HHLrZDEm0gWvnksbiciYrU/0GmET/t/DdDiMJroA7rfDrHM3AInwGVYw2fwAU2oNYUyUEw==}
+  mongodb@6.7.0:
+    resolution: {integrity: sha512-TMKyHdtMcO0fYBNORiYdmM25ijsHs+Njs963r4Tro4OQZzqYigAzYQouwWRg4OIaiLRUEGUh/1UAcH5lxdSLIA==}
     engines: {node: '>=16.20.1'}
     peerDependencies:
       '@aws-sdk/credential-providers': ^3.188.0
     engines: {node: '>=16.20.1'}
     peerDependencies:
       '@aws-sdk/credential-providers': ^3.188.0
@@ -4490,8 +4507,8 @@ packages:
   no-case@2.3.2:
     resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==}
 
   no-case@2.3.2:
     resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==}
 
-  node-abi@3.62.0:
-    resolution: {integrity: sha512-CPMcGa+y33xuL1E0TcNIu4YyaZCxnnvkVaEXrsosR3FxN+fV8xvb7Mzpb7IgKler10qeMkE6+Dp8qJhpzdq35g==}
+  node-abi@3.63.0:
+    resolution: {integrity: sha512-vAszCsOUrUxjGAmdnM/pq7gUgie0IRteCQMX6d4A534fQCR93EJU5qgzBvU6EkFfK27s0T3HEV3BOyJIr7OMYw==}
     engines: {node: '>=10'}
 
   node-addon-api@7.1.0:
     engines: {node: '>=10'}
 
   node-addon-api@7.1.0:
@@ -4569,6 +4586,7 @@ packages:
   npmlog@6.0.2:
     resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
     engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
   npmlog@6.0.2:
     resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
     engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
+    deprecated: This package is no longer supported.
 
   nth-check@2.1.1:
     resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
 
   nth-check@2.1.1:
     resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
@@ -4577,8 +4595,8 @@ packages:
     resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
     engines: {node: '>=0.10.0'}
 
     resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
     engines: {node: '>=0.10.0'}
 
-  nwsapi@2.2.9:
-    resolution: {integrity: sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg==}
+  nwsapi@2.2.10:
+    resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==}
 
   oauth-sign@0.9.0:
     resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
 
   oauth-sign@0.9.0:
     resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==}
@@ -4812,9 +4830,9 @@ packages:
     resolution: {integrity: sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==}
     engines: {node: '>= 0.8.0'}
 
     resolution: {integrity: sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==}
     engines: {node: '>= 0.8.0'}
 
-  path-scurry@1.10.2:
-    resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==}
-    engines: {node: '>=16 || 14 >=14.17'}
+  path-scurry@1.11.1:
+    resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+    engines: {node: '>=16 || 14 >=14.18'}
 
   path-type@4.0.0:
     resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
 
   path-type@4.0.0:
     resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
@@ -4840,8 +4858,8 @@ packages:
   pg-connection-string@2.6.2:
     resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==}
 
   pg-connection-string@2.6.2:
     resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==}
 
-  picocolors@1.0.0:
-    resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+  picocolors@1.0.1:
+    resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
 
   picomatch@2.3.1:
     resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
 
   picomatch@2.3.1:
     resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
@@ -4856,15 +4874,15 @@ packages:
     resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
     engines: {node: '>=0.10.0'}
 
     resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
     engines: {node: '>=0.10.0'}
 
-  pkg-types@1.1.0:
-    resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==}
+  pkg-types@1.1.1:
+    resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==}
 
   pkg-up@3.1.0:
     resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
     engines: {node: '>=8'}
 
 
   pkg-up@3.1.0:
     resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==}
     engines: {node: '>=8'}
 
-  poolifier@4.0.2:
-    resolution: {integrity: sha512-hDVMaPN2DCyUcbIRdmTGSAvNx3tidMvp1Z7cPQepnaHGoYftfuDuGqsxkE8y6z0+Olo6ei/aqQjQRZ+cH8fA8A==}
+  poolifier@4.0.13:
+    resolution: {integrity: sha512-GPITJo3LZvZXGNDWn6eDpOJ+F5+rq4tvyoXFQJfyJ92w0qr4evjoOX9hymwMGmv8TuifFMIBmgCdcTvoxRdMgA==}
     engines: {node: '>=18.0.0', pnpm: '>=9.0.0'}
 
   possible-typed-array-names@1.0.0:
     engines: {node: '>=18.0.0', pnpm: '>=9.0.0'}
 
   possible-typed-array-names@1.0.0:
@@ -4877,8 +4895,8 @@ packages:
     peerDependencies:
       postcss: ^8.0.0
 
     peerDependencies:
       postcss: ^8.0.0
 
-  postcss-selector-parser@6.0.16:
-    resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==}
+  postcss-selector-parser@6.1.0:
+    resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==}
     engines: {node: '>=4'}
 
   postcss-value-parser@4.2.0:
     engines: {node: '>=4'}
 
   postcss-value-parser@4.2.0:
@@ -4905,8 +4923,8 @@ packages:
     resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
     engines: {node: '>=6.0.0'}
 
     resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
     engines: {node: '>=6.0.0'}
 
-  prettier@3.2.5:
-    resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==}
+  prettier@3.3.1:
+    resolution: {integrity: sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==}
     engines: {node: '>=14'}
     hasBin: true
 
     engines: {node: '>=14'}
     hasBin: true
 
@@ -5099,9 +5117,9 @@ packages:
   reinterval@1.1.0:
     resolution: {integrity: sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==}
 
   reinterval@1.1.0:
     resolution: {integrity: sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==}
 
-  release-it@17.2.1:
-    resolution: {integrity: sha512-zBOpaHyjrXC3g/9rHyQlvuDw9yCn9AGphrlL+t3gWNEhbZKEQ62WNY45JxllcJMNx9orQUxBZ3o7pVCqkeuTbg==}
-    engines: {node: ^18.18.0 || ^20.8.0 || ^21.0.0}
+  release-it@17.3.0:
+    resolution: {integrity: sha512-7t9a2WEwqQKCdteshZUrO/3RX60plS5CzYAFr5+4Zj8qvRx1pFOFVglJSz4BeFAEd2yejpPxfI60+qRUzLEDZw==}
+    engines: {node: ^18.18.0 || ^20.8.0 || ^22.0.0}
     hasBin: true
 
   request@2.88.2:
     hasBin: true
 
   request@2.88.2:
@@ -5137,9 +5155,6 @@ packages:
   resolve-pkg-maps@1.0.0:
     resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
 
   resolve-pkg-maps@1.0.0:
     resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
 
-  resolve@1.19.0:
-    resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
-
   resolve@1.22.8:
     resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
     hasBin: true
   resolve@1.22.8:
     resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
     hasBin: true
@@ -5180,24 +5195,28 @@ packages:
 
   rimraf@3.0.2:
     resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
 
   rimraf@3.0.2:
     resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
+    deprecated: Rimraf versions prior to v4 are no longer supported
     hasBin: true
 
     hasBin: true
 
-  rimraf@5.0.5:
-    resolution: {integrity: sha512-CqDakW+hMe/Bz202FPEymy68P+G50RfMQK+Qo5YUqc9SPipvbGjCGKd0RSKEelbsfQuw3g5NZDSrlZZAJurH1A==}
-    engines: {node: '>=14'}
+  rimraf@5.0.7:
+    resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==}
+    engines: {node: '>=14.18'}
     hasBin: true
 
   ripemd160@2.0.2:
     resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==}
 
     hasBin: true
 
   ripemd160@2.0.2:
     resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==}
 
-  rollup@4.17.2:
-    resolution: {integrity: sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==}
+  rollup@4.18.0:
+    resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==}
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
     hasBin: true
 
   rrweb-cssom@0.6.0:
     resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
 
     engines: {node: '>=18.0.0', npm: '>=8.0.0'}
     hasBin: true
 
   rrweb-cssom@0.6.0:
     resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
 
+  rrweb-cssom@0.7.0:
+    resolution: {integrity: sha512-KlSv0pm9kgQSRxXEMgtivPJ4h826YHsuob8pSHcfSZsSXGtvpEAie8S0AnXuObEJ7nhikOb4ahwxDm0H2yW17g==}
+
   run-applescript@7.0.0:
     resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==}
     engines: {node: '>=18'}
   run-applescript@7.0.0:
     resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==}
     engines: {node: '>=18'}
@@ -5259,8 +5278,8 @@ packages:
     resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==}
     engines: {node: '>=12'}
 
     resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==}
     engines: {node: '>=12'}
 
-  semver@7.6.0:
-    resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
+  semver@7.6.2:
+    resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
     engines: {node: '>=10'}
     hasBin: true
 
     engines: {node: '>=10'}
     hasBin: true
 
@@ -5411,8 +5430,8 @@ packages:
   spdx-expression-parse@4.0.0:
     resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==}
 
   spdx-expression-parse@4.0.0:
     resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==}
 
-  spdx-license-ids@3.0.17:
-    resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==}
+  spdx-license-ids@3.0.18:
+    resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==}
 
   split2@4.2.0:
     resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
 
   split2@4.2.0:
     resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
@@ -5638,8 +5657,8 @@ packages:
     resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
     engines: {node: '>=10'}
 
     resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
     engines: {node: '>=10'}
 
-  tar@7.1.0:
-    resolution: {integrity: sha512-ENhg4W6BmjYxl8GTaE7/h99f0aXiSWv4kikRZ9n2/JRxypZniE84ILZqimAhxxX7Zb8Px6pFdheW3EeHfhnXQQ==}
+  tar@7.2.0:
+    resolution: {integrity: sha512-hctwP0Nb4AB60bj8WQgRYaMOuJYRAPMGiQUAotms5igN8ppfQM+IvjQ5HcKu1MaZh2Wy2KWVTe563Yj8dfc14w==}
     engines: {node: '>=18'}
 
   tarn@3.0.2:
     engines: {node: '>=18'}
 
   tarn@3.0.2:
@@ -5655,6 +5674,10 @@ packages:
     resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
     engines: {node: '>=8'}
 
     resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
     engines: {node: '>=8'}
 
+  test-exclude@7.0.1:
+    resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==}
+    engines: {node: '>=18'}
+
   text-extensions@2.4.0:
     resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==}
     engines: {node: '>=8'}
   text-extensions@2.4.0:
     resolution: {integrity: sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==}
     engines: {node: '>=8'}
@@ -5774,11 +5797,11 @@ packages:
   tslib@1.14.1:
     resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
 
   tslib@1.14.1:
     resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
 
-  tslib@2.6.2:
-    resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
+  tslib@2.6.3:
+    resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
 
 
-  tsx@4.9.3:
-    resolution: {integrity: sha512-czVbetlILiyJZI5zGlj2kw9vFiSeyra9liPD4nG+Thh4pKTi0AmMEQ8zdV/L2xbIVKrIqif4sUNrsMAOksx9Zg==}
+  tsx@4.15.1:
+    resolution: {integrity: sha512-k/6h17jA1KfUR7SpcteOa880zGmF56s8gMIcSqUR5avyNFi9nlCEKpMiHLrzrqyARGr52A/JablmGey1DEWbCA==}
     engines: {node: '>=18.0.0'}
     hasBin: true
 
     engines: {node: '>=18.0.0'}
     hasBin: true
 
@@ -5828,8 +5851,8 @@ packages:
     resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
     engines: {node: '>=12.20'}
 
     resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
     engines: {node: '>=12.20'}
 
-  type@2.7.2:
-    resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==}
+  type@2.7.3:
+    resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==}
 
   typed-array-buffer@1.0.2:
     resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
 
   typed-array-buffer@1.0.2:
     resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==}
@@ -5864,8 +5887,8 @@ packages:
   ufo@1.5.3:
     resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
 
   ufo@1.5.3:
     resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
 
-  uglify-js@3.17.4:
-    resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
+  uglify-js@3.18.0:
+    resolution: {integrity: sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==}
     engines: {node: '>=0.8.0'}
     hasBin: true
 
     engines: {node: '>=0.8.0'}
     hasBin: true
 
@@ -5919,8 +5942,8 @@ packages:
     resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
     engines: {node: '>= 0.8'}
 
     resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
     engines: {node: '>= 0.8'}
 
-  update-browserslist-db@1.0.15:
-    resolution: {integrity: sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA==}
+  update-browserslist-db@1.0.16:
+    resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==}
     hasBin: true
     peerDependencies:
       browserslist: '>= 4.21.0'
     hasBin: true
     peerDependencies:
       browserslist: '>= 4.21.0'
@@ -5949,8 +5972,8 @@ packages:
   url@0.11.3:
     resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==}
 
   url@0.11.3:
     resolution: {integrity: sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw==}
 
-  utf-8-validate@6.0.3:
-    resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==}
+  utf-8-validate@6.0.4:
+    resolution: {integrity: sha512-xu9GQDeFp+eZ6LnCywXN/zBancWvOpUMzgjLPSjy4BRHSmTelvn2E0DG0o1sTiw5hkCKBHo8rwSKncfRfv2EEQ==}
     engines: {node: '>=6.14.2'}
 
   util-deprecate@1.0.2:
     engines: {node: '>=6.14.2'}
 
   util-deprecate@1.0.2:
@@ -5994,8 +6017,8 @@ packages:
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
 
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
 
-  vite@5.2.11:
-    resolution: {integrity: sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==}
+  vite@5.2.13:
+    resolution: {integrity: sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==}
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
     peerDependencies:
     engines: {node: ^18.0.0 || >=20.0.0}
     hasBin: true
     peerDependencies:
@@ -6050,17 +6073,17 @@ packages:
   vm-browserify@1.1.2:
     resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
 
   vm-browserify@1.1.2:
     resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==}
 
-  vue-component-type-helpers@2.0.16:
-    resolution: {integrity: sha512-qisL/iAfdO++7w+SsfYQJVPj6QKvxp4i1MMxvsNO41z/8zu3KuAw9LkhKUfP/kcOWGDxESp+pQObWppXusejCA==}
+  vue-component-type-helpers@2.0.21:
+    resolution: {integrity: sha512-3NaicyZ7N4B6cft4bfb7dOnPbE9CjLcx+6wZWAg5zwszfO4qXRh+U52dN5r5ZZfc6iMaxKCEcoH9CmxxoFZHLg==}
 
 
-  vue-eslint-parser@9.4.2:
-    resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==}
+  vue-eslint-parser@9.4.3:
+    resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=6.0.0'
 
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=6.0.0'
 
-  vue-router@4.3.2:
-    resolution: {integrity: sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==}
+  vue-router@4.3.3:
+    resolution: {integrity: sha512-8Q+u+WP4N2SXY38FDcF2H1dUEbYVHVPtPCPZj/GTZx8RCbiB8AtJP9+YIxn4Vs0svMTNQcLIzka4GH7Utkx9xQ==}
     peerDependencies:
       vue: ^3.2.0
 
     peerDependencies:
       vue: ^3.2.0
 
@@ -6259,9 +6282,10 @@ packages:
     resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
     engines: {node: '>=18'}
 
     resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==}
     engines: {node: '>=18'}
 
-  yaml@2.3.4:
-    resolution: {integrity: sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==}
+  yaml@2.4.5:
+    resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==}
     engines: {node: '>= 14'}
     engines: {node: '>= 14'}
+    hasBin: true
 
   yargs-parser@15.0.3:
     resolution: {integrity: sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==}
 
   yargs-parser@15.0.3:
     resolution: {integrity: sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==}
@@ -6293,12 +6317,12 @@ snapshots:
 
   0x@5.7.0:
     dependencies:
 
   0x@5.7.0:
     dependencies:
-      ajv: 8.13.0
+      ajv: 8.16.0
       browserify: 17.0.0
       concat-stream: 2.0.0
       d3-fg: 6.14.0
       debounce: 1.2.1
       browserify: 17.0.0
       concat-stream: 2.0.0
       d3-fg: 6.14.0
       debounce: 1.2.1
-      debug: 4.3.4
+      debug: 4.3.5
       end-of-stream: 1.4.4
       env-string: 1.0.1
       escape-string-regexp: 4.0.0
       end-of-stream: 1.4.4
       env-string: 1.0.1
       escape-string-regexp: 4.0.0
@@ -6315,7 +6339,7 @@ snapshots:
       opn: 5.5.0
       pump: 3.0.0
       pumpify: 2.0.1
       opn: 5.5.0
       pump: 3.0.0
       pumpify: 2.0.1
-      semver: 7.6.0
+      semver: 7.6.2
       single-line-log: 1.1.2
       split2: 4.2.0
       tachyons: 4.12.0
       single-line-log: 1.1.2
       split2: 4.2.0
       tachyons: 4.12.0
@@ -6331,190 +6355,209 @@ snapshots:
 
   '@assemblyscript/loader@0.19.23': {}
 
 
   '@assemblyscript/loader@0.19.23': {}
 
-  '@babel/code-frame@7.24.2':
+  '@babel/code-frame@7.24.7':
     dependencies:
     dependencies:
-      '@babel/highlight': 7.24.5
-      picocolors: 1.0.0
+      '@babel/highlight': 7.24.7
+      picocolors: 1.0.1
 
 
-  '@babel/compat-data@7.24.4': {}
+  '@babel/compat-data@7.24.7': {}
 
 
-  '@babel/core@7.24.5':
+  '@babel/core@7.24.7':
     dependencies:
       '@ampproject/remapping': 2.3.0
     dependencies:
       '@ampproject/remapping': 2.3.0
-      '@babel/code-frame': 7.24.2
-      '@babel/generator': 7.24.5
-      '@babel/helper-compilation-targets': 7.23.6
-      '@babel/helper-module-transforms': 7.24.5(@babel/core@7.24.5)
-      '@babel/helpers': 7.24.5
-      '@babel/parser': 7.24.5
-      '@babel/template': 7.24.0
-      '@babel/traverse': 7.24.5
-      '@babel/types': 7.24.5
+      '@babel/code-frame': 7.24.7
+      '@babel/generator': 7.24.7
+      '@babel/helper-compilation-targets': 7.24.7
+      '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7)
+      '@babel/helpers': 7.24.7
+      '@babel/parser': 7.24.7
+      '@babel/template': 7.24.7
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
       convert-source-map: 2.0.0
       convert-source-map: 2.0.0
-      debug: 4.3.4
+      debug: 4.3.5
       gensync: 1.0.0-beta.2
       json5: 2.2.3
       gensync: 1.0.0-beta.2
       json5: 2.2.3
-      semver: 7.6.0
+      semver: 7.6.2
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
-  '@babel/generator@7.24.5':
+  '@babel/generator@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/types': 7.24.7
       '@jridgewell/gen-mapping': 0.3.5
       '@jridgewell/trace-mapping': 0.3.25
       jsesc: 2.5.2
 
       '@jridgewell/gen-mapping': 0.3.5
       '@jridgewell/trace-mapping': 0.3.25
       jsesc: 2.5.2
 
-  '@babel/helper-annotate-as-pure@7.22.5':
+  '@babel/helper-annotate-as-pure@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/types': 7.24.7
 
 
-  '@babel/helper-compilation-targets@7.23.6':
+  '@babel/helper-compilation-targets@7.24.7':
     dependencies:
     dependencies:
-      '@babel/compat-data': 7.24.4
-      '@babel/helper-validator-option': 7.23.5
-      browserslist: 4.23.0
+      '@babel/compat-data': 7.24.7
+      '@babel/helper-validator-option': 7.24.7
+      browserslist: 4.23.1
       lru-cache: 5.1.1
       lru-cache: 5.1.1
-      semver: 7.6.0
+      semver: 7.6.2
+
+  '@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7)':
+    dependencies:
+      '@babel/core': 7.24.7
+      '@babel/helper-annotate-as-pure': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-function-name': 7.24.7
+      '@babel/helper-member-expression-to-functions': 7.24.7
+      '@babel/helper-optimise-call-expression': 7.24.7
+      '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7)
+      '@babel/helper-skip-transparent-expression-wrappers': 7.24.7
+      '@babel/helper-split-export-declaration': 7.24.7
+      semver: 7.6.2
+    transitivePeerDependencies:
+      - supports-color
 
 
-  '@babel/helper-create-class-features-plugin@7.24.5(@babel/core@7.24.5)':
+  '@babel/helper-environment-visitor@7.24.7':
     dependencies:
     dependencies:
-      '@babel/core': 7.24.5
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-member-expression-to-functions': 7.24.5
-      '@babel/helper-optimise-call-expression': 7.22.5
-      '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.5)
-      '@babel/helper-skip-transparent-expression-wrappers': 7.22.5
-      '@babel/helper-split-export-declaration': 7.24.5
-      semver: 7.6.0
+      '@babel/types': 7.24.7
 
 
-  '@babel/helper-environment-visitor@7.22.20': {}
-
-  '@babel/helper-function-name@7.23.0':
+  '@babel/helper-function-name@7.24.7':
     dependencies:
     dependencies:
-      '@babel/template': 7.24.0
-      '@babel/types': 7.24.5
+      '@babel/template': 7.24.7
+      '@babel/types': 7.24.7
 
 
-  '@babel/helper-hoist-variables@7.22.5':
+  '@babel/helper-hoist-variables@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/types': 7.24.7
 
 
-  '@babel/helper-member-expression-to-functions@7.24.5':
+  '@babel/helper-member-expression-to-functions@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
 
   '@babel/helper-module-imports@7.22.15':
     dependencies:
 
   '@babel/helper-module-imports@7.22.15':
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/types': 7.24.7
 
 
-  '@babel/helper-module-imports@7.24.3':
+  '@babel/helper-module-imports@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
 
 
-  '@babel/helper-module-transforms@7.24.5(@babel/core@7.24.5)':
+  '@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7)':
     dependencies:
     dependencies:
-      '@babel/core': 7.24.5
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-module-imports': 7.24.3
-      '@babel/helper-simple-access': 7.24.5
-      '@babel/helper-split-export-declaration': 7.24.5
-      '@babel/helper-validator-identifier': 7.24.5
+      '@babel/core': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-module-imports': 7.24.7
+      '@babel/helper-simple-access': 7.24.7
+      '@babel/helper-split-export-declaration': 7.24.7
+      '@babel/helper-validator-identifier': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
 
 
-  '@babel/helper-optimise-call-expression@7.22.5':
+  '@babel/helper-optimise-call-expression@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/types': 7.24.7
 
 
-  '@babel/helper-plugin-utils@7.24.5': {}
+  '@babel/helper-plugin-utils@7.24.7': {}
 
 
-  '@babel/helper-replace-supers@7.24.1(@babel/core@7.24.5)':
+  '@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7)':
     dependencies:
     dependencies:
-      '@babel/core': 7.24.5
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-member-expression-to-functions': 7.24.5
-      '@babel/helper-optimise-call-expression': 7.22.5
+      '@babel/core': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-member-expression-to-functions': 7.24.7
+      '@babel/helper-optimise-call-expression': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
 
 
-  '@babel/helper-simple-access@7.24.5':
+  '@babel/helper-simple-access@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
 
 
-  '@babel/helper-skip-transparent-expression-wrappers@7.22.5':
+  '@babel/helper-skip-transparent-expression-wrappers@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
+    transitivePeerDependencies:
+      - supports-color
 
 
-  '@babel/helper-split-export-declaration@7.24.5':
+  '@babel/helper-split-export-declaration@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/types': 7.24.7
 
 
-  '@babel/helper-string-parser@7.24.1': {}
+  '@babel/helper-string-parser@7.24.7': {}
 
 
-  '@babel/helper-validator-identifier@7.24.5': {}
+  '@babel/helper-validator-identifier@7.24.7': {}
 
 
-  '@babel/helper-validator-option@7.23.5': {}
+  '@babel/helper-validator-option@7.24.7': {}
 
 
-  '@babel/helpers@7.24.5':
+  '@babel/helpers@7.24.7':
     dependencies:
     dependencies:
-      '@babel/template': 7.24.0
-      '@babel/traverse': 7.24.5
-      '@babel/types': 7.24.5
-    transitivePeerDependencies:
-      - supports-color
+      '@babel/template': 7.24.7
+      '@babel/types': 7.24.7
 
 
-  '@babel/highlight@7.24.5':
+  '@babel/highlight@7.24.7':
     dependencies:
     dependencies:
-      '@babel/helper-validator-identifier': 7.24.5
+      '@babel/helper-validator-identifier': 7.24.7
       chalk: 2.4.2
       js-tokens: 4.0.0
       chalk: 2.4.2
       js-tokens: 4.0.0
-      picocolors: 1.0.0
+      picocolors: 1.0.1
 
 
-  '@babel/parser@7.24.5':
+  '@babel/parser@7.24.7':
     dependencies:
     dependencies:
-      '@babel/types': 7.24.5
+      '@babel/types': 7.24.7
 
 
-  '@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.5)':
+  '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.7)':
     dependencies:
     dependencies:
-      '@babel/core': 7.24.5
-      '@babel/helper-plugin-utils': 7.24.5
+      '@babel/core': 7.24.7
+      '@babel/helper-plugin-utils': 7.24.7
 
 
-  '@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.5)':
+  '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.7)':
     dependencies:
     dependencies:
-      '@babel/core': 7.24.5
-      '@babel/helper-plugin-utils': 7.24.5
+      '@babel/core': 7.24.7
+      '@babel/helper-plugin-utils': 7.24.7
 
 
-  '@babel/plugin-transform-typescript@7.24.5(@babel/core@7.24.5)':
+  '@babel/plugin-transform-typescript@7.24.7(@babel/core@7.24.7)':
     dependencies:
     dependencies:
-      '@babel/core': 7.24.5
-      '@babel/helper-annotate-as-pure': 7.22.5
-      '@babel/helper-create-class-features-plugin': 7.24.5(@babel/core@7.24.5)
-      '@babel/helper-plugin-utils': 7.24.5
-      '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.5)
+      '@babel/core': 7.24.7
+      '@babel/helper-annotate-as-pure': 7.24.7
+      '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7)
+      '@babel/helper-plugin-utils': 7.24.7
+      '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.7)
+    transitivePeerDependencies:
+      - supports-color
 
 
-  '@babel/template@7.24.0':
+  '@babel/template@7.24.7':
     dependencies:
     dependencies:
-      '@babel/code-frame': 7.24.2
-      '@babel/parser': 7.24.5
-      '@babel/types': 7.24.5
+      '@babel/code-frame': 7.24.7
+      '@babel/parser': 7.24.7
+      '@babel/types': 7.24.7
 
 
-  '@babel/traverse@7.24.5':
+  '@babel/traverse@7.24.7':
     dependencies:
     dependencies:
-      '@babel/code-frame': 7.24.2
-      '@babel/generator': 7.24.5
-      '@babel/helper-environment-visitor': 7.22.20
-      '@babel/helper-function-name': 7.23.0
-      '@babel/helper-hoist-variables': 7.22.5
-      '@babel/helper-split-export-declaration': 7.24.5
-      '@babel/parser': 7.24.5
-      '@babel/types': 7.24.5
-      debug: 4.3.4
+      '@babel/code-frame': 7.24.7
+      '@babel/generator': 7.24.7
+      '@babel/helper-environment-visitor': 7.24.7
+      '@babel/helper-function-name': 7.24.7
+      '@babel/helper-hoist-variables': 7.24.7
+      '@babel/helper-split-export-declaration': 7.24.7
+      '@babel/parser': 7.24.7
+      '@babel/types': 7.24.7
+      debug: 4.3.5
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
 
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
 
-  '@babel/types@7.24.5':
+  '@babel/types@7.24.7':
     dependencies:
     dependencies:
-      '@babel/helper-string-parser': 7.24.1
-      '@babel/helper-validator-identifier': 7.24.5
+      '@babel/helper-string-parser': 7.24.7
+      '@babel/helper-validator-identifier': 7.24.7
       to-fast-properties: 2.0.0
 
   '@bcoe/v8-coverage@0.2.3': {}
       to-fast-properties: 2.0.0
 
   '@bcoe/v8-coverage@0.2.3': {}
@@ -6573,7 +6616,7 @@ snapshots:
       d3-selection: 1.4.2
       d3-shape: 1.3.7
       d3-time-format: 2.3.0
       d3-selection: 1.4.2
       d3-shape: 1.3.7
       d3-time-format: 2.3.0
-      debug: 4.3.4
+      debug: 4.3.5
       distributions: 2.2.0
       endpoint: 0.4.5
       hidden-markov-model-tf: 4.0.0(@tensorflow/tfjs-core@3.21.0(encoding@0.1.13))
       distributions: 2.2.0
       endpoint: 0.4.5
       hidden-markov-model-tf: 4.0.0(@tensorflow/tfjs-core@3.21.0(encoding@0.1.13))
@@ -6583,7 +6626,7 @@ snapshots:
       protocol-buffers: 4.2.0
       pump: 3.0.0
       pumpify: 2.0.1
       protocol-buffers: 4.2.0
       pump: 3.0.0
       pumpify: 2.0.1
-      semver: 7.6.0
+      semver: 7.6.2
       showdown: 1.9.1
       stream-template: 0.0.10
       streaming-json-stringify: 3.1.0
       showdown: 1.9.1
       stream-template: 0.0.10
       streaming-json-stringify: 3.1.0
@@ -6641,11 +6684,11 @@ snapshots:
 
   '@colors/colors@1.6.0': {}
 
 
   '@colors/colors@1.6.0': {}
 
-  '@commitlint/cli@19.3.0(@types/node@20.12.10)(typescript@5.4.5)':
+  '@commitlint/cli@19.3.0(@types/node@20.14.2)(typescript@5.4.5)':
     dependencies:
       '@commitlint/format': 19.3.0
       '@commitlint/lint': 19.2.2
     dependencies:
       '@commitlint/format': 19.3.0
       '@commitlint/lint': 19.2.2
-      '@commitlint/load': 19.2.0(@types/node@20.12.10)(typescript@5.4.5)
+      '@commitlint/load': 19.2.0(@types/node@20.14.2)(typescript@5.4.5)
       '@commitlint/read': 19.2.1
       '@commitlint/types': 19.0.3
       execa: 8.0.1
       '@commitlint/read': 19.2.1
       '@commitlint/types': 19.0.3
       execa: 8.0.1
@@ -6662,7 +6705,7 @@ snapshots:
   '@commitlint/config-validator@19.0.3':
     dependencies:
       '@commitlint/types': 19.0.3
   '@commitlint/config-validator@19.0.3':
     dependencies:
       '@commitlint/types': 19.0.3
-      ajv: 8.13.0
+      ajv: 8.16.0
 
   '@commitlint/ensure@19.0.3':
     dependencies:
 
   '@commitlint/ensure@19.0.3':
     dependencies:
@@ -6683,7 +6726,7 @@ snapshots:
   '@commitlint/is-ignored@19.2.2':
     dependencies:
       '@commitlint/types': 19.0.3
   '@commitlint/is-ignored@19.2.2':
     dependencies:
       '@commitlint/types': 19.0.3
-      semver: 7.6.0
+      semver: 7.6.2
 
   '@commitlint/lint@19.2.2':
     dependencies:
 
   '@commitlint/lint@19.2.2':
     dependencies:
@@ -6692,7 +6735,7 @@ snapshots:
       '@commitlint/rules': 19.0.3
       '@commitlint/types': 19.0.3
 
       '@commitlint/rules': 19.0.3
       '@commitlint/types': 19.0.3
 
-  '@commitlint/load@19.2.0(@types/node@20.12.10)(typescript@5.4.5)':
+  '@commitlint/load@19.2.0(@types/node@20.14.2)(typescript@5.4.5)':
     dependencies:
       '@commitlint/config-validator': 19.0.3
       '@commitlint/execute-rule': 19.0.0
     dependencies:
       '@commitlint/config-validator': 19.0.3
       '@commitlint/execute-rule': 19.0.0
@@ -6700,7 +6743,7 @@ snapshots:
       '@commitlint/types': 19.0.3
       chalk: 5.3.0
       cosmiconfig: 9.0.0(typescript@5.4.5)
       '@commitlint/types': 19.0.3
       chalk: 5.3.0
       cosmiconfig: 9.0.0(typescript@5.4.5)
-      cosmiconfig-typescript-loader: 5.0.0(@types/node@20.12.10)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5)
+      cosmiconfig-typescript-loader: 5.0.0(@types/node@20.14.2)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5)
       lodash.isplainobject: 4.0.6
       lodash.merge: 4.6.2
       lodash.uniq: 4.5.0
       lodash.isplainobject: 4.0.6
       lodash.merge: 4.6.2
       lodash.uniq: 4.5.0
@@ -6762,8 +6805,11 @@ snapshots:
       enabled: 2.0.0
       kuler: 2.0.0
 
       enabled: 2.0.0
       kuler: 2.0.0
 
-  '@es-joy/jsdoccomment@0.42.0':
+  '@es-joy/jsdoccomment@0.43.1':
     dependencies:
     dependencies:
+      '@types/eslint': 8.56.10
+      '@types/estree': 1.0.5
+      '@typescript-eslint/types': 7.12.0
       comment-parser: 1.4.1
       esquery: 1.5.0
       jsdoc-type-pratt-parser: 4.0.0
       comment-parser: 1.4.1
       esquery: 1.5.0
       jsdoc-type-pratt-parser: 4.0.0
@@ -6771,139 +6817,139 @@ snapshots:
   '@esbuild/aix-ppc64@0.20.2':
     optional: true
 
   '@esbuild/aix-ppc64@0.20.2':
     optional: true
 
-  '@esbuild/aix-ppc64@0.21.0':
+  '@esbuild/aix-ppc64@0.21.5':
     optional: true
 
   '@esbuild/android-arm64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/android-arm64@0.20.2':
     optional: true
 
-  '@esbuild/android-arm64@0.21.0':
+  '@esbuild/android-arm64@0.21.5':
     optional: true
 
   '@esbuild/android-arm@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/android-arm@0.20.2':
     optional: true
 
-  '@esbuild/android-arm@0.21.0':
+  '@esbuild/android-arm@0.21.5':
     optional: true
 
   '@esbuild/android-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/android-x64@0.20.2':
     optional: true
 
-  '@esbuild/android-x64@0.21.0':
+  '@esbuild/android-x64@0.21.5':
     optional: true
 
   '@esbuild/darwin-arm64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/darwin-arm64@0.20.2':
     optional: true
 
-  '@esbuild/darwin-arm64@0.21.0':
+  '@esbuild/darwin-arm64@0.21.5':
     optional: true
 
   '@esbuild/darwin-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/darwin-x64@0.20.2':
     optional: true
 
-  '@esbuild/darwin-x64@0.21.0':
+  '@esbuild/darwin-x64@0.21.5':
     optional: true
 
   '@esbuild/freebsd-arm64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/freebsd-arm64@0.20.2':
     optional: true
 
-  '@esbuild/freebsd-arm64@0.21.0':
+  '@esbuild/freebsd-arm64@0.21.5':
     optional: true
 
   '@esbuild/freebsd-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/freebsd-x64@0.20.2':
     optional: true
 
-  '@esbuild/freebsd-x64@0.21.0':
+  '@esbuild/freebsd-x64@0.21.5':
     optional: true
 
   '@esbuild/linux-arm64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-arm64@0.20.2':
     optional: true
 
-  '@esbuild/linux-arm64@0.21.0':
+  '@esbuild/linux-arm64@0.21.5':
     optional: true
 
   '@esbuild/linux-arm@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-arm@0.20.2':
     optional: true
 
-  '@esbuild/linux-arm@0.21.0':
+  '@esbuild/linux-arm@0.21.5':
     optional: true
 
   '@esbuild/linux-ia32@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-ia32@0.20.2':
     optional: true
 
-  '@esbuild/linux-ia32@0.21.0':
+  '@esbuild/linux-ia32@0.21.5':
     optional: true
 
   '@esbuild/linux-loong64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-loong64@0.20.2':
     optional: true
 
-  '@esbuild/linux-loong64@0.21.0':
+  '@esbuild/linux-loong64@0.21.5':
     optional: true
 
   '@esbuild/linux-mips64el@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-mips64el@0.20.2':
     optional: true
 
-  '@esbuild/linux-mips64el@0.21.0':
+  '@esbuild/linux-mips64el@0.21.5':
     optional: true
 
   '@esbuild/linux-ppc64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-ppc64@0.20.2':
     optional: true
 
-  '@esbuild/linux-ppc64@0.21.0':
+  '@esbuild/linux-ppc64@0.21.5':
     optional: true
 
   '@esbuild/linux-riscv64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-riscv64@0.20.2':
     optional: true
 
-  '@esbuild/linux-riscv64@0.21.0':
+  '@esbuild/linux-riscv64@0.21.5':
     optional: true
 
   '@esbuild/linux-s390x@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-s390x@0.20.2':
     optional: true
 
-  '@esbuild/linux-s390x@0.21.0':
+  '@esbuild/linux-s390x@0.21.5':
     optional: true
 
   '@esbuild/linux-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/linux-x64@0.20.2':
     optional: true
 
-  '@esbuild/linux-x64@0.21.0':
+  '@esbuild/linux-x64@0.21.5':
     optional: true
 
   '@esbuild/netbsd-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/netbsd-x64@0.20.2':
     optional: true
 
-  '@esbuild/netbsd-x64@0.21.0':
+  '@esbuild/netbsd-x64@0.21.5':
     optional: true
 
   '@esbuild/openbsd-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/openbsd-x64@0.20.2':
     optional: true
 
-  '@esbuild/openbsd-x64@0.21.0':
+  '@esbuild/openbsd-x64@0.21.5':
     optional: true
 
   '@esbuild/sunos-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/sunos-x64@0.20.2':
     optional: true
 
-  '@esbuild/sunos-x64@0.21.0':
+  '@esbuild/sunos-x64@0.21.5':
     optional: true
 
   '@esbuild/win32-arm64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/win32-arm64@0.20.2':
     optional: true
 
-  '@esbuild/win32-arm64@0.21.0':
+  '@esbuild/win32-arm64@0.21.5':
     optional: true
 
   '@esbuild/win32-ia32@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/win32-ia32@0.20.2':
     optional: true
 
-  '@esbuild/win32-ia32@0.21.0':
+  '@esbuild/win32-ia32@0.21.5':
     optional: true
 
   '@esbuild/win32-x64@0.20.2':
     optional: true
 
     optional: true
 
   '@esbuild/win32-x64@0.20.2':
     optional: true
 
-  '@esbuild/win32-x64@0.21.0':
+  '@esbuild/win32-x64@0.21.5':
     optional: true
 
   '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
     optional: true
 
   '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)':
@@ -6911,12 +6957,12 @@ snapshots:
       eslint: 8.57.0
       eslint-visitor-keys: 3.4.3
 
       eslint: 8.57.0
       eslint-visitor-keys: 3.4.3
 
-  '@eslint-community/regexpp@4.10.0': {}
+  '@eslint-community/regexpp@4.10.1': {}
 
   '@eslint/eslintrc@2.1.4':
     dependencies:
       ajv: 6.12.6
 
   '@eslint/eslintrc@2.1.4':
     dependencies:
       ajv: 6.12.6
-      debug: 4.3.4
+      debug: 4.3.5
       espree: 9.6.1
       globals: 13.24.0
       ignore: 5.3.1
       espree: 9.6.1
       globals: 13.24.0
       ignore: 5.3.1
@@ -6935,7 +6981,7 @@ snapshots:
   '@humanwhocodes/config-array@0.11.14':
     dependencies:
       '@humanwhocodes/object-schema': 2.0.3
   '@humanwhocodes/config-array@0.11.14':
     dependencies:
       '@humanwhocodes/object-schema': 2.0.3
-      debug: 4.3.4
+      debug: 4.3.5
       minimatch: 3.1.2
     transitivePeerDependencies:
       - supports-color
       minimatch: 3.1.2
     transitivePeerDependencies:
       - supports-color
@@ -6946,7 +6992,7 @@ snapshots:
 
   '@iarna/toml@2.2.5': {}
 
 
   '@iarna/toml@2.2.5': {}
 
-  '@inquirer/figures@1.0.1': {}
+  '@inquirer/figures@1.0.3': {}
 
   '@isaacs/cliui@8.0.2':
     dependencies:
 
   '@isaacs/cliui@8.0.2':
     dependencies:
@@ -6959,7 +7005,7 @@ snapshots:
 
   '@isaacs/fs-minipass@4.0.1':
     dependencies:
 
   '@isaacs/fs-minipass@4.0.1':
     dependencies:
-      minipass: 7.1.0
+      minipass: 7.1.2
 
   '@istanbuljs/schema@0.1.3': {}
 
 
   '@istanbuljs/schema@0.1.3': {}
 
@@ -6982,7 +7028,7 @@ snapshots:
       '@jest/schemas': 29.6.3
       '@types/istanbul-lib-coverage': 2.0.6
       '@types/istanbul-reports': 3.0.4
       '@jest/schemas': 29.6.3
       '@types/istanbul-lib-coverage': 2.0.6
       '@types/istanbul-reports': 3.0.4
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
       '@types/yargs': 17.0.32
       chalk: 4.1.2
 
       '@types/yargs': 17.0.32
       chalk: 4.1.2
 
@@ -7012,25 +7058,27 @@ snapshots:
     dependencies:
       call-bind: 1.0.7
 
     dependencies:
       call-bind: 1.0.7
 
-  '@microsoft/tsdoc-config@0.16.2':
+  '@microsoft/tsdoc-config@0.17.0':
     dependencies:
     dependencies:
-      '@microsoft/tsdoc': 0.14.2
-      ajv: 6.12.6
+      '@microsoft/tsdoc': 0.15.0
+      ajv: 8.12.0
       jju: 1.4.0
       jju: 1.4.0
-      resolve: 1.19.0
+      resolve: 1.22.8
 
 
-  '@microsoft/tsdoc@0.14.2': {}
+  '@microsoft/tsdoc@0.15.0': {}
 
 
-  '@mikro-orm/cli@6.2.5':
+  '@mikro-orm/cli@6.2.9(mariadb@3.3.0)':
     dependencies:
       '@jercle/yargonaut': 1.1.5
     dependencies:
       '@jercle/yargonaut': 1.1.5
-      '@mikro-orm/core': 6.2.5
-      '@mikro-orm/knex': 6.2.5(@mikro-orm/core@6.2.5)(sqlite3@5.1.7)
+      '@mikro-orm/core': 6.2.9
+      '@mikro-orm/knex': 6.2.9(@mikro-orm/core@6.2.9)(mariadb@3.3.0)(sqlite3@5.1.7)
       fs-extra: 11.2.0
       tsconfig-paths: 4.2.0
       yargs: 17.7.2
     transitivePeerDependencies:
       - better-sqlite3
       fs-extra: 11.2.0
       tsconfig-paths: 4.2.0
       yargs: 17.7.2
     transitivePeerDependencies:
       - better-sqlite3
+      - libsql
+      - mariadb
       - mysql
       - mysql2
       - pg
       - mysql
       - mysql2
       - pg
@@ -7039,24 +7087,25 @@ snapshots:
       - supports-color
       - tedious
 
       - supports-color
       - tedious
 
-  '@mikro-orm/core@6.2.5':
+  '@mikro-orm/core@6.2.9':
     dependencies:
       dataloader: 2.2.2
       dotenv: 16.4.5
       esprima: 4.0.1
       fs-extra: 11.2.0
       globby: 11.1.0
     dependencies:
       dataloader: 2.2.2
       dotenv: 16.4.5
       esprima: 4.0.1
       fs-extra: 11.2.0
       globby: 11.1.0
-      mikro-orm: 6.2.5
+      mikro-orm: 6.2.9
       reflect-metadata: 0.2.2
 
       reflect-metadata: 0.2.2
 
-  '@mikro-orm/knex@6.2.5(@mikro-orm/core@6.2.5)(sqlite3@5.1.7)':
+  '@mikro-orm/knex@6.2.9(@mikro-orm/core@6.2.9)(mariadb@3.3.0)(sqlite3@5.1.7)':
     dependencies:
     dependencies:
-      '@mikro-orm/core': 6.2.5
+      '@mikro-orm/core': 6.2.9
       fs-extra: 11.2.0
       knex: 3.1.0(sqlite3@5.1.7)
       sqlstring: 2.3.3
       fs-extra: 11.2.0
       knex: 3.1.0(sqlite3@5.1.7)
       sqlstring: 2.3.3
+    optionalDependencies:
+      mariadb: 3.3.0
     transitivePeerDependencies:
     transitivePeerDependencies:
-      - better-sqlite3
       - mysql
       - mysql2
       - pg
       - mysql
       - mysql2
       - pg
@@ -7065,13 +7114,14 @@ snapshots:
       - supports-color
       - tedious
 
       - supports-color
       - tedious
 
-  '@mikro-orm/mariadb@6.2.5(@mikro-orm/core@6.2.5)':
+  '@mikro-orm/mariadb@6.2.9(@mikro-orm/core@6.2.9)':
     dependencies:
     dependencies:
-      '@mikro-orm/core': 6.2.5
-      '@mikro-orm/knex': 6.2.5(@mikro-orm/core@6.2.5)(sqlite3@5.1.7)
+      '@mikro-orm/core': 6.2.9
+      '@mikro-orm/knex': 6.2.9(@mikro-orm/core@6.2.9)(mariadb@3.3.0)(sqlite3@5.1.7)
       mariadb: 3.3.0
     transitivePeerDependencies:
       - better-sqlite3
       mariadb: 3.3.0
     transitivePeerDependencies:
       - better-sqlite3
+      - libsql
       - mysql
       - mysql2
       - pg
       - mysql
       - mysql2
       - pg
@@ -7080,22 +7130,24 @@ snapshots:
       - supports-color
       - tedious
 
       - supports-color
       - tedious
 
-  '@mikro-orm/reflection@6.2.5(@mikro-orm/core@6.2.5)':
+  '@mikro-orm/reflection@6.2.9(@mikro-orm/core@6.2.9)':
     dependencies:
     dependencies:
-      '@mikro-orm/core': 6.2.5
+      '@mikro-orm/core': 6.2.9
       globby: 11.1.0
       ts-morph: 22.0.0
 
       globby: 11.1.0
       ts-morph: 22.0.0
 
-  '@mikro-orm/sqlite@6.2.5(@mikro-orm/core@6.2.5)':
+  '@mikro-orm/sqlite@6.2.9(@mikro-orm/core@6.2.9)(mariadb@3.3.0)':
     dependencies:
     dependencies:
-      '@mikro-orm/core': 6.2.5
-      '@mikro-orm/knex': 6.2.5(@mikro-orm/core@6.2.5)(sqlite3@5.1.7)
+      '@mikro-orm/core': 6.2.9
+      '@mikro-orm/knex': 6.2.9(@mikro-orm/core@6.2.9)(mariadb@3.3.0)(sqlite3@5.1.7)
       fs-extra: 11.2.0
       sqlite3: 5.1.7
       sqlstring-sqlite: 0.1.1
     transitivePeerDependencies:
       - better-sqlite3
       - bluebird
       fs-extra: 11.2.0
       sqlite3: 5.1.7
       sqlstring-sqlite: 0.1.1
     transitivePeerDependencies:
       - better-sqlite3
       - bluebird
+      - libsql
+      - mariadb
       - mysql
       - mysql2
       - pg
       - mysql
       - mysql2
       - pg
@@ -7103,7 +7155,7 @@ snapshots:
       - supports-color
       - tedious
 
       - supports-color
       - tedious
 
-  '@mongodb-js/saslprep@1.1.6':
+  '@mongodb-js/saslprep@1.1.7':
     dependencies:
       sparse-bitfield: 3.0.3
 
     dependencies:
       sparse-bitfield: 3.0.3
 
@@ -7127,7 +7179,7 @@ snapshots:
   '@npmcli/fs@1.1.1':
     dependencies:
       '@gar/promisify': 1.1.3
   '@npmcli/fs@1.1.1':
     dependencies:
       '@gar/promisify': 1.1.3
-      semver: 7.6.0
+      semver: 7.6.2
     optional: true
 
   '@npmcli/move-file@1.1.2':
     optional: true
 
   '@npmcli/move-file@1.1.2':
@@ -7159,23 +7211,21 @@ snapshots:
       '@octokit/types': 13.5.0
       universal-user-agent: 6.0.1
 
       '@octokit/types': 13.5.0
       universal-user-agent: 6.0.1
 
-  '@octokit/openapi-types@20.0.0': {}
-
   '@octokit/openapi-types@22.2.0': {}
 
   '@octokit/openapi-types@22.2.0': {}
 
-  '@octokit/plugin-paginate-rest@9.2.1(@octokit/core@5.2.0)':
+  '@octokit/plugin-paginate-rest@11.3.1(@octokit/core@5.2.0)':
     dependencies:
       '@octokit/core': 5.2.0
     dependencies:
       '@octokit/core': 5.2.0
-      '@octokit/types': 12.6.0
+      '@octokit/types': 13.5.0
 
   '@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.0)':
     dependencies:
       '@octokit/core': 5.2.0
 
 
   '@octokit/plugin-request-log@4.0.1(@octokit/core@5.2.0)':
     dependencies:
       '@octokit/core': 5.2.0
 
-  '@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.2.0)':
+  '@octokit/plugin-rest-endpoint-methods@13.2.2(@octokit/core@5.2.0)':
     dependencies:
       '@octokit/core': 5.2.0
     dependencies:
       '@octokit/core': 5.2.0
-      '@octokit/types': 12.6.0
+      '@octokit/types': 13.5.0
 
   '@octokit/request-error@5.1.0':
     dependencies:
 
   '@octokit/request-error@5.1.0':
     dependencies:
@@ -7190,16 +7240,12 @@ snapshots:
       '@octokit/types': 13.5.0
       universal-user-agent: 6.0.1
 
       '@octokit/types': 13.5.0
       universal-user-agent: 6.0.1
 
-  '@octokit/rest@20.1.0':
+  '@octokit/rest@20.1.1':
     dependencies:
       '@octokit/core': 5.2.0
     dependencies:
       '@octokit/core': 5.2.0
-      '@octokit/plugin-paginate-rest': 9.2.1(@octokit/core@5.2.0)
+      '@octokit/plugin-paginate-rest': 11.3.1(@octokit/core@5.2.0)
       '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.0)
       '@octokit/plugin-request-log': 4.0.1(@octokit/core@5.2.0)
-      '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.0)
-
-  '@octokit/types@12.6.0':
-    dependencies:
-      '@octokit/openapi-types': 20.0.0
+      '@octokit/plugin-rest-endpoint-methods': 13.2.2(@octokit/core@5.2.0)
 
   '@octokit/types@13.5.0':
     dependencies:
 
   '@octokit/types@13.5.0':
     dependencies:
@@ -7224,66 +7270,66 @@ snapshots:
       '@pnpm/network.ca-file': 1.0.2
       config-chain: 1.1.13
 
       '@pnpm/network.ca-file': 1.0.2
       config-chain: 1.1.13
 
-  '@release-it/bumper@6.0.1(release-it@17.2.1(typescript@5.4.5))':
+  '@release-it/bumper@6.0.1(release-it@17.3.0(typescript@5.4.5))':
     dependencies:
       '@iarna/toml': 2.2.5
       detect-indent: 7.0.1
       fast-glob: 3.3.2
     dependencies:
       '@iarna/toml': 2.2.5
       detect-indent: 7.0.1
       fast-glob: 3.3.2
-      ini: 4.1.2
+      ini: 4.1.3
       js-yaml: 4.1.0
       lodash-es: 4.17.21
       js-yaml: 4.1.0
       lodash-es: 4.17.21
-      release-it: 17.2.1(typescript@5.4.5)
-      semver: 7.6.0
+      release-it: 17.3.0(typescript@5.4.5)
+      semver: 7.6.2
 
 
-  '@rollup/rollup-android-arm-eabi@4.17.2':
+  '@rollup/rollup-android-arm-eabi@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-android-arm64@4.17.2':
+  '@rollup/rollup-android-arm64@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-darwin-arm64@4.17.2':
+  '@rollup/rollup-darwin-arm64@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-darwin-x64@4.17.2':
+  '@rollup/rollup-darwin-x64@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-arm-gnueabihf@4.17.2':
+  '@rollup/rollup-linux-arm-gnueabihf@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-arm-musleabihf@4.17.2':
+  '@rollup/rollup-linux-arm-musleabihf@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-arm64-gnu@4.17.2':
+  '@rollup/rollup-linux-arm64-gnu@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-arm64-musl@4.17.2':
+  '@rollup/rollup-linux-arm64-musl@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-powerpc64le-gnu@4.17.2':
+  '@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-riscv64-gnu@4.17.2':
+  '@rollup/rollup-linux-riscv64-gnu@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-s390x-gnu@4.17.2':
+  '@rollup/rollup-linux-s390x-gnu@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-x64-gnu@4.17.2':
+  '@rollup/rollup-linux-x64-gnu@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-linux-x64-musl@4.17.2':
+  '@rollup/rollup-linux-x64-musl@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-win32-arm64-msvc@4.17.2':
+  '@rollup/rollup-win32-arm64-msvc@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-win32-ia32-msvc@4.17.2':
+  '@rollup/rollup-win32-ia32-msvc@4.18.0':
     optional: true
 
     optional: true
 
-  '@rollup/rollup-win32-x64-msvc@4.17.2':
+  '@rollup/rollup-win32-x64-msvc@4.18.0':
     optional: true
 
     optional: true
 
-  '@rushstack/eslint-patch@1.10.2': {}
+  '@rushstack/eslint-patch@1.10.3': {}
 
   '@sinclair/typebox@0.27.8': {}
 
 
   '@sinclair/typebox@0.27.8': {}
 
@@ -7338,7 +7384,12 @@ snapshots:
 
   '@types/conventional-commits-parser@5.0.0':
     dependencies:
 
   '@types/conventional-commits-parser@5.0.0':
     dependencies:
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
+
+  '@types/eslint@8.56.10':
+    dependencies:
+      '@types/estree': 1.0.5
+      '@types/json-schema': 7.0.15
 
   '@types/estree@1.0.5': {}
 
 
   '@types/estree@1.0.5': {}
 
@@ -7356,9 +7407,9 @@ snapshots:
     dependencies:
       '@types/istanbul-lib-report': 3.0.3
 
     dependencies:
       '@types/istanbul-lib-report': 3.0.3
 
-  '@types/jsdom@21.1.6':
+  '@types/jsdom@21.1.7':
     dependencies:
     dependencies:
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
       '@types/tough-cookie': 4.0.5
       parse5: 7.1.2
 
       '@types/tough-cookie': 4.0.5
       parse5: 7.1.2
 
@@ -7368,7 +7419,7 @@ snapshots:
 
   '@types/long@4.0.2': {}
 
 
   '@types/long@4.0.2': {}
 
-  '@types/node@20.12.10':
+  '@types/node@20.14.2':
     dependencies:
       undici-types: 5.26.5
 
     dependencies:
       undici-types: 5.26.5
 
@@ -7388,13 +7439,13 @@ snapshots:
 
   '@types/webidl-conversions@7.0.3': {}
 
 
   '@types/webidl-conversions@7.0.3': {}
 
-  '@types/whatwg-url@11.0.4':
+  '@types/whatwg-url@11.0.5':
     dependencies:
       '@types/webidl-conversions': 7.0.3
 
   '@types/ws@8.5.10':
     dependencies:
     dependencies:
       '@types/webidl-conversions': 7.0.3
 
   '@types/ws@8.5.10':
     dependencies:
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
 
   '@types/yargs-parser@21.0.3': {}
 
 
   '@types/yargs-parser@21.0.3': {}
 
@@ -7402,49 +7453,47 @@ snapshots:
     dependencies:
       '@types/yargs-parser': 21.0.3
 
     dependencies:
       '@types/yargs-parser': 21.0.3
 
-  '@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)':
+  '@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)':
     dependencies:
     dependencies:
-      '@eslint-community/regexpp': 4.10.0
-      '@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
-      '@typescript-eslint/scope-manager': 7.8.0
-      '@typescript-eslint/type-utils': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
-      '@typescript-eslint/utils': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
-      '@typescript-eslint/visitor-keys': 7.8.0
-      debug: 4.3.4
+      '@eslint-community/regexpp': 4.10.1
+      '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/scope-manager': 7.12.0
+      '@typescript-eslint/type-utils': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/utils': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/visitor-keys': 7.12.0
       eslint: 8.57.0
       graphemer: 1.4.0
       ignore: 5.3.1
       natural-compare: 1.4.0
       eslint: 8.57.0
       graphemer: 1.4.0
       ignore: 5.3.1
       natural-compare: 1.4.0
-      semver: 7.6.0
       ts-api-utils: 1.3.0(typescript@5.4.5)
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
       - supports-color
 
       ts-api-utils: 1.3.0(typescript@5.4.5)
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5)':
+  '@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5)':
     dependencies:
     dependencies:
-      '@typescript-eslint/scope-manager': 7.8.0
-      '@typescript-eslint/types': 7.8.0
-      '@typescript-eslint/typescript-estree': 7.8.0(typescript@5.4.5)
-      '@typescript-eslint/visitor-keys': 7.8.0
-      debug: 4.3.4
+      '@typescript-eslint/scope-manager': 7.12.0
+      '@typescript-eslint/types': 7.12.0
+      '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5)
+      '@typescript-eslint/visitor-keys': 7.12.0
+      debug: 4.3.5
       eslint: 8.57.0
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
       - supports-color
 
       eslint: 8.57.0
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/scope-manager@7.8.0':
+  '@typescript-eslint/scope-manager@7.12.0':
     dependencies:
     dependencies:
-      '@typescript-eslint/types': 7.8.0
-      '@typescript-eslint/visitor-keys': 7.8.0
+      '@typescript-eslint/types': 7.12.0
+      '@typescript-eslint/visitor-keys': 7.12.0
 
 
-  '@typescript-eslint/type-utils@7.8.0(eslint@8.57.0)(typescript@5.4.5)':
+  '@typescript-eslint/type-utils@7.12.0(eslint@8.57.0)(typescript@5.4.5)':
     dependencies:
     dependencies:
-      '@typescript-eslint/typescript-estree': 7.8.0(typescript@5.4.5)
-      '@typescript-eslint/utils': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
-      debug: 4.3.4
+      '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5)
+      '@typescript-eslint/utils': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
+      debug: 4.3.5
       eslint: 8.57.0
       ts-api-utils: 1.3.0(typescript@5.4.5)
     optionalDependencies:
       eslint: 8.57.0
       ts-api-utils: 1.3.0(typescript@5.4.5)
     optionalDependencies:
@@ -7452,75 +7501,72 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/types@7.8.0': {}
+  '@typescript-eslint/types@7.12.0': {}
 
 
-  '@typescript-eslint/typescript-estree@7.8.0(typescript@5.4.5)':
+  '@typescript-eslint/typescript-estree@7.12.0(typescript@5.4.5)':
     dependencies:
     dependencies:
-      '@typescript-eslint/types': 7.8.0
-      '@typescript-eslint/visitor-keys': 7.8.0
-      debug: 4.3.4
+      '@typescript-eslint/types': 7.12.0
+      '@typescript-eslint/visitor-keys': 7.12.0
+      debug: 4.3.5
       globby: 11.1.0
       is-glob: 4.0.3
       minimatch: 9.0.4
       globby: 11.1.0
       is-glob: 4.0.3
       minimatch: 9.0.4
-      semver: 7.6.0
+      semver: 7.6.2
       ts-api-utils: 1.3.0(typescript@5.4.5)
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
       - supports-color
 
       ts-api-utils: 1.3.0(typescript@5.4.5)
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
       - supports-color
 
-  '@typescript-eslint/utils@7.8.0(eslint@8.57.0)(typescript@5.4.5)':
+  '@typescript-eslint/utils@7.12.0(eslint@8.57.0)(typescript@5.4.5)':
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
-      '@types/json-schema': 7.0.15
-      '@types/semver': 7.5.8
-      '@typescript-eslint/scope-manager': 7.8.0
-      '@typescript-eslint/types': 7.8.0
-      '@typescript-eslint/typescript-estree': 7.8.0(typescript@5.4.5)
+      '@typescript-eslint/scope-manager': 7.12.0
+      '@typescript-eslint/types': 7.12.0
+      '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5)
       eslint: 8.57.0
       eslint: 8.57.0
-      semver: 7.6.0
     transitivePeerDependencies:
       - supports-color
       - typescript
 
     transitivePeerDependencies:
       - supports-color
       - typescript
 
-  '@typescript-eslint/visitor-keys@7.8.0':
+  '@typescript-eslint/visitor-keys@7.12.0':
     dependencies:
     dependencies:
-      '@typescript-eslint/types': 7.8.0
+      '@typescript-eslint/types': 7.12.0
       eslint-visitor-keys: 3.4.3
 
   '@ungap/structured-clone@1.2.0': {}
 
       eslint-visitor-keys: 3.4.3
 
   '@ungap/structured-clone@1.2.0': {}
 
-  '@vitejs/plugin-vue-jsx@3.1.0(vite@5.2.11(@types/node@20.12.10))(vue@3.4.27(typescript@5.4.5))':
+  '@vitejs/plugin-vue-jsx@4.0.0(vite@5.2.13(@types/node@20.14.2))(vue@3.4.27(typescript@5.4.5))':
     dependencies:
     dependencies:
-      '@babel/core': 7.24.5
-      '@babel/plugin-transform-typescript': 7.24.5(@babel/core@7.24.5)
-      '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.24.5)
-      vite: 5.2.11(@types/node@20.12.10)
+      '@babel/core': 7.24.7
+      '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.7)
+      '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.24.7)
+      vite: 5.2.13(@types/node@20.14.2)
       vue: 3.4.27(typescript@5.4.5)
     transitivePeerDependencies:
       - supports-color
 
       vue: 3.4.27(typescript@5.4.5)
     transitivePeerDependencies:
       - supports-color
 
-  '@vitejs/plugin-vue@5.0.4(vite@5.2.11(@types/node@20.12.10))(vue@3.4.27(typescript@5.4.5))':
+  '@vitejs/plugin-vue@5.0.5(vite@5.2.13(@types/node@20.14.2))(vue@3.4.27(typescript@5.4.5))':
     dependencies:
     dependencies:
-      vite: 5.2.11(@types/node@20.12.10)
+      vite: 5.2.13(@types/node@20.14.2)
       vue: 3.4.27(typescript@5.4.5)
 
       vue: 3.4.27(typescript@5.4.5)
 
-  '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.12.10)(jsdom@24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)))':
+  '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@20.14.2)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)))':
     dependencies:
       '@ampproject/remapping': 2.3.0
       '@bcoe/v8-coverage': 0.2.3
     dependencies:
       '@ampproject/remapping': 2.3.0
       '@bcoe/v8-coverage': 0.2.3
-      debug: 4.3.4
+      debug: 4.3.5
       istanbul-lib-coverage: 3.2.2
       istanbul-lib-report: 3.0.1
       istanbul-lib-source-maps: 5.0.4
       istanbul-reports: 3.1.7
       magic-string: 0.30.10
       magicast: 0.3.4
       istanbul-lib-coverage: 3.2.2
       istanbul-lib-report: 3.0.1
       istanbul-lib-source-maps: 5.0.4
       istanbul-reports: 3.1.7
       magic-string: 0.30.10
       magicast: 0.3.4
-      picocolors: 1.0.0
+      picocolors: 1.0.1
       std-env: 3.7.0
       strip-literal: 2.1.0
       test-exclude: 6.0.0
       std-env: 3.7.0
       strip-literal: 2.1.0
       test-exclude: 6.0.0
-      vitest: 1.6.0(@types/node@20.12.10)(jsdom@24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3))
+      vitest: 1.6.0(@types/node@20.14.2)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4))
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
@@ -7555,36 +7601,36 @@ snapshots:
 
   '@vue/babel-helper-vue-transform-on@1.2.2': {}
 
 
   '@vue/babel-helper-vue-transform-on@1.2.2': {}
 
-  '@vue/babel-plugin-jsx@1.2.2(@babel/core@7.24.5)':
+  '@vue/babel-plugin-jsx@1.2.2(@babel/core@7.24.7)':
     dependencies:
       '@babel/helper-module-imports': 7.22.15
     dependencies:
       '@babel/helper-module-imports': 7.22.15
-      '@babel/helper-plugin-utils': 7.24.5
-      '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5)
-      '@babel/template': 7.24.0
-      '@babel/traverse': 7.24.5
-      '@babel/types': 7.24.5
+      '@babel/helper-plugin-utils': 7.24.7
+      '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7)
+      '@babel/template': 7.24.7
+      '@babel/traverse': 7.24.7
+      '@babel/types': 7.24.7
       '@vue/babel-helper-vue-transform-on': 1.2.2
       '@vue/babel-helper-vue-transform-on': 1.2.2
-      '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.24.5)
+      '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.24.7)
       camelcase: 6.3.0
       html-tags: 3.3.1
       svg-tags: 1.0.0
     optionalDependencies:
       camelcase: 6.3.0
       html-tags: 3.3.1
       svg-tags: 1.0.0
     optionalDependencies:
-      '@babel/core': 7.24.5
+      '@babel/core': 7.24.7
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
-  '@vue/babel-plugin-resolve-type@1.2.2(@babel/core@7.24.5)':
+  '@vue/babel-plugin-resolve-type@1.2.2(@babel/core@7.24.7)':
     dependencies:
     dependencies:
-      '@babel/code-frame': 7.24.2
-      '@babel/core': 7.24.5
+      '@babel/code-frame': 7.24.7
+      '@babel/core': 7.24.7
       '@babel/helper-module-imports': 7.22.15
       '@babel/helper-module-imports': 7.22.15
-      '@babel/helper-plugin-utils': 7.24.5
-      '@babel/parser': 7.24.5
+      '@babel/helper-plugin-utils': 7.24.7
+      '@babel/parser': 7.24.7
       '@vue/compiler-sfc': 3.4.27
 
   '@vue/compiler-core@3.4.27':
     dependencies:
       '@vue/compiler-sfc': 3.4.27
 
   '@vue/compiler-core@3.4.27':
     dependencies:
-      '@babel/parser': 7.24.5
+      '@babel/parser': 7.24.7
       '@vue/shared': 3.4.27
       entities: 4.5.0
       estree-walker: 2.0.2
       '@vue/shared': 3.4.27
       entities: 4.5.0
       estree-walker: 2.0.2
@@ -7597,7 +7643,7 @@ snapshots:
 
   '@vue/compiler-sfc@3.4.27':
     dependencies:
 
   '@vue/compiler-sfc@3.4.27':
     dependencies:
-      '@babel/parser': 7.24.5
+      '@babel/parser': 7.24.7
       '@vue/compiler-core': 3.4.27
       '@vue/compiler-dom': 3.4.27
       '@vue/compiler-ssr': 3.4.27
       '@vue/compiler-core': 3.4.27
       '@vue/compiler-dom': 3.4.27
       '@vue/compiler-ssr': 3.4.27
@@ -7612,24 +7658,24 @@ snapshots:
       '@vue/compiler-dom': 3.4.27
       '@vue/shared': 3.4.27
 
       '@vue/compiler-dom': 3.4.27
       '@vue/shared': 3.4.27
 
-  '@vue/devtools-api@6.6.1': {}
+  '@vue/devtools-api@6.6.3': {}
 
 
-  '@vue/eslint-config-prettier@9.0.0(eslint@8.57.0)(prettier@3.2.5)':
+  '@vue/eslint-config-prettier@9.0.0(@types/eslint@8.56.10)(eslint@8.57.0)(prettier@3.3.1)':
     dependencies:
       eslint: 8.57.0
       eslint-config-prettier: 9.1.0(eslint@8.57.0)
     dependencies:
       eslint: 8.57.0
       eslint-config-prettier: 9.1.0(eslint@8.57.0)
-      eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5)
-      prettier: 3.2.5
+      eslint-plugin-prettier: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.1)
+      prettier: 3.3.1
     transitivePeerDependencies:
       - '@types/eslint'
 
     transitivePeerDependencies:
       - '@types/eslint'
 
-  '@vue/eslint-config-typescript@13.0.0(eslint-plugin-vue@9.25.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5)':
+  '@vue/eslint-config-typescript@13.0.0(eslint-plugin-vue@9.26.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5)':
     dependencies:
     dependencies:
-      '@typescript-eslint/eslint-plugin': 7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
-      '@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/eslint-plugin': 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
       eslint: 8.57.0
       eslint: 8.57.0
-      eslint-plugin-vue: 9.25.0(eslint@8.57.0)
-      vue-eslint-parser: 9.4.2(eslint@8.57.0)
+      eslint-plugin-vue: 9.26.0(eslint@8.57.0)
+      vue-eslint-parser: 9.4.3(eslint@8.57.0)
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
     optionalDependencies:
       typescript: 5.4.5
     transitivePeerDependencies:
@@ -7661,7 +7707,7 @@ snapshots:
   '@vue/test-utils@2.4.6':
     dependencies:
       js-beautify: 1.15.1
   '@vue/test-utils@2.4.6':
     dependencies:
       js-beautify: 1.15.1
-      vue-component-type-helpers: 2.0.16
+      vue-component-type-helpers: 2.0.21
 
   '@vue/tsconfig@0.5.1': {}
 
 
   '@vue/tsconfig@0.5.1': {}
 
@@ -7701,14 +7747,14 @@ snapshots:
 
   agent-base@6.0.2:
     dependencies:
 
   agent-base@6.0.2:
     dependencies:
-      debug: 4.3.4
+      debug: 4.3.5
     transitivePeerDependencies:
       - supports-color
     optional: true
 
   agent-base@7.1.1:
     dependencies:
     transitivePeerDependencies:
       - supports-color
     optional: true
 
   agent-base@7.1.1:
     dependencies:
-      debug: 4.3.4
+      debug: 4.3.5
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
@@ -7722,13 +7768,13 @@ snapshots:
       clean-stack: 2.2.0
       indent-string: 4.0.0
 
       clean-stack: 2.2.0
       indent-string: 4.0.0
 
-  ajv-formats@2.1.1(ajv@8.13.0):
+  ajv-formats@2.1.1(ajv@8.16.0):
     optionalDependencies:
     optionalDependencies:
-      ajv: 8.13.0
+      ajv: 8.16.0
 
 
-  ajv-formats@3.0.1(ajv@8.13.0):
+  ajv-formats@3.0.1(ajv@8.16.0):
     optionalDependencies:
     optionalDependencies:
-      ajv: 8.13.0
+      ajv: 8.16.0
 
   ajv@6.12.6:
     dependencies:
 
   ajv@6.12.6:
     dependencies:
@@ -7737,7 +7783,14 @@ snapshots:
       json-schema-traverse: 0.4.1
       uri-js: 4.4.1
 
       json-schema-traverse: 0.4.1
       uri-js: 4.4.1
 
-  ajv@8.13.0:
+  ajv@8.12.0:
+    dependencies:
+      fast-deep-equal: 3.1.3
+      json-schema-traverse: 1.0.0
+      require-from-string: 2.0.2
+      uri-js: 4.4.1
+
+  ajv@8.16.0:
     dependencies:
       fast-deep-equal: 3.1.3
       json-schema-traverse: 1.0.0
     dependencies:
       fast-deep-equal: 3.1.3
       json-schema-traverse: 1.0.0
@@ -7888,7 +7941,7 @@ snapshots:
 
   ast-types@0.13.4:
     dependencies:
 
   ast-types@0.13.4:
     dependencies:
-      tslib: 2.6.2
+      tslib: 2.6.3
 
   async-retry@1.3.3:
     dependencies:
 
   async-retry@1.3.3:
     dependencies:
@@ -7912,7 +7965,7 @@ snapshots:
       handlebars: 4.7.8
       node-fetch: 2.7.0(encoding@0.1.13)
       parse-github-url: 1.0.2
       handlebars: 4.7.8
       node-fetch: 2.7.0(encoding@0.1.13)
       parse-github-url: 1.0.2
-      semver: 7.6.0
+      semver: 7.6.2
     transitivePeerDependencies:
       - encoding
 
     transitivePeerDependencies:
       - encoding
 
@@ -7920,7 +7973,7 @@ snapshots:
     dependencies:
       chalk: 4.1.2
       char-spinner: 1.0.1
     dependencies:
       chalk: 4.1.2
       char-spinner: 1.0.1
-      cli-table3: 0.6.4
+      cli-table3: 0.6.5
       color-support: 1.1.3
       cross-argv: 2.0.0
       form-data: 4.0.0
       color-support: 1.1.3
       cross-argv: 2.0.0
       form-data: 4.0.0
@@ -7938,7 +7991,7 @@ snapshots:
       progress: 2.0.3
       reinterval: 1.1.0
       retimer: 3.0.0
       progress: 2.0.3
       reinterval: 1.1.0
       retimer: 3.0.0
-      semver: 7.6.0
+      semver: 7.6.2
       subarg: 1.0.0
       timestring: 6.0.0
 
       subarg: 1.0.0
       timestring: 6.0.0
 
@@ -7948,7 +8001,7 @@ snapshots:
 
   aws-sign2@0.7.0: {}
 
 
   aws-sign2@0.7.0: {}
 
-  aws4@1.12.0: {}
+  aws4@1.13.0: {}
 
   b4a@1.6.6: {}
 
 
   b4a@1.6.6: {}
 
@@ -8015,9 +8068,9 @@ snapshots:
     dependencies:
       balanced-match: 1.0.2
 
     dependencies:
       balanced-match: 1.0.2
 
-  braces@3.0.2:
+  braces@3.0.3:
     dependencies:
     dependencies:
-      fill-range: 7.0.1
+      fill-range: 7.1.1
 
   brfs@2.0.2:
     dependencies:
 
   brfs@2.0.2:
     dependencies:
@@ -8138,12 +8191,12 @@ snapshots:
       vm-browserify: 1.1.2
       xtend: 4.0.2
 
       vm-browserify: 1.1.2
       xtend: 4.0.2
 
-  browserslist@4.23.0:
+  browserslist@4.23.1:
     dependencies:
     dependencies:
-      caniuse-lite: 1.0.30001616
-      electron-to-chromium: 1.4.757
+      caniuse-lite: 1.0.30001632
+      electron-to-chromium: 1.4.796
       node-releases: 2.0.14
       node-releases: 2.0.14
-      update-browserslist-db: 1.0.15(browserslist@4.23.0)
+      update-browserslist-db: 1.0.16(browserslist@4.23.1)
 
   bson@6.7.0: {}
 
 
   bson@6.7.0: {}
 
@@ -8168,15 +8221,13 @@ snapshots:
       node-gyp-build: 4.8.1
     optional: true
 
       node-gyp-build: 4.8.1
     optional: true
 
-  builtin-modules@3.3.0: {}
-
   builtin-status-codes@3.0.0: {}
 
   bundle-name@4.1.0:
     dependencies:
       run-applescript: 7.0.0
 
   builtin-status-codes@3.0.0: {}
 
   bundle-name@4.1.0:
     dependencies:
       run-applescript: 7.0.0
 
-  c8@9.1.0:
+  c8@10.0.0:
     dependencies:
       '@bcoe/v8-coverage': 0.2.3
       '@istanbuljs/schema': 0.1.3
     dependencies:
       '@bcoe/v8-coverage': 0.2.3
       '@istanbuljs/schema': 0.1.3
@@ -8185,7 +8236,7 @@ snapshots:
       istanbul-lib-coverage: 3.2.2
       istanbul-lib-report: 3.0.1
       istanbul-reports: 3.1.7
       istanbul-lib-coverage: 3.2.2
       istanbul-lib-report: 3.0.1
       istanbul-reports: 3.1.7
-      test-exclude: 6.0.0
+      test-exclude: 7.0.1
       v8-to-istanbul: 9.2.0
       yargs: 17.7.2
       yargs-parser: 21.1.1
       v8-to-istanbul: 9.2.0
       yargs: 17.7.2
       yargs-parser: 21.1.1
@@ -8251,7 +8302,7 @@ snapshots:
 
   camelcase@7.0.1: {}
 
 
   camelcase@7.0.1: {}
 
-  caniuse-lite@1.0.30001616: {}
+  caniuse-lite@1.0.30001632: {}
 
   caseless@0.12.0: {}
 
 
   caseless@0.12.0: {}
 
@@ -8261,7 +8312,7 @@ snapshots:
     dependencies:
       assertion-error: 1.1.0
       check-error: 1.0.3
     dependencies:
       assertion-error: 1.1.0
       check-error: 1.0.3
-      deep-eql: 4.1.3
+      deep-eql: 4.1.4
       get-func-name: 2.0.2
       loupe: 2.3.7
       pathval: 1.1.1
       get-func-name: 2.0.2
       loupe: 2.3.7
       pathval: 1.1.1
@@ -8299,7 +8350,7 @@ snapshots:
   chokidar@3.6.0:
     dependencies:
       anymatch: 3.1.3
   chokidar@3.6.0:
     dependencies:
       anymatch: 3.1.3
-      braces: 3.0.2
+      braces: 3.0.3
       glob-parent: 5.1.2
       is-binary-path: 2.1.0
       is-glob: 4.0.3
       glob-parent: 5.1.2
       is-binary-path: 2.1.0
       is-glob: 4.0.3
@@ -8343,7 +8394,7 @@ snapshots:
 
   cli-spinners@2.9.2: {}
 
 
   cli-spinners@2.9.2: {}
 
-  cli-table3@0.6.4:
+  cli-table3@0.6.5:
     dependencies:
       string-width: 4.2.3
     optionalDependencies:
     dependencies:
       string-width: 4.2.3
     optionalDependencies:
@@ -8450,7 +8501,7 @@ snapshots:
 
   commander@10.0.1: {}
 
 
   commander@10.0.1: {}
 
-  commander@11.1.0: {}
+  commander@12.1.0: {}
 
   commander@2.20.3: {}
 
 
   commander@2.20.3: {}
 
@@ -8486,8 +8537,8 @@ snapshots:
 
   conf@10.2.0:
     dependencies:
 
   conf@10.2.0:
     dependencies:
-      ajv: 8.13.0
-      ajv-formats: 2.1.1(ajv@8.13.0)
+      ajv: 8.16.0
+      ajv-formats: 2.1.1(ajv@8.16.0)
       atomically: 1.7.0
       debounce-fn: 4.0.0
       dot-prop: 6.0.1
       atomically: 1.7.0
       debounce-fn: 4.0.0
       dot-prop: 6.0.1
@@ -8495,7 +8546,7 @@ snapshots:
       json-schema-typed: 7.0.3
       onetime: 5.1.2
       pkg-up: 3.1.0
       json-schema-typed: 7.0.3
       onetime: 5.1.2
       pkg-up: 3.1.0
-      semver: 7.6.0
+      semver: 7.6.2
 
   confbox@0.1.7: {}
 
 
   confbox@0.1.7: {}
 
@@ -8557,11 +8608,11 @@ snapshots:
 
   core-util-is@1.0.3: {}
 
 
   core-util-is@1.0.3: {}
 
-  cosmiconfig-typescript-loader@5.0.0(@types/node@20.12.10)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5):
+  cosmiconfig-typescript-loader@5.0.0(@types/node@20.14.2)(cosmiconfig@9.0.0(typescript@5.4.5))(typescript@5.4.5):
     dependencies:
     dependencies:
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
       cosmiconfig: 9.0.0(typescript@5.4.5)
       cosmiconfig: 9.0.0(typescript@5.4.5)
-      jiti: 1.21.0
+      jiti: 1.21.6
       typescript: 5.4.5
 
   cosmiconfig@9.0.0(typescript@5.4.5):
       typescript: 5.4.5
 
   cosmiconfig@9.0.0(typescript@5.4.5):
@@ -8728,7 +8779,7 @@ snapshots:
   d@1.0.2:
     dependencies:
       es5-ext: 0.10.64
   d@1.0.2:
     dependencies:
       es5-ext: 0.10.64
-      type: 2.7.2
+      type: 2.7.3
 
   dargs@7.0.0: {}
 
 
   dargs@7.0.0: {}
 
@@ -8791,6 +8842,10 @@ snapshots:
     dependencies:
       ms: 2.1.2
 
     dependencies:
       ms: 2.1.2
 
+  debug@4.3.5:
+    dependencies:
+      ms: 2.1.2
+
   decamelize@1.2.0: {}
 
   decimal.js@10.4.3: {}
   decamelize@1.2.0: {}
 
   decimal.js@10.4.3: {}
@@ -8799,7 +8854,7 @@ snapshots:
     dependencies:
       mimic-response: 3.1.0
 
     dependencies:
       mimic-response: 3.1.0
 
-  deep-eql@4.1.3:
+  deep-eql@4.1.4:
     dependencies:
       type-detect: 4.0.8
 
     dependencies:
       type-detect: 4.0.8
 
@@ -8951,11 +9006,11 @@ snapshots:
       '@one-ini/wasm': 0.1.1
       commander: 10.0.1
       minimatch: 9.0.1
       '@one-ini/wasm': 0.1.1
       commander: 10.0.1
       minimatch: 9.0.1
-      semver: 7.6.0
+      semver: 7.6.2
 
   ee-first@1.1.1: {}
 
 
   ee-first@1.1.1: {}
 
-  electron-to-chromium@1.4.757: {}
+  electron-to-chromium@1.4.796: {}
 
   elliptic@6.5.5:
     dependencies:
 
   elliptic@6.5.5:
     dependencies:
@@ -8992,7 +9047,7 @@ snapshots:
     dependencies:
       inherits: 2.0.4
 
     dependencies:
       inherits: 2.0.4
 
-  enhanced-resolve@5.16.0:
+  enhanced-resolve@5.17.0:
     dependencies:
       graceful-fs: 4.2.11
       tapable: 2.2.1
     dependencies:
       graceful-fs: 4.2.11
       tapable: 2.2.1
@@ -9128,24 +9183,24 @@ snapshots:
       es6-iterator: 2.0.3
       es6-symbol: 3.1.4
       event-emitter: 0.3.5
       es6-iterator: 2.0.3
       es6-symbol: 3.1.4
       event-emitter: 0.3.5
-      type: 2.7.2
+      type: 2.7.3
 
   es6-symbol@3.1.4:
     dependencies:
       d: 1.0.2
       ext: 1.7.0
 
 
   es6-symbol@3.1.4:
     dependencies:
       d: 1.0.2
       ext: 1.7.0
 
-  esbuild-plugin-clean@1.0.1(esbuild@0.21.0):
+  esbuild-plugin-clean@1.0.1(esbuild@0.21.5):
     dependencies:
       chalk: 4.1.2
       del: 6.1.1
     dependencies:
       chalk: 4.1.2
       del: 6.1.1
-      esbuild: 0.21.0
+      esbuild: 0.21.5
 
 
-  esbuild-plugin-copy@2.1.1(esbuild@0.21.0):
+  esbuild-plugin-copy@2.1.1(esbuild@0.21.5):
     dependencies:
       chalk: 4.1.2
       chokidar: 3.6.0
     dependencies:
       chalk: 4.1.2
       chokidar: 3.6.0
-      esbuild: 0.21.0
+      esbuild: 0.21.5
       fs-extra: 10.1.0
       globby: 11.1.0
 
       fs-extra: 10.1.0
       globby: 11.1.0
 
@@ -9175,31 +9230,31 @@ snapshots:
       '@esbuild/win32-ia32': 0.20.2
       '@esbuild/win32-x64': 0.20.2
 
       '@esbuild/win32-ia32': 0.20.2
       '@esbuild/win32-x64': 0.20.2
 
-  esbuild@0.21.0:
+  esbuild@0.21.5:
     optionalDependencies:
     optionalDependencies:
-      '@esbuild/aix-ppc64': 0.21.0
-      '@esbuild/android-arm': 0.21.0
-      '@esbuild/android-arm64': 0.21.0
-      '@esbuild/android-x64': 0.21.0
-      '@esbuild/darwin-arm64': 0.21.0
-      '@esbuild/darwin-x64': 0.21.0
-      '@esbuild/freebsd-arm64': 0.21.0
-      '@esbuild/freebsd-x64': 0.21.0
-      '@esbuild/linux-arm': 0.21.0
-      '@esbuild/linux-arm64': 0.21.0
-      '@esbuild/linux-ia32': 0.21.0
-      '@esbuild/linux-loong64': 0.21.0
-      '@esbuild/linux-mips64el': 0.21.0
-      '@esbuild/linux-ppc64': 0.21.0
-      '@esbuild/linux-riscv64': 0.21.0
-      '@esbuild/linux-s390x': 0.21.0
-      '@esbuild/linux-x64': 0.21.0
-      '@esbuild/netbsd-x64': 0.21.0
-      '@esbuild/openbsd-x64': 0.21.0
-      '@esbuild/sunos-x64': 0.21.0
-      '@esbuild/win32-arm64': 0.21.0
-      '@esbuild/win32-ia32': 0.21.0
-      '@esbuild/win32-x64': 0.21.0
+      '@esbuild/aix-ppc64': 0.21.5
+      '@esbuild/android-arm': 0.21.5
+      '@esbuild/android-arm64': 0.21.5
+      '@esbuild/android-x64': 0.21.5
+      '@esbuild/darwin-arm64': 0.21.5
+      '@esbuild/darwin-x64': 0.21.5
+      '@esbuild/freebsd-arm64': 0.21.5
+      '@esbuild/freebsd-x64': 0.21.5
+      '@esbuild/linux-arm': 0.21.5
+      '@esbuild/linux-arm64': 0.21.5
+      '@esbuild/linux-ia32': 0.21.5
+      '@esbuild/linux-loong64': 0.21.5
+      '@esbuild/linux-mips64el': 0.21.5
+      '@esbuild/linux-ppc64': 0.21.5
+      '@esbuild/linux-riscv64': 0.21.5
+      '@esbuild/linux-s390x': 0.21.5
+      '@esbuild/linux-x64': 0.21.5
+      '@esbuild/netbsd-x64': 0.21.5
+      '@esbuild/openbsd-x64': 0.21.5
+      '@esbuild/sunos-x64': 0.21.5
+      '@esbuild/win32-arm64': 0.21.5
+      '@esbuild/win32-ia32': 0.21.5
+      '@esbuild/win32-x64': 0.21.5
 
   escalade@3.1.2: {}
 
 
   escalade@3.1.2: {}
 
@@ -9232,18 +9287,18 @@ snapshots:
     optionalDependencies:
       source-map: 0.6.1
 
     optionalDependencies:
       source-map: 0.6.1
 
-  eslint-compat-utils@0.5.0(eslint@8.57.0):
+  eslint-compat-utils@0.5.1(eslint@8.57.0):
     dependencies:
       eslint: 8.57.0
     dependencies:
       eslint: 8.57.0
-      semver: 7.6.0
+      semver: 7.6.2
 
 
-  eslint-config-love@47.0.0(@typescript-eslint/eslint-plugin@7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.5.0(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5):
+  eslint-config-love@47.0.0(@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.8.1(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0)(typescript@5.4.5):
     dependencies:
     dependencies:
-      '@typescript-eslint/eslint-plugin': 7.8.0(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
-      '@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/eslint-plugin': 7.12.0(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
       eslint: 8.57.0
       eslint: 8.57.0
-      eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
-      eslint-plugin-n: 17.5.0(eslint@8.57.0)
+      eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+      eslint-plugin-n: 17.8.1(eslint@8.57.0)
       eslint-plugin-promise: 6.1.1(eslint@8.57.0)
       typescript: 5.4.5
     transitivePeerDependencies:
       eslint-plugin-promise: 6.1.1(eslint@8.57.0)
       typescript: 5.4.5
     transitivePeerDependencies:
@@ -9253,11 +9308,11 @@ snapshots:
     dependencies:
       eslint: 8.57.0
 
     dependencies:
       eslint: 8.57.0
 
-  eslint-config-standard@17.1.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.5.0(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0):
+  eslint-config-standard@17.1.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0))(eslint-plugin-n@17.8.1(eslint@8.57.0))(eslint-plugin-promise@6.1.1(eslint@8.57.0))(eslint@8.57.0):
     dependencies:
       eslint: 8.57.0
     dependencies:
       eslint: 8.57.0
-      eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
-      eslint-plugin-n: 17.5.0(eslint@8.57.0)
+      eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+      eslint-plugin-n: 17.8.1(eslint@8.57.0)
       eslint-plugin-promise: 6.1.1(eslint@8.57.0)
 
   eslint-define-config@2.1.0: {}
       eslint-plugin-promise: 6.1.1(eslint@8.57.0)
 
   eslint-define-config@2.1.0: {}
@@ -9270,15 +9325,15 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
-  eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0):
+  eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0):
     dependencies:
     dependencies:
-      debug: 4.3.4
-      enhanced-resolve: 5.16.0
+      debug: 4.3.5
+      enhanced-resolve: 5.17.0
       eslint: 8.57.0
       eslint: 8.57.0
-      eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
-      eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+      eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
+      eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
       fast-glob: 3.3.2
       fast-glob: 3.3.2
-      get-tsconfig: 4.7.4
+      get-tsconfig: 4.7.5
       is-core-module: 2.13.1
       is-glob: 4.0.3
     transitivePeerDependencies:
       is-core-module: 2.13.1
       is-glob: 4.0.3
     transitivePeerDependencies:
@@ -9287,25 +9342,25 @@ snapshots:
       - eslint-import-resolver-webpack
       - supports-color
 
       - eslint-import-resolver-webpack
       - supports-color
 
-  eslint-module-utils@2.8.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
+  eslint-module-utils@2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0):
     dependencies:
       debug: 3.2.7
     optionalDependencies:
     dependencies:
       debug: 3.2.7
     optionalDependencies:
-      '@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
-      eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
+      eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0)
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
-  eslint-plugin-es-x@7.6.0(eslint@8.57.0):
+  eslint-plugin-es-x@7.7.0(eslint@8.57.0):
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
-      '@eslint-community/regexpp': 4.10.0
+      '@eslint-community/regexpp': 4.10.1
       eslint: 8.57.0
       eslint: 8.57.0
-      eslint-compat-utils: 0.5.0(eslint@8.57.0)
+      eslint-compat-utils: 0.5.1(eslint@8.57.0)
 
 
-  eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
+  eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
     dependencies:
       array-includes: 3.1.8
       array.prototype.findlastindex: 1.2.5
     dependencies:
       array-includes: 3.1.8
       array.prototype.findlastindex: 1.2.5
@@ -9315,7 +9370,7 @@ snapshots:
       doctrine: 2.1.0
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
       doctrine: 2.1.0
       eslint: 8.57.0
       eslint-import-resolver-node: 0.3.9
-      eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.8.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
+      eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
       hasown: 2.0.2
       is-core-module: 2.13.1
       is-glob: 4.0.3
       hasown: 2.0.2
       is-core-module: 2.13.1
       is-glob: 4.0.3
@@ -9323,49 +9378,49 @@ snapshots:
       object.fromentries: 2.0.8
       object.groupby: 1.0.3
       object.values: 1.2.0
       object.fromentries: 2.0.8
       object.groupby: 1.0.3
       object.values: 1.2.0
-      semver: 7.6.0
+      semver: 7.6.2
       tsconfig-paths: 3.15.0
     optionalDependencies:
       tsconfig-paths: 3.15.0
     optionalDependencies:
-      '@typescript-eslint/parser': 7.8.0(eslint@8.57.0)(typescript@5.4.5)
+      '@typescript-eslint/parser': 7.12.0(eslint@8.57.0)(typescript@5.4.5)
     transitivePeerDependencies:
       - eslint-import-resolver-typescript
       - eslint-import-resolver-webpack
       - supports-color
 
     transitivePeerDependencies:
       - eslint-import-resolver-typescript
       - eslint-import-resolver-webpack
       - supports-color
 
-  eslint-plugin-jsdoc@48.2.3(eslint@8.57.0):
+  eslint-plugin-jsdoc@48.2.9(eslint@8.57.0):
     dependencies:
     dependencies:
-      '@es-joy/jsdoccomment': 0.42.0
+      '@es-joy/jsdoccomment': 0.43.1
       are-docs-informative: 0.0.2
       comment-parser: 1.4.1
       are-docs-informative: 0.0.2
       comment-parser: 1.4.1
-      debug: 4.3.4
+      debug: 4.3.5
       escape-string-regexp: 4.0.0
       eslint: 8.57.0
       esquery: 1.5.0
       escape-string-regexp: 4.0.0
       eslint: 8.57.0
       esquery: 1.5.0
-      is-builtin-module: 3.2.1
-      semver: 7.6.0
+      semver: 7.6.2
       spdx-expression-parse: 4.0.0
     transitivePeerDependencies:
       - supports-color
 
       spdx-expression-parse: 4.0.0
     transitivePeerDependencies:
       - supports-color
 
-  eslint-plugin-n@17.5.0(eslint@8.57.0):
+  eslint-plugin-n@17.8.1(eslint@8.57.0):
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
-      enhanced-resolve: 5.16.0
+      enhanced-resolve: 5.17.0
       eslint: 8.57.0
       eslint: 8.57.0
-      eslint-plugin-es-x: 7.6.0(eslint@8.57.0)
-      get-tsconfig: 4.7.4
-      globals: 15.1.0
+      eslint-plugin-es-x: 7.7.0(eslint@8.57.0)
+      get-tsconfig: 4.7.5
+      globals: 15.4.0
       ignore: 5.3.1
       minimatch: 9.0.4
       ignore: 5.3.1
       minimatch: 9.0.4
-      semver: 7.6.0
+      semver: 7.6.2
 
 
-  eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.2.5):
+  eslint-plugin-prettier@5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@8.57.0))(eslint@8.57.0)(prettier@3.3.1):
     dependencies:
       eslint: 8.57.0
     dependencies:
       eslint: 8.57.0
-      prettier: 3.2.5
+      prettier: 3.3.1
       prettier-linter-helpers: 1.0.0
       synckit: 0.8.8
     optionalDependencies:
       prettier-linter-helpers: 1.0.0
       synckit: 0.8.8
     optionalDependencies:
+      '@types/eslint': 8.56.10
       eslint-config-prettier: 9.1.0(eslint@8.57.0)
 
   eslint-plugin-promise@6.1.1(eslint@8.57.0):
       eslint-config-prettier: 9.1.0(eslint@8.57.0)
 
   eslint-plugin-promise@6.1.1(eslint@8.57.0):
@@ -9376,21 +9431,21 @@ snapshots:
     dependencies:
       eslint: 8.57.0
 
     dependencies:
       eslint: 8.57.0
 
-  eslint-plugin-tsdoc@0.2.17:
+  eslint-plugin-tsdoc@0.3.0:
     dependencies:
     dependencies:
-      '@microsoft/tsdoc': 0.14.2
-      '@microsoft/tsdoc-config': 0.16.2
+      '@microsoft/tsdoc': 0.15.0
+      '@microsoft/tsdoc-config': 0.17.0
 
 
-  eslint-plugin-vue@9.25.0(eslint@8.57.0):
+  eslint-plugin-vue@9.26.0(eslint@8.57.0):
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
       eslint: 8.57.0
       globals: 13.24.0
       natural-compare: 1.4.0
       nth-check: 2.1.1
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
       eslint: 8.57.0
       globals: 13.24.0
       natural-compare: 1.4.0
       nth-check: 2.1.1
-      postcss-selector-parser: 6.0.16
-      semver: 7.6.0
-      vue-eslint-parser: 9.4.2(eslint@8.57.0)
+      postcss-selector-parser: 6.1.0
+      semver: 7.6.2
+      vue-eslint-parser: 9.4.3(eslint@8.57.0)
       xml-name-validator: 4.0.0
     transitivePeerDependencies:
       - supports-color
       xml-name-validator: 4.0.0
     transitivePeerDependencies:
       - supports-color
@@ -9405,7 +9460,7 @@ snapshots:
   eslint@8.57.0:
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
   eslint@8.57.0:
     dependencies:
       '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
-      '@eslint-community/regexpp': 4.10.0
+      '@eslint-community/regexpp': 4.10.1
       '@eslint/eslintrc': 2.1.4
       '@eslint/js': 8.57.0
       '@humanwhocodes/config-array': 0.11.14
       '@eslint/eslintrc': 2.1.4
       '@eslint/js': 8.57.0
       '@humanwhocodes/config-array': 0.11.14
@@ -9415,7 +9470,7 @@ snapshots:
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.3
       ajv: 6.12.6
       chalk: 4.1.2
       cross-spawn: 7.0.3
-      debug: 4.3.4
+      debug: 4.3.5
       doctrine: 3.0.0
       escape-string-regexp: 4.0.0
       eslint-scope: 7.2.2
       doctrine: 3.0.0
       escape-string-regexp: 4.0.0
       eslint-scope: 7.2.2
@@ -9452,7 +9507,7 @@ snapshots:
       d: 1.0.2
       es5-ext: 0.10.64
       event-emitter: 0.3.5
       d: 1.0.2
       es5-ext: 0.10.64
       event-emitter: 0.3.5
-      type: 2.7.2
+      type: 2.7.3
 
   espree@9.6.1:
     dependencies:
 
   espree@9.6.1:
     dependencies:
@@ -9556,7 +9611,7 @@ snapshots:
 
   ext@1.7.0:
     dependencies:
 
   ext@1.7.0:
     dependencies:
-      type: 2.7.2
+      type: 2.7.3
 
   extend@3.0.2: {}
 
 
   extend@3.0.2: {}
 
@@ -9578,7 +9633,7 @@ snapshots:
       '@nodelib/fs.walk': 1.2.8
       glob-parent: 5.1.2
       merge2: 1.4.1
       '@nodelib/fs.walk': 1.2.8
       glob-parent: 5.1.2
       merge2: 1.4.1
-      micromatch: 4.0.5
+      micromatch: 4.0.7
 
   fast-json-stable-stringify@2.1.0: {}
 
 
   fast-json-stable-stringify@2.1.0: {}
 
@@ -9613,7 +9668,7 @@ snapshots:
 
   file-uri-to-path@1.0.0: {}
 
 
   file-uri-to-path@1.0.0: {}
 
-  fill-range@7.0.1:
+  fill-range@7.1.1:
     dependencies:
       to-regex-range: 5.0.1
 
     dependencies:
       to-regex-range: 5.0.1
 
@@ -9788,7 +9843,7 @@ snapshots:
       es-errors: 1.3.0
       get-intrinsic: 1.2.4
 
       es-errors: 1.3.0
       get-intrinsic: 1.2.4
 
-  get-tsconfig@4.7.4:
+  get-tsconfig@4.7.5:
     dependencies:
       resolve-pkg-maps: 1.0.0
 
     dependencies:
       resolve-pkg-maps: 1.0.0
 
@@ -9796,7 +9851,7 @@ snapshots:
     dependencies:
       basic-ftp: 5.0.5
       data-uri-to-buffer: 6.0.2
     dependencies:
       basic-ftp: 5.0.5
       data-uri-to-buffer: 6.0.2
-      debug: 4.3.4
+      debug: 4.3.5
       fs-extra: 11.2.0
     transitivePeerDependencies:
       - supports-color
       fs-extra: 11.2.0
     transitivePeerDependencies:
       - supports-color
@@ -9832,13 +9887,13 @@ snapshots:
     dependencies:
       is-glob: 4.0.3
 
     dependencies:
       is-glob: 4.0.3
 
-  glob@10.3.12:
+  glob@10.4.1:
     dependencies:
       foreground-child: 3.1.1
     dependencies:
       foreground-child: 3.1.1
-      jackspeak: 2.3.6
+      jackspeak: 3.4.0
       minimatch: 9.0.4
       minimatch: 9.0.4
-      minipass: 7.1.0
-      path-scurry: 1.10.2
+      minipass: 7.1.2
+      path-scurry: 1.11.1
 
   glob@7.2.3:
     dependencies:
 
   glob@7.2.3:
     dependencies:
@@ -9863,7 +9918,7 @@ snapshots:
     dependencies:
       type-fest: 0.20.2
 
     dependencies:
       type-fest: 0.20.2
 
-  globals@15.1.0: {}
+  globals@15.4.0: {}
 
   globalthis@1.0.4:
     dependencies:
 
   globalthis@1.0.4:
     dependencies:
@@ -9919,7 +9974,7 @@ snapshots:
       source-map: 0.6.1
       wordwrap: 1.0.0
     optionalDependencies:
       source-map: 0.6.1
       wordwrap: 1.0.0
     optionalDependencies:
-      uglify-js: 3.17.4
+      uglify-js: 3.18.0
 
   har-schema@2.0.0: {}
 
 
   har-schema@2.0.0: {}
 
@@ -9995,7 +10050,7 @@ snapshots:
       ndarray-determinant: 1.0.0
       ndarray-inv: 0.2.0
       seedrandom: 3.0.5
       ndarray-determinant: 1.0.0
       ndarray-inv: 0.2.0
       seedrandom: 3.0.5
-      semver: 7.6.0
+      semver: 7.6.2
 
   hmac-drbg@1.0.1:
     dependencies:
 
   hmac-drbg@1.0.1:
     dependencies:
@@ -10031,7 +10086,7 @@ snapshots:
     dependencies:
       '@tootallnate/once': 1.1.2
       agent-base: 6.0.2
     dependencies:
       '@tootallnate/once': 1.1.2
       agent-base: 6.0.2
-      debug: 4.3.4
+      debug: 4.3.5
     transitivePeerDependencies:
       - supports-color
     optional: true
     transitivePeerDependencies:
       - supports-color
     optional: true
@@ -10039,7 +10094,7 @@ snapshots:
   http-proxy-agent@7.0.2:
     dependencies:
       agent-base: 7.1.1
   http-proxy-agent@7.0.2:
     dependencies:
       agent-base: 7.1.1
-      debug: 4.3.4
+      debug: 4.3.5
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
@@ -10061,7 +10116,7 @@ snapshots:
   https-proxy-agent@5.0.1:
     dependencies:
       agent-base: 6.0.2
   https-proxy-agent@5.0.1:
     dependencies:
       agent-base: 6.0.2
-      debug: 4.3.4
+      debug: 4.3.5
     transitivePeerDependencies:
       - supports-color
     optional: true
     transitivePeerDependencies:
       - supports-color
     optional: true
@@ -10069,7 +10124,7 @@ snapshots:
   https-proxy-agent@7.0.4:
     dependencies:
       agent-base: 7.1.1
   https-proxy-agent@7.0.4:
     dependencies:
       agent-base: 7.1.1
-      debug: 4.3.4
+      debug: 4.3.5
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
@@ -10143,7 +10198,7 @@ snapshots:
 
   ini@4.1.1: {}
 
 
   ini@4.1.1: {}
 
-  ini@4.1.2: {}
+  ini@4.1.3: {}
 
   inline-source-map@0.6.3:
     dependencies:
 
   inline-source-map@0.6.3:
     dependencies:
@@ -10165,9 +10220,9 @@ snapshots:
       strip-ansi: 5.2.0
       through: 2.3.8
 
       strip-ansi: 5.2.0
       through: 2.3.8
 
-  inquirer@9.2.19:
+  inquirer@9.2.22:
     dependencies:
     dependencies:
-      '@inquirer/figures': 1.0.1
+      '@inquirer/figures': 1.0.3
       '@ljharb/through': 2.3.13
       ansi-escapes: 4.3.2
       chalk: 5.3.0
       '@ljharb/through': 2.3.13
       ansi-escapes: 4.3.2
       chalk: 5.3.0
@@ -10262,10 +10317,6 @@ snapshots:
 
   is-buffer@2.0.5: {}
 
 
   is-buffer@2.0.5: {}
 
-  is-builtin-module@3.2.1:
-    dependencies:
-      builtin-modules: 3.3.0
-
   is-callable@1.2.7: {}
 
   is-ci@2.0.0:
   is-callable@1.2.7: {}
 
   is-ci@2.0.0:
@@ -10444,7 +10495,7 @@ snapshots:
   istanbul-lib-source-maps@5.0.4:
     dependencies:
       '@jridgewell/trace-mapping': 0.3.25
   istanbul-lib-source-maps@5.0.4:
     dependencies:
       '@jridgewell/trace-mapping': 0.3.25
-      debug: 4.3.4
+      debug: 4.3.5
       istanbul-lib-coverage: 3.2.2
     transitivePeerDependencies:
       - supports-color
       istanbul-lib-coverage: 3.2.2
     transitivePeerDependencies:
       - supports-color
@@ -10461,7 +10512,7 @@ snapshots:
       es-get-iterator: 1.1.3
       iterate-iterator: 1.0.2
 
       es-get-iterator: 1.1.3
       iterate-iterator: 1.0.2
 
-  jackspeak@2.3.6:
+  jackspeak@3.4.0:
     dependencies:
       '@isaacs/cliui': 8.0.2
     optionalDependencies:
     dependencies:
       '@isaacs/cliui': 8.0.2
     optionalDependencies:
@@ -10485,12 +10536,12 @@ snapshots:
 
   jest-message-util@29.7.0:
     dependencies:
 
   jest-message-util@29.7.0:
     dependencies:
-      '@babel/code-frame': 7.24.2
+      '@babel/code-frame': 7.24.7
       '@jest/types': 29.6.3
       '@types/stack-utils': 2.0.3
       chalk: 4.1.2
       graceful-fs: 4.2.11
       '@jest/types': 29.6.3
       '@types/stack-utils': 2.0.3
       chalk: 4.1.2
       graceful-fs: 4.2.11
-      micromatch: 4.0.5
+      micromatch: 4.0.7
       pretty-format: 29.7.0
       slash: 3.0.0
       stack-utils: 2.0.6
       pretty-format: 29.7.0
       slash: 3.0.0
       stack-utils: 2.0.6
@@ -10498,13 +10549,13 @@ snapshots:
   jest-util@29.7.0:
     dependencies:
       '@jest/types': 29.6.3
   jest-util@29.7.0:
     dependencies:
       '@jest/types': 29.6.3
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
       chalk: 4.1.2
       ci-info: 3.9.0
       graceful-fs: 4.2.11
       picomatch: 2.3.1
 
       chalk: 4.1.2
       ci-info: 3.9.0
       graceful-fs: 4.2.11
       picomatch: 2.3.1
 
-  jiti@1.21.0: {}
+  jiti@1.21.6: {}
 
   jju@1.4.0: {}
 
 
   jju@1.4.0: {}
 
@@ -10512,7 +10563,7 @@ snapshots:
     dependencies:
       config-chain: 1.1.13
       editorconfig: 1.0.4
     dependencies:
       config-chain: 1.1.13
       editorconfig: 1.0.4
-      glob: 10.3.12
+      glob: 10.4.1
       js-cookie: 3.0.5
       nopt: 7.2.1
 
       js-cookie: 3.0.5
       nopt: 7.2.1
 
@@ -10532,7 +10583,7 @@ snapshots:
 
   jsdoc-type-pratt-parser@4.0.0: {}
 
 
   jsdoc-type-pratt-parser@4.0.0: {}
 
-  jsdom@24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3):
+  jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4):
     dependencies:
       cssstyle: 4.0.1
       data-urls: 5.0.0
     dependencies:
       cssstyle: 4.0.1
       data-urls: 5.0.0
@@ -10542,9 +10593,9 @@ snapshots:
       http-proxy-agent: 7.0.2
       https-proxy-agent: 7.0.4
       is-potential-custom-element-name: 1.0.1
       http-proxy-agent: 7.0.2
       https-proxy-agent: 7.0.4
       is-potential-custom-element-name: 1.0.1
-      nwsapi: 2.2.9
+      nwsapi: 2.2.10
       parse5: 7.1.2
       parse5: 7.1.2
-      rrweb-cssom: 0.6.0
+      rrweb-cssom: 0.7.0
       saxes: 6.0.0
       symbol-tree: 3.2.4
       tough-cookie: 4.1.4
       saxes: 6.0.0
       symbol-tree: 3.2.4
       tough-cookie: 4.1.4
@@ -10553,7 +10604,7 @@ snapshots:
       whatwg-encoding: 3.1.1
       whatwg-mimetype: 4.0.0
       whatwg-url: 14.0.0
       whatwg-encoding: 3.1.1
       whatwg-mimetype: 4.0.0
       whatwg-url: 14.0.0
-      ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
+      ws: 8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
       xml-name-validator: 5.0.0
     transitivePeerDependencies:
       - bufferutil
       xml-name-validator: 5.0.0
     transitivePeerDependencies:
       - bufferutil
@@ -10657,26 +10708,26 @@ snapshots:
       prelude-ls: 1.2.1
       type-check: 0.4.0
 
       prelude-ls: 1.2.1
       type-check: 0.4.0
 
-  lilconfig@3.0.0: {}
+  lilconfig@3.1.2: {}
 
   lines-and-columns@1.2.4: {}
 
 
   lines-and-columns@1.2.4: {}
 
-  lint-staged@15.2.2:
+  lint-staged@15.2.5:
     dependencies:
       chalk: 5.3.0
     dependencies:
       chalk: 5.3.0
-      commander: 11.1.0
-      debug: 4.3.4
+      commander: 12.1.0
+      debug: 4.3.5
       execa: 8.0.1
       execa: 8.0.1
-      lilconfig: 3.0.0
-      listr2: 8.0.1
-      micromatch: 4.0.5
+      lilconfig: 3.1.2
+      listr2: 8.2.1
+      micromatch: 4.0.7
       pidtree: 0.6.0
       string-argv: 0.3.2
       pidtree: 0.6.0
       string-argv: 0.3.2
-      yaml: 2.3.4
+      yaml: 2.4.5
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
-  listr2@8.0.1:
+  listr2@8.2.1:
     dependencies:
       cli-truncate: 4.0.0
       colorette: 2.0.20
     dependencies:
       cli-truncate: 4.0.0
       colorette: 2.0.20
@@ -10687,8 +10738,8 @@ snapshots:
 
   local-pkg@0.5.0:
     dependencies:
 
   local-pkg@0.5.0:
     dependencies:
-      mlly: 1.7.0
-      pkg-types: 1.1.0
+      mlly: 1.7.1
+      pkg-types: 1.1.1
 
   locate-path@3.0.0:
     dependencies:
 
   locate-path@3.0.0:
     dependencies:
@@ -10793,6 +10844,7 @@ snapshots:
   lru-cache@6.0.0:
     dependencies:
       yallist: 4.0.0
   lru-cache@6.0.0:
     dependencies:
       yallist: 4.0.0
+    optional: true
 
   lru-cache@7.18.3: {}
 
 
   lru-cache@7.18.3: {}
 
@@ -10814,17 +10866,17 @@ snapshots:
 
   magicast@0.3.4:
     dependencies:
 
   magicast@0.3.4:
     dependencies:
-      '@babel/parser': 7.24.5
-      '@babel/types': 7.24.5
+      '@babel/parser': 7.24.7
+      '@babel/types': 7.24.7
       source-map-js: 1.2.0
 
   make-dir@3.1.0:
     dependencies:
       source-map-js: 1.2.0
 
   make-dir@3.1.0:
     dependencies:
-      semver: 7.6.0
+      semver: 7.6.2
 
   make-dir@4.0.0:
     dependencies:
 
   make-dir@4.0.0:
     dependencies:
-      semver: 7.6.0
+      semver: 7.6.2
 
   make-error@1.3.6: {}
 
 
   make-error@1.3.6: {}
 
@@ -10856,7 +10908,7 @@ snapshots:
   mariadb@3.3.0:
     dependencies:
       '@types/geojson': 7946.0.14
   mariadb@3.3.0:
     dependencies:
       '@types/geojson': 7946.0.14
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
       denque: 2.1.0
       iconv-lite: 0.6.3
       lru-cache: 10.2.2
       denque: 2.1.0
       iconv-lite: 0.6.3
       lru-cache: 10.2.2
@@ -10879,12 +10931,12 @@ snapshots:
 
   merge2@1.4.1: {}
 
 
   merge2@1.4.1: {}
 
-  micromatch@4.0.5:
+  micromatch@4.0.7:
     dependencies:
     dependencies:
-      braces: 3.0.2
+      braces: 3.0.3
       picomatch: 2.3.1
 
       picomatch: 2.3.1
 
-  mikro-orm@6.2.5: {}
+  mikro-orm@6.2.9: {}
 
   miller-rabin@4.0.1:
     dependencies:
 
   miller-rabin@4.0.1:
     dependencies:
@@ -10973,7 +11025,7 @@ snapshots:
 
   minipass@5.0.0: {}
 
 
   minipass@5.0.0: {}
 
-  minipass@7.1.0: {}
+  minipass@7.1.2: {}
 
   minizlib@2.1.2:
     dependencies:
 
   minizlib@2.1.2:
     dependencies:
@@ -10982,8 +11034,8 @@ snapshots:
 
   minizlib@3.0.1:
     dependencies:
 
   minizlib@3.0.1:
     dependencies:
-      minipass: 7.1.0
-      rimraf: 5.0.5
+      minipass: 7.1.2
+      rimraf: 5.0.7
 
   mkdirp-classic@0.5.3: {}
 
 
   mkdirp-classic@0.5.3: {}
 
@@ -11029,11 +11081,11 @@ snapshots:
 
   ml-xsadd@2.0.0: {}
 
 
   ml-xsadd@2.0.0: {}
 
-  mlly@1.7.0:
+  mlly@1.7.1:
     dependencies:
       acorn: 8.11.3
       pathe: 1.1.2
     dependencies:
       acorn: 8.11.3
       pathe: 1.1.2
-      pkg-types: 1.1.0
+      pkg-types: 1.1.1
       ufo: 1.5.3
 
   mnemonist@0.40.0-rc1:
       ufo: 1.5.3
 
   mnemonist@0.40.0-rc1:
@@ -11060,16 +11112,16 @@ snapshots:
 
   moment@2.30.1: {}
 
 
   moment@2.30.1: {}
 
-  mongodb-connection-string-url@3.0.0:
+  mongodb-connection-string-url@3.0.1:
     dependencies:
     dependencies:
-      '@types/whatwg-url': 11.0.4
+      '@types/whatwg-url': 11.0.5
       whatwg-url: 13.0.0
 
       whatwg-url: 13.0.0
 
-  mongodb@6.6.1(socks@2.8.3):
+  mongodb@6.7.0(socks@2.8.3):
     dependencies:
     dependencies:
-      '@mongodb-js/saslprep': 1.1.6
+      '@mongodb-js/saslprep': 1.1.7
       bson: 6.7.0
       bson: 6.7.0
-      mongodb-connection-string-url: 3.0.0
+      mongodb-connection-string-url: 3.0.1
     optionalDependencies:
       socks: 2.8.3
 
     optionalDependencies:
       socks: 2.8.3
 
@@ -11181,9 +11233,9 @@ snapshots:
     dependencies:
       lower-case: 1.1.4
 
     dependencies:
       lower-case: 1.1.4
 
-  node-abi@3.62.0:
+  node-abi@3.63.0:
     dependencies:
     dependencies:
-      semver: 7.6.0
+      semver: 7.6.2
 
   node-addon-api@7.1.0: {}
 
 
   node-addon-api@7.1.0: {}
 
@@ -11219,7 +11271,7 @@ snapshots:
       nopt: 5.0.0
       npmlog: 6.0.2
       rimraf: 3.0.2
       nopt: 5.0.0
       npmlog: 6.0.2
       rimraf: 3.0.2
-      semver: 7.6.0
+      semver: 7.6.2
       tar: 6.2.1
       which: 2.0.2
     transitivePeerDependencies:
       tar: 6.2.1
       which: 2.0.2
     transitivePeerDependencies:
@@ -11266,7 +11318,7 @@ snapshots:
 
   number-is-nan@1.0.1: {}
 
 
   number-is-nan@1.0.1: {}
 
-  nwsapi@2.2.9: {}
+  nwsapi@2.2.10: {}
 
   oauth-sign@0.9.0: {}
 
 
   oauth-sign@0.9.0: {}
 
@@ -11442,7 +11494,7 @@ snapshots:
     dependencies:
       '@tootallnate/quickjs-emscripten': 0.23.0
       agent-base: 7.1.1
     dependencies:
       '@tootallnate/quickjs-emscripten': 0.23.0
       agent-base: 7.1.1
-      debug: 4.3.4
+      debug: 4.3.5
       get-uri: 6.0.3
       http-proxy-agent: 7.0.2
       https-proxy-agent: 7.0.4
       get-uri: 6.0.3
       http-proxy-agent: 7.0.2
       https-proxy-agent: 7.0.4
@@ -11461,14 +11513,14 @@ snapshots:
       got: 12.6.1
       registry-auth-token: 4.2.2
       registry-url: 5.1.0
       got: 12.6.1
       registry-auth-token: 4.2.2
       registry-url: 5.1.0
-      semver: 7.6.0
+      semver: 7.6.2
 
   package-json@8.1.1:
     dependencies:
       got: 12.6.1
       registry-auth-token: 5.0.2
       registry-url: 6.0.1
 
   package-json@8.1.1:
     dependencies:
       got: 12.6.1
       registry-auth-token: 5.0.2
       registry-url: 6.0.1
-      semver: 7.6.0
+      semver: 7.6.2
 
   pako@1.0.11: {}
 
 
   pako@1.0.11: {}
 
@@ -11495,7 +11547,7 @@ snapshots:
 
   parse-json@5.2.0:
     dependencies:
 
   parse-json@5.2.0:
     dependencies:
-      '@babel/code-frame': 7.24.2
+      '@babel/code-frame': 7.24.7
       error-ex: 1.3.2
       json-parse-even-better-errors: 2.3.1
       lines-and-columns: 1.2.4
       error-ex: 1.3.2
       json-parse-even-better-errors: 2.3.1
       lines-and-columns: 1.2.4
@@ -11532,10 +11584,10 @@ snapshots:
 
   path-platform@0.11.15: {}
 
 
   path-platform@0.11.15: {}
 
-  path-scurry@1.10.2:
+  path-scurry@1.11.1:
     dependencies:
       lru-cache: 10.2.2
     dependencies:
       lru-cache: 10.2.2
-      minipass: 7.1.0
+      minipass: 7.1.2
 
   path-type@4.0.0: {}
 
 
   path-type@4.0.0: {}
 
@@ -11557,7 +11609,7 @@ snapshots:
 
   pg-connection-string@2.6.2: {}
 
 
   pg-connection-string@2.6.2: {}
 
-  picocolors@1.0.0: {}
+  picocolors@1.0.1: {}
 
   picomatch@2.3.1: {}
 
 
   picomatch@2.3.1: {}
 
@@ -11565,17 +11617,17 @@ snapshots:
 
   pify@2.3.0: {}
 
 
   pify@2.3.0: {}
 
-  pkg-types@1.1.0:
+  pkg-types@1.1.1:
     dependencies:
       confbox: 0.1.7
     dependencies:
       confbox: 0.1.7
-      mlly: 1.7.0
+      mlly: 1.7.1
       pathe: 1.1.2
 
   pkg-up@3.1.0:
     dependencies:
       find-up: 3.0.0
 
       pathe: 1.1.2
 
   pkg-up@3.1.0:
     dependencies:
       find-up: 3.0.0
 
-  poolifier@4.0.2: {}
+  poolifier@4.0.13: {}
 
   possible-typed-array-names@1.0.0: {}
 
 
   possible-typed-array-names@1.0.0: {}
 
@@ -11586,7 +11638,7 @@ snapshots:
       read-cache: 1.0.0
       resolve: 1.22.8
 
       read-cache: 1.0.0
       resolve: 1.22.8
 
-  postcss-selector-parser@6.0.16:
+  postcss-selector-parser@6.1.0:
     dependencies:
       cssesc: 3.0.0
       util-deprecate: 1.0.2
     dependencies:
       cssesc: 3.0.0
       util-deprecate: 1.0.2
@@ -11596,7 +11648,7 @@ snapshots:
   postcss@8.4.38:
     dependencies:
       nanoid: 3.3.7
   postcss@8.4.38:
     dependencies:
       nanoid: 3.3.7
-      picocolors: 1.0.0
+      picocolors: 1.0.1
       source-map-js: 1.2.0
 
   prebuild-install@7.1.2:
       source-map-js: 1.2.0
 
   prebuild-install@7.1.2:
@@ -11607,7 +11659,7 @@ snapshots:
       minimist: 1.2.8
       mkdirp-classic: 0.5.3
       napi-build-utils: 1.0.2
       minimist: 1.2.8
       mkdirp-classic: 0.5.3
       napi-build-utils: 1.0.2
-      node-abi: 3.62.0
+      node-abi: 3.63.0
       pump: 3.0.0
       rc: 1.2.8
       simple-get: 4.0.1
       pump: 3.0.0
       rc: 1.2.8
       simple-get: 4.0.1
@@ -11622,7 +11674,7 @@ snapshots:
     dependencies:
       fast-diff: 1.3.0
 
     dependencies:
       fast-diff: 1.3.0
 
-  prettier@3.2.5: {}
+  prettier@3.3.1: {}
 
   pretty-bytes@5.6.0: {}
 
 
   pretty-bytes@5.6.0: {}
 
@@ -11682,7 +11734,7 @@ snapshots:
   proxy-agent@6.4.0:
     dependencies:
       agent-base: 7.1.1
   proxy-agent@6.4.0:
     dependencies:
       agent-base: 7.1.1
-      debug: 4.3.4
+      debug: 4.3.5
       http-proxy-agent: 7.0.2
       https-proxy-agent: 7.0.4
       lru-cache: 7.18.3
       http-proxy-agent: 7.0.2
       https-proxy-agent: 7.0.4
       lru-cache: 7.18.3
@@ -11835,10 +11887,10 @@ snapshots:
 
   reinterval@1.1.0: {}
 
 
   reinterval@1.1.0: {}
 
-  release-it@17.2.1(typescript@5.4.5):
+  release-it@17.3.0(typescript@5.4.5):
     dependencies:
       '@iarna/toml': 2.2.5
     dependencies:
       '@iarna/toml': 2.2.5
-      '@octokit/rest': 20.1.0
+      '@octokit/rest': 20.1.1
       async-retry: 1.3.3
       chalk: 5.3.0
       cosmiconfig: 9.0.0(typescript@5.4.5)
       async-retry: 1.3.3
       chalk: 5.3.0
       cosmiconfig: 9.0.0(typescript@5.4.5)
@@ -11846,7 +11898,7 @@ snapshots:
       git-url-parse: 14.0.0
       globby: 14.0.1
       got: 12.6.1
       git-url-parse: 14.0.0
       globby: 14.0.1
       got: 12.6.1
-      inquirer: 9.2.19
+      inquirer: 9.2.22
       is-ci: 3.0.1
       issue-parser: 7.0.0
       lodash: 4.17.21
       is-ci: 3.0.1
       issue-parser: 7.0.0
       lodash: 4.17.21
@@ -11858,7 +11910,7 @@ snapshots:
       os-name: 5.1.0
       promise.allsettled: 1.0.7
       proxy-agent: 6.4.0
       os-name: 5.1.0
       promise.allsettled: 1.0.7
       proxy-agent: 6.4.0
-      semver: 7.6.0
+      semver: 7.6.2
       shelljs: 0.8.5
       update-notifier: 7.0.0
       url-join: 5.0.0
       shelljs: 0.8.5
       update-notifier: 7.0.0
       url-join: 5.0.0
@@ -11871,7 +11923,7 @@ snapshots:
   request@2.88.2:
     dependencies:
       aws-sign2: 0.7.0
   request@2.88.2:
     dependencies:
       aws-sign2: 0.7.0
-      aws4: 1.12.0
+      aws4: 1.13.0
       caseless: 0.12.0
       combined-stream: 1.0.8
       extend: 3.0.2
       caseless: 0.12.0
       combined-stream: 1.0.8
       extend: 3.0.2
@@ -11907,11 +11959,6 @@ snapshots:
 
   resolve-pkg-maps@1.0.0: {}
 
 
   resolve-pkg-maps@1.0.0: {}
 
-  resolve@1.19.0:
-    dependencies:
-      is-core-module: 2.13.1
-      path-parse: 1.0.7
-
   resolve@1.22.8:
     dependencies:
       is-core-module: 2.13.1
   resolve@1.22.8:
     dependencies:
       is-core-module: 2.13.1
@@ -11952,39 +11999,41 @@ snapshots:
     dependencies:
       glob: 7.2.3
 
     dependencies:
       glob: 7.2.3
 
-  rimraf@5.0.5:
+  rimraf@5.0.7:
     dependencies:
     dependencies:
-      glob: 10.3.12
+      glob: 10.4.1
 
   ripemd160@2.0.2:
     dependencies:
       hash-base: 3.1.0
       inherits: 2.0.4
 
 
   ripemd160@2.0.2:
     dependencies:
       hash-base: 3.1.0
       inherits: 2.0.4
 
-  rollup@4.17.2:
+  rollup@4.18.0:
     dependencies:
       '@types/estree': 1.0.5
     optionalDependencies:
     dependencies:
       '@types/estree': 1.0.5
     optionalDependencies:
-      '@rollup/rollup-android-arm-eabi': 4.17.2
-      '@rollup/rollup-android-arm64': 4.17.2
-      '@rollup/rollup-darwin-arm64': 4.17.2
-      '@rollup/rollup-darwin-x64': 4.17.2
-      '@rollup/rollup-linux-arm-gnueabihf': 4.17.2
-      '@rollup/rollup-linux-arm-musleabihf': 4.17.2
-      '@rollup/rollup-linux-arm64-gnu': 4.17.2
-      '@rollup/rollup-linux-arm64-musl': 4.17.2
-      '@rollup/rollup-linux-powerpc64le-gnu': 4.17.2
-      '@rollup/rollup-linux-riscv64-gnu': 4.17.2
-      '@rollup/rollup-linux-s390x-gnu': 4.17.2
-      '@rollup/rollup-linux-x64-gnu': 4.17.2
-      '@rollup/rollup-linux-x64-musl': 4.17.2
-      '@rollup/rollup-win32-arm64-msvc': 4.17.2
-      '@rollup/rollup-win32-ia32-msvc': 4.17.2
-      '@rollup/rollup-win32-x64-msvc': 4.17.2
+      '@rollup/rollup-android-arm-eabi': 4.18.0
+      '@rollup/rollup-android-arm64': 4.18.0
+      '@rollup/rollup-darwin-arm64': 4.18.0
+      '@rollup/rollup-darwin-x64': 4.18.0
+      '@rollup/rollup-linux-arm-gnueabihf': 4.18.0
+      '@rollup/rollup-linux-arm-musleabihf': 4.18.0
+      '@rollup/rollup-linux-arm64-gnu': 4.18.0
+      '@rollup/rollup-linux-arm64-musl': 4.18.0
+      '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0
+      '@rollup/rollup-linux-riscv64-gnu': 4.18.0
+      '@rollup/rollup-linux-s390x-gnu': 4.18.0
+      '@rollup/rollup-linux-x64-gnu': 4.18.0
+      '@rollup/rollup-linux-x64-musl': 4.18.0
+      '@rollup/rollup-win32-arm64-msvc': 4.18.0
+      '@rollup/rollup-win32-ia32-msvc': 4.18.0
+      '@rollup/rollup-win32-x64-msvc': 4.18.0
       fsevents: 2.3.3
 
   rrweb-cssom@0.6.0: {}
 
       fsevents: 2.3.3
 
   rrweb-cssom@0.6.0: {}
 
+  rrweb-cssom@0.7.0: {}
+
   run-applescript@7.0.0: {}
 
   run-async@2.4.1: {}
   run-applescript@7.0.0: {}
 
   run-async@2.4.1: {}
@@ -12001,7 +12050,7 @@ snapshots:
 
   rxjs@7.8.1:
     dependencies:
 
   rxjs@7.8.1:
     dependencies:
-      tslib: 2.6.2
+      tslib: 2.6.3
 
   safe-array-concat@1.1.2:
     dependencies:
 
   safe-array-concat@1.1.2:
     dependencies:
@@ -12042,15 +12091,13 @@ snapshots:
 
   semver-diff@3.1.1:
     dependencies:
 
   semver-diff@3.1.1:
     dependencies:
-      semver: 7.6.0
+      semver: 7.6.2
 
   semver-diff@4.0.0:
     dependencies:
 
   semver-diff@4.0.0:
     dependencies:
-      semver: 7.6.0
+      semver: 7.6.2
 
 
-  semver@7.6.0:
-    dependencies:
-      lru-cache: 6.0.0
+  semver@7.6.2: {}
 
   send@0.18.0:
     dependencies:
 
   send@0.18.0:
     dependencies:
@@ -12182,7 +12229,7 @@ snapshots:
   socks-proxy-agent@6.2.1:
     dependencies:
       agent-base: 6.0.2
   socks-proxy-agent@6.2.1:
     dependencies:
       agent-base: 6.0.2
-      debug: 4.3.4
+      debug: 4.3.5
       socks: 2.8.3
     transitivePeerDependencies:
       - supports-color
       socks: 2.8.3
     transitivePeerDependencies:
       - supports-color
@@ -12191,7 +12238,7 @@ snapshots:
   socks-proxy-agent@8.0.3:
     dependencies:
       agent-base: 7.1.1
   socks-proxy-agent@8.0.3:
     dependencies:
       agent-base: 7.1.1
-      debug: 4.3.4
+      debug: 4.3.5
       socks: 2.8.3
     transitivePeerDependencies:
       - supports-color
       socks: 2.8.3
     transitivePeerDependencies:
       - supports-color
@@ -12228,9 +12275,9 @@ snapshots:
   spdx-expression-parse@4.0.0:
     dependencies:
       spdx-exceptions: 2.5.0
   spdx-expression-parse@4.0.0:
     dependencies:
       spdx-exceptions: 2.5.0
-      spdx-license-ids: 3.0.17
+      spdx-license-ids: 3.0.18
 
 
-  spdx-license-ids@3.0.17: {}
+  spdx-license-ids@3.0.18: {}
 
   split2@4.2.0: {}
 
 
   split2@4.2.0: {}
 
@@ -12469,7 +12516,7 @@ snapshots:
   synckit@0.8.8:
     dependencies:
       '@pkgr/core': 0.1.1
   synckit@0.8.8:
     dependencies:
       '@pkgr/core': 0.1.1
-      tslib: 2.6.2
+      tslib: 2.6.3
 
   syntax-error@1.4.0:
     dependencies:
 
   syntax-error@1.4.0:
     dependencies:
@@ -12503,11 +12550,11 @@ snapshots:
       mkdirp: 1.0.4
       yallist: 4.0.0
 
       mkdirp: 1.0.4
       yallist: 4.0.0
 
-  tar@7.1.0:
+  tar@7.2.0:
     dependencies:
       '@isaacs/fs-minipass': 4.0.1
       chownr: 3.0.0
     dependencies:
       '@isaacs/fs-minipass': 4.0.1
       chownr: 3.0.0
-      minipass: 7.1.0
+      minipass: 7.1.2
       minizlib: 3.0.1
       mkdirp: 3.0.1
       yallist: 5.0.0
       minizlib: 3.0.1
       mkdirp: 3.0.1
       yallist: 5.0.0
@@ -12527,6 +12574,12 @@ snapshots:
       glob: 7.2.3
       minimatch: 3.1.2
 
       glob: 7.2.3
       minimatch: 3.1.2
 
+  test-exclude@7.0.1:
+    dependencies:
+      '@istanbuljs/schema': 0.1.3
+      glob: 10.4.1
+      minimatch: 9.0.4
+
   text-extensions@2.4.0: {}
 
   text-hex@1.0.0: {}
   text-extensions@2.4.0: {}
 
   text-hex@1.0.0: {}
@@ -12615,14 +12668,14 @@ snapshots:
       '@ts-morph/common': 0.23.0
       code-block-writer: 13.0.1
 
       '@ts-morph/common': 0.23.0
       code-block-writer: 13.0.1
 
-  ts-node@10.9.2(@types/node@20.12.10)(typescript@5.4.5):
+  ts-node@10.9.2(@types/node@20.14.2)(typescript@5.4.5):
     dependencies:
       '@cspotcode/source-map-support': 0.8.1
       '@tsconfig/node10': 1.0.11
       '@tsconfig/node12': 1.0.11
       '@tsconfig/node14': 1.0.3
       '@tsconfig/node16': 1.0.4
     dependencies:
       '@cspotcode/source-map-support': 0.8.1
       '@tsconfig/node10': 1.0.11
       '@tsconfig/node12': 1.0.11
       '@tsconfig/node14': 1.0.3
       '@tsconfig/node16': 1.0.4
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
       acorn: 8.11.3
       acorn-walk: 8.3.2
       arg: 4.1.3
       acorn: 8.11.3
       acorn-walk: 8.3.2
       arg: 4.1.3
@@ -12648,12 +12701,12 @@ snapshots:
 
   tslib@1.14.1: {}
 
 
   tslib@1.14.1: {}
 
-  tslib@2.6.2: {}
+  tslib@2.6.3: {}
 
 
-  tsx@4.9.3:
+  tsx@4.15.1:
     dependencies:
     dependencies:
-      esbuild: 0.20.2
-      get-tsconfig: 4.7.4
+      esbuild: 0.21.5
+      get-tsconfig: 4.7.5
     optionalDependencies:
       fsevents: 2.3.3
 
     optionalDependencies:
       fsevents: 2.3.3
 
@@ -12694,7 +12747,7 @@ snapshots:
 
   type-fest@2.19.0: {}
 
 
   type-fest@2.19.0: {}
 
-  type@2.7.2: {}
+  type@2.7.3: {}
 
   typed-array-buffer@1.0.2:
     dependencies:
 
   typed-array-buffer@1.0.2:
     dependencies:
@@ -12743,7 +12796,7 @@ snapshots:
 
   ufo@1.5.3: {}
 
 
   ufo@1.5.3: {}
 
-  uglify-js@3.17.4:
+  uglify-js@3.18.0:
     optional: true
 
   umd@3.0.3: {}
     optional: true
 
   umd@3.0.3: {}
@@ -12795,11 +12848,11 @@ snapshots:
 
   unpipe@1.0.0: {}
 
 
   unpipe@1.0.0: {}
 
-  update-browserslist-db@1.0.15(browserslist@4.23.0):
+  update-browserslist-db@1.0.16(browserslist@4.23.1):
     dependencies:
     dependencies:
-      browserslist: 4.23.0
+      browserslist: 4.23.1
       escalade: 3.1.2
       escalade: 3.1.2
-      picocolors: 1.0.0
+      picocolors: 1.0.1
 
   update-notifier@5.1.0:
     dependencies:
 
   update-notifier@5.1.0:
     dependencies:
@@ -12814,7 +12867,7 @@ snapshots:
       is-yarn-global: 0.3.0
       latest-version: 5.1.0
       pupa: 2.1.1
       is-yarn-global: 0.3.0
       latest-version: 5.1.0
       pupa: 2.1.1
-      semver: 7.6.0
+      semver: 7.6.2
       semver-diff: 3.1.1
       xdg-basedir: 4.0.0
 
       semver-diff: 3.1.1
       xdg-basedir: 4.0.0
 
@@ -12829,7 +12882,7 @@ snapshots:
       is-npm: 6.0.0
       latest-version: 7.0.0
       pupa: 3.1.0
       is-npm: 6.0.0
       latest-version: 7.0.0
       pupa: 3.1.0
-      semver: 7.6.0
+      semver: 7.6.2
       semver-diff: 4.0.0
       xdg-basedir: 5.1.0
 
       semver-diff: 4.0.0
       xdg-basedir: 5.1.0
 
@@ -12851,7 +12904,7 @@ snapshots:
       punycode: 1.4.1
       qs: 6.12.1
 
       punycode: 1.4.1
       qs: 6.12.1
 
-  utf-8-validate@6.0.3:
+  utf-8-validate@6.0.4:
     dependencies:
       node-gyp-build: 4.8.1
     optional: true
     dependencies:
       node-gyp-build: 4.8.1
     optional: true
@@ -12894,13 +12947,13 @@ snapshots:
       core-util-is: 1.0.2
       extsprintf: 1.3.0
 
       core-util-is: 1.0.2
       extsprintf: 1.3.0
 
-  vite-node@1.6.0(@types/node@20.12.10):
+  vite-node@1.6.0(@types/node@20.14.2):
     dependencies:
       cac: 6.7.14
     dependencies:
       cac: 6.7.14
-      debug: 4.3.4
+      debug: 4.3.5
       pathe: 1.1.2
       pathe: 1.1.2
-      picocolors: 1.0.0
-      vite: 5.2.11(@types/node@20.12.10)
+      picocolors: 1.0.1
+      vite: 5.2.13(@types/node@20.14.2)
     transitivePeerDependencies:
       - '@types/node'
       - less
     transitivePeerDependencies:
       - '@types/node'
       - less
@@ -12911,16 +12964,16 @@ snapshots:
       - supports-color
       - terser
 
       - supports-color
       - terser
 
-  vite@5.2.11(@types/node@20.12.10):
+  vite@5.2.13(@types/node@20.14.2):
     dependencies:
       esbuild: 0.20.2
       postcss: 8.4.38
     dependencies:
       esbuild: 0.20.2
       postcss: 8.4.38
-      rollup: 4.17.2
+      rollup: 4.18.0
     optionalDependencies:
     optionalDependencies:
-      '@types/node': 20.12.10
+      '@types/node': 20.14.2
       fsevents: 2.3.3
 
       fsevents: 2.3.3
 
-  vitest@1.6.0(@types/node@20.12.10)(jsdom@24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)):
+  vitest@1.6.0(@types/node@20.14.2)(jsdom@24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)):
     dependencies:
       '@vitest/expect': 1.6.0
       '@vitest/runner': 1.6.0
     dependencies:
       '@vitest/expect': 1.6.0
       '@vitest/runner': 1.6.0
@@ -12929,22 +12982,22 @@ snapshots:
       '@vitest/utils': 1.6.0
       acorn-walk: 8.3.2
       chai: 4.4.1
       '@vitest/utils': 1.6.0
       acorn-walk: 8.3.2
       chai: 4.4.1
-      debug: 4.3.4
+      debug: 4.3.5
       execa: 8.0.1
       local-pkg: 0.5.0
       magic-string: 0.30.10
       pathe: 1.1.2
       execa: 8.0.1
       local-pkg: 0.5.0
       magic-string: 0.30.10
       pathe: 1.1.2
-      picocolors: 1.0.0
+      picocolors: 1.0.1
       std-env: 3.7.0
       strip-literal: 2.1.0
       tinybench: 2.8.0
       tinypool: 0.8.4
       std-env: 3.7.0
       strip-literal: 2.1.0
       tinybench: 2.8.0
       tinypool: 0.8.4
-      vite: 5.2.11(@types/node@20.12.10)
-      vite-node: 1.6.0(@types/node@20.12.10)
+      vite: 5.2.13(@types/node@20.14.2)
+      vite-node: 1.6.0(@types/node@20.14.2)
       why-is-node-running: 2.2.2
     optionalDependencies:
       why-is-node-running: 2.2.2
     optionalDependencies:
-      '@types/node': 20.12.10
-      jsdom: 24.0.0(bufferutil@4.0.8)(utf-8-validate@6.0.3)
+      '@types/node': 20.14.2
+      jsdom: 24.1.0(bufferutil@4.0.8)(utf-8-validate@6.0.4)
     transitivePeerDependencies:
       - less
       - lightningcss
     transitivePeerDependencies:
       - less
       - lightningcss
@@ -12956,24 +13009,24 @@ snapshots:
 
   vm-browserify@1.1.2: {}
 
 
   vm-browserify@1.1.2: {}
 
-  vue-component-type-helpers@2.0.16: {}
+  vue-component-type-helpers@2.0.21: {}
 
 
-  vue-eslint-parser@9.4.2(eslint@8.57.0):
+  vue-eslint-parser@9.4.3(eslint@8.57.0):
     dependencies:
     dependencies:
-      debug: 4.3.4
+      debug: 4.3.5
       eslint: 8.57.0
       eslint-scope: 7.2.2
       eslint-visitor-keys: 3.4.3
       espree: 9.6.1
       esquery: 1.5.0
       lodash: 4.17.21
       eslint: 8.57.0
       eslint-scope: 7.2.2
       eslint-visitor-keys: 3.4.3
       espree: 9.6.1
       esquery: 1.5.0
       lodash: 4.17.21
-      semver: 7.6.0
+      semver: 7.6.2
     transitivePeerDependencies:
       - supports-color
 
     transitivePeerDependencies:
       - supports-color
 
-  vue-router@4.3.2(vue@3.4.27(typescript@5.4.5)):
+  vue-router@4.3.3(vue@3.4.27(typescript@5.4.5)):
     dependencies:
     dependencies:
-      '@vue/devtools-api': 6.6.1
+      '@vue/devtools-api': 6.6.3
       vue: 3.4.27(typescript@5.4.5)
 
   vue-toast-notification@3.1.2(vue@3.4.27(typescript@5.4.5)):
       vue: 3.4.27(typescript@5.4.5)
 
   vue-toast-notification@3.1.2(vue@3.4.27(typescript@5.4.5)):
@@ -13148,10 +13201,10 @@ snapshots:
       signal-exit: 3.0.7
       typedarray-to-buffer: 3.1.5
 
       signal-exit: 3.0.7
       typedarray-to-buffer: 3.1.5
 
-  ws@8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.3):
+  ws@8.17.0(bufferutil@4.0.8)(utf-8-validate@6.0.4):
     optionalDependencies:
       bufferutil: 4.0.8
     optionalDependencies:
       bufferutil: 4.0.8
-      utf-8-validate: 6.0.3
+      utf-8-validate: 6.0.4
 
   xdg-basedir@4.0.0: {}
 
 
   xdg-basedir@4.0.0: {}
 
@@ -13175,7 +13228,7 @@ snapshots:
 
   yallist@5.0.0: {}
 
 
   yallist@5.0.0: {}
 
-  yaml@2.3.4: {}
+  yaml@2.4.5: {}
 
   yargs-parser@15.0.3:
     dependencies:
 
   yargs-parser@15.0.3:
     dependencies:
index e181f0e008798cb6151a924d13807f4e1d1f8e60..fb2477d707f2b57a8f3bb0760a775a92f13ee5b2 100644 (file)
@@ -1,6 +1,6 @@
 import { env, exit } from 'node:process'
 
 import { env, exit } from 'node:process'
 
-const skipPreinstall = parseInt(env.SKIP_PREINSTALL) || env.VCAP_APPLICATION != null
+const skipPreinstall = Number.parseInt(env.SKIP_PREINSTALL) || env.VCAP_APPLICATION != null
 if (skipPreinstall) {
   // eslint-disable-next-line n/no-process-exit
   exit()
 if (skipPreinstall) {
   // eslint-disable-next-line n/no-process-exit
   exit()
index e17480be1567f9cf9aca9a4c17d8ff81f1ba31a1..d614cceb9ec1759f45ecc5e376f595e46baa6f93 100644 (file)
@@ -3,7 +3,7 @@ sonar.organization=sap-1
 
 # This is the name and version displayed in the SonarCloud UI.
 sonar.projectName=e-mobility-charging-stations-simulator
 
 # This is the name and version displayed in the SonarCloud UI.
 sonar.projectName=e-mobility-charging-stations-simulator
-sonar.projectVersion=1.3.3
+sonar.projectVersion=1.3.6
 
 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
 sonar.sources=src
 
 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
 sonar.sources=src
index da32bbcbe72fd610919fc704ab5e1cb21234d5a1..e172ad29bbd5386c843a558f37b4f0080b92807c 100644 (file)
         "username": "admin",
         "password": "admin"
       },
         "username": "admin",
         "password": "admin"
       },
-      "dataPropertyOrder": { "&": ["baseUrl", "protocol", "version", "username", "password"] },
+      "dataPropertyOrder": {
+        "&": ["baseUrl", "protocol", "version", "username", "password"]
+      },
       "color": null,
       "isPrivate": false,
       "metaSortKey": 1661789025528,
       "color": null,
       "isPrivate": false,
       "metaSortKey": 1661789025528,
index 1312150c6d97b57eae80ffe854adbb4c42fd283f..3d9a5405f723c131bc6cdd607fe6910c9722a867 100644 (file)
         "protocol": "ui",
         "version": "0.0.1"
       },
         "protocol": "ui",
         "version": "0.0.1"
       },
-      "dataPropertyOrder": { "&": ["baseUrl", "username", "password", "protocol", "version"] },
+      "dataPropertyOrder": {
+        "&": ["baseUrl", "username", "password", "protocol", "version"]
+      },
       "color": null,
       "isPrivate": false,
       "metaSortKey": 1671183662529,
       "color": null,
       "isPrivate": false,
       "metaSortKey": 1671183662529,
index 4b9b8f6cdbd6ef55cf4bf4fdf65a804640b1b6d1..9f1c4d39af45133373e889711eab2739e8c11da4 100644 (file)
@@ -8,6 +8,7 @@ import { BaseError } from '../exception/index.js'
 import { PerformanceStatistics } from '../performance/index.js'
 import {
   AuthorizationStatus,
 import { PerformanceStatistics } from '../performance/index.js'
 import {
   AuthorizationStatus,
+  ChargingStationEvents,
   RequestCommand,
   type StartTransactionRequest,
   type StartTransactionResponse,
   RequestCommand,
   type StartTransactionRequest,
   type StartTransactionResponse,
@@ -262,9 +263,10 @@ export class AutomaticTransactionGenerator {
       )}`
     )
     logger.debug(
       )}`
     )
     logger.debug(
-      `${this.logPrefix(connectorId)} connector status: %j`,
+      `${this.logPrefix(connectorId)} stopped with connector status: %j`,
       this.connectorsStatus.get(connectorId)
     )
       this.connectorsStatus.get(connectorId)
     )
+    this.chargingStation.emit(ChargingStationEvents.updated)
   }
 
   private setStartConnectorStatus (
   }
 
   private setStartConnectorStatus (
@@ -294,6 +296,7 @@ export class AutomaticTransactionGenerator {
     this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.connectorsStatus.get(connectorId)!.start = true
     this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.connectorsStatus.get(connectorId)!.start = true
+    this.chargingStation.emit(ChargingStationEvents.updated)
   }
 
   private canStartConnector (connectorId: number): boolean {
   }
 
   private canStartConnector (connectorId: number): boolean {
@@ -333,9 +336,9 @@ export class AutomaticTransactionGenerator {
     const connectorStatus = this.chargingStation.getConnectorStatus(connectorId)
     if (connectorStatus?.transactionStarted === true) {
       logger.info(
     const connectorStatus = this.chargingStation.getConnectorStatus(connectorId)
     if (connectorStatus?.transactionStarted === true) {
       logger.info(
-        `${this.logPrefix(
-          connectorId
-        )} entered in transaction loop while a transaction ${connectorStatus.transactionId} is already started on connector ${connectorId}`
+        `${this.logPrefix(connectorId)} entered in transaction loop while a transaction ${
+          connectorStatus.transactionId
+        } is already started on connector ${connectorId}`
       )
       return false
     }
       )
       return false
     }
@@ -378,9 +381,9 @@ export class AutomaticTransactionGenerator {
     while (connectorStatus?.transactionStarted === true) {
       if (!logged) {
         logger.info(
     while (connectorStatus?.transactionStarted === true) {
       if (!logged) {
         logger.info(
-          `${this.logPrefix(
-            connectorId
-          )} transaction loop waiting for started transaction ${connectorStatus.transactionId} on connector ${connectorId} to be stopped`
+          `${this.logPrefix(connectorId)} transaction loop waiting for started transaction ${
+            connectorStatus.transactionId
+          } on connector ${connectorId} to be stopped`
         )
         logged = true
       }
         )
         logged = true
       }
@@ -408,15 +411,21 @@ export class AutomaticTransactionGenerator {
 
   private getConnectorStatus (connectorId: number): Status {
     const statusIndex = connectorId - 1
 
   private getConnectorStatus (connectorId: number): Status {
     const statusIndex = connectorId - 1
+    if (statusIndex < 0) {
+      logger.error(`${this.logPrefix(connectorId)} invalid connector id`)
+      throw new BaseError(`Invalid connector id ${connectorId}`)
+    }
     let connectorStatus: Status | undefined
     if (this.chargingStation.getAutomaticTransactionGeneratorStatuses()?.[statusIndex] != null) {
       connectorStatus = clone<Status>(
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         this.chargingStation.getAutomaticTransactionGeneratorStatuses()![statusIndex]
       )
     let connectorStatus: Status | undefined
     if (this.chargingStation.getAutomaticTransactionGeneratorStatuses()?.[statusIndex] != null) {
       connectorStatus = clone<Status>(
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         this.chargingStation.getAutomaticTransactionGeneratorStatuses()![statusIndex]
       )
-    } else if (this.chargingStation.getAutomaticTransactionGeneratorStatuses() != null) {
+    } else {
       logger.warn(
       logger.warn(
-        `${this.logPrefix(connectorId)} no status found for connector #${connectorId} in charging station configuration file. New status will be created`
+        `${this.logPrefix(
+          connectorId
+        )} no status found for connector #${connectorId} in charging station configuration file. New status will be created`
       )
     }
     if (connectorStatus != null) {
       )
     }
     if (connectorStatus != null) {
@@ -507,7 +516,9 @@ export class AutomaticTransactionGenerator {
     startResponse = await this.chargingStation.ocppRequestService.requestHandler<
     Partial<StartTransactionRequest>,
     StartTransactionResponse
     startResponse = await this.chargingStation.ocppRequestService.requestHandler<
     Partial<StartTransactionRequest>,
     StartTransactionResponse
-    >(this.chargingStation, RequestCommand.START_TRANSACTION, { connectorId })
+    >(this.chargingStation, RequestCommand.START_TRANSACTION, {
+      connectorId
+    })
     this.handleStartTransactionResponse(connectorId, startResponse)
     PerformanceStatistics.endMeasure(measureId, beginId)
     return startResponse
     this.handleStartTransactionResponse(connectorId, startResponse)
     PerformanceStatistics.endMeasure(measureId, beginId)
     return startResponse
index 5293a9a83c28a9a1791f166606d3ca275f2cbb67..d12f78f9b326e79152a11e33d3ccf9f09f2bd2d6 100644 (file)
@@ -225,9 +225,13 @@ export class Bootstrap extends EventEmitter {
         )
         console.info(
           chalk.green(
         )
         console.info(
           chalk.green(
-            `Charging stations simulator ${
-              this.version
-            } started with ${this.numberOfConfiguredChargingStations} configured and ${this.numberOfProvisionedChargingStations} provisioned charging station(s) from ${this.numberOfChargingStationTemplates} charging station template(s) and ${
+            `Charging stations simulator ${this.version} started with ${
+              this.numberOfConfiguredChargingStations
+            } configured and ${
+              this.numberOfProvisionedChargingStations
+            } provisioned charging station(s) from ${
+              this.numberOfChargingStationTemplates
+            } charging station template(s) and ${
               Configuration.workerDynamicPoolInUse() ? `${workerConfiguration.poolMinSize}/` : ''
             }${this.workerImplementation?.size}${
               Configuration.workerPoolInUse() ? `/${workerConfiguration.poolMaxSize}` : ''
               Configuration.workerDynamicPoolInUse() ? `${workerConfiguration.poolMinSize}/` : ''
             }${this.workerImplementation?.size}${
               Configuration.workerPoolInUse() ? `/${workerConfiguration.poolMaxSize}` : ''
@@ -373,7 +377,9 @@ export class Bootstrap extends EventEmitter {
         poolOptions: {
           messageHandler: this.messageHandler.bind(this) as MessageHandler<Worker>,
           ...(workerConfiguration.resourceLimits != null && {
         poolOptions: {
           messageHandler: this.messageHandler.bind(this) as MessageHandler<Worker>,
           ...(workerConfiguration.resourceLimits != null && {
-            workerOptions: { resourceLimits: workerConfiguration.resourceLimits }
+            workerOptions: {
+              resourceLimits: workerConfiguration.resourceLimits
+            }
           })
         }
       }
           })
         }
       }
@@ -418,7 +424,11 @@ export class Bootstrap extends EventEmitter {
           break
         default:
           throw new BaseError(
           break
         default:
           throw new BaseError(
-            `Unknown charging station worker message event: '${event}' received with data: ${JSON.stringify(data, undefined, 2)}`
+            `Unknown charging station worker message event: '${event}' received with data: ${JSON.stringify(
+              data,
+              undefined,
+              2
+            )}`
           )
       }
     } catch (error) {
           )
       }
     } catch (error) {
@@ -436,7 +446,9 @@ export class Bootstrap extends EventEmitter {
         data.stationInfo.chargingStationId
       } (hashId: ${data.stationInfo.hashId}) added (${
         this.numberOfAddedChargingStations
         data.stationInfo.chargingStationId
       } (hashId: ${data.stationInfo.hashId}) added (${
         this.numberOfAddedChargingStations
-      } added from ${this.numberOfConfiguredChargingStations} configured and ${this.numberOfProvisionedChargingStations} provisioned charging station(s))`
+      } added from ${this.numberOfConfiguredChargingStations} configured and ${
+        this.numberOfProvisionedChargingStations
+      } provisioned charging station(s))`
     )
   }
 
     )
   }
 
@@ -451,7 +463,9 @@ export class Bootstrap extends EventEmitter {
         data.stationInfo.chargingStationId
       } (hashId: ${data.stationInfo.hashId}) deleted (${
         this.numberOfAddedChargingStations
         data.stationInfo.chargingStationId
       } (hashId: ${data.stationInfo.hashId}) deleted (${
         this.numberOfAddedChargingStations
-      } added from ${this.numberOfConfiguredChargingStations} configured and ${this.numberOfProvisionedChargingStations} provisioned charging station(s))`
+      } added from ${this.numberOfConfiguredChargingStations} configured and ${
+        this.numberOfProvisionedChargingStations
+      } provisioned charging station(s))`
     )
   }
 
     )
   }
 
index 080349eae731cbe27e9ba6b00354da0d40a66f7e..e217991ac8aad3c7c4256010687929df0f0162a3 100644 (file)
@@ -120,8 +120,9 @@ import {
   createSerialNumber,
   getAmperageLimitationUnitDivider,
   getBootConnectorStatus,
   createSerialNumber,
   getAmperageLimitationUnitDivider,
   getBootConnectorStatus,
-  getChargingStationConnectorChargingProfilesPowerLimit,
+  getChargingStationChargingProfilesLimit,
   getChargingStationId,
   getChargingStationId,
+  getConnectorChargingProfilesLimit,
   getDefaultVoltageOut,
   getHashId,
   getIdTagsFile,
   getDefaultVoltageOut,
   getHashId,
   getIdTagsFile,
@@ -131,6 +132,7 @@ import {
   hasFeatureProfile,
   hasReservationExpired,
   initializeConnectorsMapStatus,
   hasFeatureProfile,
   hasReservationExpired,
   initializeConnectorsMapStatus,
+  prepareConnectorStatus,
   propagateSerialNumber,
   setChargingStationOptions,
   stationTemplateToStationInfo,
   propagateSerialNumber,
   setChargingStationOptions,
   stationTemplateToStationInfo,
@@ -181,7 +183,6 @@ export class ChargingStation extends EventEmitter {
   private ocppIncomingRequestService!: OCPPIncomingRequestService
   private readonly messageBuffer: Set<string>
   private configuredSupervisionUrl!: URL
   private ocppIncomingRequestService!: OCPPIncomingRequestService
   private readonly messageBuffer: Set<string>
   private configuredSupervisionUrl!: URL
-  private wsConnectionRetried: boolean
   private wsConnectionRetryCount: number
   private templateFileWatcher?: FSWatcher
   private templateFileHash!: string
   private wsConnectionRetryCount: number
   private templateFileWatcher?: FSWatcher
   private templateFileHash!: string
@@ -196,7 +197,6 @@ export class ChargingStation extends EventEmitter {
     this.starting = false
     this.stopping = false
     this.wsConnection = null
     this.starting = false
     this.stopping = false
     this.wsConnection = null
-    this.wsConnectionRetried = false
     this.wsConnectionRetryCount = 0
     this.index = index
     this.templateFile = templateFile
     this.wsConnectionRetryCount = 0
     this.index = index
     this.templateFile = templateFile
@@ -225,16 +225,21 @@ export class ChargingStation extends EventEmitter {
     })
     this.on(ChargingStationEvents.accepted, () => {
       this.startMessageSequence(
     })
     this.on(ChargingStationEvents.accepted, () => {
       this.startMessageSequence(
-        this.wsConnectionRetried
+        this.wsConnectionRetryCount > 0
           ? true
           : this.getAutomaticTransactionGeneratorConfiguration()?.stopAbsoluteDuration
       ).catch((error: unknown) => {
         logger.error(`${this.logPrefix()} Error while starting the message sequence:`, error)
       })
           ? true
           : this.getAutomaticTransactionGeneratorConfiguration()?.stopAbsoluteDuration
       ).catch((error: unknown) => {
         logger.error(`${this.logPrefix()} Error while starting the message sequence:`, error)
       })
-      this.wsConnectionRetried = false
+      this.wsConnectionRetryCount = 0
     })
     this.on(ChargingStationEvents.rejected, () => {
     })
     this.on(ChargingStationEvents.rejected, () => {
-      this.wsConnectionRetried = false
+      this.wsConnectionRetryCount = 0
+    })
+    this.on(ChargingStationEvents.connected, () => {
+      if (this.wsPingSetInterval == null) {
+        this.startWebSocketPing()
+      }
     })
     this.on(ChargingStationEvents.disconnected, () => {
       try {
     })
     this.on(ChargingStationEvents.disconnected, () => {
       try {
@@ -269,7 +274,9 @@ export class ChargingStation extends EventEmitter {
         : this.configuredSupervisionUrl.href
     }`
     return new URL(
         : this.configuredSupervisionUrl.href
     }`
     return new URL(
-      `${wsConnectionBaseUrlStr}${!wsConnectionBaseUrlStr.endsWith('/') ? '/' : ''}${this.stationInfo?.chargingStationId}`
+      `${wsConnectionBaseUrlStr}${
+        !wsConnectionBaseUrlStr.endsWith('/') ? '/' : ''
+      }${this.stationInfo?.chargingStationId}`
     )
   }
 
     )
   }
 
@@ -385,14 +392,14 @@ export class ChargingStation extends EventEmitter {
   }
 
   public getConnectorMaximumAvailablePower (connectorId: number): number {
   }
 
   public getConnectorMaximumAvailablePower (connectorId: number): number {
-    let connectorAmperageLimitationPowerLimit: number | undefined
+    let connectorAmperageLimitationLimit: number | undefined
     const amperageLimitation = this.getAmperageLimitation()
     if (
       amperageLimitation != null &&
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       amperageLimitation < this.stationInfo!.maximumAmperage!
     ) {
     const amperageLimitation = this.getAmperageLimitation()
     if (
       amperageLimitation != null &&
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       amperageLimitation < this.stationInfo!.maximumAmperage!
     ) {
-      connectorAmperageLimitationPowerLimit =
+      connectorAmperageLimitationLimit =
         (this.stationInfo?.currentOutType === CurrentType.AC
           ? ACElectricUtils.powerTotal(
             this.getNumberOfPhases(),
         (this.stationInfo?.currentOutType === CurrentType.AC
           ? ACElectricUtils.powerTotal(
             this.getNumberOfPhases(),
@@ -408,17 +415,25 @@ export class ChargingStation extends EventEmitter {
     }
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     const connectorMaximumPower = this.stationInfo!.maximumPower! / this.powerDivider!
     }
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     const connectorMaximumPower = this.stationInfo!.maximumPower! / this.powerDivider!
-    const connectorChargingProfilesPowerLimit =
-      getChargingStationConnectorChargingProfilesPowerLimit(this, connectorId)
+    const chargingStationChargingProfilesLimit =
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      getChargingStationChargingProfilesLimit(this)! / this.powerDivider!
+    const connectorChargingProfilesLimit = getConnectorChargingProfilesLimit(this, connectorId)
     return min(
     return min(
-      isNaN(connectorMaximumPower) ? Infinity : connectorMaximumPower,
+      isNaN(connectorMaximumPower) ? Number.POSITIVE_INFINITY : connectorMaximumPower,
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      isNaN(connectorAmperageLimitationPowerLimit!)
-        ? Infinity
+      isNaN(connectorAmperageLimitationLimit!)
+        ? Number.POSITIVE_INFINITY
         : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        connectorAmperageLimitationPowerLimit!,
+        connectorAmperageLimitationLimit!,
+      isNaN(chargingStationChargingProfilesLimit)
+        ? Number.POSITIVE_INFINITY
+        : chargingStationChargingProfilesLimit,
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      isNaN(connectorChargingProfilesPowerLimit!) ? Infinity : connectorChargingProfilesPowerLimit!
+      isNaN(connectorChargingProfilesLimit!)
+        ? Number.POSITIVE_INFINITY
+        : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        connectorChargingProfilesLimit!
     )
   }
 
     )
   }
 
@@ -549,7 +564,8 @@ export class ChargingStation extends EventEmitter {
   }
 
   public startHeartbeat (): void {
   }
 
   public startHeartbeat (): void {
-    if (this.getHeartbeatInterval() > 0 && this.heartbeatSetInterval == null) {
+    const heartbeatInterval = this.getHeartbeatInterval()
+    if (heartbeatInterval > 0 && this.heartbeatSetInterval == null) {
       this.heartbeatSetInterval = setInterval(() => {
         this.ocppRequestService
           .requestHandler<HeartbeatRequest, HeartbeatResponse>(this, RequestCommand.HEARTBEAT)
       this.heartbeatSetInterval = setInterval(() => {
         this.ocppRequestService
           .requestHandler<HeartbeatRequest, HeartbeatResponse>(this, RequestCommand.HEARTBEAT)
@@ -559,21 +575,21 @@ export class ChargingStation extends EventEmitter {
               error
             )
           })
               error
             )
           })
-      }, this.getHeartbeatInterval())
+      }, heartbeatInterval)
       logger.info(
         `${this.logPrefix()} Heartbeat started every ${formatDurationMilliSeconds(
       logger.info(
         `${this.logPrefix()} Heartbeat started every ${formatDurationMilliSeconds(
-          this.getHeartbeatInterval()
+          heartbeatInterval
         )}`
       )
     } else if (this.heartbeatSetInterval != null) {
       logger.info(
         `${this.logPrefix()} Heartbeat already started every ${formatDurationMilliSeconds(
         )}`
       )
     } else if (this.heartbeatSetInterval != null) {
       logger.info(
         `${this.logPrefix()} Heartbeat already started every ${formatDurationMilliSeconds(
-          this.getHeartbeatInterval()
+          heartbeatInterval
         )}`
       )
     } else {
       logger.error(
         )}`
       )
     } else {
       logger.error(
-        `${this.logPrefix()} Heartbeat interval set to ${this.getHeartbeatInterval()}, not starting the heartbeat`
+        `${this.logPrefix()} Heartbeat interval set to ${heartbeatInterval}, not starting the heartbeat`
       )
     }
   }
       )
     }
   }
@@ -661,6 +677,11 @@ export class ChargingStation extends EventEmitter {
     }
   }
 
     }
   }
 
+  public restartMeterValues (connectorId: number, interval: number): void {
+    this.stopMeterValues(connectorId)
+    this.startMeterValues(connectorId, interval)
+  }
+
   private add (): void {
     this.emit(ChargingStationEvents.added)
   }
   private add (): void {
     this.emit(ChargingStationEvents.added)
   }
@@ -1359,7 +1380,9 @@ export class ChargingStation extends EventEmitter {
       addConfigurationKey(this, StandardParametersKey.HeartbeatInterval, '0')
     }
     if (getConfigurationKey(this, StandardParametersKey.HeartBeatInterval) == null) {
       addConfigurationKey(this, StandardParametersKey.HeartbeatInterval, '0')
     }
     if (getConfigurationKey(this, StandardParametersKey.HeartBeatInterval) == null) {
-      addConfigurationKey(this, StandardParametersKey.HeartBeatInterval, '0', { visible: false })
+      addConfigurationKey(this, StandardParametersKey.HeartBeatInterval, '0', {
+        visible: false
+      })
     }
     if (
       this.stationInfo?.supervisionUrlOcppConfiguration === true &&
     }
     if (
       this.stationInfo?.supervisionUrlOcppConfiguration === true &&
@@ -1377,7 +1400,9 @@ export class ChargingStation extends EventEmitter {
       isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
       getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey) != null
     ) {
       isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
       getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey) != null
     ) {
-      deleteConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey, { save: false })
+      deleteConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey, {
+        save: false
+      })
     }
     if (
       isNotEmptyString(this.stationInfo?.amperageLimitationOcppKey) &&
     }
     if (
       isNotEmptyString(this.stationInfo?.amperageLimitationOcppKey) &&
@@ -1459,7 +1484,10 @@ export class ChargingStation extends EventEmitter {
   private initializeConnectorsOrEvsesFromFile (configuration: ChargingStationConfiguration): void {
     if (configuration.connectorsStatus != null && configuration.evsesStatus == null) {
       for (const [connectorId, connectorStatus] of configuration.connectorsStatus.entries()) {
   private initializeConnectorsOrEvsesFromFile (configuration: ChargingStationConfiguration): void {
     if (configuration.connectorsStatus != null && configuration.evsesStatus == null) {
       for (const [connectorId, connectorStatus] of configuration.connectorsStatus.entries()) {
-        this.connectors.set(connectorId, clone<ConnectorStatus>(connectorStatus))
+        this.connectors.set(
+          connectorId,
+          prepareConnectorStatus(clone<ConnectorStatus>(connectorStatus))
+        )
       }
     } else if (configuration.evsesStatus != null && configuration.connectorsStatus == null) {
       for (const [evseId, evseStatusConfiguration] of configuration.evsesStatus.entries()) {
       }
     } else if (configuration.evsesStatus != null && configuration.connectorsStatus == null) {
       for (const [evseId, evseStatusConfiguration] of configuration.evsesStatus.entries()) {
@@ -1471,7 +1499,7 @@ export class ChargingStation extends EventEmitter {
             // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
             evseStatusConfiguration.connectorsStatus!.map((connectorStatus, connectorId) => [
               connectorId,
             // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
             evseStatusConfiguration.connectorsStatus!.map((connectorStatus, connectorId) => [
               connectorId,
-              connectorStatus
+              prepareConnectorStatus(connectorStatus)
             ])
           )
         })
             ])
           )
         })
@@ -1736,7 +1764,9 @@ export class ChargingStation extends EventEmitter {
               ...(this.connectors.size > 0 && {
                 connectorsStatus: configurationData.connectorsStatus
               }),
               ...(this.connectors.size > 0 && {
                 connectorsStatus: configurationData.connectorsStatus
               }),
-              ...(this.evses.size > 0 && { evsesStatus: configurationData.evsesStatus })
+              ...(this.evses.size > 0 && {
+                evsesStatus: configurationData.evsesStatus
+              })
             } satisfies ChargingStationConfiguration)
           )
           .digest('hex')
             } satisfies ChargingStationConfiguration)
           )
           .digest('hex')
@@ -1811,27 +1841,27 @@ export class ChargingStation extends EventEmitter {
 
   private async onOpen (): Promise<void> {
     if (this.isWebSocketConnectionOpened()) {
 
   private async onOpen (): Promise<void> {
     if (this.isWebSocketConnectionOpened()) {
+      this.emit(ChargingStationEvents.connected)
       this.emit(ChargingStationEvents.updated)
       logger.info(
       this.emit(ChargingStationEvents.updated)
       logger.info(
-        `${this.logPrefix()} Connection to OCPP server through ${this.wsConnectionUrl.href} succeeded`
+        `${this.logPrefix()} Connection to OCPP server through ${
+          this.wsConnectionUrl.href
+        } succeeded`
       )
       let registrationRetryCount = 0
       if (!this.isRegistered()) {
         // Send BootNotification
         do {
       )
       let registrationRetryCount = 0
       if (!this.isRegistered()) {
         // Send BootNotification
         do {
-          this.bootNotificationResponse = await this.ocppRequestService.requestHandler<
+          await this.ocppRequestService.requestHandler<
           BootNotificationRequest,
           BootNotificationResponse
           >(this, RequestCommand.BOOT_NOTIFICATION, this.bootNotificationRequest, {
             skipBufferingOnError: true
           })
           BootNotificationRequest,
           BootNotificationResponse
           >(this, RequestCommand.BOOT_NOTIFICATION, this.bootNotificationRequest, {
             skipBufferingOnError: true
           })
-          // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
-          if (this.bootNotificationResponse?.currentTime != null) {
-            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-            this.bootNotificationResponse.currentTime = convertToDate(
-              this.bootNotificationResponse.currentTime
-            )!
-          }
+          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+          this.bootNotificationResponse!.currentTime = convertToDate(
+            this.bootNotificationResponse?.currentTime
+          )!
           if (!this.isRegistered()) {
             this.stationInfo?.registrationMaxRetries !== -1 && ++registrationRetryCount
             await sleep(
           if (!this.isRegistered()) {
             this.stationInfo?.registrationMaxRetries !== -1 && ++registrationRetryCount
             await sleep(
@@ -1848,22 +1878,13 @@ export class ChargingStation extends EventEmitter {
             this.stationInfo?.registrationMaxRetries === -1)
         )
       }
             this.stationInfo?.registrationMaxRetries === -1)
         )
       }
-      if (this.isRegistered()) {
-        this.emit(ChargingStationEvents.registered)
-        if (this.inAcceptedState()) {
-          this.emit(ChargingStationEvents.accepted)
-        }
-      } else {
-        if (this.inRejectedState()) {
-          this.emit(ChargingStationEvents.rejected)
-        }
+      if (!this.isRegistered()) {
         logger.error(
           `${this.logPrefix()} Registration failure: maximum retries reached (${registrationRetryCount}) or retry disabled (${
             this.stationInfo?.registrationMaxRetries
           })`
         )
       }
         logger.error(
           `${this.logPrefix()} Registration failure: maximum retries reached (${registrationRetryCount}) or retry disabled (${
             this.stationInfo?.registrationMaxRetries
           })`
         )
       }
-      this.wsConnectionRetryCount = 0
       this.emit(ChargingStationEvents.updated)
     } else {
       logger.warn(
       this.emit(ChargingStationEvents.updated)
     } else {
       logger.warn(
@@ -1915,7 +1936,7 @@ export class ChargingStation extends EventEmitter {
     }
     throw new OCPPError(
       ErrorType.PROTOCOL_ERROR,
     }
     throw new OCPPError(
       ErrorType.PROTOCOL_ERROR,
-      `Cached request for message id ${messageId} ${getMessageTypeString(
+      `Cached request for message id '${messageId}' ${getMessageTypeString(
         messageType
       )} is not an array`,
       undefined,
         messageType
       )} is not an array`,
       undefined,
@@ -1925,6 +1946,14 @@ export class ChargingStation extends EventEmitter {
 
   private async handleIncomingMessage (request: IncomingRequest): Promise<void> {
     const [messageType, messageId, commandName, commandPayload] = request
 
   private async handleIncomingMessage (request: IncomingRequest): Promise<void> {
     const [messageType, messageId, commandName, commandPayload] = request
+    if (this.requests.has(messageId)) {
+      throw new OCPPError(
+        ErrorType.SECURITY_ERROR,
+        `Received message with duplicate message id '${messageId}'`,
+        commandName,
+        commandPayload
+      )
+    }
     if (this.stationInfo?.enableStatistics === true) {
       this.performanceStatistics?.addRequestStatistic(commandName, messageType)
     }
     if (this.stationInfo?.enableStatistics === true) {
       this.performanceStatistics?.addRequestStatistic(commandName, messageType)
     }
@@ -1949,7 +1978,7 @@ export class ChargingStation extends EventEmitter {
       // Error
       throw new OCPPError(
         ErrorType.INTERNAL_ERROR,
       // Error
       throw new OCPPError(
         ErrorType.INTERNAL_ERROR,
-        `Response for unknown message id ${messageId}`,
+        `Response for unknown message id '${messageId}'`,
         undefined,
         commandPayload
       )
         undefined,
         commandPayload
       )
@@ -1974,7 +2003,7 @@ export class ChargingStation extends EventEmitter {
       // Error
       throw new OCPPError(
         ErrorType.INTERNAL_ERROR,
       // Error
       throw new OCPPError(
         ErrorType.INTERNAL_ERROR,
-        `Error response for unknown message id ${messageId}`,
+        `Error response for unknown message id '${messageId}'`,
         undefined,
         { errorType, errorMessage, errorDetails }
       )
         undefined,
         { errorType, errorMessage, errorDetails }
       )
@@ -2059,10 +2088,10 @@ export class ChargingStation extends EventEmitter {
       }
       if (!(error instanceof OCPPError)) {
         logger.warn(
       }
       if (!(error instanceof OCPPError)) {
         logger.warn(
-          `${this.logPrefix()} Error thrown at incoming OCPP command '${
+          `${this.logPrefix()} Error thrown at incoming OCPP command ${
             commandName ?? requestCommandName ?? Constants.UNKNOWN_OCPP_COMMAND
             // eslint-disable-next-line @typescript-eslint/no-base-to-string
             commandName ?? requestCommandName ?? Constants.UNKNOWN_OCPP_COMMAND
             // eslint-disable-next-line @typescript-eslint/no-base-to-string
-          }' message '${data.toString()}' handling is not an OCPPError:`,
+          } message '${data.toString()}' handling is not an OCPPError:`,
           error
         )
       }
           error
         )
       }
@@ -2072,7 +2101,9 @@ export class ChargingStation extends EventEmitter {
           // eslint-disable-next-line @typescript-eslint/no-base-to-string
         }' message '${data.toString()}'${
           this.requests.has(messageId)
           // eslint-disable-next-line @typescript-eslint/no-base-to-string
         }' message '${data.toString()}'${
           this.requests.has(messageId)
-            ? ` matching cached request '${JSON.stringify(this.getCachedRequest(messageType, messageId))}'`
+            ? ` matching cached request '${JSON.stringify(
+                this.getCachedRequest(messageType, messageId)
+              )}'`
             : ''
         } processing error:`,
         error
             : ''
         } processing error:`,
         error
@@ -2214,9 +2245,13 @@ export class ChargingStation extends EventEmitter {
       })
     }
     // Start WebSocket ping
       })
     }
     // Start WebSocket ping
-    this.startWebSocketPing()
+    if (this.wsPingSetInterval == null) {
+      this.startWebSocketPing()
+    }
     // Start heartbeat
     // Start heartbeat
-    this.startHeartbeat()
+    if (this.heartbeatSetInterval == null) {
+      this.startHeartbeat()
+    }
     // Initialize connectors status
     if (this.hasEvses) {
       for (const [evseId, evseStatus] of this.evses) {
     // Initialize connectors status
     if (this.hasEvses) {
       for (const [evseId, evseStatus] of this.evses) {
@@ -2306,13 +2341,14 @@ export class ChargingStation extends EventEmitter {
     }
   }
 
     }
   }
 
+  private getWebSocketPingInterval (): number {
+    return getConfigurationKey(this, StandardParametersKey.WebSocketPingInterval) != null
+      ? convertToInt(getConfigurationKey(this, StandardParametersKey.WebSocketPingInterval)?.value)
+      : 0
+  }
+
   private startWebSocketPing (): void {
   private startWebSocketPing (): void {
-    const webSocketPingInterval =
-      getConfigurationKey(this, StandardParametersKey.WebSocketPingInterval) != null
-        ? convertToInt(
-          getConfigurationKey(this, StandardParametersKey.WebSocketPingInterval)?.value
-        )
-        : 0
+    const webSocketPingInterval = this.getWebSocketPingInterval()
     if (webSocketPingInterval > 0 && this.wsPingSetInterval == null) {
       this.wsPingSetInterval = setInterval(() => {
         if (this.isWebSocketConnectionOpened()) {
     if (webSocketPingInterval > 0 && this.wsPingSetInterval == null) {
       this.wsPingSetInterval = setInterval(() => {
         if (this.isWebSocketConnectionOpened()) {
@@ -2402,7 +2438,6 @@ export class ChargingStation extends EventEmitter {
       this.wsConnectionRetryCount < this.stationInfo!.autoReconnectMaxRetries! ||
       this.stationInfo?.autoReconnectMaxRetries === -1
     ) {
       this.wsConnectionRetryCount < this.stationInfo!.autoReconnectMaxRetries! ||
       this.stationInfo?.autoReconnectMaxRetries === -1
     ) {
-      this.wsConnectionRetried = true
       ++this.wsConnectionRetryCount
       const reconnectDelay =
         this.stationInfo?.reconnectExponentialDelay === true
       ++this.wsConnectionRetryCount
       const reconnectDelay =
         this.stationInfo?.reconnectExponentialDelay === true
@@ -2429,9 +2464,7 @@ export class ChargingStation extends EventEmitter {
       )
     } else if (this.stationInfo?.autoReconnectMaxRetries !== -1) {
       logger.error(
       )
     } else if (this.stationInfo?.autoReconnectMaxRetries !== -1) {
       logger.error(
-        `${this.logPrefix()} WebSocket connection retries failure: maximum retries reached (${
-          this.wsConnectionRetryCount
-        }) or retries disabled (${this.stationInfo?.autoReconnectMaxRetries})`
+        `${this.logPrefix()} WebSocket connection retries failure: maximum retries reached (${this.wsConnectionRetryCount.toString()}) or retries disabled (${this.stationInfo?.autoReconnectMaxRetries?.toString()})`
       )
     }
   }
       )
     }
   }
index 735a0b39c9bcf967f69297aa1a66618d2b4f9752..6163f6780c379d0942e74f58a1b27aa04bd13503 100644 (file)
@@ -31,6 +31,7 @@ import {
   BootReasonEnumType,
   type ChargingProfile,
   ChargingProfileKindType,
   BootReasonEnumType,
   type ChargingProfile,
   ChargingProfileKindType,
+  ChargingProfilePurposeType,
   ChargingRateUnitType,
   type ChargingSchedulePeriod,
   type ChargingStationConfiguration,
   ChargingRateUnitType,
   type ChargingSchedulePeriod,
   type ChargingStationConfiguration,
@@ -306,7 +307,11 @@ export const checkConnectorsConfiguration = (
     )
     stationTemplate.randomConnectors = true
   }
     )
     stationTemplate.randomConnectors = true
   }
-  return { configuredMaxConnectors, templateMaxConnectors, templateMaxAvailableConnectors }
+  return {
+    configuredMaxConnectors,
+    templateMaxConnectors,
+    templateMaxAvailableConnectors
+  }
 }
 
 export const checkStationInfoConnectorStatus = (
 }
 
 export const checkStationInfoConnectorStatus = (
@@ -323,27 +328,6 @@ export const checkStationInfoConnectorStatus = (
   }
 }
 
   }
 }
 
-export const buildConnectorsMap = (
-  connectors: Record<string, ConnectorStatus>,
-  logPrefix: string,
-  templateFile: string
-): Map<number, ConnectorStatus> => {
-  const connectorsMap = new Map<number, ConnectorStatus>()
-  if (getMaxNumberOfConnectors(connectors) > 0) {
-    for (const connector in connectors) {
-      const connectorStatus = connectors[connector]
-      const connectorId = convertToInt(connector)
-      checkStationInfoConnectorStatus(connectorId, connectorStatus, logPrefix, templateFile)
-      connectorsMap.set(connectorId, clone<ConnectorStatus>(connectorStatus))
-    }
-  } else {
-    logger.warn(
-      `${logPrefix} Charging station information from template ${templateFile} with no connectors, cannot build connectors map`
-    )
-  }
-  return connectorsMap
-}
-
 export const setChargingStationOptions = (
   stationInfo: ChargingStationInfo,
   options?: ChargingStationOptions
 export const setChargingStationOptions = (
   stationInfo: ChargingStationInfo,
   options?: ChargingStationOptions
@@ -375,6 +359,27 @@ export const setChargingStationOptions = (
   return stationInfo
 }
 
   return stationInfo
 }
 
+export const buildConnectorsMap = (
+  connectors: Record<string, ConnectorStatus>,
+  logPrefix: string,
+  templateFile: string
+): Map<number, ConnectorStatus> => {
+  const connectorsMap = new Map<number, ConnectorStatus>()
+  if (getMaxNumberOfConnectors(connectors) > 0) {
+    for (const connector in connectors) {
+      const connectorStatus = connectors[connector]
+      const connectorId = convertToInt(connector)
+      checkStationInfoConnectorStatus(connectorId, connectorStatus, logPrefix, templateFile)
+      connectorsMap.set(connectorId, clone<ConnectorStatus>(connectorStatus))
+    }
+  } else {
+    logger.warn(
+      `${logPrefix} Charging station information from template ${templateFile} with no connectors, cannot build connectors map`
+    )
+  }
+  return connectorsMap
+}
+
 export const initializeConnectorsMapStatus = (
   connectors: Map<number, ConnectorStatus>,
   logPrefix: string
 export const initializeConnectorsMapStatus = (
   connectors: Map<number, ConnectorStatus>,
   logPrefix: string
@@ -401,29 +406,60 @@ export const initializeConnectorsMapStatus = (
   }
 }
 
   }
 }
 
+export const resetAuthorizeConnectorStatus = (connectorStatus: ConnectorStatus): void => {
+  connectorStatus.idTagLocalAuthorized = false
+  connectorStatus.idTagAuthorized = false
+  delete connectorStatus.localAuthorizeIdTag
+  delete connectorStatus.authorizeIdTag
+}
+
 export const resetConnectorStatus = (connectorStatus: ConnectorStatus | undefined): void => {
   if (connectorStatus == null) {
     return
   }
 export const resetConnectorStatus = (connectorStatus: ConnectorStatus | undefined): void => {
   if (connectorStatus == null) {
     return
   }
-  connectorStatus.chargingProfiles =
-    connectorStatus.transactionId != null && isNotEmptyArray(connectorStatus.chargingProfiles)
-      ? connectorStatus.chargingProfiles.filter(
-        chargingProfile => chargingProfile.transactionId !== connectorStatus.transactionId
-      )
-      : []
-  connectorStatus.idTagLocalAuthorized = false
-  connectorStatus.idTagAuthorized = false
+  if (isNotEmptyArray(connectorStatus.chargingProfiles)) {
+    connectorStatus.chargingProfiles = connectorStatus.chargingProfiles.filter(
+      chargingProfile =>
+        (chargingProfile.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE &&
+          chargingProfile.transactionId != null &&
+          connectorStatus.transactionId != null &&
+          chargingProfile.transactionId !== connectorStatus.transactionId) ||
+        chargingProfile.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE
+    )
+  }
+  resetAuthorizeConnectorStatus(connectorStatus)
   connectorStatus.transactionRemoteStarted = false
   connectorStatus.transactionStarted = false
   delete connectorStatus.transactionStart
   delete connectorStatus.transactionId
   connectorStatus.transactionRemoteStarted = false
   connectorStatus.transactionStarted = false
   delete connectorStatus.transactionStart
   delete connectorStatus.transactionId
-  delete connectorStatus.localAuthorizeIdTag
-  delete connectorStatus.authorizeIdTag
   delete connectorStatus.transactionIdTag
   connectorStatus.transactionEnergyActiveImportRegisterValue = 0
   delete connectorStatus.transactionBeginMeterValue
 }
 
   delete connectorStatus.transactionIdTag
   connectorStatus.transactionEnergyActiveImportRegisterValue = 0
   delete connectorStatus.transactionBeginMeterValue
 }
 
+export const prepareConnectorStatus = (connectorStatus: ConnectorStatus): ConnectorStatus => {
+  if (connectorStatus.reservation != null) {
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    connectorStatus.reservation.expiryDate = convertToDate(connectorStatus.reservation.expiryDate)!
+  }
+  if (isNotEmptyArray(connectorStatus.chargingProfiles)) {
+    connectorStatus.chargingProfiles = connectorStatus.chargingProfiles
+      .filter(
+        chargingProfile =>
+          chargingProfile.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE
+      )
+      .map(chargingProfile => {
+        chargingProfile.chargingSchedule.startSchedule = convertToDate(
+          chargingProfile.chargingSchedule.startSchedule
+        )
+        chargingProfile.validFrom = convertToDate(chargingProfile.validFrom)
+        chargingProfile.validTo = convertToDate(chargingProfile.validTo)
+        return chargingProfile
+      })
+  }
+  return connectorStatus
+}
+
 export const createBootNotificationRequest = (
   stationInfo: ChargingStationInfo,
   bootReason: BootReasonEnumType = BootReasonEnumType.PowerUp
 export const createBootNotificationRequest = (
   stationInfo: ChargingStationInfo,
   bootReason: BootReasonEnumType = BootReasonEnumType.PowerUp
@@ -524,7 +560,10 @@ export const createSerialNumber = (
     randomSerialNumber?: boolean
   }
 ): void => {
     randomSerialNumber?: boolean
   }
 ): void => {
-  params = { ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true }, ...params }
+  params = {
+    ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true },
+    ...params
+  }
   const serialNumberSuffix =
     params.randomSerialNumber === true
       ? getRandomSerialNumberSuffix({
   const serialNumberSuffix =
     params.randomSerialNumber === true
       ? getRandomSerialNumberSuffix({
@@ -589,80 +628,138 @@ export const getAmperageLimitationUnitDivider = (stationInfo: ChargingStationInf
   return unitDivider
 }
 
   return unitDivider
 }
 
+const getChargingStationChargingProfiles = (
+  chargingStation: ChargingStation
+): ChargingProfile[] => {
+  return (chargingStation.getConnectorStatus(0)?.chargingProfiles ?? [])
+    .filter(
+      chargingProfile =>
+        chargingProfile.chargingProfilePurpose ===
+        ChargingProfilePurposeType.CHARGE_POINT_MAX_PROFILE
+    )
+    .sort((a, b) => b.stackLevel - a.stackLevel)
+}
+
+export const getChargingStationChargingProfilesLimit = (
+  chargingStation: ChargingStation
+): number | undefined => {
+  const chargingProfiles = getChargingStationChargingProfiles(chargingStation)
+  if (isNotEmptyArray(chargingProfiles)) {
+    const chargingProfilesLimit = getChargingProfilesLimit(chargingStation, 0, chargingProfiles)
+    if (chargingProfilesLimit != null) {
+      const limit = buildChargingProfilesLimit(chargingStation, chargingProfilesLimit)
+      const chargingStationMaximumPower =
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        chargingStation.stationInfo!.maximumPower!
+      if (limit > chargingStationMaximumPower) {
+        logger.error(
+          `${chargingStation.logPrefix()} ${moduleName}.getChargingStationChargingProfilesLimit: Charging profile id ${
+            chargingProfilesLimit.chargingProfile.chargingProfileId
+          } limit ${limit} is greater than charging station maximum ${chargingStationMaximumPower}: %j`,
+          chargingProfilesLimit
+        )
+        return chargingStationMaximumPower
+      }
+      return limit
+    }
+  }
+}
+
 /**
 /**
- * Gets the connector cloned charging profiles applying a power limitation
- * and sorted by connector id descending then stack level descending
+ * Gets the connector charging profiles relevant for power limitation shallow cloned
+ * and sorted by priorities
  *
  *
- * @param chargingStation -
- * @param connectorId -
+ * @param chargingStation - Charging station
+ * @param connectorId - Connector id
  * @returns connector charging profiles array
  */
 export const getConnectorChargingProfiles = (
   chargingStation: ChargingStation,
   connectorId: number
 ): ChargingProfile[] => {
  * @returns connector charging profiles array
  */
 export const getConnectorChargingProfiles = (
   chargingStation: ChargingStation,
   connectorId: number
 ): ChargingProfile[] => {
-  return clone<ChargingProfile[]>(
-    (chargingStation.getConnectorStatus(connectorId)?.chargingProfiles ?? [])
-      .sort((a, b) => b.stackLevel - a.stackLevel)
-      .concat(
-        (chargingStation.getConnectorStatus(0)?.chargingProfiles ?? []).sort(
-          (a, b) => b.stackLevel - a.stackLevel
+  return (chargingStation.getConnectorStatus(connectorId)?.chargingProfiles ?? [])
+    .slice()
+    .sort((a, b) => {
+      if (
+        a.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE &&
+        b.chargingProfilePurpose === ChargingProfilePurposeType.TX_DEFAULT_PROFILE
+      ) {
+        return -1
+      } else if (
+        a.chargingProfilePurpose === ChargingProfilePurposeType.TX_DEFAULT_PROFILE &&
+        b.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE
+      ) {
+        return 1
+      }
+      return b.stackLevel - a.stackLevel
+    })
+    .concat(
+      (chargingStation.getConnectorStatus(0)?.chargingProfiles ?? [])
+        .filter(
+          chargingProfile =>
+            chargingProfile.chargingProfilePurpose === ChargingProfilePurposeType.TX_DEFAULT_PROFILE
         )
         )
-      )
-  )
+        .sort((a, b) => b.stackLevel - a.stackLevel)
+    )
 }
 
 }
 
-export const getChargingStationConnectorChargingProfilesPowerLimit = (
+export const getConnectorChargingProfilesLimit = (
   chargingStation: ChargingStation,
   connectorId: number
 ): number | undefined => {
   chargingStation: ChargingStation,
   connectorId: number
 ): number | undefined => {
-  let limit: number | undefined, chargingProfile: ChargingProfile | undefined
-  // Get charging profiles sorted by connector id then stack level
   const chargingProfiles = getConnectorChargingProfiles(chargingStation, connectorId)
   if (isNotEmptyArray(chargingProfiles)) {
   const chargingProfiles = getConnectorChargingProfiles(chargingStation, connectorId)
   if (isNotEmptyArray(chargingProfiles)) {
-    const result = getLimitFromChargingProfiles(
+    const chargingProfilesLimit = getChargingProfilesLimit(
       chargingStation,
       connectorId,
       chargingStation,
       connectorId,
-      chargingProfiles,
-      chargingStation.logPrefix()
+      chargingProfiles
     )
     )
-    if (result != null) {
-      limit = result.limit
-      chargingProfile = result.chargingProfile
-      switch (chargingStation.stationInfo?.currentOutType) {
-        case CurrentType.AC:
-          limit =
-            chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
-              ? limit
-              : ACElectricUtils.powerTotal(
-                chargingStation.getNumberOfPhases(),
-                // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-                chargingStation.stationInfo.voltageOut!,
-                limit
-              )
-          break
-        case CurrentType.DC:
-          limit =
-            chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
-              ? limit
-              : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-              DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit)
-      }
+    if (chargingProfilesLimit != null) {
+      const limit = buildChargingProfilesLimit(chargingStation, chargingProfilesLimit)
       const connectorMaximumPower =
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         chargingStation.stationInfo!.maximumPower! / chargingStation.powerDivider!
       if (limit > connectorMaximumPower) {
         logger.error(
       const connectorMaximumPower =
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         chargingStation.stationInfo!.maximumPower! / chargingStation.powerDivider!
       if (limit > connectorMaximumPower) {
         logger.error(
-          `${chargingStation.logPrefix()} ${moduleName}.getChargingStationConnectorChargingProfilesPowerLimit: Charging profile id ${
-            chargingProfile.chargingProfileId
-          } limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}: %j`,
-          result
+          `${chargingStation.logPrefix()} ${moduleName}.getConnectorChargingProfilesLimit: Charging profile id ${
+            chargingProfilesLimit.chargingProfile.chargingProfileId
+          } limit ${limit} is greater than connector ${connectorId} maximum ${connectorMaximumPower}: %j`,
+          chargingProfilesLimit
         )
         )
-        limit = connectorMaximumPower
+        return connectorMaximumPower
       }
       }
+      return limit
     }
   }
     }
   }
-  return limit
+}
+
+const buildChargingProfilesLimit = (
+  chargingStation: ChargingStation,
+  chargingProfilesLimit: ChargingProfilesLimit
+): number => {
+  const errorMsg = `Unknown ${chargingStation.stationInfo?.currentOutType} currentOutType in charging station information, cannot build charging profiles limit`
+  const { limit, chargingProfile } = chargingProfilesLimit
+  switch (chargingStation.stationInfo?.currentOutType) {
+    case CurrentType.AC:
+      return chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
+        ? limit
+        : ACElectricUtils.powerTotal(
+          chargingStation.getNumberOfPhases(),
+          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+          chargingStation.stationInfo.voltageOut!,
+          limit
+        )
+    case CurrentType.DC:
+      return chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT
+        ? limit
+        : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit)
+    default:
+      logger.error(
+        `${chargingStation.logPrefix()} ${moduleName}.buildChargingProfilesLimit: ${errorMsg}`
+      )
+      throw new BaseError(errorMsg)
+  }
 }
 
 export const getDefaultVoltageOut = (
 }
 
 export const getDefaultVoltageOut = (
@@ -817,50 +914,57 @@ interface ChargingProfilesLimit {
 }
 
 /**
 }
 
 /**
- * Charging profiles shall already be sorted by connector id descending then stack level descending
+ * Get the charging profiles limit for a connector
+ * Charging profiles shall already be sorted by priorities
  *
  * @param chargingStation -
  * @param connectorId -
  * @param chargingProfiles -
  *
  * @param chargingStation -
  * @param connectorId -
  * @param chargingProfiles -
- * @param logPrefix -
  * @returns ChargingProfilesLimit
  */
  * @returns ChargingProfilesLimit
  */
-const getLimitFromChargingProfiles = (
+const getChargingProfilesLimit = (
   chargingStation: ChargingStation,
   connectorId: number,
   chargingStation: ChargingStation,
   connectorId: number,
-  chargingProfiles: ChargingProfile[],
-  logPrefix: string
+  chargingProfiles: ChargingProfile[]
 ): ChargingProfilesLimit | undefined => {
 ): ChargingProfilesLimit | undefined => {
-  const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j`
+  const debugLogMsg = `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profiles limit found: %j`
   const currentDate = new Date()
   const connectorStatus = chargingStation.getConnectorStatus(connectorId)
   const currentDate = new Date()
   const connectorStatus = chargingStation.getConnectorStatus(connectorId)
+  let previousActiveChargingProfile: ChargingProfile | undefined
   for (const chargingProfile of chargingProfiles) {
     const chargingSchedule = chargingProfile.chargingSchedule
     if (chargingSchedule.startSchedule == null) {
       logger.debug(
   for (const chargingProfile of chargingProfiles) {
     const chargingSchedule = chargingProfile.chargingSchedule
     if (chargingSchedule.startSchedule == null) {
       logger.debug(
-        `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined. Trying to set it to the connector current transaction start date`
+        `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined. Trying to set it to the connector current transaction start date`
       )
       // OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction
       chargingSchedule.startSchedule = connectorStatus?.transactionStart
     }
     if (!isDate(chargingSchedule.startSchedule)) {
       logger.warn(
       )
       // OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction
       chargingSchedule.startSchedule = connectorStatus?.transactionStart
     }
     if (!isDate(chargingSchedule.startSchedule)) {
       logger.warn(
-        `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} startSchedule property is not a Date instance. Trying to convert it to a Date instance`
+        `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} startSchedule property is not a Date instance. Trying to convert it to a Date instance`
       )
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       chargingSchedule.startSchedule = convertToDate(chargingSchedule.startSchedule)!
     }
     if (chargingSchedule.duration == null) {
       logger.debug(
       )
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       chargingSchedule.startSchedule = convertToDate(chargingSchedule.startSchedule)!
     }
     if (chargingSchedule.duration == null) {
       logger.debug(
-        `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no duration defined and will be set to the maximum time allowed`
+        `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} has no duration defined and will be set to the maximum time allowed`
       )
       // OCPP specifies that if duration is not defined, it should be infinite
       chargingSchedule.duration = differenceInSeconds(maxTime, chargingSchedule.startSchedule)
     }
       )
       // OCPP specifies that if duration is not defined, it should be infinite
       chargingSchedule.duration = differenceInSeconds(maxTime, chargingSchedule.startSchedule)
     }
-    if (!prepareChargingProfileKind(connectorStatus, chargingProfile, currentDate, logPrefix)) {
+    if (
+      !prepareChargingProfileKind(
+        connectorStatus,
+        chargingProfile,
+        currentDate,
+        chargingStation.logPrefix()
+      )
+    ) {
       continue
     }
       continue
     }
-    if (!canProceedChargingProfile(chargingProfile, currentDate, logPrefix)) {
+    if (!canProceedChargingProfile(chargingProfile, currentDate, chargingStation.logPrefix())) {
       continue
     }
     // Check if the charging profile is active
       continue
     }
     // Check if the charging profile is active
@@ -882,25 +986,25 @@ const getLimitFromChargingProfiles = (
           )
         ) {
           logger.warn(
           )
         ) {
           logger.warn(
-            `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} schedule periods are not sorted by start period`
+            `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} schedule periods are not sorted by start period`
           )
           chargingSchedule.chargingSchedulePeriod.sort(chargingSchedulePeriodCompareFn)
         }
         // Check if the first schedule period startPeriod property is equal to 0
         if (chargingSchedule.chargingSchedulePeriod[0].startPeriod !== 0) {
           logger.error(
           )
           chargingSchedule.chargingSchedulePeriod.sort(chargingSchedulePeriodCompareFn)
         }
         // Check if the first schedule period startPeriod property is equal to 0
         if (chargingSchedule.chargingSchedulePeriod[0].startPeriod !== 0) {
           logger.error(
-            `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} first schedule period start period ${chargingSchedule.chargingSchedulePeriod[0].startPeriod} is not equal to 0`
+            `${chargingStation.logPrefix()} ${moduleName}.getChargingProfilesLimit: Charging profile id ${chargingProfile.chargingProfileId} first schedule period start period ${chargingSchedule.chargingSchedulePeriod[0].startPeriod} is not equal to 0`
           )
           continue
         }
         // Handle only one schedule period
         if (chargingSchedule.chargingSchedulePeriod.length === 1) {
           )
           continue
         }
         // Handle only one schedule period
         if (chargingSchedule.chargingSchedulePeriod.length === 1) {
-          const result: ChargingProfilesLimit = {
+          const chargingProfilesLimit: ChargingProfilesLimit = {
             limit: chargingSchedule.chargingSchedulePeriod[0].limit,
             chargingProfile
           }
             limit: chargingSchedule.chargingSchedulePeriod[0].limit,
             chargingProfile
           }
-          logger.debug(debugLogMsg, result)
-          return result
+          logger.debug(debugLogMsg, chargingProfilesLimit)
+          return chargingProfilesLimit
         }
         let previousChargingSchedulePeriod: ChargingSchedulePeriod | undefined
         // Search for the right schedule period
         }
         let previousChargingSchedulePeriod: ChargingSchedulePeriod | undefined
         // Search for the right schedule period
@@ -916,16 +1020,13 @@ const getLimitFromChargingProfiles = (
             )
           ) {
             // Found the schedule period: previous is the correct one
             )
           ) {
             // Found the schedule period: previous is the correct one
-            const result: ChargingProfilesLimit = {
-              // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-              limit: previousChargingSchedulePeriod!.limit,
-              chargingProfile
+            const chargingProfilesLimit: ChargingProfilesLimit = {
+              limit: previousChargingSchedulePeriod?.limit ?? chargingSchedulePeriod.limit,
+              chargingProfile: previousActiveChargingProfile ?? chargingProfile
             }
             }
-            logger.debug(debugLogMsg, result)
-            return result
+            logger.debug(debugLogMsg, chargingProfilesLimit)
+            return chargingProfilesLimit
           }
           }
-          // Keep a reference to previous one
-          previousChargingSchedulePeriod = chargingSchedulePeriod
           // Handle the last schedule period within the charging profile duration
           if (
             index === chargingSchedule.chargingSchedulePeriod.length - 1 ||
           // Handle the last schedule period within the charging profile duration
           if (
             index === chargingSchedule.chargingSchedulePeriod.length - 1 ||
@@ -938,15 +1039,19 @@ const getLimitFromChargingProfiles = (
                 chargingSchedule.startSchedule
               ) > chargingSchedule.duration)
           ) {
                 chargingSchedule.startSchedule
               ) > chargingSchedule.duration)
           ) {
-            const result: ChargingProfilesLimit = {
-              limit: previousChargingSchedulePeriod.limit,
+            const chargingProfilesLimit: ChargingProfilesLimit = {
+              limit: chargingSchedulePeriod.limit,
               chargingProfile
             }
               chargingProfile
             }
-            logger.debug(debugLogMsg, result)
-            return result
+            logger.debug(debugLogMsg, chargingProfilesLimit)
+            return chargingProfilesLimit
           }
           }
+          // Keep a reference to previous charging schedule period
+          previousChargingSchedulePeriod = chargingSchedulePeriod
         }
       }
         }
       }
+      // Keep a reference to previous active charging profile
+      previousActiveChargingProfile = chargingProfile
     }
   }
 }
     }
   }
 }
index b5fc1cef13cc76b3f8e5250227485594c55e4210..9acdd3a42c94c491587ead7839156d95949ec797 100644 (file)
@@ -155,23 +155,21 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne
       [
         BroadcastChannelProcedureName.BOOT_NOTIFICATION,
         async (requestPayload?: BroadcastChannelRequestPayload) => {
       [
         BroadcastChannelProcedureName.BOOT_NOTIFICATION,
         async (requestPayload?: BroadcastChannelRequestPayload) => {
-          this.chargingStation.bootNotificationResponse =
-            await this.chargingStation.ocppRequestService.requestHandler<
-            BootNotificationRequest,
-            BootNotificationResponse
-            >(
-              this.chargingStation,
-              RequestCommand.BOOT_NOTIFICATION,
-              {
-                ...this.chargingStation.bootNotificationRequest,
-                ...requestPayload
-              },
-              {
-                skipBufferingOnError: true,
-                throwError: true
-              }
-            )
-          return this.chargingStation.bootNotificationResponse
+          return await this.chargingStation.ocppRequestService.requestHandler<
+          BootNotificationRequest,
+          BootNotificationResponse
+          >(
+            this.chargingStation,
+            RequestCommand.BOOT_NOTIFICATION,
+            {
+              ...this.chargingStation.bootNotificationRequest,
+              ...requestPayload
+            },
+            {
+              skipBufferingOnError: true,
+              throwError: true
+            }
+          )
         }
       ],
       [
         }
       ],
       [
index 8d8a83c3586549c074e4e4b1feeff5cf905d6b98..1a5f955f52011ae05e8979f81ba9e3614d42964f 100644 (file)
@@ -14,5 +14,6 @@ export {
   hasReservationExpired,
   prepareChargingProfileKind,
   removeExpiredReservations,
   hasReservationExpired,
   prepareChargingProfileKind,
   removeExpiredReservations,
+  resetAuthorizeConnectorStatus,
   resetConnectorStatus
 } from './Helpers.js'
   resetConnectorStatus
 } from './Helpers.js'
index 4a604f1c4635d8d39658c8537ab04f19e49fe49e..214c5a85bf9797377d49d64813aa04d4116a319c 100644 (file)
@@ -7,15 +7,33 @@ export class OCPP16Constants extends OCPPConstants {
   > = Object.freeze([
       { to: OCPP16ChargePointStatus.Available },
       // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Available },
   > = Object.freeze([
       { to: OCPP16ChargePointStatus.Available },
       // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Available },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.Unavailable
+      },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       { to: OCPP16ChargePointStatus.Unavailable },
       { to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Available },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.Available
+      },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Unavailable },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       { to: OCPP16ChargePointStatus.Faulted },
       { to: OCPP16ChargePointStatus.Faulted },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Available },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Unavailable }
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Available
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Unavailable
+      }
     // { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Faulted }
     ])
 
     // { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Faulted }
     ])
 
@@ -23,93 +41,252 @@ export class OCPP16Constants extends OCPPConstants {
     Object.freeze([
       { to: OCPP16ChargePointStatus.Available },
       // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Available },
     Object.freeze([
       { to: OCPP16ChargePointStatus.Available },
       // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Available },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Preparing },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Charging },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.SuspendedEV },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.SuspendedEVSE },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.Preparing
+      },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.Charging
+      },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.SuspendedEV
+      },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.SuspendedEVSE
+      },
       // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Finishing },
       // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Finishing },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.Reserved
+      },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.Unavailable
+      },
+      {
+        from: OCPP16ChargePointStatus.Available,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       // { to: OCPP16ChargePointStatus.Preparing },
       // { to: OCPP16ChargePointStatus.Preparing },
-      { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Available },
+      {
+        from: OCPP16ChargePointStatus.Preparing,
+        to: OCPP16ChargePointStatus.Available
+      },
       // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Preparing },
       // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Preparing },
-      { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Charging },
-      { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.SuspendedEV },
-      { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.SuspendedEVSE },
-      { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Finishing },
+      {
+        from: OCPP16ChargePointStatus.Preparing,
+        to: OCPP16ChargePointStatus.Charging
+      },
+      {
+        from: OCPP16ChargePointStatus.Preparing,
+        to: OCPP16ChargePointStatus.SuspendedEV
+      },
+      {
+        from: OCPP16ChargePointStatus.Preparing,
+        to: OCPP16ChargePointStatus.SuspendedEVSE
+      },
+      {
+        from: OCPP16ChargePointStatus.Preparing,
+        to: OCPP16ChargePointStatus.Finishing
+      },
       // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Unavailable },
       // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Preparing,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       // { to: OCPP16ChargePointStatus.Charging },
       // { to: OCPP16ChargePointStatus.Charging },
-      { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Available },
+      {
+        from: OCPP16ChargePointStatus.Charging,
+        to: OCPP16ChargePointStatus.Available
+      },
       // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Preparing },
       // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Charging },
       // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Preparing },
       // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Charging },
-      { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.SuspendedEV },
-      { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.SuspendedEVSE },
-      { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Finishing },
+      {
+        from: OCPP16ChargePointStatus.Charging,
+        to: OCPP16ChargePointStatus.SuspendedEV
+      },
+      {
+        from: OCPP16ChargePointStatus.Charging,
+        to: OCPP16ChargePointStatus.SuspendedEVSE
+      },
+      {
+        from: OCPP16ChargePointStatus.Charging,
+        to: OCPP16ChargePointStatus.Finishing
+      },
       // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Charging,
+        to: OCPP16ChargePointStatus.Unavailable
+      },
+      {
+        from: OCPP16ChargePointStatus.Charging,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       // { to: OCPP16ChargePointStatus.SuspendedEV },
       // { to: OCPP16ChargePointStatus.SuspendedEV },
-      { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Available },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEV,
+        to: OCPP16ChargePointStatus.Available
+      },
       // { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Preparing },
       // { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Preparing },
-      { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Charging },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEV,
+        to: OCPP16ChargePointStatus.Charging
+      },
       // { from: OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.SuspendedEV },
       // { from: OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.SuspendedEV },
-      { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.SuspendedEVSE },
-      { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Finishing },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEV,
+        to: OCPP16ChargePointStatus.SuspendedEVSE
+      },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEV,
+        to: OCPP16ChargePointStatus.Finishing
+      },
       // { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEV,
+        to: OCPP16ChargePointStatus.Unavailable
+      },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEV,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       // { to: OCPP16ChargePointStatus.SuspendedEVSE },
       // { to: OCPP16ChargePointStatus.SuspendedEVSE },
-      { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Available },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEVSE,
+        to: OCPP16ChargePointStatus.Available
+      },
       // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Preparing },
       // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Preparing },
-      { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Charging },
-      { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.SuspendedEV },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEVSE,
+        to: OCPP16ChargePointStatus.Charging
+      },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEVSE,
+        to: OCPP16ChargePointStatus.SuspendedEV
+      },
       // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.SuspendedEVSE },
       // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.SuspendedEVSE },
-      { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Finishing },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEVSE,
+        to: OCPP16ChargePointStatus.Finishing
+      },
       // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEVSE,
+        to: OCPP16ChargePointStatus.Unavailable
+      },
+      {
+        from: OCPP16ChargePointStatus.SuspendedEVSE,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       // { to: OCPP16ChargePointStatus.Finishing},
       // { to: OCPP16ChargePointStatus.Finishing},
-      { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Available },
-      { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Preparing },
+      {
+        from: OCPP16ChargePointStatus.Finishing,
+        to: OCPP16ChargePointStatus.Available
+      },
+      {
+        from: OCPP16ChargePointStatus.Finishing,
+        to: OCPP16ChargePointStatus.Preparing
+      },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Charging },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.SuspendedEV },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.SuspendedEVSE },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Finishing },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Charging },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.SuspendedEV },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.SuspendedEVSE },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Finishing },
       // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Finishing,
+        to: OCPP16ChargePointStatus.Unavailable
+      },
+      {
+        from: OCPP16ChargePointStatus.Finishing,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       // { to: OCPP16ChargePointStatus.Reserved },
       // { to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Available },
-      { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Preparing },
+      {
+        from: OCPP16ChargePointStatus.Reserved,
+        to: OCPP16ChargePointStatus.Available
+      },
+      {
+        from: OCPP16ChargePointStatus.Reserved,
+        to: OCPP16ChargePointStatus.Preparing
+      },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Charging },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.SuspendedEV },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.SuspendedEVSE },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Finishing },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Charging },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.SuspendedEV },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.SuspendedEVSE },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Finishing },
       // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Reserved,
+        to: OCPP16ChargePointStatus.Unavailable
+      },
+      {
+        from: OCPP16ChargePointStatus.Reserved,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       { to: OCPP16ChargePointStatus.Unavailable },
       { to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Available },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Preparing },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Charging },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.SuspendedEV },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.SuspendedEVSE },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.Available
+      },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.Preparing
+      },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.Charging
+      },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.SuspendedEV
+      },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.SuspendedEVSE
+      },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Finishing },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Unavailable },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Finishing },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Reserved },
       // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Unavailable },
-      { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Faulted },
+      {
+        from: OCPP16ChargePointStatus.Unavailable,
+        to: OCPP16ChargePointStatus.Faulted
+      },
       { to: OCPP16ChargePointStatus.Faulted },
       { to: OCPP16ChargePointStatus.Faulted },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Available },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Preparing },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Charging },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.SuspendedEV },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.SuspendedEVSE },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Finishing },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Reserved },
-      { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Unavailable }
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Available
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Preparing
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Charging
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.SuspendedEV
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.SuspendedEVSE
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Finishing
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Reserved
+      },
+      {
+        from: OCPP16ChargePointStatus.Faulted,
+        to: OCPP16ChargePointStatus.Unavailable
+      }
       // { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Faulted }
     ])
 }
       // { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Faulted }
     ])
 }
index 84fb39c18ca1bb70968a2deab618427c3e17f909..4b6a7c13f970d2fdea2b1adc335d772cb9bab53f 100644 (file)
@@ -26,6 +26,7 @@ import {
   getConnectorChargingProfiles,
   prepareChargingProfileKind,
   removeExpiredReservations,
   getConnectorChargingProfiles,
   prepareChargingProfileKind,
   removeExpiredReservations,
+  resetAuthorizeConnectorStatus,
   setConfigurationKeyValue
 } from '../../../charging-station/index.js'
 import { OCPPError } from '../../../exception/index.js'
   setConfigurationKeyValue
 } from '../../../charging-station/index.js'
 import { OCPPError } from '../../../exception/index.js'
@@ -105,6 +106,7 @@ import {
   convertToDate,
   convertToInt,
   formatDurationMilliSeconds,
   convertToDate,
   convertToInt,
   formatDurationMilliSeconds,
+  handleIncomingRequestError,
   isAsyncFunction,
   isNotEmptyArray,
   isNotEmptyString,
   isAsyncFunction,
   isNotEmptyArray,
   isNotEmptyString,
@@ -420,7 +422,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         if (response.status === GenericStatus.Accepted) {
           const { connectorId, idTag } = request
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         if (response.status === GenericStatus.Accepted) {
           const { connectorId, idTag } = request
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          chargingStation.getConnectorStatus(connectorId)!.transactionRemoteStarted = true
+          chargingStation.getConnectorStatus(connectorId!)!.transactionRemoteStarted = true
           chargingStation.ocppRequestService
             .requestHandler<Partial<OCPP16StartTransactionRequest>, OCPP16StartTransactionResponse>(
             chargingStation,
           chargingStation.ocppRequestService
             .requestHandler<Partial<OCPP16StartTransactionRequest>, OCPP16StartTransactionResponse>(
             chargingStation,
@@ -431,13 +433,17 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
             }
           )
             .then(response => {
             }
           )
             .then(response => {
-              if (response.status === OCPP16AuthorizationStatus.ACCEPTED) {
+              if (response.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) {
                 logger.debug(
                 logger.debug(
-                  `${chargingStation.logPrefix()} Remote start transaction ACCEPTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${idTag}'`
+                  `${chargingStation.logPrefix()} Remote start transaction ACCEPTED on ${
+                    chargingStation.stationInfo?.chargingStationId
+                  }#${connectorId} for idTag '${idTag}'`
                 )
               } else {
                 logger.debug(
                 )
               } else {
                 logger.debug(
-                  `${chargingStation.logPrefix()} Remote start transaction REJECTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${idTag}'`
+                  `${chargingStation.logPrefix()} Remote start transaction REJECTED on ${
+                    chargingStation.stationInfo?.chargingStationId
+                  }#${connectorId} for idTag '${idTag}'`
                 )
               }
             })
                 )
               }
             })
@@ -465,11 +471,15 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
             .then(response => {
               if (response.status === GenericStatus.Accepted) {
                 logger.debug(
             .then(response => {
               if (response.status === GenericStatus.Accepted) {
                 logger.debug(
-                  `${chargingStation.logPrefix()} Remote stop transaction ACCEPTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for transaction '${transactionId}'`
+                  `${chargingStation.logPrefix()} Remote stop transaction ACCEPTED on ${
+                    chargingStation.stationInfo?.chargingStationId
+                  }#${connectorId} for transaction '${transactionId}'`
                 )
               } else {
                 logger.debug(
                 )
               } else {
                 logger.debug(
-                  `${chargingStation.logPrefix()} Remote stop transaction REJECTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for transaction '${transactionId}'`
+                  `${chargingStation.logPrefix()} Remote stop transaction REJECTED on ${
+                    chargingStation.stationInfo?.chargingStationId
+                  }#${connectorId} for transaction '${transactionId}'`
                 )
               }
             })
                 )
               }
             })
@@ -502,15 +512,10 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         switch (requestedMessage) {
           case OCPP16MessageTrigger.BootNotification:
             chargingStation.ocppRequestService
         switch (requestedMessage) {
           case OCPP16MessageTrigger.BootNotification:
             chargingStation.ocppRequestService
-              .requestHandler<OCPP16BootNotificationRequest, OCPP16BootNotificationResponse>(
-              chargingStation,
-              OCPP16RequestCommand.BOOT_NOTIFICATION,
-              chargingStation.bootNotificationRequest as OCPP16BootNotificationRequest,
-              { skipBufferingOnError: true, triggerMessage: true }
-            )
-              .then(response => {
-                chargingStation.bootNotificationResponse = response
-              })
+              .requestHandler<
+            OCPP16BootNotificationRequest,
+            OCPP16BootNotificationResponse
+            >(chargingStation, OCPP16RequestCommand.BOOT_NOTIFICATION, chargingStation.bootNotificationRequest as OCPP16BootNotificationRequest, { skipBufferingOnError: true, triggerMessage: true })
               .catch(errorHandler)
             break
           case OCPP16MessageTrigger.Heartbeat:
               .catch(errorHandler)
             break
           case OCPP16MessageTrigger.Heartbeat:
@@ -647,7 +652,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle request PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle request PDU ${JSON.stringify(
             commandPayload,
             undefined,
             2
             commandPayload,
             undefined,
             2
@@ -835,6 +840,25 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       ) {
         chargingStation.restartWebSocketPing()
       }
       ) {
         chargingStation.restartWebSocketPing()
       }
+      if (
+        (keyToChange.key as OCPP16StandardParametersKey) ===
+          OCPP16StandardParametersKey.MeterValueSampleInterval &&
+        chargingStation.getNumberOfRunningTransactions() > 0 &&
+        valueChanged
+      ) {
+        for (
+          let connectorId = 1;
+          connectorId <= chargingStation.getNumberOfConnectors();
+          connectorId++
+        ) {
+          if (chargingStation.getConnectorStatus(connectorId)?.transactionStarted === true) {
+            chargingStation.restartMeterValues(
+              connectorId,
+              secondsToMilliseconds(convertToInt(value))
+            )
+          }
+        }
+      }
       if (keyToChange.reboot === true) {
         return OCPP16Constants.OCPP_CONFIGURATION_RESPONSE_REBOOT_REQUIRED
       }
       if (keyToChange.reboot === true) {
         return OCPP16Constants.OCPP_CONFIGURATION_RESPONSE_REBOOT_REQUIRED
       }
@@ -894,6 +918,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       csChargingProfiles.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE &&
       connectorId > 0 &&
       connectorStatus?.transactionStarted === true &&
       csChargingProfiles.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE &&
       connectorId > 0 &&
       connectorStatus?.transactionStarted === true &&
+      csChargingProfiles.transactionId != null &&
       csChargingProfiles.transactionId !== connectorStatus.transactionId
     ) {
       logger.error(
       csChargingProfiles.transactionId !== connectorStatus.transactionId
     ) {
       logger.error(
@@ -954,7 +979,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       start: currentDate,
       end: addSeconds(currentDate, duration)
     }
       start: currentDate,
       end: addSeconds(currentDate, duration)
     }
-    // Get charging profiles sorted by connector id then stack level
+    // FIXME: add and handle charging station charging profiles
     const chargingProfiles: OCPP16ChargingProfile[] = getConnectorChargingProfiles(
       chargingStation,
       connectorId
     const chargingProfiles: OCPP16ChargingProfile[] = getConnectorChargingProfiles(
       chargingStation,
       connectorId
@@ -1045,41 +1070,46 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return OCPP16Constants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN
     }
     const { connectorId } = commandPayload
       return OCPP16Constants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN
     }
     const { connectorId } = commandPayload
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    if (!chargingStation.hasConnector(connectorId!)) {
-      logger.error(
-        `${chargingStation.logPrefix()} Trying to clear a charging profile(s) to a non existing connector id ${connectorId}`
-      )
-      return OCPP16Constants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN
-    }
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    const connectorStatus = chargingStation.getConnectorStatus(connectorId!)
-    if (connectorId != null && isNotEmptyArray(connectorStatus?.chargingProfiles)) {
-      connectorStatus.chargingProfiles = []
-      logger.debug(
-        `${chargingStation.logPrefix()} Charging profile(s) cleared on connector id ${connectorId}`
-      )
-      return OCPP16Constants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_ACCEPTED
-    }
-    if (connectorId == null) {
+    if (connectorId != null) {
+      if (!chargingStation.hasConnector(connectorId)) {
+        logger.error(
+          `${chargingStation.logPrefix()} Trying to clear a charging profile(s) to a non existing connector id ${connectorId}`
+        )
+        return OCPP16Constants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN
+      }
+      const connectorStatus = chargingStation.getConnectorStatus(connectorId)
+      if (isNotEmptyArray(connectorStatus?.chargingProfiles)) {
+        connectorStatus.chargingProfiles = []
+        logger.debug(
+          `${chargingStation.logPrefix()} Charging profile(s) cleared on connector id ${connectorId}`
+        )
+        return OCPP16Constants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_ACCEPTED
+      }
+    } else {
       let clearedCP = false
       if (chargingStation.hasEvses) {
         for (const evseStatus of chargingStation.evses.values()) {
           for (const status of evseStatus.connectors.values()) {
       let clearedCP = false
       if (chargingStation.hasEvses) {
         for (const evseStatus of chargingStation.evses.values()) {
           for (const status of evseStatus.connectors.values()) {
-            clearedCP = OCPP16ServiceUtils.clearChargingProfiles(
+            const clearedConnectorCP = OCPP16ServiceUtils.clearChargingProfiles(
               chargingStation,
               commandPayload,
               status.chargingProfiles
             )
               chargingStation,
               commandPayload,
               status.chargingProfiles
             )
+            if (clearedConnectorCP && !clearedCP) {
+              clearedCP = true
+            }
           }
         }
       } else {
         for (const id of chargingStation.connectors.keys()) {
           }
         }
       } else {
         for (const id of chargingStation.connectors.keys()) {
-          clearedCP = OCPP16ServiceUtils.clearChargingProfiles(
+          const clearedConnectorCP = OCPP16ServiceUtils.clearChargingProfiles(
             chargingStation,
             commandPayload,
             chargingStation.getConnectorStatus(id)?.chargingProfiles
           )
             chargingStation,
             commandPayload,
             chargingStation.getConnectorStatus(id)?.chargingProfiles
           )
+          if (clearedConnectorCP && !clearedCP) {
+            clearedCP = true
+          }
         }
       }
       if (clearedCP) {
         }
       }
       if (clearedCP) {
@@ -1152,6 +1182,29 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
     chargingStation: ChargingStation,
     commandPayload: RemoteStartTransactionRequest
   ): Promise<GenericResponse> {
     chargingStation: ChargingStation,
     commandPayload: RemoteStartTransactionRequest
   ): Promise<GenericResponse> {
+    if (commandPayload.connectorId == null) {
+      for (
+        let connectorId = 1;
+        connectorId <= chargingStation.getNumberOfConnectors();
+        connectorId++
+      ) {
+        if (
+          chargingStation.getConnectorStatus(connectorId)?.transactionStarted === false &&
+          !OCPP16ServiceUtils.hasReservation(chargingStation, connectorId, commandPayload.idTag)
+        ) {
+          commandPayload.connectorId = connectorId
+          break
+        }
+      }
+      if (commandPayload.connectorId == null) {
+        logger.debug(
+          `${chargingStation.logPrefix()} Remote start transaction REJECTED on ${
+            chargingStation.stationInfo?.chargingStationId
+          }, idTag '${commandPayload.idTag}': no available connector found`
+        )
+        return OCPP16Constants.OCPP_RESPONSE_REJECTED
+      }
+    }
     const { connectorId: transactionConnectorId, idTag, chargingProfile } = commandPayload
     if (!chargingStation.hasConnector(transactionConnectorId)) {
       return this.notifyRemoteStartTransactionRejected(
     const { connectorId: transactionConnectorId, idTag, chargingProfile } = commandPayload
     if (!chargingStation.hasConnector(transactionConnectorId)) {
       return this.notifyRemoteStartTransactionRejected(
@@ -1196,7 +1249,9 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       )
     }
     logger.debug(
       )
     }
     logger.debug(
-      `${chargingStation.logPrefix()} Remote start transaction ACCEPTED on ${chargingStation.stationInfo?.chargingStationId}#${transactionConnectorId}}, idTag '${idTag}'`
+      `${chargingStation.logPrefix()} Remote start transaction ACCEPTED on ${
+        chargingStation.stationInfo?.chargingStationId
+      }#${transactionConnectorId}}, idTag '${idTag}'`
     )
     return OCPP16Constants.OCPP_RESPONSE_ACCEPTED
   }
     )
     return OCPP16Constants.OCPP_RESPONSE_ACCEPTED
   }
@@ -1208,7 +1263,11 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
   ): GenericResponse {
     const connectorStatus = chargingStation.getConnectorStatus(connectorId)
     logger.debug(
   ): GenericResponse {
     const connectorStatus = chargingStation.getConnectorStatus(connectorId)
     logger.debug(
-      `${chargingStation.logPrefix()} Remote start transaction REJECTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId}, idTag '${idTag}', availability '${connectorStatus?.availability}', status '${connectorStatus?.status}'`
+      `${chargingStation.logPrefix()} Remote start transaction REJECTED on ${
+        chargingStation.stationInfo?.chargingStationId
+      }#${connectorId}, idTag '${idTag}', availability '${
+        connectorStatus?.availability
+      }', status '${connectorStatus?.status}'`
     )
     return OCPP16Constants.OCPP_RESPONSE_REJECTED
   }
     )
     return OCPP16Constants.OCPP_RESPONSE_REJECTED
   }
@@ -1218,10 +1277,15 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
     connectorId: number,
     chargingProfile: OCPP16ChargingProfile
   ): boolean {
     connectorId: number,
     chargingProfile: OCPP16ChargingProfile
   ): boolean {
-    if (chargingProfile.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE) {
+    if (
+      chargingProfile.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE &&
+      chargingProfile.transactionId == null
+    ) {
       OCPP16ServiceUtils.setChargingProfile(chargingStation, connectorId, chargingProfile)
       logger.debug(
       OCPP16ServiceUtils.setChargingProfile(chargingStation, connectorId, chargingProfile)
       logger.debug(
-        `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on ${chargingStation.stationInfo?.chargingStationId}#${connectorId}`,
+        `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on ${
+          chargingStation.stationInfo?.chargingStationId
+        }#${connectorId}`,
         chargingProfile
       )
       return true
         chargingProfile
       )
       return true
@@ -1229,7 +1293,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
     logger.debug(
       `${chargingStation.logPrefix()} Not allowed to set ${
         chargingProfile.chargingProfilePurpose
     logger.debug(
       `${chargingStation.logPrefix()} Not allowed to set ${
         chargingProfile.chargingProfilePurpose
-      } charging profile(s) at remote start transaction`
+      } charging profile(s)${chargingProfile.transactionId != null ? ' with transactionId set' : ''} at remote start transaction`
     )
     return false
   }
     )
     return false
   }
@@ -1270,7 +1334,10 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     commandPayload.retrieveDate = convertToDate(commandPayload.retrieveDate)!
     const { retrieveDate } = commandPayload
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     commandPayload.retrieveDate = convertToDate(commandPayload.retrieveDate)!
     const { retrieveDate } = commandPayload
-    if (chargingStation.stationInfo?.firmwareStatus !== OCPP16FirmwareStatus.Installed) {
+    if (
+      chargingStation.stationInfo?.firmwareStatus != null &&
+      chargingStation.stationInfo.firmwareStatus !== OCPP16FirmwareStatus.Installed
+    ) {
       logger.warn(
         `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: firmware update is already in progress`
       )
       logger.warn(
         `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: firmware update is already in progress`
       )
@@ -1459,7 +1526,10 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         const logConfiguration = Configuration.getConfigurationSection<LogConfiguration>(
           ConfigurationSection.log
         )
         const logConfiguration = Configuration.getConfigurationSection<LogConfiguration>(
           ConfigurationSection.log
         )
-        const logFiles = readdirSync(resolve(dirname(fileURLToPath(import.meta.url)), '../'))
+        const logFiles = readdirSync(
+          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+          resolve((fileURLToPath(import.meta.url), '../', dirname(logConfiguration.file!)))
+        )
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           .filter(file => file.endsWith(extname(logConfiguration.file!)))
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           .filter(file => file.endsWith(extname(logConfiguration.file!)))
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -1531,7 +1601,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
         })
         ftpClient?.close()
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         })
         ftpClient?.close()
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        return this.handleIncomingRequestError<GetDiagnosticsResponse>(
+        return handleIncomingRequestError<GetDiagnosticsResponse>(
           chargingStation,
           OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
           error as Error,
           chargingStation,
           OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
           error as Error,
@@ -1601,7 +1671,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_UNKNOWN_VENDOR_ID
     } catch (error) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       return OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_UNKNOWN_VENDOR_ID
     } catch (error) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      return this.handleIncomingRequestError<OCPP16DataTransferResponse>(
+      return handleIncomingRequestError<OCPP16DataTransferResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.DATA_TRANSFER,
         error as Error,
         chargingStation,
         OCPP16IncomingRequestCommand.DATA_TRANSFER,
         error as Error,
@@ -1626,19 +1696,28 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     commandPayload.expiryDate = convertToDate(commandPayload.expiryDate)!
     const { reservationId, idTag, connectorId } = commandPayload
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     commandPayload.expiryDate = convertToDate(commandPayload.expiryDate)!
     const { reservationId, idTag, connectorId } = commandPayload
+    if (!chargingStation.hasConnector(connectorId)) {
+      logger.error(
+        `${chargingStation.logPrefix()} Trying to reserve a non existing connector id ${connectorId}`
+      )
+      return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED
+    }
+    if (connectorId > 0 && !chargingStation.isConnectorAvailable(connectorId)) {
+      return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED
+    }
+    if (connectorId === 0 && !chargingStation.getReserveConnectorZeroSupported()) {
+      return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED
+    }
+    if (!(await OCPP16ServiceUtils.isIdTagAuthorized(chargingStation, connectorId, idTag))) {
+      return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED
+    }
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    const connectorStatus = chargingStation.getConnectorStatus(connectorId)!
+    resetAuthorizeConnectorStatus(connectorStatus)
     let response: OCPP16ReserveNowResponse
     try {
     let response: OCPP16ReserveNowResponse
     try {
-      if (connectorId > 0 && !chargingStation.isConnectorAvailable(connectorId)) {
-        return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED
-      }
-      if (connectorId === 0 && !chargingStation.getReserveConnectorZeroSupported()) {
-        return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED
-      }
-      if (!(await OCPP16ServiceUtils.isIdTagAuthorized(chargingStation, connectorId, idTag))) {
-        return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED
-      }
       await removeExpiredReservations(chargingStation)
       await removeExpiredReservations(chargingStation)
-      switch (chargingStation.getConnectorStatus(connectorId)?.status) {
+      switch (connectorStatus.status) {
         case OCPP16ChargePointStatus.Faulted:
           response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED
           break
         case OCPP16ChargePointStatus.Faulted:
           response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED
           break
@@ -1675,7 +1754,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       chargingStation.getConnectorStatus(connectorId)!.status = OCPP16ChargePointStatus.Available
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       chargingStation.getConnectorStatus(connectorId)!.status = OCPP16ChargePointStatus.Available
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      return this.handleIncomingRequestError<OCPP16ReserveNowResponse>(
+      return handleIncomingRequestError<OCPP16ReserveNowResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.RESERVE_NOW,
         error as Error,
         chargingStation,
         OCPP16IncomingRequestCommand.RESERVE_NOW,
         error as Error,
@@ -1713,11 +1792,13 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
       return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_ACCEPTED
     } catch (error) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_ACCEPTED
     } catch (error) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      return this.handleIncomingRequestError<GenericResponse>(
+      return handleIncomingRequestError<GenericResponse>(
         chargingStation,
         OCPP16IncomingRequestCommand.CANCEL_RESERVATION,
         error as Error,
         chargingStation,
         OCPP16IncomingRequestCommand.CANCEL_RESERVATION,
         error as Error,
-        { errorResponse: OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED }
+        {
+          errorResponse: OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED
+        }
       )!
     }
   }
       )!
     }
   }
index b9643469a791831937d9774e4ef0b9fb68abacbf..6f772e0700d52f8c77280304f41ec7ae564ba7d4 100644 (file)
@@ -172,7 +172,7 @@ export class OCPP16RequestService extends OCPPRequestService {
   ): Promise<ResponseType> {
     // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
     if (OCPP16ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) {
   ): Promise<ResponseType> {
     // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
     if (OCPP16ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) {
-      // Post request actions hook
+      // Pre request actions hook
       switch (commandName) {
         case OCPP16RequestCommand.START_TRANSACTION:
           await OCPP16ServiceUtils.sendAndSetConnectorStatus(
       switch (commandName) {
         case OCPP16RequestCommand.START_TRANSACTION:
           await OCPP16ServiceUtils.sendAndSetConnectorStatus(
@@ -193,7 +193,7 @@ export class OCPP16RequestService extends OCPPRequestService {
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
       ErrorType.NOT_SUPPORTED,
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
       ErrorType.NOT_SUPPORTED,
-      `Unsupported OCPP command '${commandName}'`,
+      `Unsupported OCPP command ${commandName}`,
       commandName,
       commandParams
     )
       commandName,
       commandParams
     )
@@ -277,7 +277,7 @@ export class OCPP16RequestService extends OCPPRequestService {
         throw new OCPPError(
           ErrorType.NOT_SUPPORTED,
           // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
         throw new OCPPError(
           ErrorType.NOT_SUPPORTED,
           // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-          `Unsupported OCPP command '${commandName}'`,
+          `Unsupported OCPP command ${commandName}`,
           commandName,
           commandParams
         )
           commandName,
           commandParams
         )
index e6c3b43472c8ef0975f3e855deebf51b7c013919..df8374214f8e8865fea5453e9ae4075ea5ee2ece 100644 (file)
@@ -13,6 +13,7 @@ import {
 import { OCPPError } from '../../../exception/index.js'
 import {
   type ChangeConfigurationResponse,
 import { OCPPError } from '../../../exception/index.js'
 import {
   type ChangeConfigurationResponse,
+  ChargingStationEvents,
   ErrorType,
   type GenericResponse,
   type GetConfigurationResponse,
   ErrorType,
   type GenericResponse,
   type GetConfigurationResponse,
@@ -468,7 +469,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle response PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle response PDU ${JSON.stringify(
             payload,
             undefined,
             2
             payload,
             undefined,
             2
@@ -509,24 +510,30 @@ export class OCPP16ResponseService extends OCPPResponseService {
     chargingStation: ChargingStation,
     payload: OCPP16BootNotificationResponse
   ): void {
     chargingStation: ChargingStation,
     payload: OCPP16BootNotificationResponse
   ): void {
-    if (payload.status === RegistrationStatusEnumType.ACCEPTED) {
-      addConfigurationKey(
-        chargingStation,
-        OCPP16StandardParametersKey.HeartbeatInterval,
-        payload.interval.toString(),
-        {},
-        { overwrite: true, save: true }
-      )
-      addConfigurationKey(
-        chargingStation,
-        OCPP16StandardParametersKey.HeartBeatInterval,
-        payload.interval.toString(),
-        { visible: false },
-        { overwrite: true, save: true }
-      )
-      OCPP16ServiceUtils.startHeartbeatInterval(chargingStation, payload.interval)
-    }
     if (Object.values(RegistrationStatusEnumType).includes(payload.status)) {
     if (Object.values(RegistrationStatusEnumType).includes(payload.status)) {
+      chargingStation.bootNotificationResponse = payload
+      if (chargingStation.isRegistered()) {
+        chargingStation.emit(ChargingStationEvents.registered)
+        if (chargingStation.inAcceptedState()) {
+          addConfigurationKey(
+            chargingStation,
+            OCPP16StandardParametersKey.HeartbeatInterval,
+            payload.interval.toString(),
+            {},
+            { overwrite: true, save: true }
+          )
+          addConfigurationKey(
+            chargingStation,
+            OCPP16StandardParametersKey.HeartBeatInterval,
+            payload.interval.toString(),
+            { visible: false },
+            { overwrite: true, save: true }
+          )
+          chargingStation.emit(ChargingStationEvents.accepted)
+        }
+      } else if (chargingStation.inRejectedState()) {
+        chargingStation.emit(ChargingStationEvents.rejected)
+      }
       const logMsg = `${chargingStation.logPrefix()} Charging station in '${
         payload.status
       }' state on the central server`
       const logMsg = `${chargingStation.logPrefix()} Charging station in '${
         payload.status
       }' state on the central server`
@@ -534,6 +541,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
         ? logger.warn(logMsg)
         : logger.info(logMsg)
     } else {
         ? logger.warn(logMsg)
         : logger.info(logMsg)
     } else {
+      delete chargingStation.bootNotificationResponse
       logger.error(
         `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
         payload
       logger.error(
         `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
         payload
@@ -583,9 +591,9 @@ export class OCPP16ResponseService extends OCPPResponseService {
         authorizeConnectorStatus.idTagAuthorized = false
         delete authorizeConnectorStatus.authorizeIdTag
         logger.debug(
         authorizeConnectorStatus.idTagAuthorized = false
         delete authorizeConnectorStatus.authorizeIdTag
         logger.debug(
-          `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${
-            payload.idTagInfo.status
-          }'`
+          `${chargingStation.logPrefix()} idTag '${
+            requestPayload.idTag
+          }' rejected with status '${payload.idTagInfo.status}'`
         )
       }
     } else {
         )
       }
     } else {
@@ -642,6 +650,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
     }
     if (
       connectorStatus?.idTagAuthorized === true &&
     }
     if (
       connectorStatus?.idTagAuthorized === true &&
+      connectorStatus.authorizeIdTag != null &&
       connectorStatus.authorizeIdTag !== requestPayload.idTag
     ) {
       logger.error(
       connectorStatus.authorizeIdTag !== requestPayload.idTag
     ) {
       logger.error(
@@ -656,6 +665,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
     }
     if (
       connectorStatus?.idTagLocalAuthorized === true &&
     }
     if (
       connectorStatus?.idTagLocalAuthorized === true &&
+      connectorStatus.localAuthorizeIdTag != null &&
       connectorStatus.localAuthorizeIdTag !== requestPayload.idTag
     ) {
       logger.error(
       connectorStatus.localAuthorizeIdTag !== requestPayload.idTag
     ) {
       logger.error(
@@ -698,7 +708,9 @@ export class OCPP16ResponseService extends OCPPResponseService {
       connectorStatus?.status !== OCPP16ChargePointStatus.Preparing
     ) {
       logger.error(
       connectorStatus?.status !== OCPP16ChargePointStatus.Preparing
     ) {
       logger.error(
-        `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with status ${connectorStatus?.status}`
+        `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with status ${
+          connectorStatus?.status
+        }`
       )
       return
     }
       )
       return
     }
@@ -733,9 +745,9 @@ export class OCPP16ResponseService extends OCPPResponseService {
             logger.warn(
               `${chargingStation.logPrefix()} Reserved transaction ${
                 payload.transactionId
             logger.warn(
               `${chargingStation.logPrefix()} Reserved transaction ${
                 payload.transactionId
-              } started with a different idTag ${requestPayload.idTag} than the reservation one ${
-                reservation.idTag
-              }`
+              } started with a different idTag ${
+                requestPayload.idTag
+              } than the reservation one ${reservation.idTag}`
             )
           }
           if (hasReservationExpired(reservation)) {
             )
           }
           if (hasReservationExpired(reservation)) {
@@ -774,11 +786,9 @@ export class OCPP16ResponseService extends OCPPResponseService {
         OCPP16ChargePointStatus.Charging
       )
       logger.info(
         OCPP16ChargePointStatus.Charging
       )
       logger.info(
-        `${chargingStation.logPrefix()} Transaction with id ${
-          payload.transactionId
-        } STARTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${
-          requestPayload.idTag
-        }'`
+        `${chargingStation.logPrefix()} Transaction with id ${payload.transactionId} STARTED on ${
+          chargingStation.stationInfo?.chargingStationId
+        }#${connectorId} for idTag '${requestPayload.idTag}'`
       )
       if (chargingStation.stationInfo?.powerSharedByConnectors === true) {
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       )
       if (chargingStation.stationInfo?.powerSharedByConnectors === true) {
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
index 7acf7aef03ba32df4c3631a91d7ffff164b556ac..b4c73bc28963e7f998c625ce40a9257c16d274fb 100644 (file)
@@ -13,7 +13,10 @@ export class OCPP20Constants extends OCPPConstants {
         from: OCPP20ConnectorStatusEnumType.Available,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
         from: OCPP20ConnectorStatusEnumType.Available,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
-      { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Faulted },
+      {
+        from: OCPP20ConnectorStatusEnumType.Available,
+        to: OCPP20ConnectorStatusEnumType.Faulted
+      },
       { to: OCPP20ConnectorStatusEnumType.Unavailable },
       {
         from: OCPP20ConnectorStatusEnumType.Unavailable,
       { to: OCPP20ConnectorStatusEnumType.Unavailable },
       {
         from: OCPP20ConnectorStatusEnumType.Unavailable,
@@ -28,7 +31,10 @@ export class OCPP20Constants extends OCPPConstants {
         to: OCPP20ConnectorStatusEnumType.Faulted
       },
       { to: OCPP20ConnectorStatusEnumType.Faulted },
         to: OCPP20ConnectorStatusEnumType.Faulted
       },
       { to: OCPP20ConnectorStatusEnumType.Faulted },
-      { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Available },
+      {
+        from: OCPP20ConnectorStatusEnumType.Faulted,
+        to: OCPP20ConnectorStatusEnumType.Available
+      },
       {
         from: OCPP20ConnectorStatusEnumType.Faulted,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       {
         from: OCPP20ConnectorStatusEnumType.Faulted,
         to: OCPP20ConnectorStatusEnumType.Unavailable
@@ -40,31 +46,55 @@ export class OCPP20Constants extends OCPPConstants {
     [
       { to: OCPP20ConnectorStatusEnumType.Available },
       // { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Available },
     [
       { to: OCPP20ConnectorStatusEnumType.Available },
       // { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Available },
-      { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Occupied },
-      { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Reserved },
+      {
+        from: OCPP20ConnectorStatusEnumType.Available,
+        to: OCPP20ConnectorStatusEnumType.Occupied
+      },
+      {
+        from: OCPP20ConnectorStatusEnumType.Available,
+        to: OCPP20ConnectorStatusEnumType.Reserved
+      },
       {
         from: OCPP20ConnectorStatusEnumType.Available,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
       {
         from: OCPP20ConnectorStatusEnumType.Available,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
-      { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Faulted },
+      {
+        from: OCPP20ConnectorStatusEnumType.Available,
+        to: OCPP20ConnectorStatusEnumType.Faulted
+      },
       // { to: OCPP20ConnectorStatusEnumType.Occupied },
       // { to: OCPP20ConnectorStatusEnumType.Occupied },
-      { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Available },
+      {
+        from: OCPP20ConnectorStatusEnumType.Occupied,
+        to: OCPP20ConnectorStatusEnumType.Available
+      },
       // { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Occupied },
       // { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Reserved },
       {
         from: OCPP20ConnectorStatusEnumType.Occupied,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
       // { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Occupied },
       // { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Reserved },
       {
         from: OCPP20ConnectorStatusEnumType.Occupied,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
-      { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Faulted },
+      {
+        from: OCPP20ConnectorStatusEnumType.Occupied,
+        to: OCPP20ConnectorStatusEnumType.Faulted
+      },
       // { to: OCPP20ConnectorStatusEnumType.Reserved },
       // { to: OCPP20ConnectorStatusEnumType.Reserved },
-      { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Available },
-      { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Occupied },
+      {
+        from: OCPP20ConnectorStatusEnumType.Reserved,
+        to: OCPP20ConnectorStatusEnumType.Available
+      },
+      {
+        from: OCPP20ConnectorStatusEnumType.Reserved,
+        to: OCPP20ConnectorStatusEnumType.Occupied
+      },
       // { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Reserved },
       {
         from: OCPP20ConnectorStatusEnumType.Reserved,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
       // { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Reserved },
       {
         from: OCPP20ConnectorStatusEnumType.Reserved,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       },
-      { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Faulted },
+      {
+        from: OCPP20ConnectorStatusEnumType.Reserved,
+        to: OCPP20ConnectorStatusEnumType.Faulted
+      },
       { to: OCPP20ConnectorStatusEnumType.Unavailable },
       {
         from: OCPP20ConnectorStatusEnumType.Unavailable,
       { to: OCPP20ConnectorStatusEnumType.Unavailable },
       {
         from: OCPP20ConnectorStatusEnumType.Unavailable,
@@ -81,9 +111,18 @@ export class OCPP20Constants extends OCPPConstants {
         to: OCPP20ConnectorStatusEnumType.Faulted
       },
       { to: OCPP20ConnectorStatusEnumType.Faulted },
         to: OCPP20ConnectorStatusEnumType.Faulted
       },
       { to: OCPP20ConnectorStatusEnumType.Faulted },
-      { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Available },
-      { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Occupied },
-      { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Reserved },
+      {
+        from: OCPP20ConnectorStatusEnumType.Faulted,
+        to: OCPP20ConnectorStatusEnumType.Available
+      },
+      {
+        from: OCPP20ConnectorStatusEnumType.Faulted,
+        to: OCPP20ConnectorStatusEnumType.Occupied
+      },
+      {
+        from: OCPP20ConnectorStatusEnumType.Faulted,
+        to: OCPP20ConnectorStatusEnumType.Reserved
+      },
       {
         from: OCPP20ConnectorStatusEnumType.Faulted,
         to: OCPP20ConnectorStatusEnumType.Unavailable
       {
         from: OCPP20ConnectorStatusEnumType.Faulted,
         to: OCPP20ConnectorStatusEnumType.Unavailable
index b1cd51fc8e935a7cebfe05a935a623ca4e41dc6c..4ae587d43f7de90a119341843b8682985c95dccc 100644 (file)
@@ -109,7 +109,7 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle request PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle request PDU ${JSON.stringify(
             commandPayload,
             undefined,
             2
             commandPayload,
             undefined,
             2
index c9c4b17b24d6060e7ac102e9ab70664f97c2d13a..38dbedf87f9b7f426507cfa8e92bf42ca5ef606d 100644 (file)
@@ -80,7 +80,7 @@ export class OCPP20RequestService extends OCPPRequestService {
   ): Promise<ResponseType> {
     // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
     if (OCPP20ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) {
   ): Promise<ResponseType> {
     // FIXME?: add sanity checks on charging station availability, connector availability, connector status, etc.
     if (OCPP20ServiceUtils.isRequestCommandSupported(chargingStation, commandName)) {
-      // TODO: post request actions hook
+      // TODO: pre request actions hook
       return (await this.sendMessage(
         chargingStation,
         generateUUID(),
       return (await this.sendMessage(
         chargingStation,
         generateUUID(),
@@ -92,7 +92,7 @@ export class OCPP20RequestService extends OCPPRequestService {
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
       ErrorType.NOT_SUPPORTED,
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
       ErrorType.NOT_SUPPORTED,
-      `Unsupported OCPP command '${commandName}'`,
+      `Unsupported OCPP command ${commandName}`,
       commandName,
       commandParams
     )
       commandName,
       commandParams
     )
@@ -119,7 +119,7 @@ export class OCPP20RequestService extends OCPPRequestService {
         throw new OCPPError(
           ErrorType.NOT_SUPPORTED,
           // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
         throw new OCPPError(
           ErrorType.NOT_SUPPORTED,
           // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-          `Unsupported OCPP command '${commandName}'`,
+          `Unsupported OCPP command ${commandName}`,
           commandName,
           commandParams
         )
           commandName,
           commandParams
         )
index 6ab91c074d01ec4f24b01a4c5fbdffb374ad1fa9..9851d3339371d8fe3e47cb7a5dcaa835d7bcace0 100644 (file)
@@ -5,6 +5,7 @@ import type { ValidateFunction } from 'ajv'
 import { addConfigurationKey, type ChargingStation } from '../../../charging-station/index.js'
 import { OCPPError } from '../../../exception/index.js'
 import {
 import { addConfigurationKey, type ChargingStation } from '../../../charging-station/index.js'
 import { OCPPError } from '../../../exception/index.js'
 import {
+  ChargingStationEvents,
   ErrorType,
   type JsonType,
   type OCPP20BootNotificationResponse,
   ErrorType,
   type JsonType,
   type OCPP20BootNotificationResponse,
@@ -141,7 +142,7 @@ export class OCPP20ResponseService extends OCPPResponseService {
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
         // Throw exception
         throw new OCPPError(
           ErrorType.NOT_IMPLEMENTED,
-          `'${commandName}' is not implemented to handle response PDU ${JSON.stringify(
+          `${commandName} is not implemented to handle response PDU ${JSON.stringify(
             payload,
             undefined,
             2
             payload,
             undefined,
             2
@@ -182,17 +183,23 @@ export class OCPP20ResponseService extends OCPPResponseService {
     chargingStation: ChargingStation,
     payload: OCPP20BootNotificationResponse
   ): void {
     chargingStation: ChargingStation,
     payload: OCPP20BootNotificationResponse
   ): void {
-    if (payload.status === RegistrationStatusEnumType.ACCEPTED) {
-      addConfigurationKey(
-        chargingStation,
-        OCPP20OptionalVariableName.HeartbeatInterval,
-        payload.interval.toString(),
-        {},
-        { overwrite: true, save: true }
-      )
-      OCPP20ServiceUtils.startHeartbeatInterval(chargingStation, payload.interval)
-    }
     if (Object.values(RegistrationStatusEnumType).includes(payload.status)) {
     if (Object.values(RegistrationStatusEnumType).includes(payload.status)) {
+      chargingStation.bootNotificationResponse = payload
+      if (chargingStation.isRegistered()) {
+        chargingStation.emit(ChargingStationEvents.registered)
+        if (chargingStation.inAcceptedState()) {
+          addConfigurationKey(
+            chargingStation,
+            OCPP20OptionalVariableName.HeartbeatInterval,
+            payload.interval.toString(),
+            {},
+            { overwrite: true, save: true }
+          )
+          chargingStation.emit(ChargingStationEvents.accepted)
+        }
+      } else if (chargingStation.inRejectedState()) {
+        chargingStation.emit(ChargingStationEvents.rejected)
+      }
       const logMsg = `${chargingStation.logPrefix()} Charging station in '${
         payload.status
       }' state on the central server`
       const logMsg = `${chargingStation.logPrefix()} Charging station in '${
         payload.status
       }' state on the central server`
@@ -200,6 +207,7 @@ export class OCPP20ResponseService extends OCPPResponseService {
         ? logger.warn(logMsg)
         : logger.info(logMsg)
     } else {
         ? logger.warn(logMsg)
         : logger.info(logMsg)
     } else {
+      delete chargingStation.bootNotificationResponse
       logger.error(
         `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
         payload
       logger.error(
         `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`,
         payload
index b036738719944fae935f62c03ec137c06acca761..2abb197892d1bb1dc35e0dd87d0739d37e9f3d58 100644 (file)
@@ -26,8 +26,13 @@ export class OCPPConstants {
 
   static readonly OCPP_REQUEST_EMPTY = Constants.EMPTY_FROZEN_OBJECT
   static readonly OCPP_RESPONSE_EMPTY = Constants.EMPTY_FROZEN_OBJECT
 
   static readonly OCPP_REQUEST_EMPTY = Constants.EMPTY_FROZEN_OBJECT
   static readonly OCPP_RESPONSE_EMPTY = Constants.EMPTY_FROZEN_OBJECT
-  static readonly OCPP_RESPONSE_ACCEPTED = Object.freeze({ status: GenericStatus.Accepted })
-  static readonly OCPP_RESPONSE_REJECTED = Object.freeze({ status: GenericStatus.Rejected })
+  static readonly OCPP_RESPONSE_ACCEPTED = Object.freeze({
+    status: GenericStatus.Accepted
+  })
+
+  static readonly OCPP_RESPONSE_REJECTED = Object.freeze({
+    status: GenericStatus.Rejected
+  })
 
   static readonly OCPP_CONFIGURATION_RESPONSE_ACCEPTED = Object.freeze({
     status: ConfigurationStatus.ACCEPTED
 
   static readonly OCPP_CONFIGURATION_RESPONSE_ACCEPTED = Object.freeze({
     status: ConfigurationStatus.ACCEPTED
@@ -65,7 +70,10 @@ export class OCPPConstants {
     status: ClearChargingProfileStatus.UNKNOWN
   })
 
     status: ClearChargingProfileStatus.UNKNOWN
   })
 
-  static readonly OCPP_RESPONSE_UNLOCKED = Object.freeze({ status: UnlockStatus.UNLOCKED })
+  static readonly OCPP_RESPONSE_UNLOCKED = Object.freeze({
+    status: UnlockStatus.UNLOCKED
+  })
+
   static readonly OCPP_RESPONSE_UNLOCK_FAILED = Object.freeze({
     status: UnlockStatus.UNLOCK_FAILED
   })
   static readonly OCPP_RESPONSE_UNLOCK_FAILED = Object.freeze({
     status: UnlockStatus.UNLOCK_FAILED
   })
index 7c88547a6c63ce285e2009e6561b9d813fc99b53..545438d5d61dda84a995c1c4351562a1c8a94e1b 100644 (file)
@@ -7,14 +7,13 @@ import { type ChargingStation, getIdTagsFile } from '../../charging-station/inde
 import { OCPPError } from '../../exception/index.js'
 import type {
   ClearCacheResponse,
 import { OCPPError } from '../../exception/index.js'
 import type {
   ClearCacheResponse,
-  HandleErrorParams,
   IncomingRequestCommand,
   JsonType,
   OCPPVersion
 } from '../../types/index.js'
   IncomingRequestCommand,
   JsonType,
   OCPPVersion
 } from '../../types/index.js'
-import { logger, setDefaultErrorParams } from '../../utils/index.js'
+import { logger } from '../../utils/index.js'
 import { OCPPConstants } from './OCPPConstants.js'
 import { OCPPConstants } from './OCPPConstants.js'
-import { OCPPServiceUtils } from './OCPPServiceUtils.js'
+import { ajvErrorsToErrorType } from './OCPPServiceUtils.js'
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
@@ -50,28 +49,6 @@ export abstract class OCPPIncomingRequestService extends EventEmitter {
     return OCPPIncomingRequestService.instance as T
   }
 
     return OCPPIncomingRequestService.instance as T
   }
 
-  protected handleIncomingRequestError<T extends JsonType>(
-    chargingStation: ChargingStation,
-    commandName: IncomingRequestCommand,
-    error: Error,
-    params: HandleErrorParams<T> = { throwError: true, consoleOut: false }
-  ): T | undefined {
-    setDefaultErrorParams(params)
-    logger.error(
-      `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
-      error
-    )
-    if (params.throwError === false && params.errorResponse != null) {
-      return params.errorResponse
-    }
-    if (params.throwError === true && params.errorResponse == null) {
-      throw error
-    }
-    if (params.throwError === true && params.errorResponse != null) {
-      return params.errorResponse
-    }
-  }
-
   protected validateIncomingRequestPayload<T extends JsonType>(
     chargingStation: ChargingStation,
     commandName: IncomingRequestCommand,
   protected validateIncomingRequestPayload<T extends JsonType>(
     chargingStation: ChargingStation,
     commandName: IncomingRequestCommand,
@@ -89,7 +66,7 @@ export abstract class OCPPIncomingRequestService extends EventEmitter {
       validate?.errors
     )
     throw new OCPPError(
       validate?.errors
     )
     throw new OCPPError(
-      OCPPServiceUtils.ajvErrorsToErrorType(validate?.errors),
+      ajvErrorsToErrorType(validate?.errors),
       'Incoming request PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
       'Incoming request PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
index 3a27a1923d7a0234efed3c223337e7e26ba2347f..48aca2ccafb2fe79b6adab93bd2894c372d790cf 100644 (file)
@@ -28,7 +28,11 @@ import {
 } from '../../utils/index.js'
 import { OCPPConstants } from './OCPPConstants.js'
 import type { OCPPResponseService } from './OCPPResponseService.js'
 } from '../../utils/index.js'
 import { OCPPConstants } from './OCPPConstants.js'
 import type { OCPPResponseService } from './OCPPResponseService.js'
-import { OCPPServiceUtils } from './OCPPServiceUtils.js'
+import {
+  ajvErrorsToErrorType,
+  convertDateToISOString,
+  getMessageTypeString
+} from './OCPPServiceUtils.js'
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
@@ -94,9 +98,15 @@ export abstract class OCPPRequestService {
         commandName
       )
     } catch (error) {
         commandName
       )
     } catch (error) {
-      handleSendMessageError(chargingStation, commandName, error as Error, {
-        throwError: true
-      })
+      handleSendMessageError(
+        chargingStation,
+        commandName,
+        MessageType.CALL_RESULT_MESSAGE,
+        error as Error,
+        {
+          throwError: true
+        }
+      )
       return null
     }
   }
       return null
     }
   }
@@ -117,7 +127,12 @@ export abstract class OCPPRequestService {
         commandName
       )
     } catch (error) {
         commandName
       )
     } catch (error) {
-      handleSendMessageError(chargingStation, commandName, error as Error)
+      handleSendMessageError(
+        chargingStation,
+        commandName,
+        MessageType.CALL_ERROR_MESSAGE,
+        error as Error
+      )
       return null
     }
   }
       return null
     }
   }
@@ -143,9 +158,15 @@ export abstract class OCPPRequestService {
         params
       )
     } catch (error) {
         params
       )
     } catch (error) {
-      handleSendMessageError(chargingStation, commandName, error as Error, {
-        throwError: params.throwError
-      })
+      handleSendMessageError(
+        chargingStation,
+        commandName,
+        MessageType.CALL_MESSAGE,
+        error as Error,
+        {
+          throwError: params.throwError
+        }
+      )
       return null
     }
   }
       return null
     }
   }
@@ -166,7 +187,7 @@ export abstract class OCPPRequestService {
     }
     const validate = this.payloadValidateFunctions.get(commandName as RequestCommand)
     payload = clone<T>(payload)
     }
     const validate = this.payloadValidateFunctions.get(commandName as RequestCommand)
     payload = clone<T>(payload)
-    OCPPServiceUtils.convertDateToISOString<T>(payload)
+    convertDateToISOString<T>(payload)
     if (validate?.(payload) === true) {
       return true
     }
     if (validate?.(payload) === true) {
       return true
     }
@@ -176,7 +197,7 @@ export abstract class OCPPRequestService {
     )
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
     )
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
-      OCPPServiceUtils.ajvErrorsToErrorType(validate?.errors),
+      ajvErrorsToErrorType(validate?.errors),
       'Request PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
       'Request PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
@@ -205,7 +226,7 @@ export abstract class OCPPRequestService {
       commandName as IncomingRequestCommand
     )
     payload = clone<T>(payload)
       commandName as IncomingRequestCommand
     )
     payload = clone<T>(payload)
-    OCPPServiceUtils.convertDateToISOString<T>(payload)
+    convertDateToISOString<T>(payload)
     if (validate?.(payload) === true) {
       return true
     }
     if (validate?.(payload) === true) {
       return true
     }
@@ -215,7 +236,7 @@ export abstract class OCPPRequestService {
     )
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
     )
     // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
     throw new OCPPError(
-      OCPPServiceUtils.ajvErrorsToErrorType(validate?.errors),
+      ajvErrorsToErrorType(validate?.errors),
       'Response PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
       'Response PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
@@ -291,7 +312,7 @@ export abstract class OCPPRequestService {
             )
           }
           logger.error(
             )
           }
           logger.error(
-            `${chargingStation.logPrefix()} Error occurred at ${OCPPServiceUtils.getMessageTypeString(
+            `${chargingStation.logPrefix()} Error occurred at ${getMessageTypeString(
               messageType
             )} command ${commandName} with PDU %j:`,
             messagePayload,
               messageType
             )} command ${commandName} with PDU %j:`,
             messagePayload,
@@ -358,7 +379,7 @@ export abstract class OCPPRequestService {
             clearTimeout(sendTimeout)
             if (error == null) {
               logger.debug(
             clearTimeout(sendTimeout)
             if (error == null) {
               logger.debug(
-                `${chargingStation.logPrefix()} >> Command '${commandName}' sent ${OCPPServiceUtils.getMessageTypeString(
+                `${chargingStation.logPrefix()} >> Command '${commandName}' sent ${getMessageTypeString(
                   messageType
                 )} payload: ${messageToSend}`
               )
                   messageType
                 )} payload: ${messageToSend}`
               )
@@ -383,7 +404,11 @@ export abstract class OCPPRequestService {
                     params.skipBufferingOnError === false ? '' : 'non '
                   }buffered message id '${messageId}' with content '${messageToSend}'`,
                   commandName,
                     params.skipBufferingOnError === false ? '' : 'non '
                   }buffered message id '${messageId}' with content '${messageToSend}'`,
                   commandName,
-                  { name: error.name, message: error.message, stack: error.stack }
+                  {
+                    name: error.name,
+                    message: error.message,
+                    stack: error.stack
+                  }
                 )
               )
             }
                 )
               )
             }
index 0e9c6164d299a927dd8adf3f58a15d7247e6ced6..00d539b7c214b1f4ed973299d31836dbcf4b2ae3 100644 (file)
@@ -10,7 +10,7 @@ import type {
   RequestCommand
 } from '../../types/index.js'
 import { Constants, logger } from '../../utils/index.js'
   RequestCommand
 } from '../../types/index.js'
 import { Constants, logger } from '../../utils/index.js'
-import { OCPPServiceUtils } from './OCPPServiceUtils.js'
+import { ajvErrorsToErrorType } from './OCPPServiceUtils.js'
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
 type Ajv = _Ajv.default
 // eslint-disable-next-line @typescript-eslint/no-redeclare
 const Ajv = _Ajv.default
@@ -69,7 +69,7 @@ export abstract class OCPPResponseService {
       validate?.errors
     )
     throw new OCPPError(
       validate?.errors
     )
     throw new OCPPError(
-      OCPPServiceUtils.ajvErrorsToErrorType(validate?.errors),
+      ajvErrorsToErrorType(validate?.errors),
       'Response PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
       'Response PDU is invalid',
       commandName,
       JSON.stringify(validate?.errors, undefined, 2)
index 256544fa50090a5a88319f08fdcbe47c2c845f05..b077b03a6603610c8464c07170f5e6d07df77802 100644 (file)
@@ -264,6 +264,38 @@ const checkConnectorStatusTransition = (
   return transitionAllowed
 }
 
   return transitionAllowed
 }
 
+export const ajvErrorsToErrorType = (errors: ErrorObject[] | undefined | null): ErrorType => {
+  if (isNotEmptyArray(errors)) {
+    for (const error of errors as DefinedError[]) {
+      switch (error.keyword) {
+        case 'type':
+          return ErrorType.TYPE_CONSTRAINT_VIOLATION
+        case 'dependencies':
+        case 'required':
+          return ErrorType.OCCURRENCE_CONSTRAINT_VIOLATION
+        case 'pattern':
+        case 'format':
+          return ErrorType.PROPERTY_CONSTRAINT_VIOLATION
+      }
+    }
+  }
+  return ErrorType.FORMAT_VIOLATION
+}
+
+export const convertDateToISOString = <T extends JsonType>(object: T): void => {
+  for (const key in object) {
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
+    if (isDate(object![key])) {
+      // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
+      (object![key] as string) = (object![key] as Date).toISOString()
+      // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-condition
+    } else if (typeof object![key] === 'object' && object![key] !== null) {
+      // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
+      convertDateToISOString<T>(object![key] as T)
+    }
+  }
+}
+
 export const buildMeterValue = (
   chargingStation: ChargingStation,
   connectorId: number,
 export const buildMeterValue = (
   chargingStation: ChargingStation,
   connectorId: number,
@@ -273,6 +305,7 @@ export const buildMeterValue = (
 ): MeterValue => {
   const connector = chargingStation.getConnectorStatus(connectorId)
   let meterValue: MeterValue
 ): MeterValue => {
   const connector = chargingStation.getConnectorStatus(connectorId)
   let meterValue: MeterValue
+  let connectorMaximumAvailablePower: number | undefined
   let socSampledValueTemplate: SampledValueTemplate | undefined
   let voltageSampledValueTemplate: SampledValueTemplate | undefined
   let powerSampledValueTemplate: SampledValueTemplate | undefined
   let socSampledValueTemplate: SampledValueTemplate | undefined
   let voltageSampledValueTemplate: SampledValueTemplate | undefined
   let powerSampledValueTemplate: SampledValueTemplate | undefined
@@ -297,7 +330,7 @@ export const buildMeterValue = (
         const socMinimumValue = socSampledValueTemplate.minimumValue ?? 0
         const socSampledValueTemplateValue = isNotEmptyString(socSampledValueTemplate.value)
           ? getRandomFloatFluctuatedRounded(
         const socMinimumValue = socSampledValueTemplate.minimumValue ?? 0
         const socSampledValueTemplateValue = isNotEmptyString(socSampledValueTemplate.value)
           ? getRandomFloatFluctuatedRounded(
-            parseInt(socSampledValueTemplate.value),
+            Number.parseInt(socSampledValueTemplate.value),
             socSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT
           )
           : randomInt(socMinimumValue, socMaximumValue)
             socSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT
           )
           : randomInt(socMinimumValue, socMaximumValue)
@@ -314,7 +347,9 @@ export const buildMeterValue = (
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
-            }: connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${socMinimumValue}/${
+            }: connector id ${connectorId}, transaction id ${
+              connector?.transactionId
+            }, value: ${socMinimumValue}/${
               meterValue.sampledValue[sampledValuesIndex].value
             }/${socMaximumValue}`
           )
               meterValue.sampledValue[sampledValuesIndex].value
             }/${socMaximumValue}`
           )
@@ -328,7 +363,7 @@ export const buildMeterValue = (
       )
       if (voltageSampledValueTemplate != null) {
         const voltageSampledValueTemplateValue = isNotEmptyString(voltageSampledValueTemplate.value)
       )
       if (voltageSampledValueTemplate != null) {
         const voltageSampledValueTemplateValue = isNotEmptyString(voltageSampledValueTemplate.value)
-          ? parseInt(voltageSampledValueTemplate.value)
+          ? Number.parseInt(voltageSampledValueTemplate.value)
           : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           chargingStation.stationInfo.voltageOut!
         const fluctuationPercent =
           : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           chargingStation.stationInfo.voltageOut!
         const fluctuationPercent =
@@ -363,7 +398,7 @@ export const buildMeterValue = (
             const voltagePhaseLineToNeutralSampledValueTemplateValue = isNotEmptyString(
               voltagePhaseLineToNeutralSampledValueTemplate.value
             )
             const voltagePhaseLineToNeutralSampledValueTemplateValue = isNotEmptyString(
               voltagePhaseLineToNeutralSampledValueTemplate.value
             )
-              ? parseInt(voltagePhaseLineToNeutralSampledValueTemplate.value)
+              ? Number.parseInt(voltagePhaseLineToNeutralSampledValueTemplate.value)
               : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
               chargingStation.stationInfo.voltageOut!
             const fluctuationPhaseToNeutralPercent =
               : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
               chargingStation.stationInfo.voltageOut!
             const fluctuationPhaseToNeutralPercent =
@@ -405,7 +440,7 @@ export const buildMeterValue = (
               const voltagePhaseLineToLineSampledValueTemplateValue = isNotEmptyString(
                 voltagePhaseLineToLineSampledValueTemplate.value
               )
               const voltagePhaseLineToLineSampledValueTemplateValue = isNotEmptyString(
                 voltagePhaseLineToLineSampledValueTemplate.value
               )
-                ? parseInt(voltagePhaseLineToLineSampledValueTemplate.value)
+                ? Number.parseInt(voltagePhaseLineToLineSampledValueTemplate.value)
                 : voltagePhaseLineToLineValueRounded
               const fluctuationPhaseLineToLinePercent =
                 voltagePhaseLineToLineSampledValueTemplate.fluctuationPercent ??
                 : voltagePhaseLineToLineValueRounded
               const fluctuationPhaseLineToLinePercent =
                 voltagePhaseLineToLineSampledValueTemplate.fluctuationPercent ??
@@ -470,7 +505,7 @@ export const buildMeterValue = (
         // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
         const powerMeasurandValues: MeasurandValues = {} as MeasurandValues
         const unitDivider = powerSampledValueTemplate.unit === MeterValueUnit.KILO_WATT ? 1000 : 1
         // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
         const powerMeasurandValues: MeasurandValues = {} as MeasurandValues
         const unitDivider = powerSampledValueTemplate.unit === MeterValueUnit.KILO_WATT ? 1000 : 1
-        const connectorMaximumAvailablePower =
+        connectorMaximumAvailablePower =
           chargingStation.getConnectorMaximumAvailablePower(connectorId)
         const connectorMaximumPower = Math.round(connectorMaximumAvailablePower)
         const connectorMaximumPowerPerPhase = Math.round(
           chargingStation.getConnectorMaximumAvailablePower(connectorId)
         const connectorMaximumPower = Math.round(connectorMaximumAvailablePower)
         const connectorMaximumPowerPerPhase = Math.round(
@@ -646,7 +681,9 @@ export const buildMeterValue = (
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
-            }: connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${connectorMinimumPowerRounded}/${
+            }: connector id ${connectorId}, transaction id ${
+              connector?.transactionId
+            }, value: ${connectorMinimumPowerRounded}/${
               meterValue.sampledValue[sampledValuesIndex].value
             }/${connectorMaximumPowerRounded}`
           )
               meterValue.sampledValue[sampledValuesIndex].value
             }/${connectorMaximumPowerRounded}`
           )
@@ -689,7 +726,9 @@ export const buildMeterValue = (
                 MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
               }: phase ${
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].phase
                 MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
               }: phase ${
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].phase
-              }, connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${connectorMinimumPowerPerPhaseRounded}/${
+              }, connector id ${connectorId}, transaction id ${
+                connector?.transactionId
+              }, value: ${connectorMinimumPowerPerPhaseRounded}/${
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].value
               }/${connectorMaximumPowerPerPhaseRounded}`
             )
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].value
               }/${connectorMaximumPowerPerPhaseRounded}`
             )
@@ -736,8 +775,9 @@ export const buildMeterValue = (
         } measurand value`
         // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
         const currentMeasurandValues: MeasurandValues = {} as MeasurandValues
         } measurand value`
         // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
         const currentMeasurandValues: MeasurandValues = {} as MeasurandValues
-        const connectorMaximumAvailablePower =
-          chargingStation.getConnectorMaximumAvailablePower(connectorId)
+        connectorMaximumAvailablePower == null &&
+          (connectorMaximumAvailablePower =
+            chargingStation.getConnectorMaximumAvailablePower(connectorId))
         const connectorMinimumAmperage = currentSampledValueTemplate.minimumValue ?? 0
         let connectorMaximumAmperage: number
         switch (chargingStation.stationInfo.currentOutType) {
         const connectorMinimumAmperage = currentSampledValueTemplate.minimumValue ?? 0
         let connectorMaximumAmperage: number
         switch (chargingStation.stationInfo.currentOutType) {
@@ -901,7 +941,9 @@ export const buildMeterValue = (
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
-            }: connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${connectorMinimumAmperage}/${
+            }: connector id ${connectorId}, transaction id ${
+              connector?.transactionId
+            }, value: ${connectorMinimumAmperage}/${
               meterValue.sampledValue[sampledValuesIndex].value
             }/${connectorMaximumAmperage}`
           )
               meterValue.sampledValue[sampledValuesIndex].value
             }/${connectorMaximumAmperage}`
           )
@@ -936,7 +978,9 @@ export const buildMeterValue = (
                 MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
               }: phase ${
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].phase
                 MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
               }: phase ${
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].phase
-              }, connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${connectorMinimumAmperage}/${
+              }, connector id ${connectorId}, transaction id ${
+                connector?.transactionId
+              }, value: ${connectorMinimumAmperage}/${
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].value
               }/${connectorMaximumAmperage}`
             )
                 meterValue.sampledValue[sampledValuesPerPhaseIndex].value
               }/${connectorMaximumAmperage}`
             )
@@ -949,8 +993,9 @@ export const buildMeterValue = (
         checkMeasurandPowerDivider(chargingStation, energySampledValueTemplate.measurand)
         const unitDivider =
           energySampledValueTemplate.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1
         checkMeasurandPowerDivider(chargingStation, energySampledValueTemplate.measurand)
         const unitDivider =
           energySampledValueTemplate.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1
-        const connectorMaximumAvailablePower =
-          chargingStation.getConnectorMaximumAvailablePower(connectorId)
+        connectorMaximumAvailablePower == null &&
+          (connectorMaximumAvailablePower =
+            chargingStation.getConnectorMaximumAvailablePower(connectorId))
         const connectorMaximumEnergyRounded = roundTo(
           (connectorMaximumAvailablePower * interval) / (3600 * 1000),
           2
         const connectorMaximumEnergyRounded = roundTo(
           (connectorMaximumAvailablePower * interval) / (3600 * 1000),
           2
@@ -1009,7 +1054,9 @@ export const buildMeterValue = (
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
             `${chargingStation.logPrefix()} MeterValues measurand ${
               meterValue.sampledValue[sampledValuesIndex].measurand ??
               MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
-            }: connector id ${connectorId}, transaction id ${connector?.transactionId}, value: ${connectorMinimumEnergyRounded}/${energyValueRounded}/${connectorMaximumEnergyRounded}, duration: ${interval}ms`
+            }: connector id ${connectorId}, transaction id ${
+              connector?.transactionId
+            }, value: ${connectorMinimumEnergyRounded}/${energyValueRounded}/${connectorMaximumEnergyRounded}, duration: ${interval}ms`
           )
         }
       }
           )
         }
       }
@@ -1081,7 +1128,11 @@ const getLimitFromSampledValueTemplateCustomValue = (
   value: string | undefined,
   maxLimit: number,
   minLimit: number,
   value: string | undefined,
   maxLimit: number,
   minLimit: number,
-  options?: { limitationEnabled?: boolean, fallbackValue?: number, unitMultiplier?: number }
+  options?: {
+    limitationEnabled?: boolean
+    fallbackValue?: number
+    unitMultiplier?: number
+  }
 ): number => {
   options = {
     ...{
 ): number => {
   options = {
     ...{
@@ -1091,11 +1142,14 @@ const getLimitFromSampledValueTemplateCustomValue = (
     },
     ...options
   }
     },
     ...options
   }
-  const parsedValue = parseInt(value ?? '')
+  const parsedValue = Number.parseInt(value ?? '')
   if (options.limitationEnabled === true) {
     return max(
   if (options.limitationEnabled === true) {
     return max(
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      min((!isNaN(parsedValue) ? parsedValue : Infinity) * options.unitMultiplier!, maxLimit),
+      min(
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        (!isNaN(parsedValue) ? parsedValue : Number.POSITIVE_INFINITY) * options.unitMultiplier!,
+        maxLimit
+      ),
       minLimit
     )
   }
       minLimit
     )
   }
@@ -1242,7 +1296,6 @@ const getMeasurandDefaultLocation = (
 
 // eslint-disable-next-line @typescript-eslint/no-extraneous-class
 export class OCPPServiceUtils {
 
 // eslint-disable-next-line @typescript-eslint/no-extraneous-class
 export class OCPPServiceUtils {
-  public static readonly getMessageTypeString = getMessageTypeString
   public static readonly sendAndSetConnectorStatus = sendAndSetConnectorStatus
   public static readonly restoreConnectorStatus = restoreConnectorStatus
   public static readonly isIdTagAuthorized = isIdTagAuthorized
   public static readonly sendAndSetConnectorStatus = sendAndSetConnectorStatus
   public static readonly restoreConnectorStatus = restoreConnectorStatus
   public static readonly isIdTagAuthorized = isIdTagAuthorized
@@ -1254,24 +1307,6 @@ export class OCPPServiceUtils {
     // This is intentional
   }
 
     // This is intentional
   }
 
-  public static ajvErrorsToErrorType (errors: ErrorObject[] | undefined | null): ErrorType {
-    if (isNotEmptyArray(errors)) {
-      for (const error of errors as DefinedError[]) {
-        switch (error.keyword) {
-          case 'type':
-            return ErrorType.TYPE_CONSTRAINT_VIOLATION
-          case 'dependencies':
-          case 'required':
-            return ErrorType.OCCURRENCE_CONSTRAINT_VIOLATION
-          case 'pattern':
-          case 'format':
-            return ErrorType.PROPERTY_CONSTRAINT_VIOLATION
-        }
-      }
-    }
-    return ErrorType.FORMAT_VIOLATION
-  }
-
   public static isRequestCommandSupported (
     chargingStation: ChargingStation,
     command: RequestCommand
   public static isRequestCommandSupported (
     chargingStation: ChargingStation,
     command: RequestCommand
@@ -1346,28 +1381,6 @@ export class OCPPServiceUtils {
     return true
   }
 
     return true
   }
 
-  public static convertDateToISOString<T extends JsonType>(object: T): void {
-    for (const key in object) {
-      // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
-      if (isDate(object![key])) {
-        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
-        (object![key] as string) = (object![key] as Date).toISOString()
-        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-condition
-      } else if (typeof object![key] === 'object' && object![key] !== null) {
-        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion
-        OCPPServiceUtils.convertDateToISOString<T>(object![key] as T)
-      }
-    }
-  }
-
-  public static startHeartbeatInterval (chargingStation: ChargingStation, interval: number): void {
-    if (chargingStation.heartbeatSetInterval == null) {
-      chargingStation.startHeartbeat()
-    } else if (chargingStation.getHeartbeatInterval() !== interval) {
-      chargingStation.restartHeartbeat()
-    }
-  }
-
   protected static parseJsonSchemaFile<T extends JsonType>(
     relativePath: string,
     ocppVersion: OCPPVersion,
   protected static parseJsonSchemaFile<T extends JsonType>(
     relativePath: string,
     ocppVersion: OCPPVersion,
index 9d2705f28f677f37ffcc869c60587ade090745f5..a786fbbddc2ed43623316f297a7f5ac94503d474 100644 (file)
@@ -166,7 +166,9 @@ export abstract class AbstractUIServer {
     const authorizationProtocol = req.headers['sec-websocket-protocol']?.split(/,\s+/).pop()
     const [username, password] = getUsernameAndPasswordFromAuthorizationToken(
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     const authorizationProtocol = req.headers['sec-websocket-protocol']?.split(/,\s+/).pop()
     const [username, password] = getUsernameAndPasswordFromAuthorizationToken(
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      `${authorizationProtocol}${Array(((4 - (authorizationProtocol!.length % 4)) % 4) + 1).join('=')}`
+      `${authorizationProtocol}${Array(((4 - (authorizationProtocol!.length % 4)) % 4) + 1).join(
+        '='
+      )}`
         .split('.')
         .pop() ?? '',
       next
         .split('.')
         .pop() ?? '',
       next
index 34138e02b0204636b79d5ab884fe9f6328514d8f..cf176bdc0403d2be85890204ba7b67e06f9b6c4a 100644 (file)
@@ -68,8 +68,10 @@ export class UIServerFactory {
             uiServerConfiguration.type as ApplicationProtocol
           )
         ) {
             uiServerConfiguration.type as ApplicationProtocol
           )
         ) {
-          // eslint-disable-next-line @typescript-eslint/no-base-to-string
-          const logMsg = `Unknown application protocol type '${uiServerConfiguration.type}' in '${ConfigurationSection.uiServer}' configuration section from values '${ApplicationProtocol.toString()}', defaulting to '${
+          const logMsg = `Unknown application protocol type '${uiServerConfiguration.type}' in '${
+            ConfigurationSection.uiServer
+            // eslint-disable-next-line @typescript-eslint/no-base-to-string
+          }' configuration section from values '${ApplicationProtocol.toString()}', defaulting to '${
             ApplicationProtocol.WS
           }'`
           logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`)
             ApplicationProtocol.WS
           }'`
           logger.warn(`${UIServerFactory.logPrefix()} ${logMsg}`)
index 265cb6c963918b1a3970a95e5822742f3202c0d4..864446c6ce30ee1bad805c65a61eec9b46755e2d 100644 (file)
@@ -5,6 +5,7 @@ import type { URL } from 'node:url'
 import { parentPort } from 'node:worker_threads'
 
 import { secondsToMilliseconds } from 'date-fns'
 import { parentPort } from 'node:worker_threads'
 
 import { secondsToMilliseconds } from 'date-fns'
+import { CircularBuffer } from 'mnemonist'
 import { is, mean, median } from 'rambda'
 
 import { BaseError } from '../exception/index.js'
 import { is, mean, median } from 'rambda'
 
 import { BaseError } from '../exception/index.js'
@@ -22,7 +23,6 @@ import {
 } from '../types/index.js'
 import {
   buildPerformanceStatisticsMessage,
 } from '../types/index.js'
 import {
   buildPerformanceStatisticsMessage,
-  CircularArray,
   Configuration,
   Constants,
   extractTimeSeriesValues,
   Configuration,
   Constants,
   extractTimeSeriesValues,
@@ -179,9 +179,9 @@ export class PerformanceStatistics {
       )
     if (performanceStorageConfiguration.enabled === true) {
       logger.info(
       )
     if (performanceStorageConfiguration.enabled === true) {
       logger.info(
-        `${this.logPrefix()} storage enabled: type ${performanceStorageConfiguration.type}, uri: ${
-          performanceStorageConfiguration.uri
-        }`
+        `${this.logPrefix()} storage enabled: type ${
+          performanceStorageConfiguration.type
+        }, uri: ${performanceStorageConfiguration.uri}`
       )
     }
   }
       )
     }
   }
@@ -267,29 +267,37 @@ export class PerformanceStatistics {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.minTimeMeasurement = min(
       entry.duration,
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.minTimeMeasurement = min(
       entry.duration,
-      this.statistics.statisticsData.get(entry.name)?.minTimeMeasurement ?? Infinity
+      this.statistics.statisticsData.get(entry.name)?.minTimeMeasurement ?? Number.POSITIVE_INFINITY
     )
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.maxTimeMeasurement = max(
       entry.duration,
     )
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.maxTimeMeasurement = max(
       entry.duration,
-      this.statistics.statisticsData.get(entry.name)?.maxTimeMeasurement ?? -Infinity
+      this.statistics.statisticsData.get(entry.name)?.maxTimeMeasurement ?? Number.NEGATIVE_INFINITY
     )
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.totalTimeMeasurement =
       (this.statistics.statisticsData.get(entry.name)?.totalTimeMeasurement ?? 0) + entry.duration
     )
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.totalTimeMeasurement =
       (this.statistics.statisticsData.get(entry.name)?.totalTimeMeasurement ?? 0) + entry.duration
-    this.statistics.statisticsData.get(entry.name)?.measurementTimeSeries instanceof CircularArray
-      ? this.statistics.statisticsData
-        .get(entry.name)
-        ?.measurementTimeSeries?.push({ timestamp: entry.startTime, value: entry.duration })
-      : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        (this.statistics.statisticsData.get(entry.name)!.measurementTimeSeries =
-          new CircularArray<TimestampedData>(Constants.DEFAULT_CIRCULAR_BUFFER_CAPACITY, {
-            timestamp: entry.startTime,
-            value: entry.duration
-          }))
+    if (
+      !(
+        this.statistics.statisticsData.get(entry.name)?.measurementTimeSeries instanceof
+        CircularBuffer
+      )
+    ) {
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      this.statistics.statisticsData.get(entry.name)!.measurementTimeSeries =
+        new CircularBuffer<TimestampedData>(
+          Array<TimestampedData>,
+          Constants.DEFAULT_CIRCULAR_BUFFER_CAPACITY
+        )
+    }
+    this.statistics.statisticsData.get(entry.name)?.measurementTimeSeries?.push({
+      timestamp: entry.startTime,
+      value: entry.duration
+    })
     const timeMeasurementValues = extractTimeSeriesValues(
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     const timeMeasurementValues = extractTimeSeriesValues(
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.statistics.statisticsData.get(entry.name)!.measurementTimeSeries!
+      this.statistics.statisticsData.get(entry.name)!
+        .measurementTimeSeries as CircularBuffer<TimestampedData>
     )
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.avgTimeMeasurement = mean(timeMeasurementValues)
     )
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     this.statistics.statisticsData.get(entry.name)!.avgTimeMeasurement = mean(timeMeasurementValues)
index 7b4545bdff36ba824597c22549889641c6f60538..7269ce76dae82587822e38cfafd485e3aca03e64 100644 (file)
@@ -28,7 +28,11 @@ export class MikroOrmStorage extends Storage {
         }))
       } satisfies PerformanceRecord)
     } catch (error) {
         }))
       } satisfies PerformanceRecord)
     } catch (error) {
-      this.handleDBError(this.storageType, error as Error, Constants.PERFORMANCE_RECORDS_TABLE)
+      this.handleDBStorageError(
+        this.storageType,
+        error as Error,
+        Constants.PERFORMANCE_RECORDS_TABLE
+      )
     }
   }
 
     }
   }
 
@@ -46,7 +50,7 @@ export class MikroOrmStorage extends Storage {
         }
       }
     } catch (error) {
         }
       }
     } catch (error) {
-      this.handleDBError(this.storageType, error as Error)
+      this.handleDBStorageError(this.storageType, error as Error)
     }
   }
 
     }
   }
 
@@ -58,7 +62,7 @@ export class MikroOrmStorage extends Storage {
         delete this.orm
       }
     } catch (error) {
         delete this.orm
       }
     } catch (error) {
-      this.handleDBError(this.storageType, error as Error)
+      this.handleDBStorageError(this.storageType, error as Error)
     }
   }
 
     }
   }
 
index c3c98022d4204c63aa6d940f7cac887d2424ed58..982e55bf682800ba02da10dc717bf6dea08fa736 100644 (file)
@@ -25,9 +25,15 @@ export class MongoDBStorage extends Storage {
       await this.client
         ?.db(this.dbName)
         .collection<Statistics>(Constants.PERFORMANCE_RECORDS_TABLE)
       await this.client
         ?.db(this.dbName)
         .collection<Statistics>(Constants.PERFORMANCE_RECORDS_TABLE)
-        .replaceOne({ id: performanceStatistics.id }, performanceStatistics, { upsert: true })
+        .replaceOne({ id: performanceStatistics.id }, performanceStatistics, {
+          upsert: true
+        })
     } catch (error) {
     } catch (error) {
-      this.handleDBError(StorageType.MONGO_DB, error as Error, Constants.PERFORMANCE_RECORDS_TABLE)
+      this.handleDBStorageError(
+        StorageType.MONGO_DB,
+        error as Error,
+        Constants.PERFORMANCE_RECORDS_TABLE
+      )
     }
   }
 
     }
   }
 
@@ -38,7 +44,7 @@ export class MongoDBStorage extends Storage {
         this.connected = true
       }
     } catch (error) {
         this.connected = true
       }
     } catch (error) {
-      this.handleDBError(StorageType.MONGO_DB, error as Error)
+      this.handleDBStorageError(StorageType.MONGO_DB, error as Error)
     }
   }
 
     }
   }
 
@@ -50,7 +56,7 @@ export class MongoDBStorage extends Storage {
         this.connected = false
       }
     } catch (error) {
         this.connected = false
       }
     } catch (error) {
-      this.handleDBError(StorageType.MONGO_DB, error as Error)
+      this.handleDBStorageError(StorageType.MONGO_DB, error as Error)
     }
   }
 
     }
   }
 
index aee3ae9efbb5ca86b17a8a7ddf3fcd01b7b80684..ccdbb3f835411c27521e1c17df33002d7cfd259a 100644 (file)
@@ -22,13 +22,16 @@ export abstract class Storage {
     this.logPrefix = logPrefix
   }
 
     this.logPrefix = logPrefix
   }
 
-  protected handleDBError (
+  protected handleDBStorageError (
     type: StorageType,
     error: Error,
     table?: string,
     type: StorageType,
     error: Error,
     table?: string,
-    params: HandleErrorParams<EmptyObject> = { throwError: false, consoleOut: false }
+    params: HandleErrorParams<EmptyObject> = {
+      throwError: false,
+      consoleOut: false
+    }
   ): void {
   ): void {
-    setDefaultErrorParams(params, { throwError: false, consoleOut: false })
+    params = setDefaultErrorParams(params, { throwError: false, consoleOut: false })
     const inTableOrCollectionStr = table != null && ` in table or collection '${table}'`
     logger.error(
       `${this.logPrefix} ${this.getDBNameFromStorageType(type)} error '${
     const inTableOrCollectionStr = table != null && ` in table or collection '${table}'`
     logger.error(
       `${this.logPrefix} ${this.getDBNameFromStorageType(type)} error '${
index 19fd71855cdd5ed9451573e72e93deab177c9c46..345381425e7422f428b4a8fed775b2344ad057b4 100755 (executable)
@@ -14,7 +14,7 @@ const config = JSON.parse(fs.readFileSync('scriptConfig.json', 'utf8'))
 // Mongo Connection and Query
 if (config?.mongoConnectionString) {
   // eslint-disable-next-line n/handle-callback-err
 // Mongo Connection and Query
 if (config?.mongoConnectionString) {
   // eslint-disable-next-line n/handle-callback-err
-  MongoClient.connect(config.mongoConnectionString, async function (_err, client) {
+  MongoClient.connect(config.mongoConnectionString, async (_err, client) => {
     const db = client.db()
 
     for await (const tenantID of config.tenantIDs) {
     const db = client.db()
 
     for await (const tenantID of config.tenantIDs) {
index d41dc1665bb1c4c7f783b35a1fb05f5e0902d269..09e5873b62319fec802d382d21ea54b907c6701f 100755 (executable)
@@ -15,7 +15,7 @@ const config = JSON.parse(fs.readFileSync('scriptConfig.json', 'utf8'))
 // Mongo Connection and Query
 if (config?.mongoConnectionString) {
   // eslint-disable-next-line n/handle-callback-err
 // Mongo Connection and Query
 if (config?.mongoConnectionString) {
   // eslint-disable-next-line n/handle-callback-err
-  MongoClient.connect(config.mongoConnectionString, async function (_err, client) {
+  MongoClient.connect(config.mongoConnectionString, async (_err, client) => {
     const db = client.db()
 
     for await (const tenantID of config.tenantIDs) {
     const db = client.db()
 
     for await (const tenantID of config.tenantIDs) {
index b690bc916f2dca73d604349dc508f11177ff0643..3fa6adeccf6310ebebac3dbb679133dfe9f10aa3 100644 (file)
@@ -7,6 +7,7 @@ export enum ChargingStationEvents {
   registered = 'registered',
   accepted = 'accepted',
   rejected = 'rejected',
   registered = 'registered',
   accepted = 'accepted',
   rejected = 'rejected',
+  connected = 'connected',
   disconnected = 'disconnected',
   connectorStatusChanged = 'connectorStatusChanged'
 }
   disconnected = 'disconnected',
   connectorStatusChanged = 'connectorStatusChanged'
 }
index 4c03dd9d73c62c06f35d432bbc18cf9be62ec082..9601a90cb70e2ace501599190aba61f1d834c14a 100644 (file)
@@ -1,4 +1,5 @@
-import type { CircularArray } from '../utils/index.js'
+import type { CircularBuffer } from 'mnemonist'
+
 import type { WorkerData } from '../worker/index.js'
 import type { IncomingRequestCommand, RequestCommand } from './ocpp/Requests.js'
 
 import type { WorkerData } from '../worker/index.js'
 import type { IncomingRequestCommand, RequestCommand } from './ocpp/Requests.js'
 
@@ -12,7 +13,7 @@ export type StatisticsData = Partial<{
   responseCount: number
   errorCount: number
   timeMeasurementCount: number
   responseCount: number
   errorCount: number
   timeMeasurementCount: number
-  measurementTimeSeries: CircularArray<TimestampedData>
+  measurementTimeSeries: CircularBuffer<TimestampedData> | TimestampedData[]
   currentTimeMeasurement: number
   minTimeMeasurement: number
   maxTimeMeasurement: number
   currentTimeMeasurement: number
   minTimeMeasurement: number
   maxTimeMeasurement: number
index 868dd73df07ea4fa37b95a333357c8bf4436a381..6fa70636b9d3e9b153d90c8f5dd20a4b36d75018 100644 (file)
@@ -162,6 +162,7 @@ export { ChargePointErrorCode } from './ocpp/ChargePointErrorCode.js'
 export {
   type ChargingProfile,
   ChargingProfileKindType,
 export {
   type ChargingProfile,
   ChargingProfileKindType,
+  ChargingProfilePurposeType,
   ChargingRateUnitType,
   type ChargingSchedulePeriod,
   RecurrencyKindType
   ChargingRateUnitType,
   type ChargingSchedulePeriod,
   RecurrencyKindType
index c57be2032751277115f298947575d7877457d4cd..e186679f5004938c7662615dfa4fde8d29133300 100644 (file)
@@ -77,7 +77,7 @@ export interface ChangeConfigurationRequest extends JsonObject {
 }
 
 export interface RemoteStartTransactionRequest extends JsonObject {
 }
 
 export interface RemoteStartTransactionRequest extends JsonObject {
-  connectorId: number
+  connectorId?: number
   idTag: string
   chargingProfile?: OCPP16ChargingProfile
 }
   idTag: string
   chargingProfile?: OCPP16ChargingProfile
 }
index efc25b90083ad54a28aa977ee587e63851d643f0..8fc773b73a5352642006bd249a4f6fc42e44e09e 100644 (file)
@@ -1,6 +1,7 @@
 import {
   type OCPP16ChargingProfile,
   OCPP16ChargingProfileKindType,
 import {
   type OCPP16ChargingProfile,
   OCPP16ChargingProfileKindType,
+  OCPP16ChargingProfilePurposeType,
   OCPP16ChargingRateUnitType,
   type OCPP16ChargingSchedulePeriod,
   OCPP16RecurrencyKindType
   OCPP16ChargingRateUnitType,
   type OCPP16ChargingSchedulePeriod,
   OCPP16RecurrencyKindType
@@ -10,6 +11,12 @@ export type ChargingProfile = OCPP16ChargingProfile
 
 export type ChargingSchedulePeriod = OCPP16ChargingSchedulePeriod
 
 
 export type ChargingSchedulePeriod = OCPP16ChargingSchedulePeriod
 
+export const ChargingProfilePurposeType = {
+  ...OCPP16ChargingProfilePurposeType
+} as const
+// eslint-disable-next-line @typescript-eslint/no-redeclare
+export type ChargingProfilePurposeType = OCPP16ChargingProfilePurposeType
+
 export const ChargingProfileKindType = {
   ...OCPP16ChargingProfileKindType
 } as const
 export const ChargingProfileKindType = {
   ...OCPP16ChargingProfileKindType
 } as const
index 7b5346d52392deb1996673bc7210e1a3bf300708..c5330a0d95ecd700b997d618261ab70909967e71 100644 (file)
@@ -25,7 +25,7 @@ export const buildConnectorsStatus = (chargingStation: ChargingStation): Connect
   )
 }
 
   )
 }
 
-export const enum OutputFormat {
+export enum OutputFormat {
   configuration = 'configuration',
   worker = 'worker'
 }
   configuration = 'configuration',
   worker = 'worker'
 }
diff --git a/src/utils/CircularArray.ts b/src/utils/CircularArray.ts
deleted file mode 100644 (file)
index f84b21a..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright Jerome Benoit. 2021-2024. All Rights Reserved.
-
-export const DEFAULT_CIRCULAR_ARRAY_SIZE = 1024
-
-/**
- * Array with a maximum length and shifting items when full.
- */
-export class CircularArray<T> extends Array<T> {
-  public size: number
-
-  constructor (size: number = DEFAULT_CIRCULAR_ARRAY_SIZE, ...items: T[]) {
-    super()
-    this.checkSize(size)
-    this.size = size
-    if (arguments.length > 1) {
-      this.push(...items)
-    }
-  }
-
-  public push (...items: T[]): number {
-    const length = super.push(...items)
-    if (length > this.size) {
-      super.splice(0, length - this.size)
-    }
-    return this.length
-  }
-
-  public unshift (...items: T[]): number {
-    const length = super.unshift(...items)
-    if (length > this.size) {
-      super.splice(this.size, items.length)
-    }
-    return this.length
-  }
-
-  public concat (...items: Array<T | ConcatArray<T>>): CircularArray<T> {
-    const concatenatedCircularArray = super.concat(items as T[]) as CircularArray<T>
-    concatenatedCircularArray.size = this.size
-    if (concatenatedCircularArray.length > concatenatedCircularArray.size) {
-      concatenatedCircularArray.splice(
-        0,
-        concatenatedCircularArray.length - concatenatedCircularArray.size
-      )
-    }
-    return concatenatedCircularArray
-  }
-
-  public splice (start: number, deleteCount?: number, ...items: T[]): CircularArray<T> {
-    let itemsRemoved: T[] = []
-    if (arguments.length >= 3 && deleteCount != null) {
-      itemsRemoved = super.splice(start, deleteCount, ...items)
-      if (this.length > this.size) {
-        const itemsOverflowing = super.splice(0, this.length - this.size)
-        itemsRemoved = new CircularArray<T>(
-          itemsRemoved.length + itemsOverflowing.length,
-          ...itemsRemoved,
-          ...itemsOverflowing
-        )
-      }
-    } else if (arguments.length === 2) {
-      itemsRemoved = super.splice(start, deleteCount)
-    } else {
-      itemsRemoved = super.splice(start)
-    }
-    return itemsRemoved as CircularArray<T>
-  }
-
-  public resize (size: number): void {
-    this.checkSize(size)
-    if (size === 0) {
-      this.length = 0
-    } else if (size < this.size) {
-      for (let i = size; i < this.size; i++) {
-        super.pop()
-      }
-    }
-    this.size = size
-  }
-
-  public empty (): boolean {
-    return this.length === 0
-  }
-
-  public full (): boolean {
-    return this.length === this.size
-  }
-
-  private checkSize (size: number): void {
-    if (!Number.isSafeInteger(size)) {
-      throw new TypeError(`Invalid circular array size: ${size} is not a safe integer`)
-    }
-    if (size < 0) {
-      throw new RangeError(`Invalid circular array size: ${size} < 0`)
-    }
-  }
-}
index 25a1475bc2a5f6ec9a6ea40df049048db9538ad8..06f543a58f017bcb3dec3cf10a4683fad3f79180 100644 (file)
@@ -1,4 +1,4 @@
-import { type FSWatcher, readFileSync, watch } from 'node:fs'
+import { existsSync, type FSWatcher, readFileSync, watch } from 'node:fs'
 import { dirname, join } from 'node:path'
 import { env } from 'node:process'
 import { fileURLToPath } from 'node:url'
 import { dirname, join } from 'node:path'
 import { env } from 'node:process'
 import { fileURLToPath } from 'node:url'
@@ -44,28 +44,85 @@ type ConfigurationSectionType =
   | WorkerConfiguration
   | UIServerConfiguration
 
   | WorkerConfiguration
   | UIServerConfiguration
 
+const defaultUIServerConfiguration: UIServerConfiguration = {
+  enabled: false,
+  type: ApplicationProtocol.WS,
+  version: ApplicationProtocolVersion.VERSION_11,
+  options: {
+    host: Constants.DEFAULT_UI_SERVER_HOST,
+    port: Constants.DEFAULT_UI_SERVER_PORT
+  }
+}
+
+const defaultStorageConfiguration: StorageConfiguration = {
+  enabled: true,
+  type: StorageType.NONE
+}
+
+const defaultLogConfiguration: LogConfiguration = {
+  enabled: true,
+  file: 'logs/combined.log',
+  errorFile: 'logs/error.log',
+  statisticsInterval: Constants.DEFAULT_LOG_STATISTICS_INTERVAL,
+  level: 'info',
+  format: 'simple',
+  rotate: true
+}
+
+const defaultWorkerConfiguration: WorkerConfiguration = {
+  processType: WorkerProcessType.workerSet,
+  startDelay: DEFAULT_WORKER_START_DELAY,
+  elementsPerWorker: 'auto',
+  elementAddDelay: DEFAULT_ELEMENT_ADD_DELAY,
+  poolMinSize: DEFAULT_POOL_MIN_SIZE,
+  poolMaxSize: DEFAULT_POOL_MAX_SIZE
+}
+
 // eslint-disable-next-line @typescript-eslint/no-extraneous-class
 export class Configuration {
   public static configurationChangeCallback?: () => Promise<void>
 
 // eslint-disable-next-line @typescript-eslint/no-extraneous-class
 export class Configuration {
   public static configurationChangeCallback?: () => Promise<void>
 
-  private static readonly configurationFile = join(
-    dirname(fileURLToPath(import.meta.url)),
-    'assets',
-    'config.json'
-  )
-
+  private static configurationFile: string | undefined
   private static configurationFileReloading = false
   private static configurationData?: ConfigurationData
   private static configurationFileWatcher?: FSWatcher
   private static configurationFileReloading = false
   private static configurationData?: ConfigurationData
   private static configurationFileWatcher?: FSWatcher
-  private static readonly configurationSectionCache = new Map<
-  ConfigurationSection,
-  ConfigurationSectionType
-  >([
-    [ConfigurationSection.log, Configuration.buildLogSection()],
-    [ConfigurationSection.performanceStorage, Configuration.buildPerformanceStorageSection()],
-    [ConfigurationSection.worker, Configuration.buildWorkerSection()],
-    [ConfigurationSection.uiServer, Configuration.buildUIServerSection()]
-  ])
+  private static configurationSectionCache: Map<ConfigurationSection, ConfigurationSectionType>
+
+  static {
+    const configurationFile = join(dirname(fileURLToPath(import.meta.url)), 'assets', 'config.json')
+    if (existsSync(configurationFile)) {
+      Configuration.configurationFile = configurationFile
+    } else {
+      console.error(
+        `${chalk.green(logPrefix())} ${chalk.red(
+          "Configuration file './src/assets/config.json' not found, using default configuration"
+        )}`
+      )
+      Configuration.configurationData = {
+        stationTemplateUrls: [
+          {
+            file: 'siemens.station-template.json',
+            numberOfStations: 1
+          }
+        ],
+        supervisionUrls: 'ws://localhost:8180/steve/websocket/CentralSystemService',
+        supervisionUrlDistribution: SupervisionUrlDistribution.ROUND_ROBIN,
+        uiServer: defaultUIServerConfiguration,
+        performanceStorage: defaultStorageConfiguration,
+        log: defaultLogConfiguration,
+        worker: defaultWorkerConfiguration
+      }
+    }
+    Configuration.configurationSectionCache = new Map<
+    ConfigurationSection,
+    ConfigurationSectionType
+    >([
+      [ConfigurationSection.log, Configuration.buildLogSection()],
+      [ConfigurationSection.performanceStorage, Configuration.buildPerformanceStorageSection()],
+      [ConfigurationSection.worker, Configuration.buildWorkerSection()],
+      [ConfigurationSection.uiServer, Configuration.buildUIServerSection()]
+    ])
+  }
 
   private constructor () {
     // This is intentional
 
   private constructor () {
     // This is intentional
@@ -152,15 +209,7 @@ export class Configuration {
   }
 
   private static buildUIServerSection (): UIServerConfiguration {
   }
 
   private static buildUIServerSection (): UIServerConfiguration {
-    let uiServerConfiguration: UIServerConfiguration = {
-      enabled: false,
-      type: ApplicationProtocol.WS,
-      version: ApplicationProtocolVersion.VERSION_11,
-      options: {
-        host: Constants.DEFAULT_UI_SERVER_HOST,
-        port: Constants.DEFAULT_UI_SERVER_PORT
-      }
-    }
+    let uiServerConfiguration: UIServerConfiguration = defaultUIServerConfiguration
     if (hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.uiServer)) {
       uiServerConfiguration = mergeDeepRight(
         uiServerConfiguration,
     if (hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.uiServer)) {
       uiServerConfiguration = mergeDeepRight(
         uiServerConfiguration,
@@ -171,7 +220,7 @@ export class Configuration {
     if (isCFEnvironment()) {
       delete uiServerConfiguration.options?.host
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     if (isCFEnvironment()) {
       delete uiServerConfiguration.options?.host
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      uiServerConfiguration.options!.port = parseInt(env.PORT!)
+      uiServerConfiguration.options!.port = Number.parseInt(env.PORT!)
     }
     return uiServerConfiguration
   }
     }
     return uiServerConfiguration
   }
@@ -195,10 +244,7 @@ export class Configuration {
         break
       case StorageType.NONE:
       default:
         break
       case StorageType.NONE:
       default:
-        storageConfiguration = {
-          enabled: true,
-          type: StorageType.NONE
-        }
+        storageConfiguration = defaultStorageConfiguration
         break
     }
     if (hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.performanceStorage)) {
         break
     }
     if (hasOwnProp(Configuration.getConfigurationData(), ConfigurationSection.performanceStorage)) {
@@ -220,15 +266,6 @@ export class Configuration {
   }
 
   private static buildLogSection (): LogConfiguration {
   }
 
   private static buildLogSection (): LogConfiguration {
-    const defaultLogConfiguration: LogConfiguration = {
-      enabled: true,
-      file: 'logs/combined.log',
-      errorFile: 'logs/error.log',
-      statisticsInterval: Constants.DEFAULT_LOG_STATISTICS_INTERVAL,
-      level: 'info',
-      format: 'simple',
-      rotate: true
-    }
     const deprecatedLogConfiguration: LogConfiguration = {
       ...(hasOwnProp(Configuration.getConfigurationData(), 'logEnabled') && {
         enabled: Configuration.getConfigurationData()?.logEnabled
     const deprecatedLogConfiguration: LogConfiguration = {
       ...(hasOwnProp(Configuration.getConfigurationData(), 'logEnabled') && {
         enabled: Configuration.getConfigurationData()?.logEnabled
@@ -271,15 +308,6 @@ export class Configuration {
   }
 
   private static buildWorkerSection (): WorkerConfiguration {
   }
 
   private static buildWorkerSection (): WorkerConfiguration {
-    const defaultWorkerConfiguration: WorkerConfiguration = {
-      processType: WorkerProcessType.workerSet,
-      startDelay: DEFAULT_WORKER_START_DELAY,
-      elementsPerWorker: 'auto',
-      elementAddDelay: DEFAULT_ELEMENT_ADD_DELAY,
-      poolMinSize: DEFAULT_POOL_MIN_SIZE,
-      poolMaxSize: DEFAULT_POOL_MAX_SIZE
-    }
-
     const deprecatedWorkerConfiguration: WorkerConfiguration = {
       ...(hasOwnProp(Configuration.getConfigurationData(), 'workerProcess') && {
         processType: Configuration.getConfigurationData()?.workerProcess
     const deprecatedWorkerConfiguration: WorkerConfiguration = {
       ...(hasOwnProp(Configuration.getConfigurationData(), 'workerProcess') && {
         processType: Configuration.getConfigurationData()?.workerProcess
@@ -545,7 +573,11 @@ export class Configuration {
   }
 
   public static getConfigurationData (): ConfigurationData | undefined {
   }
 
   public static getConfigurationData (): ConfigurationData | undefined {
-    if (Configuration.configurationData == null) {
+    if (
+      Configuration.configurationData == null &&
+      Configuration.configurationFile != null &&
+      Configuration.configurationFile.length > 0
+    ) {
       try {
         Configuration.configurationData = JSON.parse(
           readFileSync(Configuration.configurationFile, 'utf8')
       try {
         Configuration.configurationData = JSON.parse(
           readFileSync(Configuration.configurationFile, 'utf8')
@@ -566,6 +598,9 @@ export class Configuration {
   }
 
   private static getConfigurationFileWatcher (): FSWatcher | undefined {
   }
 
   private static getConfigurationFileWatcher (): FSWatcher | undefined {
+    if (Configuration.configurationFile == null || Configuration.configurationFile.length === 0) {
+      return
+    }
     try {
       return watch(Configuration.configurationFile, (event, filename): void => {
         if (
     try {
       return watch(Configuration.configurationFile, (event, filename): void => {
         if (
index 3746c4fdd91e8277ebc5167c563cbd3cf88fb673..2d66659889e3a5418d083b9b60b7cdeb8960a18c 100644 (file)
@@ -67,7 +67,7 @@ export class Constants {
       stopAbsoluteDuration: false
     })
 
       stopAbsoluteDuration: false
     })
 
-  static readonly DEFAULT_CIRCULAR_BUFFER_CAPACITY = 4096
+  static readonly DEFAULT_CIRCULAR_BUFFER_CAPACITY = 386
 
   static readonly DEFAULT_HASH_ALGORITHM = 'sha384'
 
 
   static readonly DEFAULT_HASH_ALGORITHM = 'sha384'
 
index 9c243a299e769f67c4e70859aae110651a3444cd..0a444c6b1f5d945e5577dd7fbebc6ec235df16e6 100644 (file)
@@ -3,17 +3,21 @@ import process from 'node:process'
 import chalk from 'chalk'
 
 import type { ChargingStation } from '../charging-station/index.js'
 import chalk from 'chalk'
 
 import type { ChargingStation } from '../charging-station/index.js'
+import { getMessageTypeString } from '../charging-station/ocpp/OCPPServiceUtils.js'
 import type {
   EmptyObject,
   FileType,
   HandleErrorParams,
   IncomingRequestCommand,
   JsonType,
 import type {
   EmptyObject,
   FileType,
   HandleErrorParams,
   IncomingRequestCommand,
   JsonType,
+  MessageType,
   RequestCommand
 } from '../types/index.js'
 import { logger } from './Logger.js'
 import { isNotEmptyString } from './Utils.js'
 
   RequestCommand
 } from '../types/index.js'
 import { logger } from './Logger.js'
 import { isNotEmptyString } from './Utils.js'
 
+const moduleName = 'ErrorUtils'
+
 const defaultErrorParams = {
   throwError: true,
   consoleOut: false
 const defaultErrorParams = {
   throwError: true,
   consoleOut: false
@@ -38,7 +42,7 @@ export const handleFileException = (
   logPrefix: string,
   params: HandleErrorParams<EmptyObject> = defaultErrorParams
 ): void => {
   logPrefix: string,
   params: HandleErrorParams<EmptyObject> = defaultErrorParams
 ): void => {
-  setDefaultErrorParams(params)
+  params = setDefaultErrorParams(params)
   const prefix = isNotEmptyString(logPrefix) ? `${logPrefix} ` : ''
   let logMsg: string
   switch (error.code) {
   const prefix = isNotEmptyString(logPrefix) ? `${logPrefix} ` : ''
   let logMsg: string
   switch (error.code) {
@@ -79,20 +83,48 @@ export const handleFileException = (
 export const handleSendMessageError = (
   chargingStation: ChargingStation,
   commandName: RequestCommand | IncomingRequestCommand,
 export const handleSendMessageError = (
   chargingStation: ChargingStation,
   commandName: RequestCommand | IncomingRequestCommand,
+  messageType: MessageType,
   error: Error,
   error: Error,
-  params: HandleErrorParams<EmptyObject> = { throwError: false, consoleOut: false }
+  params: HandleErrorParams<EmptyObject> = {
+    throwError: false,
+    consoleOut: false
+  }
 ): void => {
 ): void => {
-  setDefaultErrorParams(params, { throwError: false, consoleOut: false })
-  logger.error(`${chargingStation.logPrefix()} Request command '${commandName}' error:`, error)
+  params = setDefaultErrorParams(params, { throwError: false, consoleOut: false })
+  logger.error(
+    `${chargingStation.logPrefix()} ${moduleName}.handleSendMessageError: Send ${getMessageTypeString(messageType)} command '${commandName}' error:`,
+    error
+  )
   if (params.throwError === true) {
     throw error
   }
 }
 
   if (params.throwError === true) {
     throw error
   }
 }
 
+export const handleIncomingRequestError = <T extends JsonType>(
+  chargingStation: ChargingStation,
+  commandName: IncomingRequestCommand,
+  error: Error,
+  params: HandleErrorParams<T> = { throwError: true, consoleOut: false }
+): T | undefined => {
+  params = setDefaultErrorParams(params)
+  logger.error(
+    `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
+    error
+  )
+  if (params.throwError === false && params.errorResponse != null) {
+    return params.errorResponse
+  }
+  if (params.throwError === true && params.errorResponse == null) {
+    throw error
+  }
+  if (params.throwError === true && params.errorResponse != null) {
+    return params.errorResponse
+  }
+}
+
 export const setDefaultErrorParams = <T extends JsonType>(
   params: HandleErrorParams<T>,
   defaultParams: HandleErrorParams<T> = defaultErrorParams
 ): HandleErrorParams<T> => {
 export const setDefaultErrorParams = <T extends JsonType>(
   params: HandleErrorParams<T>,
   defaultParams: HandleErrorParams<T> = defaultErrorParams
 ): HandleErrorParams<T> => {
-  params = { ...defaultParams, ...params }
-  return params
+  return { ...defaultParams, ...params }
 }
 }
index 4164c36bf11c96f18b8250cfd47be98bdeb897d5..f9d1e14980017606a7c1f64ec0135eb47bf8e80b 100644 (file)
@@ -1,9 +1,12 @@
+import { CircularBuffer } from 'mnemonist'
+
 import type { ChargingStation } from '../charging-station/index.js'
 import {
   type ChargingStationData,
   type ChargingStationWorkerMessage,
   ChargingStationWorkerMessageEvents,
 import type { ChargingStation } from '../charging-station/index.js'
 import {
   type ChargingStationData,
   type ChargingStationWorkerMessage,
   ChargingStationWorkerMessageEvents,
-  type Statistics
+  type Statistics,
+  type TimestampedData
 } from '../types/index.js'
 import {
   buildChargingStationAutomaticTransactionGeneratorConfiguration,
 } from '../types/index.js'
 import {
   buildChargingStationAutomaticTransactionGeneratorConfiguration,
@@ -60,9 +63,22 @@ export const buildUpdatedMessage = (
 export const buildPerformanceStatisticsMessage = (
   statistics: Statistics
 ): ChargingStationWorkerMessage<Statistics> => {
 export const buildPerformanceStatisticsMessage = (
   statistics: Statistics
 ): ChargingStationWorkerMessage<Statistics> => {
+  const statisticsData = [...statistics.statisticsData].map(([key, value]) => {
+    if (value.measurementTimeSeries instanceof CircularBuffer) {
+      value.measurementTimeSeries = value.measurementTimeSeries.toArray() as TimestampedData[]
+    }
+    return [key, value]
+  })
   return {
     event: ChargingStationWorkerMessageEvents.performanceStatistics,
   return {
     event: ChargingStationWorkerMessageEvents.performanceStatistics,
-    data: statistics
+    data: {
+      id: statistics.id,
+      name: statistics.name,
+      uri: statistics.uri,
+      createdAt: statistics.createdAt,
+      updatedAt: statistics.updatedAt,
+      statisticsData
+    }
   }
 }
 
   }
 }
 
index 9f50b8eaa12b08037ef9c49b042ac96a62463bef..501dea7797ec30ecc469604ed1e93697551ad095 100644 (file)
@@ -1,10 +1,10 @@
 import { mean } from 'rambda'
 
 export const min = (...args: number[]): number =>
 import { mean } from 'rambda'
 
 export const min = (...args: number[]): number =>
-  args.reduce((minimum, num) => (minimum < num ? minimum : num), Infinity)
+  args.reduce((minimum, num) => (minimum < num ? minimum : num), Number.POSITIVE_INFINITY)
 
 export const max = (...args: number[]): number =>
 
 export const max = (...args: number[]): number =>
-  args.reduce((maximum, num) => (maximum > num ? maximum : num), -Infinity)
+  args.reduce((maximum, num) => (maximum > num ? maximum : num), Number.NEGATIVE_INFINITY)
 
 // TODO: use order statistics tree https://en.wikipedia.org/wiki/Order_statistic_tree
 export const nthPercentile = (dataSet: number[], percentile: number): number => {
 
 // TODO: use order statistics tree https://en.wikipedia.org/wiki/Order_statistic_tree
 export const nthPercentile = (dataSet: number[], percentile: number): number => {
index aeed9b0fa44b4a073bff682583c95695cbb954ac..9a06c64ed5658e01e7409bb38ae95baaba61be5c 100644 (file)
@@ -12,6 +12,7 @@ import {
   minutesToSeconds,
   secondsToMilliseconds
 } from 'date-fns'
   minutesToSeconds,
   secondsToMilliseconds
 } from 'date-fns'
+import type { CircularBuffer } from 'mnemonist'
 import { is } from 'rambda'
 
 import {
 import { is } from 'rambda'
 
 import {
@@ -112,7 +113,7 @@ export const convertToInt = (value: unknown): number => {
   }
   let changedValue: number = value as number
   if (typeof value === 'string') {
   }
   let changedValue: number = value as number
   if (typeof value === 'string') {
-    changedValue = parseInt(value)
+    changedValue = Number.parseInt(value)
   }
   if (isNaN(changedValue)) {
     throw new Error(`Cannot convert to integer: '${String(value)}'`)
   }
   if (isNaN(changedValue)) {
     throw new Error(`Cannot convert to integer: '${String(value)}'`)
@@ -126,7 +127,7 @@ export const convertToFloat = (value: unknown): number => {
   }
   let changedValue: number = value as number
   if (typeof value === 'string') {
   }
   let changedValue: number = value as number
   if (typeof value === 'string') {
-    changedValue = parseFloat(value)
+    changedValue = Number.parseFloat(value)
   }
   if (isNaN(changedValue)) {
     throw new Error(`Cannot convert to float: '${String(value)}'`)
   }
   if (isNaN(changedValue)) {
     throw new Error(`Cannot convert to float: '${String(value)}'`)
@@ -153,7 +154,7 @@ export const getRandomFloat = (max = Number.MAX_VALUE, min = 0): number => {
   if (max < min) {
     throw new RangeError('Invalid interval')
   }
   if (max < min) {
     throw new RangeError('Invalid interval')
   }
-  if (max - min === Infinity) {
+  if (max - min === Number.POSITIVE_INFINITY) {
     throw new RangeError('Invalid interval')
   }
   return (randomBytes(4).readUInt32LE() / 0xffffffff) * (max - min) + min
     throw new RangeError('Invalid interval')
   }
   return (randomBytes(4).readUInt32LE() / 0xffffffff) * (max - min) + min
@@ -200,8 +201,8 @@ export const getRandomFloatFluctuatedRounded = (
   )
 }
 
   )
 }
 
-export const extractTimeSeriesValues = (timeSeries: TimestampedData[]): number[] => {
-  return timeSeries.map(timeSeriesItem => timeSeriesItem.value)
+export const extractTimeSeriesValues = (timeSeries: CircularBuffer<TimestampedData>): number[] => {
+  return (timeSeries.toArray() as TimestampedData[]).map(timeSeriesItem => timeSeriesItem.value)
 }
 
 export const clone = <T>(object: T): T => {
 }
 
 export const clone = <T>(object: T): T => {
@@ -281,7 +282,9 @@ export const JSONStringify = <
       if (is(Map, value)) {
         switch (mapFormat) {
           case MapStringifyFormat.object:
       if (is(Map, value)) {
         switch (mapFormat) {
           case MapStringifyFormat.object:
-            return { ...Object.fromEntries<Map<string, Record<string, unknown>>>(value.entries()) }
+            return {
+              ...Object.fromEntries<Map<string, Record<string, unknown>>>(value.entries())
+            }
           case MapStringifyFormat.array:
           default:
             return [...value]
           case MapStringifyFormat.array:
           default:
             return [...value]
@@ -325,6 +328,9 @@ export const getWebSocketCloseEventStatusString = (code: number): string => {
 }
 
 export const isArraySorted = <T>(array: T[], compareFn: (a: T, b: T) => number): boolean => {
 }
 
 export const isArraySorted = <T>(array: T[], compareFn: (a: T, b: T) => number): boolean => {
+  if (array.length <= 1) {
+    return true
+  }
   for (let index = 0; index < array.length - 1; ++index) {
     if (compareFn(array[index], array[index + 1]) > 0) {
       return false
   for (let index = 0; index < array.length - 1; ++index) {
     if (compareFn(array[index], array[index + 1]) > 0) {
       return false
index e1d6734c9c1fba31a6bf7eaeaad68e3e44abd913..5fedbc57e20ab849439f4628c28390b4433015f5 100644 (file)
@@ -5,12 +5,12 @@ export {
   buildEvsesStatus,
   OutputFormat
 } from './ChargingStationConfigurationUtils.js'
   buildEvsesStatus,
   OutputFormat
 } from './ChargingStationConfigurationUtils.js'
-export { CircularArray } from './CircularArray.js'
 export { Configuration } from './Configuration.js'
 export { Constants } from './Constants.js'
 export { ACElectricUtils, DCElectricUtils } from './ElectricUtils.js'
 export {
   handleFileException,
 export { Configuration } from './Configuration.js'
 export { Constants } from './Constants.js'
 export { ACElectricUtils, DCElectricUtils } from './ElectricUtils.js'
 export {
   handleFileException,
+  handleIncomingRequestError,
   handleSendMessageError,
   handleUncaughtException,
   handleUnhandledRejection,
   handleSendMessageError,
   handleUncaughtException,
   handleUnhandledRejection,
index c45e6a617147edce428800d8a777178eea9b53ea..1774c24a4f17585e8ce1c6dd4bbcef1c109a5fee 100644 (file)
@@ -130,7 +130,11 @@ export class WorkerSet<D extends WorkerData, R extends WorkerData> extends Worke
         data: elementData
       } satisfies WorkerMessage<D>
       workerSetElement.worker.postMessage(message)
         data: elementData
       } satisfies WorkerMessage<D>
       workerSetElement.worker.postMessage(message)
-      this.promiseResponseMap.set(message.uuid, { resolve, reject, workerSetElement })
+      this.promiseResponseMap.set(message.uuid, {
+        resolve,
+        reject,
+        workerSetElement
+      })
     })
     const response = await sendMessageToWorker
     // Add element sequentially to optimize memory at startup
     })
     const response = await sendMessageToWorker
     // Add element sequentially to optimize memory at startup
@@ -199,7 +203,10 @@ export class WorkerSet<D extends WorkerData, R extends WorkerData> extends Worke
     worker.once('exit', () => {
       this.removeWorkerSetElement(this.getWorkerSetElementByWorker(worker))
     })
     worker.once('exit', () => {
       this.removeWorkerSetElement(this.getWorkerSetElementByWorker(worker))
     })
-    const workerSetElement: WorkerSetElement = { worker, numberOfWorkerElements: 0 }
+    const workerSetElement: WorkerSetElement = {
+      worker,
+      numberOfWorkerElements: 0
+    }
     this.workerSet.add(workerSetElement)
     this.workerStartup = false
     return workerSetElement
     this.workerSet.add(workerSetElement)
     this.workerStartup = false
     return workerSetElement
diff --git a/tests/exception/OCPPError.test.ts b/tests/exception/OCPPError.test.ts
new file mode 100644 (file)
index 0000000..c6e4bc4
--- /dev/null
@@ -0,0 +1,23 @@
+import { describe, it } from 'node:test'
+
+import { expect } from 'expect'
+
+import { OCPPError } from '../../src/exception/OCPPError.js'
+import { ErrorType } from '../../src/types/index.js'
+import { Constants } from '../../src/utils/Constants.js'
+
+await describe('OCPPError test suite', async () => {
+  await it('Verify that OCPPError can be instantiated', () => {
+    const ocppError = new OCPPError(ErrorType.GENERIC_ERROR, '')
+    expect(ocppError).toBeInstanceOf(OCPPError)
+    expect(ocppError.name).toBe('OCPPError')
+    expect(ocppError.message).toBe('')
+    expect(ocppError.code).toBe(ErrorType.GENERIC_ERROR)
+    expect(ocppError.command).toBe(Constants.UNKNOWN_OCPP_COMMAND)
+    expect(ocppError.details).toBeUndefined()
+    expect(typeof ocppError.stack === 'string').toBe(true)
+    expect(ocppError.stack).not.toBe('')
+    expect(ocppError.cause).toBeUndefined()
+    expect(ocppError.date).toBeInstanceOf(Date)
+  })
+})
diff --git a/tests/ocpp-server/README.md b/tests/ocpp-server/README.md
new file mode 100644 (file)
index 0000000..332751d
--- /dev/null
@@ -0,0 +1,36 @@
+# OCPP2 Mock Server
+
+This project includes an Open Charge Point Protocol (OCPP) version 2.0.1 mock server implemented in Python.
+
+## Prerequisites
+
+This project requires Python 3.7+ and [poetry](https://python-poetry.org/) to install the required packages:
+
+```
+poetry install
+```
+
+## Running the Server
+
+To start the server, run the `server.py` script:
+
+```
+python server.py
+```
+
+The server will start listening for connections on port 9000.
+
+## Overview of the Server Scripts
+
+### Server.py
+
+The server script waits for connections from clients. When a client connects, the server creates a new instance of the `ChargePoint` class. This class includes methods for handling various OCPP actions (`BootNotification`,`GetBaseReport`), most of which return a dummy response. The `GetBaseReport` method prints the received request and returns a simple confirmation message.
+
+The server script uses the websockets and ocpp libraries to facilitate the WebSocket and OCPP communication.
+
+## Note
+
+Primarily, this software is intended for testing applications. The server script don't adhere to the full OCPP specifications and it is advised not to use them in a production environment without additional development.
+
+For reference:
+https://github.com/mobilityhouse/ocpp
diff --git a/tests/ocpp-server/__init__.py b/tests/ocpp-server/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/ocpp-server/poetry.lock b/tests/ocpp-server/poetry.lock
new file mode 100644 (file)
index 0000000..3bcabcc
--- /dev/null
@@ -0,0 +1,278 @@
+# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
+
+[[package]]
+name = "attrs"
+version = "23.2.0"
+description = "Classes Without Boilerplate"
+optional = false
+python-versions = ">=3.7"
+files = [
+    {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
+    {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
+]
+
+[package.extras]
+cov = ["attrs[tests]", "coverage[toml] (>=5.3)"]
+dev = ["attrs[tests]", "pre-commit"]
+docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"]
+tests = ["attrs[tests-no-zope]", "zope-interface"]
+tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
+tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
+
+[[package]]
+name = "jsonschema"
+version = "4.22.0"
+description = "An implementation of JSON Schema validation for Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"},
+    {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"},
+]
+
+[package.dependencies]
+attrs = ">=22.2.0"
+jsonschema-specifications = ">=2023.03.6"
+referencing = ">=0.28.4"
+rpds-py = ">=0.7.1"
+
+[package.extras]
+format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
+format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"]
+
+[[package]]
+name = "jsonschema-specifications"
+version = "2023.12.1"
+description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"},
+    {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"},
+]
+
+[package.dependencies]
+referencing = ">=0.31.0"
+
+[[package]]
+name = "ocpp"
+version = "2.0.0rc1"
+description = "Python package implementing the JSON version of the Open Charge Point Protocol (OCPP)."
+optional = false
+python-versions = "<4.0,>=3.8"
+files = [
+    {file = "ocpp-2.0.0rc1-py3-none-any.whl", hash = "sha256:c3c99483eb3985c069e230fe9f230fbe448cadc2d56f8dbf4c7ca10c8ddfd755"},
+    {file = "ocpp-2.0.0rc1.tar.gz", hash = "sha256:67a4b1f662dbd17bac248a31211999b89b52575abca277baa243b62e16b0ec4d"},
+]
+
+[package.dependencies]
+jsonschema = ">=4.4.0,<5.0.0"
+
+[[package]]
+name = "referencing"
+version = "0.35.1"
+description = "JSON Referencing + Python"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"},
+    {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"},
+]
+
+[package.dependencies]
+attrs = ">=22.2.0"
+rpds-py = ">=0.7.0"
+
+[[package]]
+name = "rpds-py"
+version = "0.18.1"
+description = "Python bindings to Rust's persistent data structures (rpds)"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"},
+    {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"},
+    {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"},
+    {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"},
+    {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"},
+    {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"},
+    {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"},
+    {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"},
+    {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"},
+    {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"},
+    {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"},
+    {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"},
+    {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"},
+    {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"},
+    {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"},
+    {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"},
+    {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"},
+    {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"},
+    {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"},
+    {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"},
+    {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"},
+    {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"},
+    {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"},
+    {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"},
+    {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"},
+    {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"},
+    {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"},
+    {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"},
+    {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"},
+    {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"},
+    {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"},
+    {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"},
+    {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"},
+    {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"},
+    {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"},
+    {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"},
+    {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"},
+    {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"},
+    {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"},
+    {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"},
+    {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"},
+    {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"},
+    {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"},
+    {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"},
+    {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"},
+    {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"},
+    {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"},
+    {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"},
+    {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"},
+    {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"},
+    {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"},
+    {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"},
+    {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"},
+    {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"},
+    {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"},
+    {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"},
+    {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"},
+    {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"},
+    {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"},
+    {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"},
+    {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"},
+    {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"},
+    {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"},
+    {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"},
+    {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"},
+    {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"},
+    {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"},
+    {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"},
+    {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"},
+]
+
+[[package]]
+name = "websockets"
+version = "12.0"
+description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
+optional = false
+python-versions = ">=3.8"
+files = [
+    {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
+    {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
+    {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
+    {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
+    {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
+    {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
+    {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
+    {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
+    {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
+    {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
+    {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
+    {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
+    {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
+    {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
+    {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
+    {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
+    {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
+    {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
+    {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
+    {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
+    {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
+    {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
+    {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
+    {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
+    {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
+    {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
+    {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
+    {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
+    {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
+    {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
+    {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
+    {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
+    {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
+    {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"},
+    {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"},
+    {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"},
+    {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"},
+    {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"},
+    {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"},
+    {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"},
+    {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"},
+    {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"},
+    {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"},
+    {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"},
+    {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"},
+    {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"},
+    {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"},
+    {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"},
+    {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"},
+    {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"},
+    {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"},
+    {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"},
+    {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"},
+    {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"},
+    {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"},
+    {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
+    {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
+    {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
+    {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
+    {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
+    {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
+    {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
+    {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
+    {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
+    {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
+    {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
+    {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
+    {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
+    {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
+    {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
+    {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
+    {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
+]
+
+[metadata]
+lock-version = "2.0"
+python-versions = "^3.12"
+content-hash = "e76eceb912dc1457ae116b3ecc0f0fc5a58ae23d2c2652dcd69b4cd9df207099"
diff --git a/tests/ocpp-server/pyproject.toml b/tests/ocpp-server/pyproject.toml
new file mode 100644 (file)
index 0000000..e1a30e5
--- /dev/null
@@ -0,0 +1,16 @@
+[tool.poetry]
+name = "ocpp-server"
+version = "0.1.0"
+description = ""
+authors = ["Jérôme Benoit <jerome.benoit@piment-noir.org>"]
+readme = "README.md"
+
+[tool.poetry.dependencies]
+python = "^3.12"
+websockets = "^12.0"
+ocpp = "^2.0.0rc1"
+
+
+[build-system]
+requires = ["poetry-core"]
+build-backend = "poetry.core.masonry.api"
diff --git a/tests/ocpp-server/server.py b/tests/ocpp-server/server.py
new file mode 100644 (file)
index 0000000..e8e1e6a
--- /dev/null
@@ -0,0 +1,90 @@
+import asyncio
+import logging
+import websockets
+from datetime import datetime, timezone
+
+from ocpp.routing import on
+from ocpp.v201 import ChargePoint as cp
+from ocpp.v201 import call_result
+from ocpp.v201.enums import RegistrationStatusType, GenericDeviceModelStatusType
+
+# Setting up the logging configuration to display debug level messages.
+logging.basicConfig(level=logging.DEBUG)
+
+# Define a ChargePoint class inheriting from the OCPP 2.0.1 ChargePoint class.
+class ChargePoint(cp):
+    # Define a handler for the BootNotification message.
+    @on('BootNotification')
+    async def on_boot_notification(self, charging_station, reason, **kwargs):
+        logging.info("Received BootNotification")
+        # Create and return a BootNotification response with the current time,
+        # an interval of 10 seconds, and an accepted status.
+        return call_result.BootNotification(
+            current_time = datetime.now(timezone.utc).isoformat(),
+            interval=10,
+            status=RegistrationStatusType.accepted
+        )
+
+    # Define a handler for the GetBaseReport message.
+    @on('GetBaseReport')
+    async def on_get_base_report(self, request_id, report_base, **kwargs):
+        try:
+            logging.info(f"Received GetBaseReport request with RequestId: {request_id} and ReportBase: {report_base}")
+
+            # Create a mock response for demonstration purposes, indicating the report is accepted.
+            response = call_result.GetBaseReport(
+                status=GenericDeviceModelStatusType.accepted
+            )
+
+            logging.info(f"Sending GetBaseReport response: {response}")
+            return response
+        except Exception as e:
+            # Log any errors that occur while handling the GetBaseReport request.
+            logging.error(f"Error handling GetBaseReport request: {e}", exc_info=True)
+            # Return a rejected status in case of error.
+            return call_result.GetBaseReport(
+                status=GenericDeviceModelStatusType.rejected
+            )
+
+# Function to handle new WebSocket connections.
+async def on_connect(websocket, path):
+    """ For every new charge point that connects, create a ChargePoint instance and start
+    listening for messages."""
+    try:
+        requested_protocols = websocket.request_headers['Sec-WebSocket-Protocol']
+    except KeyError:
+        logging.info("Client hasn't requested any Subprotocol. Closing Connection")
+        return await websocket.close()
+
+    if websocket.subprotocol:
+        logging.info("Protocols Matched: %s", websocket.subprotocol)
+    else:
+        logging.warning('Protocols Mismatched | Expected Subprotocols: %s,'
+                        ' but client supports %s | Closing connection',
+                        websocket.available_subprotocols,
+                        requested_protocols)
+        return await websocket.close()
+
+    charge_point_id = path.strip('/')
+    cp = ChargePoint(charge_point_id, websocket)
+
+    # Start the ChargePoint instance to listen for incoming messages.
+    await cp.start()
+
+# Main function to start the WebSocket server.
+async def main():
+    # Create the WebSocket server and specify the handler for new connections.
+    server = await websockets.serve(
+        on_connect,
+        '127.0.0.1',  # Listen on loopback.
+        9000,         # Port number.
+        subprotocols=['ocpp2.0', 'ocpp2.0.1']  # Specify OCPP 2.0.1 subprotocols.
+    )
+    logging.info("WebSocket Server Started")
+    # Wait for the server to close (runs indefinitely).
+    await server.wait_closed()
+
+# Entry point of the script.
+if __name__ == '__main__':
+    # Run the main function to start the server.
+    asyncio.run(main())
diff --git a/tests/utils/CircularArray.test.ts b/tests/utils/CircularArray.test.ts
deleted file mode 100644 (file)
index 74be021..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-import { describe, it } from 'node:test'
-
-import { expect } from 'expect'
-
-import { CircularArray, DEFAULT_CIRCULAR_ARRAY_SIZE } from '../../src/utils/CircularArray.js'
-
-await describe('CircularArray test suite', async () => {
-  await it('Verify that circular array can be instantiated', () => {
-    const circularArray = new CircularArray()
-    expect(circularArray).toBeInstanceOf(CircularArray)
-  })
-
-  await it('Verify circular array default size at instance creation', () => {
-    const circularArray = new CircularArray()
-    expect(circularArray.size).toBe(DEFAULT_CIRCULAR_ARRAY_SIZE)
-  })
-
-  await it('Verify that circular array size can be set at instance creation', () => {
-    const circularArray = new CircularArray(1000)
-    expect(circularArray.size).toBe(1000)
-  })
-
-  await it('Verify that circular array size and items can be set at instance creation', () => {
-    let circularArray = new CircularArray(1000, 1, 2, 3, 4, 5)
-    expect(circularArray.size).toBe(1000)
-    expect(circularArray.length).toBe(5)
-    circularArray = new CircularArray(4, 1, 2, 3, 4, 5)
-    expect(circularArray.size).toBe(4)
-    expect(circularArray.length).toBe(4)
-  })
-
-  await it('Verify that circular array size is valid at instance creation', () => {
-    expect(() => new CircularArray(0.25)).toThrow(
-      new TypeError('Invalid circular array size: 0.25 is not a safe integer')
-    )
-    expect(() => new CircularArray(-1)).toThrow(
-      new RangeError('Invalid circular array size: -1 < 0')
-    )
-    expect(() => new CircularArray(Number.MAX_SAFE_INTEGER + 1)).toThrow(
-      new TypeError(
-        `Invalid circular array size: ${Number.MAX_SAFE_INTEGER + 1} is not a safe integer`
-      )
-    )
-  })
-
-  await it('Verify that circular array empty works as intended', () => {
-    const circularArray = new CircularArray()
-    expect(circularArray.empty()).toBe(true)
-  })
-
-  await it('Verify that circular array full works as intended', () => {
-    const circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
-    expect(circularArray.full()).toBe(true)
-  })
-
-  await it('Verify that circular array push works as intended', () => {
-    let circularArray = new CircularArray(4)
-    let arrayLength = circularArray.push(1, 2, 3, 4, 5)
-    expect(arrayLength).toBe(circularArray.size)
-    expect(circularArray.length).toBe(circularArray.size)
-    expect(circularArray).toStrictEqual(new CircularArray(4, 2, 3, 4, 5))
-    arrayLength = circularArray.push(6, 7)
-    expect(arrayLength).toBe(circularArray.size)
-    expect(circularArray.length).toBe(circularArray.size)
-    expect(circularArray).toStrictEqual(new CircularArray(4, 4, 5, 6, 7))
-    circularArray = new CircularArray(100)
-    arrayLength = circularArray.push(1, 2, 3, 4, 5)
-    expect(arrayLength).toBe(5)
-    expect(circularArray.size).toBe(100)
-    expect(circularArray.length).toBe(5)
-    expect(circularArray).toStrictEqual(new CircularArray(100, 1, 2, 3, 4, 5))
-  })
-
-  await it('Verify that circular array splice works as intended', () => {
-    let circularArray = new CircularArray(1000, 1, 2, 3, 4, 5)
-    let deletedItems = circularArray.splice(2)
-    expect(deletedItems).toStrictEqual(new CircularArray(3, 3, 4, 5))
-    expect(circularArray.length).toBe(2)
-    expect(circularArray).toStrictEqual(new CircularArray(1000, 1, 2))
-    circularArray = new CircularArray(1000, 1, 2, 3, 4, 5)
-    deletedItems = circularArray.splice(2, 1)
-    expect(deletedItems).toStrictEqual(new CircularArray(1, 3))
-    expect(circularArray.length).toBe(4)
-    expect(circularArray).toStrictEqual(new CircularArray(1000, 1, 2, 4, 5))
-    circularArray = new CircularArray(4, 1, 2, 3, 4)
-    deletedItems = circularArray.splice(2, 1, 5, 6)
-    expect(deletedItems).toStrictEqual(new CircularArray(2, 3, 1))
-    expect(circularArray.length).toBe(4)
-    expect(circularArray).toStrictEqual(new CircularArray(4, 2, 5, 6, 4))
-  })
-
-  await it('Verify that circular array concat works as intended', () => {
-    let circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
-    circularArray = circularArray.concat(6, 7)
-    expect(circularArray.length).toBe(5)
-    expect(circularArray).toStrictEqual(new CircularArray(5, 3, 4, 5, 6, 7))
-    circularArray = new CircularArray(1)
-    circularArray = circularArray.concat(6, 7)
-    expect(circularArray.length).toBe(1)
-    expect(circularArray).toStrictEqual(new CircularArray(1, 7))
-  })
-
-  await it('Verify that circular array unshift works as intended', () => {
-    let circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
-    let arrayLength = circularArray.unshift(6, 7)
-    expect(arrayLength).toBe(5)
-    expect(circularArray.length).toBe(5)
-    expect(circularArray).toStrictEqual(new CircularArray(5, 6, 7, 1, 2, 3))
-    circularArray = new CircularArray(1)
-    arrayLength = circularArray.unshift(6, 7)
-    expect(arrayLength).toBe(1)
-    expect(circularArray.length).toBe(1)
-    expect(circularArray).toStrictEqual(new CircularArray(1, 6))
-  })
-
-  await it('Verify that circular array resize works as intended', () => {
-    expect(() => {
-      new CircularArray().resize(0.25)
-    }).toThrow(new TypeError('Invalid circular array size: 0.25 is not a safe integer'))
-    expect(() => {
-      new CircularArray().resize(-1)
-    }).toThrow(new RangeError('Invalid circular array size: -1 < 0'))
-    expect(() => {
-      new CircularArray().resize(Number.MAX_SAFE_INTEGER + 1)
-    }).toThrow(
-      new TypeError(
-        `Invalid circular array size: ${Number.MAX_SAFE_INTEGER + 1} is not a safe integer`
-      )
-    )
-    let circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
-    circularArray.resize(0)
-    expect(circularArray.size).toBe(0)
-    expect(circularArray).toStrictEqual(new CircularArray(0))
-    circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
-    circularArray.resize(1)
-    expect(circularArray.size).toBe(1)
-    expect(circularArray).toStrictEqual(new CircularArray(1, 1))
-    circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
-    circularArray.resize(3)
-    expect(circularArray.size).toBe(3)
-    expect(circularArray).toStrictEqual(new CircularArray(3, 1, 2, 3))
-    circularArray = new CircularArray(5, 1, 2, 3, 4, 5)
-    circularArray.resize(8)
-    expect(circularArray.size).toBe(8)
-    expect(circularArray).toStrictEqual(new CircularArray(8, 1, 2, 3, 4, 5))
-  })
-})
diff --git a/tests/utils/ConfigurationUtils.test.ts b/tests/utils/ConfigurationUtils.test.ts
new file mode 100644 (file)
index 0000000..b0689b8
--- /dev/null
@@ -0,0 +1,23 @@
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+import { describe, it } from 'node:test'
+
+import { expect } from 'expect'
+
+import { FileType } from '../../src/types/index.js'
+import { handleFileException, logPrefix } from '../../src/utils/ConfigurationUtils.js'
+
+await describe('ConfigurationUtils test suite', async () => {
+  await it('Verify logPrefix()', () => {
+    expect(logPrefix()).toContain(' Simulator configuration |')
+  })
+
+  await it('Verify handleFileException()', t => {
+    t.mock.method(console, 'error')
+    const error = new Error()
+    error.code = 'ENOENT'
+    expect(() => {
+      handleFileException('path/to/module.js', FileType.Authorization, error, 'log prefix |')
+    }).toThrow(error)
+    expect(console.error.mock.calls.length).toBe(1)
+  })
+})
diff --git a/tests/utils/ErrorUtils.test.ts b/tests/utils/ErrorUtils.test.ts
new file mode 100644 (file)
index 0000000..edf088c
--- /dev/null
@@ -0,0 +1,129 @@
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+import { describe, it } from 'node:test'
+
+import { expect } from 'expect'
+
+import type { ChargingStation } from '../../src/charging-station/index.js'
+import {
+  FileType,
+  GenericStatus,
+  IncomingRequestCommand,
+  MessageType,
+  RequestCommand
+} from '../../src/types/index.js'
+import {
+  handleFileException,
+  handleIncomingRequestError,
+  handleSendMessageError,
+  setDefaultErrorParams
+} from '../../src/utils/ErrorUtils.js'
+import { logger } from '../../src/utils/Logger.js'
+
+await describe('ErrorUtils test suite', async () => {
+  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
+  const chargingStation = {
+    logPrefix: () => 'CS-TEST |'
+  } as ChargingStation
+
+  await it('Verify handleFileException()', t => {
+    t.mock.method(console, 'warn')
+    t.mock.method(console, 'error')
+    t.mock.method(logger, 'warn')
+    t.mock.method(logger, 'error')
+    const error = new Error()
+    error.code = 'ENOENT'
+    expect(() => {
+      handleFileException('path/to/module.js', FileType.Authorization, error, 'log prefix |', {})
+    }).toThrow(error)
+    expect(() => {
+      handleFileException('path/to/module.js', FileType.Authorization, error, 'log prefix |', {
+        throwError: false
+      })
+    }).not.toThrow()
+    expect(logger.warn.mock.calls.length).toBe(1)
+    expect(logger.error.mock.calls.length).toBe(1)
+    expect(() => {
+      handleFileException('path/to/module.js', FileType.Authorization, error, 'log prefix |', {
+        consoleOut: true
+      })
+    }).toThrow(error)
+    expect(() => {
+      handleFileException('path/to/module.js', FileType.Authorization, error, 'log prefix |', {
+        throwError: false,
+        consoleOut: true
+      })
+    }).not.toThrow()
+    expect(console.warn.mock.calls.length).toBe(1)
+    expect(console.error.mock.calls.length).toBe(1)
+  })
+
+  await it('Verify handleSendMessageError()', t => {
+    t.mock.method(logger, 'error')
+    t.mock.method(chargingStation, 'logPrefix')
+    const error = new Error()
+    expect(() => {
+      handleSendMessageError(
+        chargingStation,
+        RequestCommand.BOOT_NOTIFICATION,
+        MessageType.CALL_MESSAGE,
+        error
+      )
+    }).not.toThrow()
+    expect(() => {
+      handleSendMessageError(
+        chargingStation,
+        RequestCommand.BOOT_NOTIFICATION,
+        MessageType.CALL_MESSAGE,
+        error,
+        { throwError: true }
+      )
+    }).toThrow(error)
+    expect(chargingStation.logPrefix.mock.calls.length).toBe(2)
+    expect(logger.error.mock.calls.length).toBe(2)
+  })
+
+  await it('Verify handleIncomingRequestError()', t => {
+    t.mock.method(logger, 'error')
+    t.mock.method(chargingStation, 'logPrefix')
+    const error = new Error()
+    expect(() => {
+      handleIncomingRequestError(chargingStation, IncomingRequestCommand.CLEAR_CACHE, error)
+    }).toThrow(error)
+    expect(() => {
+      handleIncomingRequestError(chargingStation, IncomingRequestCommand.CLEAR_CACHE, error, {
+        throwError: false
+      })
+    }).not.toThrow()
+    const errorResponse = {
+      status: GenericStatus.Rejected
+    }
+    expect(
+      handleIncomingRequestError(chargingStation, IncomingRequestCommand.CLEAR_CACHE, error, {
+        throwError: false,
+        errorResponse
+      })
+    ).toStrictEqual(errorResponse)
+    expect(chargingStation.logPrefix.mock.calls.length).toBe(3)
+    expect(logger.error.mock.calls.length).toBe(3)
+  })
+
+  await it('Verify setDefaultErrorParams()', () => {
+    expect(setDefaultErrorParams({})).toStrictEqual({ throwError: true, consoleOut: false })
+    expect(setDefaultErrorParams({ throwError: false })).toStrictEqual({
+      throwError: false,
+      consoleOut: false
+    })
+    expect(setDefaultErrorParams({ throwError: false, consoleOut: true })).toStrictEqual({
+      throwError: false,
+      consoleOut: true
+    })
+    expect(setDefaultErrorParams({ throwError: true, consoleOut: true })).toStrictEqual({
+      throwError: true,
+      consoleOut: true
+    })
+    expect(setDefaultErrorParams({}, { throwError: false, consoleOut: false })).toStrictEqual({
+      throwError: false,
+      consoleOut: false
+    })
+  })
+})
index b54cdee86a3d64325117dc59a4e3c6066a3f9c0c..c0bf1b6cc8bf4e7a0ee3329eb1f1e73b9eb45b3e 100644 (file)
@@ -6,7 +6,7 @@ import { max, min, nthPercentile, stdDeviation } from '../../src/utils/Statistic
 
 await describe('StatisticUtils test suite', async () => {
   await it('Verify min()', () => {
 
 await describe('StatisticUtils test suite', async () => {
   await it('Verify min()', () => {
-    expect(min()).toBe(Infinity)
+    expect(min()).toBe(Number.POSITIVE_INFINITY)
     expect(min(0, 1)).toBe(0)
     expect(min(1, 0)).toBe(0)
     expect(min(0, -1)).toBe(-1)
     expect(min(0, 1)).toBe(0)
     expect(min(1, 0)).toBe(0)
     expect(min(0, -1)).toBe(-1)
@@ -14,7 +14,7 @@ await describe('StatisticUtils test suite', async () => {
   })
 
   await it('Verify max()', () => {
   })
 
   await it('Verify max()', () => {
-    expect(max()).toBe(-Infinity)
+    expect(max()).toBe(Number.NEGATIVE_INFINITY)
     expect(max(0, 1)).toBe(1)
     expect(max(1, 0)).toBe(1)
     expect(max(0, -1)).toBe(0)
     expect(max(0, 1)).toBe(1)
     expect(max(1, 0)).toBe(1)
     expect(max(0, -1)).toBe(0)
index 5672b032187e336ba48e6a85c73a0d5b5f981a02..11b9973eacc8db0160f79f924d54d98204b2f554 100644 (file)
@@ -4,8 +4,10 @@ import { describe, it } from 'node:test'
 
 import { hoursToMilliseconds, hoursToSeconds } from 'date-fns'
 import { expect } from 'expect'
 
 import { hoursToMilliseconds, hoursToSeconds } from 'date-fns'
 import { expect } from 'expect'
+import { CircularBuffer } from 'mnemonist'
 import { satisfies } from 'semver'
 
 import { satisfies } from 'semver'
 
+import type { TimestampedData } from '../../src/types/index.js'
 import { Constants } from '../../src/utils/Constants.js'
 import {
   clone,
 import { Constants } from '../../src/utils/Constants.js'
 import {
   clone,
@@ -19,6 +21,7 @@ import {
   generateUUID,
   getRandomFloat,
   hasOwnProp,
   generateUUID,
   getRandomFloat,
   hasOwnProp,
+  insertAt,
   isArraySorted,
   isAsyncFunction,
   isNotEmptyArray,
   isArraySorted,
   isAsyncFunction,
   isNotEmptyArray,
@@ -188,14 +191,19 @@ await describe('Utils test suite', async () => {
   })
 
   await it('Verify extractTimeSeriesValues()', () => {
   })
 
   await it('Verify extractTimeSeriesValues()', () => {
-    expect(extractTimeSeriesValues([])).toEqual([])
-    expect(extractTimeSeriesValues([{ timestamp: Date.now(), value: 1.1 }])).toEqual([1.1])
     expect(
     expect(
-      extractTimeSeriesValues([
-        { timestamp: Date.now(), value: 1.1 },
-        { timestamp: Date.now(), value: 2.2 }
-      ])
-    ).toEqual([1.1, 2.2])
+      extractTimeSeriesValues(
+        new CircularBuffer<TimestampedData>(Array, Constants.DEFAULT_CIRCULAR_BUFFER_CAPACITY)
+      )
+    ).toEqual([])
+    const circularBuffer = new CircularBuffer<TimestampedData>(
+      Array,
+      Constants.DEFAULT_CIRCULAR_BUFFER_CAPACITY
+    )
+    circularBuffer.push({ timestamp: Date.now(), value: 1.1 })
+    circularBuffer.push({ timestamp: Date.now(), value: 2.2 })
+    circularBuffer.push({ timestamp: Date.now(), value: 3.3 })
+    expect(extractTimeSeriesValues(circularBuffer)).toEqual([1.1, 2.2, 3.3])
   })
 
   await it('Verify isObject()', () => {
   })
 
   await it('Verify isObject()', () => {
@@ -225,7 +233,7 @@ await describe('Utils test suite', async () => {
     expect(isAsyncFunction([])).toBe(false)
     expect(isAsyncFunction(new Date())).toBe(false)
     // eslint-disable-next-line prefer-regex-literals
     expect(isAsyncFunction([])).toBe(false)
     expect(isAsyncFunction(new Date())).toBe(false)
     // eslint-disable-next-line prefer-regex-literals
-    expect(isAsyncFunction(new RegExp('[a-z]', 'i'))).toBe(false)
+    expect(isAsyncFunction(/[a-z]/i)).toBe(false)
     expect(isAsyncFunction(new Error())).toBe(false)
     expect(isAsyncFunction(new Map())).toBe(false)
     expect(isAsyncFunction(new Set())).toBe(false)
     expect(isAsyncFunction(new Error())).toBe(false)
     expect(isAsyncFunction(new Map())).toBe(false)
     expect(isAsyncFunction(new Set())).toBe(false)
@@ -373,6 +381,11 @@ await describe('Utils test suite', async () => {
     expect(isNotEmptyArray(new WeakSet())).toBe(false)
   })
 
     expect(isNotEmptyArray(new WeakSet())).toBe(false)
   })
 
+  await it('Verify insertAt()', () => {
+    expect(insertAt('test', 'ing', 'test'.length)).toBe('testing')
+    expect(insertAt('test', 'ing', 2)).toBe('teingst')
+  })
+
   await it('Verify isArraySorted()', () => {
     expect(
       isArraySorted([], (a, b) => {
   await it('Verify isArraySorted()', () => {
     expect(
       isArraySorted([], (a, b) => {
index 5188248a5285ba06f37b5468096961766a38e078..f9fa35260aee5973ab56dc0e9cbdc8ff04fbe01f 100644 (file)
@@ -8,10 +8,10 @@
     "pnpm": ">=9.0.0"
   },
   "volta": {
     "pnpm": ">=9.0.0"
   },
   "volta": {
-    "node": "22.1.0",
-    "pnpm": "9.1.0"
+    "node": "22.2.0",
+    "pnpm": "9.3.0"
   },
   },
-  "packageManager": "pnpm@9.1.0",
+  "packageManager": "pnpm@9.3.0",
   "type": "module",
   "scripts": {
     "build": "vite build",
   "type": "module",
   "scripts": {
     "build": "vite build",
     "finalhandler": "^1.2.0",
     "serve-static": "^1.15.0",
     "vue": "^3.4.27",
     "finalhandler": "^1.2.0",
     "serve-static": "^1.15.0",
     "vue": "^3.4.27",
-    "vue-router": "^4.3.2",
+    "vue-router": "^4.3.3",
     "vue-toast-notification": "^3.1.2"
   },
   "devDependencies": {
     "vue-toast-notification": "^3.1.2"
   },
   "devDependencies": {
-    "@rushstack/eslint-patch": "^1.10.2",
+    "@rushstack/eslint-patch": "^1.10.3",
     "@tsconfig/node20": "^20.1.4",
     "@tsconfig/node20": "^20.1.4",
-    "@types/jsdom": "^21.1.6",
-    "@types/node": "^20.12.10",
-    "@typescript-eslint/eslint-plugin": "^7.8.0",
-    "@typescript-eslint/parser": "^7.8.0",
-    "@vitejs/plugin-vue": "^5.0.4",
-    "@vitejs/plugin-vue-jsx": "^3.1.0",
+    "@types/jsdom": "^21.1.7",
+    "@types/node": "^20.14.2",
+    "@typescript-eslint/eslint-plugin": "^7.12.0",
+    "@typescript-eslint/parser": "^7.12.0",
+    "@vitejs/plugin-vue": "^5.0.5",
+    "@vitejs/plugin-vue-jsx": "^4.0.0",
     "@vitest/coverage-v8": "^1.6.0",
     "@vue/eslint-config-prettier": "^9.0.0",
     "@vue/eslint-config-typescript": "^13.0.0",
     "@vitest/coverage-v8": "^1.6.0",
     "@vue/eslint-config-prettier": "^9.0.0",
     "@vue/eslint-config-typescript": "^13.0.0",
     "eslint-import-resolver-typescript": "^3.6.1",
     "eslint-plugin-import": "^2.29.1",
     "eslint-plugin-simple-import-sort": "^12.1.0",
     "eslint-import-resolver-typescript": "^3.6.1",
     "eslint-plugin-import": "^2.29.1",
     "eslint-plugin-simple-import-sort": "^12.1.0",
-    "eslint-plugin-vue": "^9.25.0",
-    "jsdom": "^24.0.0",
-    "prettier": "^3.2.5",
-    "rimraf": "^5.0.5",
+    "eslint-plugin-vue": "^9.26.0",
+    "jsdom": "^24.1.0",
+    "prettier": "^3.3.1",
+    "rimraf": "^5.0.7",
     "typescript": "~5.4.5",
     "typescript": "~5.4.5",
-    "vite": "^5.2.11",
+    "vite": "^5.2.13",
     "vitest": "^1.6.0"
   },
   "_id": "webui@0.3.0"
     "vitest": "^1.6.0"
   },
   "_id": "webui@0.3.0"
index 9522c59213c666a526d48927447024f3e8fc065a..04587e2d8a98d7688eb8016a0833e01edc5b93a4 100644 (file)
@@ -105,7 +105,9 @@ export class UIClient {
   }
 
   public async deleteChargingStation(hashId: string): Promise<ResponsePayload> {
   }
 
   public async deleteChargingStation(hashId: string): Promise<ResponsePayload> {
-    return this.sendRequest(ProcedureName.DELETE_CHARGING_STATIONS, { hashIds: [hashId] })
+    return this.sendRequest(ProcedureName.DELETE_CHARGING_STATIONS, {
+      hashIds: [hashId]
+    })
   }
 
   public async setSupervisionUrl(hashId: string, supervisionUrl: string): Promise<ResponsePayload> {
   }
 
   public async setSupervisionUrl(hashId: string, supervisionUrl: string): Promise<ResponsePayload> {
@@ -116,11 +118,15 @@ export class UIClient {
   }
 
   public async startChargingStation(hashId: string): Promise<ResponsePayload> {
   }
 
   public async startChargingStation(hashId: string): Promise<ResponsePayload> {
-    return this.sendRequest(ProcedureName.START_CHARGING_STATION, { hashIds: [hashId] })
+    return this.sendRequest(ProcedureName.START_CHARGING_STATION, {
+      hashIds: [hashId]
+    })
   }
 
   public async stopChargingStation(hashId: string): Promise<ResponsePayload> {
   }
 
   public async stopChargingStation(hashId: string): Promise<ResponsePayload> {
-    return this.sendRequest(ProcedureName.STOP_CHARGING_STATION, { hashIds: [hashId] })
+    return this.sendRequest(ProcedureName.STOP_CHARGING_STATION, {
+      hashIds: [hashId]
+    })
   }
 
   public async openConnection(hashId: string): Promise<ResponsePayload> {
   }
 
   public async openConnection(hashId: string): Promise<ResponsePayload> {
@@ -183,11 +189,17 @@ export class UIClient {
       this.uiServerConfiguration.authentication?.type === AuthenticationType.PROTOCOL_BASIC_AUTH
         ? [
             `${this.uiServerConfiguration.protocol}${this.uiServerConfiguration.version}`,
       this.uiServerConfiguration.authentication?.type === AuthenticationType.PROTOCOL_BASIC_AUTH
         ? [
             `${this.uiServerConfiguration.protocol}${this.uiServerConfiguration.version}`,
-            `authorization.basic.${btoa(`${this.uiServerConfiguration.authentication.username}:${this.uiServerConfiguration.authentication.password}`).replace(/={1,2}$/, '')}`
+            `authorization.basic.${btoa(
+              `${this.uiServerConfiguration.authentication.username}:${this.uiServerConfiguration.authentication.password}`
+            ).replace(/={1,2}$/, '')}`
           ]
         : `${this.uiServerConfiguration.protocol}${this.uiServerConfiguration.version}`
     this.ws = new WebSocket(
           ]
         : `${this.uiServerConfiguration.protocol}${this.uiServerConfiguration.version}`
     this.ws = new WebSocket(
-      `${this.uiServerConfiguration.secure === true ? ApplicationProtocol.WSS : ApplicationProtocol.WS}://${this.uiServerConfiguration.host}:${this.uiServerConfiguration.port}`,
+      `${
+        this.uiServerConfiguration.secure === true
+          ? ApplicationProtocol.WSS
+          : ApplicationProtocol.WS
+      }://${this.uiServerConfiguration.host}:${this.uiServerConfiguration.port}`,
       protocols
     )
     this.ws.onopen = () => {
       protocols
     )
     this.ws.onopen = () => {
index 0c8a83996e905c7e046d624ad9a8bd64124d1df1..b1bebc92582b5ae64c82b6839ab244a05c0c6075 100644 (file)
@@ -27,7 +27,7 @@ export const convertToInt = (value: unknown): number => {
   }
   let changedValue: number = value as number
   if (typeof value === 'string') {
   }
   let changedValue: number = value as number
   if (typeof value === 'string') {
-    changedValue = parseInt(value)
+    changedValue = Number.parseInt(value)
   }
   if (isNaN(changedValue)) {
     throw new Error(`Cannot convert to integer: '${String(value)}'`)
   }
   if (isNaN(changedValue)) {
     throw new Error(`Cannot convert to integer: '${String(value)}'`)
index 6f0d76e38bac14a980a967753b9db65609cc0a46..48265c5acbcd3d56459240ccbfe0ebe4ee2bd2ee 100644 (file)
@@ -1,4 +1,4 @@
-export {}
+export type {}
 
 declare module 'vue' {
   export interface GlobalComponents {
 
 declare module 'vue' {
   export interface GlobalComponents {
index 695b88608b4df60c0e90ff848167057ddcbcdfb7..af6fbe99a4d771068a2429845ad6632bd13be2b0 100644 (file)
@@ -142,7 +142,9 @@ const simulatorButtonClass = computed<string>(() =>
 )
 const simulatorButtonMessage = computed<string>(
   () =>
 )
 const simulatorButtonMessage = computed<string>(
   () =>
-    `${simulatorState.value?.started === true ? 'Stop' : 'Start'} Simulator${simulatorState.value?.version != null ? ` (${simulatorState.value.version})` : ''}`
+    `${simulatorState.value?.started === true ? 'Stop' : 'Start'} Simulator${
+      simulatorState.value?.version != null ? ` (${simulatorState.value.version})` : ''
+    }`
 )
 
 const state = ref<{
 )
 
 const state = ref<{
@@ -286,7 +288,10 @@ onUnmounted(() => {
   unregisterWSEventListeners()
 })
 
   unregisterWSEventListeners()
 })
 
-const uiServerConfigurations: { index: number; configuration: UIServerConfigurationSection }[] = (
+const uiServerConfigurations: {
+  index: number
+  configuration: UIServerConfigurationSection
+}[] = (
   app?.appContext.config.globalProperties.$configuration.value
     .uiServer as UIServerConfigurationSection[]
 ).map((configuration: UIServerConfigurationSection, index: number) => ({
   app?.appContext.config.globalProperties.$configuration.value
     .uiServer as UIServerConfigurationSection[]
 ).map((configuration: UIServerConfigurationSection, index: number) => ({
index 46a8bb75884f67da0c4b2ecfc9138bff44fb7ab2..3eb2838e8925cb1b38e872695e66162c97883607 100644 (file)
@@ -7,7 +7,7 @@ import finalhandler from 'finalhandler'
 import serveStatic from 'serve-static'
 
 const isCFEnvironment = env.VCAP_APPLICATION != null
 import serveStatic from 'serve-static'
 
 const isCFEnvironment = env.VCAP_APPLICATION != null
-const PORT = isCFEnvironment ? parseInt(env.PORT) : 3030
+const PORT = isCFEnvironment ? Number.parseInt(env.PORT) : 3030
 const uiPath = join(dirname(fileURLToPath(import.meta.url)), './dist')
 
 const serve = serveStatic(uiPath)
 const uiPath = join(dirname(fileURLToPath(import.meta.url)), './dist')
 
 const serve = serveStatic(uiPath)