Merge branch 'main' into reservation-feature
authorJérôme Benoit <jerome.benoit@sap.com>
Mon, 5 Jun 2023 15:36:45 +0000 (17:36 +0200)
committerGitHub <noreply@github.com>
Mon, 5 Jun 2023 15:36:45 +0000 (17:36 +0200)
52 files changed:
.cfignore
.vscode/settings.json
CHANGELOG.md
README.md
package.json
pnpm-lock.yaml
rollup.config.mjs
sonar-project.properties
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/Bootstrap.ts
src/charging-station/ChargingStation.ts
src/charging-station/ChargingStationWorker.ts
src/charging-station/IdTagsCache.ts
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
src/charging-station/ocpp/OCPPConstants.ts
src/charging-station/ocpp/OCPPIncomingRequestService.ts
src/charging-station/ocpp/OCPPRequestService.ts
src/charging-station/ocpp/OCPPServiceUtils.ts
src/charging-station/ui-server/AbstractUIServer.ts
src/charging-station/ui-server/UIHttpServer.ts
src/charging-station/ui-server/UIWebSocketServer.ts
src/charging-station/ui-server/ui-services/AbstractUIService.ts
src/performance/PerformanceStatistics.ts
src/performance/storage/JsonFileStorage.ts
src/performance/storage/Storage.ts
src/types/ChargingStationInfo.ts
src/types/ChargingStationTemplate.ts
src/types/ConfigurationData.ts
src/utils/AsyncLock.ts
src/utils/Configuration.ts
src/utils/ErrorUtils.ts
src/utils/FileUtils.ts
src/utils/Logger.ts
src/utils/MessageChannelUtils.ts
src/utils/StatisticUtils.ts [new file with mode: 0644]
src/utils/Utils.ts
src/utils/index.ts
src/worker/WorkerAbstract.ts
src/worker/WorkerDynamicPool.ts
src/worker/WorkerSet.ts
src/worker/WorkerStaticPool.ts
src/worker/WorkerTypes.ts
src/worker/WorkerUtils.ts
test/charging-station/ChargingStation.test.ts [moved from test/charging-station/ChargingStationTest.ts with 100% similarity]
test/utils/CircularArray.test.ts [moved from test/utils/CircularArrayTest.ts with 99% similarity]
test/utils/StatisticUtils.test.ts [new file with mode: 0644]
test/utils/Utils.test.ts [moved from test/utils/UtilsTest.ts with 93% similarity]
tsconfig-base.json
tsconfig-orm.json
ui/web/package.json
ui/web/pnpm-lock.yaml

index 30ad46d7aad45f179813da8bc38bac0aa1ae6091..608afbfbb8fd5ea28fe19a83dabad3c7568ffc12 100644 (file)
--- a/.cfignore
+++ b/.cfignore
@@ -63,11 +63,11 @@ mta_archives
 docker
 src
 test
+ui
 temp
 outputs
 coverage
 node_modules
-!dist/node_modules
 sonar-project.properties
 performanceRecords.json
 performanceRecords.json.lock
index 47a0799f031eb80b48e03dbc8107012e7780044d..9b0e7390f63f4e23a8a267e75eb1ebfb5a3fdfbe 100644 (file)
@@ -8,14 +8,16 @@
     "--no-warnings=ExperimentalWarning",
     "--experimental-specifier-resolution=node"
   ],
-  "mochaExplorer.files": ["test/**/*Test.ts"],
+  "mochaExplorer.files": ["test/**/*.test.ts"],
   "mochaExplorer.debuggerConfig": "Debug Simulator Unit Tests",
   "cSpell.words": [
     "benoit",
     "bufferutil",
     "cacheable",
     "commitlint",
+    "corepack",
     "csms",
+    "emerg",
     "emobility",
     "evse",
     "evses",
@@ -35,7 +37,9 @@
     "poolifier",
     "preinstall",
     "Recurrency",
+    "RFID",
     "robohydra",
+    "shutdowning",
     "sonarlint",
     "SRPC",
     "tsdoc",
index de239ca8ae90e9629228ab6fc45707a80b60407a..11675ad18132a3982e4f5eb5bb410e9abff2714c 100644 (file)
 # Changelog
 
-## [v1.2.13](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.2.12...v1.2.13)
+## [v1.2.15](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.2.14...v1.2.15)
+
+- fix: fix commonjs import issue with node.js 16.x.x [`#582`](https://github.com/sap/e-mobility-charging-stations-simulator/issues/582)
+- build(deps): apply updates [`13aa228`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/13aa228baf773556a558eae4b6aa6170d57941b7)
+- refactor(simulator): convert some class method helpers to arrow function [`fa5995d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/fa5995d65e5084241af14d0ab7453fbb2fc9d8a6)
+- fix: fix CS configuration hash calculation [`5ced7e8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5ced7e80e407f1ea468d4adf2fb40341dde978de)
+- build(deps-dev): apply updates [`25fd416`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/25fd416f702bcc57137be2846ee9823844e54dbe)
+- refactor(simulator): factor out statistic helpers [`4884b8d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4884b8d37eebb90a39a8295f1b61cf822dcf0869)
+- refactor(simulator): convert more class static helpers to arrow function [`c8faabc`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c8faabc815e314d10188b9c285c61e1e4c367f8c)
+- perf: use O(1) queue implementation in async locking code [`4f9327b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4f9327bf63123fa94e86b027ad1ab9b0a22c3500)
+- refactor: use mnemonist queue implementation instead of homebrew one [`5983297`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5983297441ae1af1d5a6e9ecc38ba04f8777724b)
+- docs: refine README.md [`dda26c3`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/dda26c32c8d04e0e3cad6af61840d39909854019)
+- build(deps-dev): apply updates [`2f8d634`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/2f8d63435f05ce67cf1e9f9b542202fb9659c62c)
+- build(deps-dev): apply updates [`cc7bd8c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/cc7bd8c740bdc7b51cd3a8cab035291a8d2fbca0)
+- build(deps-dev): apply updates [`eee4fe2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/eee4fe24584ffacde1d5d905f4ab77cd9cff926e)
+- refactor: only copy assets used at runtime in the bundle [`672551e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/672551edc7fdd48814717269e2f814bd54fa387b)
+- refactor: convert WorkerUtils class static methods to constified arrow [`789871d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/789871d6585093e2ab0444bd7ca063ca86c344f8)
+- fix: allow to set some x509 certificates in templates [`d4d6573`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d4d65733e925dcc1b152eef88f3f03e6f25037c3)
+- refactor: factor out default OCPP request params value [`b9da1bc`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/b9da1bc288a2a6ffccfbca6cd19aa195bc6ccfbf)
+- build: update pnpm lockfile version [`5f0a7b0`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5f0a7b0d1d6ccfa750f6f867e7ddfea412f43f9a)
+- refactor: factor out default error handling params [`1c34e5f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1c34e5f93827b6f803bd67bdb7a8d74a264b548f)
+- docs: refine README.md [`3a28512`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/3a28512cb5a3da950f8976a7ce266113d9dffb2f)
+- fix: ensure internal counters are zeroed at simulator stop [`0f040ac`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/0f040ac07b841b0eb9ed5e65d76c85adbb084aa2)
+- build(simulator): silence rollup warning [`c98873e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c98873ea516ad29e6f50304ac53fac80f4eaf055)
+- fix: do not send UI protocol response if no handler is found [`1ca4a03`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1ca4a038d1b263b3b66a3c1872742bd98a696e75)
+- refactor(simulator): use spread syntax to handle literal arguments [`20f0b76`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/20f0b76c6d1eedd26a7a5d160101233f587ed6c5)
+- refactor: cleanup imports [`4c8782e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4c8782eeb15a7c41b4ef5a413768abd47615047a)
+- refactor: cleanup async lock acquire() [`acf727c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/acf727c70f6f0f63fc0aef528423e52553445ed3)
+- build(simulator): always minify bundle [`31b5738`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/31b5738e12a713a409827124e88d8bc03bbed519)
+- fix: ensure template has priority over CS configuration [`ba01a21`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ba01a213717165f2996c4d27151b414d87c4bbf0)
+- test(simulator): use standard file namespace for tests [`d4ad9d4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d4ad9d45e762ddb25f47b16c175a1509e89f422b)
+- refactor: cleanup configuration handling methods namespace [`cb60061`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/cb60061f9e275d5b81a75c30d51771150b24f8c5)
+- fix: clone ATG connector status before altering it [`56c2982`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/56c298254011750a08c6be90d94c098c31f6bdc3)
+- refactor: cleanup UI server variable namespace [`e64c6fa`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e64c6fa982ba3270bb015deea30eece32b4661de)
+- refactor(simulator): export directly logger helper [`1f5e5d0`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1f5e5d03f67ccfb572045a644bff79119e77c45b)
+- refactor: cleanup UI service method namespace [`7c1395a`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7c1395ab4ec7d727ac09c0f0347a8d9fc5e2c8de)
+- build(simulator): cleanup bundler configuration [`7b008a2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7b008a295bd3be13cf0776fdaa0d86cca73c1510)
+- build(simulator): ensure ui code is not included at cf push [`70b77dc`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/70b77dcd483b37e7c16e45ff277fd0e5df0690b2)
+- docs: refine README.md [`a712de6`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a712de6fb7d7883d6d55015b5f264e494b9b3008)
+- fix: fix default error params setting [`a9c8f6c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a9c8f6cbcff34dc5338c064fab986e4b01451aa2)
+- refactor: stop !== shutdown semantic [`fca8bc6`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/fca8bc64968004b4018a4d766b2121ced4fee943)
+- build: update excluded assets files list [`5d1a7b7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5d1a7b7d866d8e8f848a1119702a00bef86d54a8)
+
+## [v1.2.14](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.2.13...v1.2.14) (2023-05-26)
+
+- fix: handle relative path to performance records JSON file [`#524`](https://github.com/sap/e-mobility-charging-stations-simulator/issues/524)
+- refactor: revert internal exports [`6907417`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/69074173770c04bc5e5aa744b655edf9491daa46)
+- build(deps-dev): apply updates [`ff2521f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ff2521fc5e19d44cefa6eece98c2e1c32f09e6f1)
+- build(deps-dev): apply updates [`7e4b5b3`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7e4b5b3805347b738fbb3dc8a60d03ec34f3c3ba)
+- build(deps): apply updates [`3e8ec69`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/3e8ec6901b2734517ff71fb63a8d05eb10288d8c)
+- build(deps): apply updates [`c5b1622`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c5b16226987261809f3b2b1505537c10e10a37de)
+- build(deps-dev): apply updates [`6ae3a60`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6ae3a6074acfc635d7f8d287e9216446dd1002bb)
+- build(deps): apply updates [`eabbba9`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/eabbba958a1fef2a21d372d56d8a3809239e1c4d)
+- build(deps): apply updates [`064d000`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/064d000b1307395de86de5e20a550b5f6bb31cb8)
+- build(simulator): don't preserve modules [`51022aa`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/51022aa0d811eec79514fbeb56cb9556e7168cd7)
+- build(deps-dev): apply updates [`83e586e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/83e586e889afe95ef11eb186030c643bbac2aeba)
+- build(deps): apply updates [`1cec062`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1cec062a553fe757bd9bea7985c98676a794d139)
+- fix: fix overrides handling for dependencies [`a4e5c2e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/a4e5c2e2fc622bd263b8bd3595c37abfd0669a25)
+- refactor: revert internal exports [`4c3c0d5`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4c3c0d59f56be4d58e906e938c00390b41e0ca7f)
+- build(deps-dev): apply updates [`484411f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/484411fded1d53c6786b19142d135d4f421cd43d)
+- build(deps): apply updates [`2c7eda6`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/2c7eda64ed5d4432e436ceb39d33a66b037d09a0)
+- fix: ensure the runtime ATG configuration is saved [`179ed36`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/179ed3677e63ff8cc9c49acb55b5d6330ee3802b)
+- build(deps): apply updates [`7e2a206`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7e2a206296f489182267213371bb45f14558b917)
+- refactor(simulator): factor out common helpers [`7671fa0`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7671fa0be211e944f027ebd83f3a0ad64c2ef2d6)
+- build(deps-dev): update overrides got version [`8c4e450`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/8c4e450b90e33e8abd926095c7e7b2aa46905ad3)
+- fix: various fixes to files handling and their content caching [`7b5dbe9`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7b5dbe910fc30484324da90ee209ab7002bc5071)
+- fix: wait for charging stations to be stopped at simulator stop [`f130b8e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/f130b8e620e8808516bbf80bc4247c81fae02186)
+- chore: version 1.2.14 [`e2a96ac`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e2a96acb2f2613744b477d4a7b63f21487ab92d4)
+- refactor(simulator): move configuration related helpers [`aa7d6d9`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/aa7d6d9568ce5ec481a0a230f4ae24c9ee9d44fa)
+- refactor(simulator): factor out default ATG configuration [`1fe0632`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/1fe0632adfa4067470497e2de02249fc84a4e218)
+- build(deps-dev): apply updates [`adb88a7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/adb88a7e8f8bdd439feafc0431462677aeac852c)
+- feat: add graceful shutdown [`6bd808f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6bd808fd1dc554c8d55521b20a064447835ef04c)
+- refactor(simulator): simplify ATG default configuration usage [`86b46b4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/86b46b496311fcb6ee26c0d639b6f3c642042c2b)
+- refactor(simulator): strong type worker data for evses [`09989bb`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/09989bb8458670784c7bf68854f60567f2214dd2)
+- refactor: group conditions in connector status change check [`ff9d103`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ff9d1031c851d206c3edca93754b93a8b238aabe)
+- fix: only send UI server response when needed [`0b22144`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/0b22144c135af531858c989650e864edb352764d)
+- refactor(ui): add types export control [`4147bb7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/4147bb7ee6c183f244a10431b4dc53d71917f611)
+- refactor: revert internal exports in utils [`516dee1`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/516dee136cf113684286054f85481d66c7961b49)
+- refactor: cleanup method namaspace [`f7c2994`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/f7c2994d6d3bd83aac94fec10def8730562d3c8f)
+- refactor: organize constants [`c3da35d`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c3da35d496cbb2c78e85fb3d2e125ffd6fd297f4)
+- fix: fix chalk invocation in configuration file handling code [`c5e52a0`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c5e52a07fb5e8e570355415762fc0d97ab4016e0)
+- refactor(simulator): add more default values to ATG [`6170d8c`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6170d8cd4877c852985c90a38441da35ec026b85)
+- docs: add OCPP 2.x.x sections [`d437125`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d4371252a148a51e11d583f314f4e93840da8b1d)
+- refactor: revert internal exports [`c156502`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/c1565026eb14b8bf6aa494c89ccbfcea1ff1dc67)
+- refactor: factor out performance records JSON file path building [`e8044a6`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e8044a69a745aab08dfeea0bd9ec9dd7fe84cdd7)
+- fix: ensure no empty string as supervision url can be used at runtime [`d5c3df4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d5c3df49c705eb1baf790acd1d834235c27339ba)
+- refactor(simulator): factor out data transfer response [`b63b4a7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/b63b4a73f7869a2ff31e5bd259d056faaa53a5de)
+- refactor: align constants scope syntax [`ceec244`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ceec2441596cccd7bc5249721cd9ac8487cb920f)
+- build(simulator): refine pnpm overrides [`64378b5`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/64378b5e65eff516cbc2e3915f0a4996ff338ccf)
+- fix: ensure simulator stop wait for started CS only stop [`805e8a8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/805e8a892d75e4bd8b75f5b7c76110bde0e2dc81)
+- refactor(simulator): warn at startup for missing id tags file [`111aaf8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/111aaf897c1c7b5c2f48678923a458f62406e3e2)
+- build(simulator): use module imports for performance [`b84bca8`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/b84bca85e73f1be0db5482aee6924922e9dc10c9)
+- refactor: silence sonar [`bd5d98e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/bd5d98e0cb5cfb943ad6ac76ba9382cb0bb1f50c)
+- refactor: revert internal exports in exception [`bfa591a`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/bfa591a39d837023fb3acfc5083d3d648419f130)
+- fix: fix undefined payload check in UI server code [`bf4afa5`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/bf4afa568a47cf088c01725737aecb4be7df40b2)
+- refactor(simulator): rename checkTemplateFile() -&gt; checkTemplate() [`e189368`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/e1893686e24bb1abad28b19da833576b1d0e49db)
+- fix: properly fallback to template OCPP configuration [`60655b2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/60655b2618d2d049b20efb78c1a75a75c2874db6)
+- build(deps-dev): apply updates [`468d1c9`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/468d1c9d9d0df650de2c965ae5538ff174d09963)
+- fix: revert incorrect id tags cache key building [`6082281`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6082281f1beebdf0126417b694c134ea4753442c)
+- refactor: cleanup constants namespace [`7d34a2f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7d34a2f48aed78f2e398cae994351c6fa1bd29dc)
+- refactor: improve error logging [`7f77d16`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7f77d16f956cd81a026a042ed440aaaba37b1c56)
+- refactor(simulator): remove unused async lock class attribute [`42486f2`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/42486f2357b011f9244c6b29f4e05185138ce8d1)
+- refactor: format error message properly [`3f3ac53`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/3f3ac53e97ea4b79d0750836bd9d8ac33a7bec77)
+- fix: does not override ATG configuration with default one [`ba05643`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ba0564367ed4a5677bc4c45ab0d1cbed708ebef5)
+- refactor: improve error log messages [`49c508b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/49c508b005ac1eb8731ebccfefeee1b46de1efbd)
+- docs: fix sections level [`bc950df`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/bc950df1239562c0f61a9eaeb4fe9a19756095f8)
+- refactor(ui): order types export [`7edba9a`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/7edba9a79cf60b1d1113ec89f310788194ddb97a)
+- build(ui): sync volta versions [`26eafc4`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/26eafc45f19baa96d0df783ca37e6f7cfcedaa0a)
+- build(deps): add labels on dependabot PRs [`ca3cd0b`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/ca3cd0b1d56b5d4006799260b63059a0b5dcc9b9)
+- build: silence rollup warning [`942f972`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/942f97271c35ec7688abb1633fd2092d234422eb)
+
+## [v1.2.13](https://github.com/sap/e-mobility-charging-stations-simulator/compare/v1.2.12...v1.2.13) (2023-05-09)
 
 - build(deps-dev): apply updates [`0ba5eb0`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/0ba5eb067fbfa32d452aa2822c09796ab715b0aa)
 - build(deps-dev): apply updates [`5c683c7`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/5c683c7aa53c2ec006ac6da87066354590648eb0)
 - fix: move and fix statistic related helpers implementation [`d4c3e68`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/d4c3e68a1a6321f2f43ef0521e121e827f3eb29b)
 - test: improve statistic helpers tests [`806fe29`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/806fe296b3050d3b70adf95b8ac837568efd2d13)
+- chore: version 1.2.13 [`dcc4de1`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/dcc4de1f3c9976bab1effdcaf9773a8e2c4189e9)
 - refactor: cleanup variables namespace [`791cd51`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/791cd51356f38b482d8289e2ab50603aaaadb0af)
 - refactor: align statistic helpers return for empty data set [`6606a6f`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/6606a6f04d159ccd068b05db0e0ef6bf48523517)
 - refactor: cleanup statistic helpers code [`637942e`](https://github.com/sap/e-mobility-charging-stations-simulator/commit/637942ee11115a833f48e24634d0014ebe5b9a8c)
index 7ed5d2672d75d8871e064624bbd5b769e02da3b2..04771de2ff6647df14b63ec162a88ec675766dba 100644 (file)
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 
 ## Summary
 
-Simple [node.js](https://nodejs.org/) software to simulate and scale a set of charging stations based on the OCPP-J 1.6 protocol as part of SAP e-Mobility solution.
+Simple [node.js](https://nodejs.org/) software to simulate and scale a set of charging stations based on the OCPP-J protocol as part of [SAP e-Mobility](https://www.sap.com/products/scm/e-mobility.html) solution.
 
 ## Prerequisites
 
@@ -78,7 +78,7 @@ The charging stations simulator's configuration parameters must be within the `s
 
 All charging station configuration templates are in the directory [src/assets/station-templates](src/assets/station-templates).
 
-A list of RFID tags must be defined for the automatic transaction generator in a file with a default location and name: `src/assets/idtags.json`. A template file is available at [src/assets/idtags-template.json](src/assets/idtags-template.json).
+A list of RFID tags must be defined for the automatic transaction generator in a file with the default location and name: `src/assets/idtags.json`. A template file is available at [src/assets/idtags-template.json](src/assets/idtags-template.json).
 
 **Configuration files hierarchy and priority**:
 
@@ -86,13 +86,13 @@ A list of RFID tags must be defined for the automatic transaction generator in a
 2. charging station configuration template: [src/assets/station-templates](src/assets/station-templates);
 3. charging stations simulator configuration: [src/assets/config.json](src/assets/config.json).
 
-The charging stations simulator have an automatic configuration files reload feature at change for:
+The charging stations simulator has an automatic configuration files reload feature at change for:
 
 - charging stations simulator configuration;
 - charging station configuration templates;
 - charging station authorization RFID tags lists.
 
-But the modifications to test have to be done to the files in the build target directory [dist/assets](dist/assets). Once the modifications are finished, they have to be reported or copied to the matching files in the build source directory [src/assets](src/assets) to ensure they will be taken into account at next build.
+But the modifications to test have to be done to the files in the build target directory [dist/assets](dist/assets). Once the modifications are done, they have to be reported to the matching files in the build source directory [src/assets](src/assets) to ensure they will be taken into account at next build.
 
 ### Charging stations simulator configuration
 
@@ -103,6 +103,7 @@ But the modifications to test have to be done to the files in the build target d
 | supervisionUrls            |                                                  | []                                                                                                                                                                                                            | string \| string[]                                                                                                                                                                                                                  | string or array of global connection URIs to OCPP-J servers                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
 | supervisionUrlDistribution | round-robin/random/charging-station-affinity     | charging-station-affinity                                                                                                                                                                                     | boolean                                                                                                                                                                                                                             | supervision urls distribution policy to simulated charging stations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
 | logStatisticsInterval      |                                                  | 60                                                                                                                                                                                                            | integer                                                                                                                                                                                                                             | seconds between charging stations statistics output in the logs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
+| logEnabled                 | true/false                                       | true                                                                                                                                                                                                          | boolean                                                                                                                                                                                                                             | enable logging                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
 | logConsole                 | true/false                                       | false                                                                                                                                                                                                         | boolean                                                                                                                                                                                                                             | output logs on the console                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
 | logFormat                  |                                                  | simple                                                                                                                                                                                                        | string                                                                                                                                                                                                                              | [winston](https://github.com/winstonjs/winston) log format                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
 | logRotate                  | true/false                                       | true                                                                                                                                                                                                          | boolean                                                                                                                                                                                                                             | enable daily log files rotation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
@@ -131,62 +132,63 @@ But the modifications to test have to be done to the files in the build target d
 
 **src/assets/station-templates/\<name\>.json**:
 
-| Key                                | Value(s)      | Default Value                                                                                                                       | Value type                                                                                                                                                               | Description                                                                                                                                                                                                                         |
-| ---------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| supervisionUrls                    |               | []                                                                                                                                  | string \| string[]                                                                                                                                                       | string or array of connection URIs to OCPP-J servers                                                                                                                                                                                |
-| supervisionUser                    |               | undefined                                                                                                                           | string                                                                                                                                                                   | basic HTTP authentication user to OCPP-J server                                                                                                                                                                                     |
-| supervisionPassword                |               | undefined                                                                                                                           | string                                                                                                                                                                   | basic HTTP authentication password to OCPP-J server                                                                                                                                                                                 |
-| supervisionUrlOcppConfiguration    | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | allow supervision URL configuration via a vendor OCPP parameter key                                                                                                                                                                 |
-| supervisionUrlOcppKey              |               | 'ConnectionUrl'                                                                                                                     | string                                                                                                                                                                   | the vendor string that will be used as a vendor OCPP parameter key to set the supervision URL                                                                                                                                       |
-| ocppVersion                        | 1.6/2.0/2.0.1 | 1.6                                                                                                                                 | string                                                                                                                                                                   | OCPP version                                                                                                                                                                                                                        |
-| ocppProtocol                       | json          | json                                                                                                                                | string                                                                                                                                                                   | OCPP protocol                                                                                                                                                                                                                       |
-| ocppStrictCompliance               | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | strict adherence to the OCPP version and protocol specifications                                                                                                                                                                    |
-| ocppPersistentConfiguration        | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable persistent OCPP parameters storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in [dist/assets/configurations](dist/assets/configurations)                        |
-| stationInfoPersistentConfiguration | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable persistent station information and specifications storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in [dist/assets/configurations](dist/assets/configurations) |
-| wsOptions                          |               | {}                                                                                                                                  | ClientOptions & ClientRequestArgs                                                                                                                                        | [ws](https://github.com/websockets/ws) and node.js [http](https://nodejs.org/api/http.html) clients options intersection                                                                                                            |
-| idTagsFile                         |               | undefined                                                                                                                           | string                                                                                                                                                                   | RFID tags list file relative to src/assets path                                                                                                                                                                                     |
-| baseName                           |               | undefined                                                                                                                           | string                                                                                                                                                                   | base name to build charging stations id                                                                                                                                                                                             |
-| nameSuffix                         |               | undefined                                                                                                                           | string                                                                                                                                                                   | name suffix to build charging stations id                                                                                                                                                                                           |
-| fixedName                          | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | use the baseName as the charging stations unique name                                                                                                                                                                               |
-| chargePointModel                   |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations model                                                                                                                                                                                                             |
-| chargePointVendor                  |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations vendor                                                                                                                                                                                                            |
-| chargePointSerialNumberPrefix      |               | undefined                                                                                                                           | string                                                                                                                                                                   | charge point serial number prefix                                                                                                                                                                                                   |
-| chargeBoxSerialNumberPrefix        |               | undefined                                                                                                                           | string                                                                                                                                                                   | charge box serial number prefix (deprecated in OCPP 1.6)                                                                                                                                                                            |
-| firmwareVersionPattern             |               | Semantic versionning regular expression: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string | string                                                                                                                                                                   | charging stations firmware version pattern                                                                                                                                                                                          |
-| firmwareVersion                    |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations firmware version                                                                                                                                                                                                  |
-| power                              |               |                                                                                                                                     | float \| float[]                                                                                                                                                         | charging stations maximum power value(s)                                                                                                                                                                                            |
-| powerSharedByConnectors            | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | charging stations power shared by its connectors                                                                                                                                                                                    |
-| powerUnit                          | W/kW          | W                                                                                                                                   | string                                                                                                                                                                   | charging stations power unit                                                                                                                                                                                                        |
-| currentOutType                     | AC/DC         | AC                                                                                                                                  | string                                                                                                                                                                   | charging stations current out type                                                                                                                                                                                                  |
-| voltageOut                         |               | AC:230/DC:400                                                                                                                       | integer                                                                                                                                                                  | charging stations voltage out                                                                                                                                                                                                       |
-| numberOfPhases                     | 0/1/3         | AC:3/DC:0                                                                                                                           | integer                                                                                                                                                                  | charging stations number of phase(s)                                                                                                                                                                                                |
-| numberOfConnectors                 |               |                                                                                                                                     | integer \| integer[]                                                                                                                                                     | charging stations number of connector(s)                                                                                                                                                                                            |
-| useConnectorId0                    | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | use connector id 0 definition from the charging station configuration template                                                                                                                                                      |
-| randomConnectors                   | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | randomize runtime connector id affectation from the connector id definition in charging station configuration template                                                                                                              |
-| resetTime                          |               | 60                                                                                                                                  | integer                                                                                                                                                                  | seconds to wait before the charging stations come back at reset                                                                                                                                                                     |
-| autoRegister                       | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | set charging stations as registered at boot notification for testing purpose                                                                                                                                                        |
-| autoReconnectMaxRetries            |               | -1 (unlimited)                                                                                                                      | integer                                                                                                                                                                  | connection retries to the OCPP-J server                                                                                                                                                                                             |
-| reconnectExponentialDelay          | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | connection delay retry to the OCPP-J server                                                                                                                                                                                         |
-| registrationMaxRetries             |               | -1 (unlimited)                                                                                                                      | integer                                                                                                                                                                  | charging stations boot notification retries                                                                                                                                                                                         |
-| amperageLimitationOcppKey          |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations OCPP parameter key used to set the amperage limit, per phase for each connector on AC and global for DC                                                                                                           |
-| amperageLimitationUnit             | A/cA/dA/mA    | A                                                                                                                                   | string                                                                                                                                                                   | charging stations amperage limit unit                                                                                                                                                                                               |
-| enableStatistics                   | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | enable charging stations statistics                                                                                                                                                                                                 |
-| mustAuthorizeAtRemoteStart         | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | always send authorize at remote start transaction when AuthorizeRemoteTxRequests is enabled                                                                                                                                         |
-| payloadSchemaValidation            | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | validate OCPP commands PDU against [OCA](https://www.openchargealliance.org/) JSON schemas                                                                                                                                          |
-| beginEndMeterValues                | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | enable Transaction.{Begin,End} MeterValues                                                                                                                                                                                          |
-| outOfOrderEndMeterValues           | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | send Transaction.End MeterValues out of order. Need to relax OCPP specifications strict compliance ('ocppStrictCompliance' parameter)                                                                                               |
-| meteringPerTransaction             | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable metering history on a per transaction basis                                                                                                                                                                                  |
-| transactionDataMeterValues         | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | enable transaction data MeterValues at stop transaction                                                                                                                                                                             |
-| mainVoltageMeterValues             | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | include charging stations main voltage MeterValues on three phased charging stations                                                                                                                                                |
-| phaseLineToLineVoltageMeterValues  | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | include charging stations line to line voltage MeterValues on three phased charging stations                                                                                                                                        |
-| customValueLimitationMeterValues   | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable limitation on custom fluctuated value in MeterValues                                                                                                                                                                         |
-| firmwareUpgrade                    |               | {<br />"versionUpgrade": {<br />"step": 1<br />},<br />"reset": true<br />}                                                         | {<br />versionUpgrade: {<br />patternGroup: number;<br />step: number;<br />};<br />reset: boolean;<br />failureStatus: 'DownloadFailed' \| 'InstallationFailed';<br />} | Configuration section for simulating firmware upgrade support.                                                                                                                                                                      |
-| commandsSupport                    |               | {<br />"incomingCommands": {},<br />"outgoingCommands": {}<br />}                                                                   | {<br /> incomingCommands: Record<IncomingRequestCommand, boolean>;<br />outgoingCommands?: Record<RequestCommand, boolean>;<br />}                                       | Configuration section for OCPP commands support. Empty section or subsections means all implemented OCPP commands are supported                                                                                                     |
-| messageTriggerSupport              |               | {}                                                                                                                                  | Record<MessageTrigger, boolean>                                                                                                                                          | Configuration section for OCPP commands trigger support. Empty section means all implemented OCPP trigger commands are supported                                                                                                    |
-| Configuration                      |               |                                                                                                                                     | ChargingStationOcppConfiguration                                                                                                                                         | charging stations OCPP parameters configuration section                                                                                                                                                                             |
-| AutomaticTransactionGenerator      |               |                                                                                                                                     | AutomaticTransactionGeneratorConfiguration                                                                                                                               | charging stations ATG configuration section                                                                                                                                                                                         |
-| Connectors                         |               |                                                                                                                                     | Record<string, ConnectorStatus>                                                                                                                                          | charging stations connectors configuration section                                                                                                                                                                                  |
-| Evses                              |               |                                                                                                                                     | Record<string, EvseTemplate>                                                                                                                                             | charging stations EVSEs configuration section                                                                                                                                                                                       |
+| Key                                                  | Value(s)      | Default Value                                                                                                                       | Value type                                                                                                                                                               | Description                                                                                                                                                                                                                                |
+| ---------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| supervisionUrls                                      |               | []                                                                                                                                  | string \| string[]                                                                                                                                                       | string or array of connection URIs to OCPP-J servers                                                                                                                                                                                       |
+| supervisionUser                                      |               | undefined                                                                                                                           | string                                                                                                                                                                   | basic HTTP authentication user to OCPP-J server                                                                                                                                                                                            |
+| supervisionPassword                                  |               | undefined                                                                                                                           | string                                                                                                                                                                   | basic HTTP authentication password to OCPP-J server                                                                                                                                                                                        |
+| supervisionUrlOcppConfiguration                      | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | allow supervision URL configuration via a vendor OCPP parameter key                                                                                                                                                                        |
+| supervisionUrlOcppKey                                |               | 'ConnectionUrl'                                                                                                                     | string                                                                                                                                                                   | the vendor string that will be used as a vendor OCPP parameter key to set the supervision URL                                                                                                                                              |
+| ocppVersion                                          | 1.6/2.0/2.0.1 | 1.6                                                                                                                                 | string                                                                                                                                                                   | OCPP version                                                                                                                                                                                                                               |
+| ocppProtocol                                         | json          | json                                                                                                                                | string                                                                                                                                                                   | OCPP protocol                                                                                                                                                                                                                              |
+| ocppStrictCompliance                                 | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | strict adherence to the OCPP version and protocol specifications                                                                                                                                                                           |
+| ocppPersistentConfiguration                          | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable persistent OCPP parameters storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in [dist/assets/configurations](dist/assets/configurations)                               |
+| stationInfoPersistentConfiguration                   | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable persistent station information and specifications storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in [dist/assets/configurations](dist/assets/configurations)        |
+| automaticTransactionGeneratorPersistentConfiguration | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable persistent automatic transaction generator configuration storage by charging stations 'hashId'. The persistency is ensured by the charging stations configuration files in [dist/assets/configurations](dist/assets/configurations) |
+| wsOptions                                            |               | {}                                                                                                                                  | ClientOptions & ClientRequestArgs                                                                                                                                        | [ws](https://github.com/websockets/ws) and node.js [http](https://nodejs.org/api/http.html) clients options intersection                                                                                                                   |
+| idTagsFile                                           |               | undefined                                                                                                                           | string                                                                                                                                                                   | RFID tags list file relative to [src/assets](src/assets) path                                                                                                                                                                              |
+| baseName                                             |               | undefined                                                                                                                           | string                                                                                                                                                                   | base name to build charging stations id                                                                                                                                                                                                    |
+| nameSuffix                                           |               | undefined                                                                                                                           | string                                                                                                                                                                   | name suffix to build charging stations id                                                                                                                                                                                                  |
+| fixedName                                            | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | use the baseName as the charging stations unique name                                                                                                                                                                                      |
+| chargePointModel                                     |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations model                                                                                                                                                                                                                    |
+| chargePointVendor                                    |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations vendor                                                                                                                                                                                                                   |
+| chargePointSerialNumberPrefix                        |               | undefined                                                                                                                           | string                                                                                                                                                                   | charge point serial number prefix                                                                                                                                                                                                          |
+| chargeBoxSerialNumberPrefix                          |               | undefined                                                                                                                           | string                                                                                                                                                                   | charge box serial number prefix (deprecated in OCPP 1.6)                                                                                                                                                                                   |
+| firmwareVersionPattern                               |               | Semantic versionning regular expression: https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string | string                                                                                                                                                                   | charging stations firmware version pattern                                                                                                                                                                                                 |
+| firmwareVersion                                      |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations firmware version                                                                                                                                                                                                         |
+| power                                                |               |                                                                                                                                     | float \| float[]                                                                                                                                                         | charging stations maximum power value(s)                                                                                                                                                                                                   |
+| powerSharedByConnectors                              | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | charging stations power shared by its connectors                                                                                                                                                                                           |
+| powerUnit                                            | W/kW          | W                                                                                                                                   | string                                                                                                                                                                   | charging stations power unit                                                                                                                                                                                                               |
+| currentOutType                                       | AC/DC         | AC                                                                                                                                  | string                                                                                                                                                                   | charging stations current out type                                                                                                                                                                                                         |
+| voltageOut                                           |               | AC:230/DC:400                                                                                                                       | integer                                                                                                                                                                  | charging stations voltage out                                                                                                                                                                                                              |
+| numberOfPhases                                       | 0/1/3         | AC:3/DC:0                                                                                                                           | integer                                                                                                                                                                  | charging stations number of phase(s)                                                                                                                                                                                                       |
+| numberOfConnectors                                   |               |                                                                                                                                     | integer \| integer[]                                                                                                                                                     | charging stations number of connector(s)                                                                                                                                                                                                   |
+| useConnectorId0                                      | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | use connector id 0 definition from the charging station configuration template                                                                                                                                                             |
+| randomConnectors                                     | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | randomize runtime connector id affectation from the connector id definition in charging station configuration template                                                                                                                     |
+| resetTime                                            |               | 60                                                                                                                                  | integer                                                                                                                                                                  | seconds to wait before the charging stations come back at reset                                                                                                                                                                            |
+| autoRegister                                         | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | set charging stations as registered at boot notification for testing purpose                                                                                                                                                               |
+| autoReconnectMaxRetries                              |               | -1 (unlimited)                                                                                                                      | integer                                                                                                                                                                  | connection retries to the OCPP-J server                                                                                                                                                                                                    |
+| reconnectExponentialDelay                            | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | connection delay retry to the OCPP-J server                                                                                                                                                                                                |
+| registrationMaxRetries                               |               | -1 (unlimited)                                                                                                                      | integer                                                                                                                                                                  | charging stations boot notification retries                                                                                                                                                                                                |
+| amperageLimitationOcppKey                            |               | undefined                                                                                                                           | string                                                                                                                                                                   | charging stations OCPP parameter key used to set the amperage limit, per phase for each connector on AC and global for DC                                                                                                                  |
+| amperageLimitationUnit                               | A/cA/dA/mA    | A                                                                                                                                   | string                                                                                                                                                                   | charging stations amperage limit unit                                                                                                                                                                                                      |
+| enableStatistics                                     | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | enable charging stations statistics                                                                                                                                                                                                        |
+| mustAuthorizeAtRemoteStart                           | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | always send authorize at remote start transaction when AuthorizeRemoteTxRequests is enabled                                                                                                                                                |
+| payloadSchemaValidation                              | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | validate OCPP commands PDU against [OCA](https://www.openchargealliance.org/) JSON schemas                                                                                                                                                 |
+| beginEndMeterValues                                  | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | enable Transaction.{Begin,End} MeterValues                                                                                                                                                                                                 |
+| outOfOrderEndMeterValues                             | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | send Transaction.End MeterValues out of order. Need to relax OCPP specifications strict compliance ('ocppStrictCompliance' parameter)                                                                                                      |
+| meteringPerTransaction                               | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable metering history on a per transaction basis                                                                                                                                                                                         |
+| transactionDataMeterValues                           | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | enable transaction data MeterValues at stop transaction                                                                                                                                                                                    |
+| mainVoltageMeterValues                               | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | include charging stations main voltage MeterValues on three phased charging stations                                                                                                                                                       |
+| phaseLineToLineVoltageMeterValues                    | true/false    | false                                                                                                                               | boolean                                                                                                                                                                  | include charging stations line to line voltage MeterValues on three phased charging stations                                                                                                                                               |
+| customValueLimitationMeterValues                     | true/false    | true                                                                                                                                | boolean                                                                                                                                                                  | enable limitation on custom fluctuated value in MeterValues                                                                                                                                                                                |
+| firmwareUpgrade                                      |               | {<br />"versionUpgrade": {<br />"step": 1<br />},<br />"reset": true<br />}                                                         | {<br />versionUpgrade: {<br />patternGroup: number;<br />step: number;<br />};<br />reset: boolean;<br />failureStatus: 'DownloadFailed' \| 'InstallationFailed';<br />} | Configuration section for simulating firmware upgrade support.                                                                                                                                                                             |
+| commandsSupport                                      |               | {<br />"incomingCommands": {},<br />"outgoingCommands": {}<br />}                                                                   | {<br /> incomingCommands: Record<IncomingRequestCommand, boolean>;<br />outgoingCommands?: Record<RequestCommand, boolean>;<br />}                                       | Configuration section for OCPP commands support. Empty section or subsections means all implemented OCPP commands are supported                                                                                                            |
+| messageTriggerSupport                                |               | {}                                                                                                                                  | Record<MessageTrigger, boolean>                                                                                                                                          | Configuration section for OCPP commands trigger support. Empty section means all implemented OCPP trigger commands are supported                                                                                                           |
+| Configuration                                        |               |                                                                                                                                     | ChargingStationOcppConfiguration                                                                                                                                         | charging stations OCPP parameters configuration section                                                                                                                                                                                    |
+| AutomaticTransactionGenerator                        |               |                                                                                                                                     | AutomaticTransactionGeneratorConfiguration                                                                                                                               | charging stations ATG configuration section                                                                                                                                                                                                |
+| Connectors                                           |               |                                                                                                                                     | Record<string, ConnectorStatus>                                                                                                                                          | charging stations connectors configuration section                                                                                                                                                                                         |
+| Evses                                                |               |                                                                                                                                     | Record<string, EvseTemplate>                                                                                                                                             | charging stations EVSEs configuration section                                                                                                                                                                                              |
 
 #### Configuration section syntax example
 
@@ -338,6 +340,10 @@ The syntax is similar to charging station configuration template with some added
 
 The syntax is similar to the charging station configuration template 'Configuration' section.
 
+#### automaticTransactionGenerator section
+
+The syntax is similar to the charging station configuration template 'AutomaticTransactionGenerator' section.
+
 ## Docker
 
 In the [docker](./docker) folder:
@@ -419,7 +425,7 @@ make SUBMODULES_INIT=true
 
 ## OCPP-J standard parameters supported
 
-All kind of OCPP parameters are supported in a charging station configuration or a charging station configuration template file. The list here mention the standard ones also handled automatically in the simulator.
+All kind of OCPP parameters are supported in charging station configuration or charging station configuration template file. The list here mention the standard ones also handled automatically in the simulator.
 
 ### Version 1.6
 
index 2a82b75ff7c22f45b71d911b1799cb0e3dc9e997..dd61269d2e11ba1f1a24e15f9d44506ff6640764 100644 (file)
@@ -1,13 +1,13 @@
 {
   "name": "e-mobility-charging-stations-simulator",
-  "version": "1.2.13",
+  "version": "1.2.15",
   "engines": {
-    "node": ">=16.9.0",
-    "pnpm": ">=8.0.0"
+    "node": ">=16.14.0",
+    "pnpm": ">=8.6.0"
   },
   "volta": {
     "node": "20.2.0",
-    "pnpm": "8.5.1"
+    "pnpm": "8.6.0"
   },
   "repository": {
     "type": "git",
@@ -66,8 +66,8 @@
     "lint": "cross-env TIMING=1 eslint --cache --ext .js,.cjs,.mjs,.ts src",
     "lint:fix": "cross-env TIMING=1 eslint --cache --fix --ext .js,.cjs,.mjs,.ts src",
     "format": "prettier --cache --write .",
-    "test": "c8 mocha test/**/*Test.ts",
-    "test:debug": "mocha --no-parallel --inspect test/**/*Test.ts",
+    "test": "c8 mocha test/**/*.test.ts",
+    "test:debug": "mocha --no-parallel --inspect test/**/*.test.ts",
     "coverage": "c8 report --reporter=lcov",
     "coverage:html": "c8 report --reporter=html",
     "clinic:clean": "clinic clean",
     }
   },
   "dependencies": {
-    "@mikro-orm/core": "^5.7.9",
-    "@mikro-orm/mariadb": "^5.7.9",
-    "@mikro-orm/reflection": "^5.7.9",
-    "@mikro-orm/sqlite": "^5.7.9",
+    "@mikro-orm/core": "^5.7.11",
+    "@mikro-orm/mariadb": "^5.7.11",
+    "@mikro-orm/reflection": "^5.7.11",
+    "@mikro-orm/sqlite": "^5.7.11",
     "ajv": "^8.12.0",
     "ajv-formats": "^2.1.1",
     "basic-ftp": "^5.0.3",
     "logform": "^2.5.1",
     "mnemonist": "^0.39.5",
     "moment": "^2.29.4",
-    "mongodb": "^5.5.0",
-    "poolifier": "^2.4.14",
+    "mongodb": "^5.6.0",
+    "poolifier": "^2.5.3",
     "source-map-support": "^0.5.21",
     "tar": "^6.1.15",
-    "tslib": "^2.5.2",
-    "winston": "^3.8.2",
+    "tslib": "^2.5.3",
+    "winston": "^3.9.0",
     "winston-daily-rotate-file": "^4.7.1",
     "ws": "^8.13.0"
   },
     "utf-8-validate": "^6.0.3"
   },
   "devDependencies": {
-    "@commitlint/cli": "^17.6.3",
-    "@commitlint/config-conventional": "^17.6.3",
-    "@mikro-orm/cli": "^5.7.9",
+    "@commitlint/cli": "^17.6.5",
+    "@commitlint/config-conventional": "^17.6.5",
+    "@mikro-orm/cli": "^5.7.11",
     "@release-it/bumper": "^4.0.2",
     "@rollup/plugin-json": "^6.0.0",
     "@rollup/plugin-terser": "^0.4.3",
     "@rollup/plugin-typescript": "^11.1.1",
     "@types/mocha": "^10.0.1",
     "@types/mochawesome": "^6.2.1",
-    "@types/node": "^20.2.3",
+    "@types/node": "^20.2.5",
     "@types/sinon": "^10.0.15",
     "@types/tar": "^6.1.5",
     "@types/ws": "^8.5.4",
-    "@typescript-eslint/eslint-plugin": "^5.59.7",
-    "@typescript-eslint/parser": "^5.59.7",
+    "@typescript-eslint/eslint-plugin": "^5.59.8",
+    "@typescript-eslint/parser": "^5.59.8",
+    "@web/rollup-plugin-copy": "^0.4.0",
     "auto-changelog": "^2.4.0",
-    "c8": "^7.13.0",
+    "c8": "^7.14.0",
     "clinic": "^12.1.0",
     "cross-env": "^7.0.3",
-    "eslint": "^8.41.0",
+    "eslint": "^8.42.0",
     "eslint-config-prettier": "^8.8.0",
     "eslint-import-resolver-typescript": "^3.5.5",
     "eslint-plugin-import": "^2.27.5",
-    "eslint-plugin-jsdoc": "^44.2.4",
+    "eslint-plugin-jsdoc": "^46.2.3",
     "eslint-plugin-n": "^16.0.0",
     "eslint-plugin-prettier": "^4.2.1",
     "eslint-plugin-tsdoc": "^0.2.17",
     "mocha": "^10.2.0",
     "mochawesome": "^7.1.3",
     "prettier": "^2.8.8",
-    "release-it": "^15.10.3",
+    "release-it": "^15.10.5",
     "rimraf": "^5.0.1",
     "robohydra": "^0.6.9",
     "rollup": "^3.23.0",
     "rollup-plugin-analyzer": "^4.0.0",
-    "rollup-plugin-copy": "^3.4.0",
     "rollup-plugin-delete": "^2.0.0",
     "semver": "^7.5.1",
     "sinon": "^15.1.0",
     "ts-node": "^10.9.1",
-    "typescript": "^5.0.4"
+    "typescript": "^5.1.3"
   }
 }
index 22fa04a3c070b080ec0aef9cafcdf01782a1f91c..dbadd9ec9af2229809feb5a906272840eca24b2e 100644 (file)
@@ -1,4 +1,8 @@
-lockfileVersion: '6.0'
+lockfileVersion: '6.1'
+
+settings:
+  autoInstallPeers: true
+  excludeLinksFromLockfile: false
 
 overrides:
   cacheable-request: ^10.2.10
@@ -8,17 +12,17 @@ overrides:
 
 dependencies:
   '@mikro-orm/core':
-    specifier: ^5.7.9
-    version: 5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9)
+    specifier: ^5.7.11
+    version: 5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11)
   '@mikro-orm/mariadb':
-    specifier: ^5.7.9
-    version: 5.7.9(@mikro-orm/core@5.7.9)
+    specifier: ^5.7.11
+    version: 5.7.11(@mikro-orm/core@5.7.11)
   '@mikro-orm/reflection':
-    specifier: ^5.7.9
-    version: 5.7.9(@mikro-orm/core@5.7.9)
+    specifier: ^5.7.11
+    version: 5.7.11(@mikro-orm/core@5.7.11)
   '@mikro-orm/sqlite':
-    specifier: ^5.7.9
-    version: 5.7.9(@mikro-orm/core@5.7.9)
+    specifier: ^5.7.11
+    version: 5.7.11(@mikro-orm/core@5.7.11)
   ajv:
     specifier: ^8.12.0
     version: 8.12.0
@@ -50,11 +54,11 @@ dependencies:
     specifier: ^2.29.4
     version: 2.29.4
   mongodb:
-    specifier: ^5.5.0
-    version: 5.5.0
+    specifier: ^5.6.0
+    version: 5.6.0
   poolifier:
-    specifier: ^2.4.14
-    version: 2.4.14
+    specifier: ^2.5.3
+    version: 2.5.3
   source-map-support:
     specifier: ^0.5.21
     version: 0.5.21
@@ -62,14 +66,14 @@ dependencies:
     specifier: ^6.1.15
     version: 6.1.15
   tslib:
-    specifier: ^2.5.2
-    version: 2.5.2
+    specifier: ^2.5.3
+    version: 2.5.3
   winston:
-    specifier: ^3.8.2
-    version: 3.8.2
+    specifier: ^3.9.0
+    version: 3.9.0
   winston-daily-rotate-file:
     specifier: ^4.7.1
-    version: 4.7.1(winston@3.8.2)
+    version: 4.7.1(winston@3.9.0)
   ws:
     specifier: ^8.13.0
     version: 8.13.0(bufferutil@4.0.7)(utf-8-validate@6.0.3)
@@ -84,17 +88,17 @@ optionalDependencies:
 
 devDependencies:
   '@commitlint/cli':
-    specifier: ^17.6.3
-    version: 17.6.3
+    specifier: ^17.6.5
+    version: 17.6.5
   '@commitlint/config-conventional':
-    specifier: ^17.6.3
-    version: 17.6.3
+    specifier: ^17.6.5
+    version: 17.6.5
   '@mikro-orm/cli':
-    specifier: ^5.7.9
-    version: 5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9)
+    specifier: ^5.7.11
+    version: 5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11)
   '@release-it/bumper':
     specifier: ^4.0.2
-    version: 4.0.2(release-it@15.10.3)
+    version: 4.0.2(release-it@15.10.5)
   '@rollup/plugin-json':
     specifier: ^6.0.0
     version: 6.0.0(rollup@3.23.0)
@@ -103,7 +107,7 @@ devDependencies:
     version: 0.4.3(rollup@3.23.0)
   '@rollup/plugin-typescript':
     specifier: ^11.1.1
-    version: 11.1.1(rollup@3.23.0)(tslib@2.5.2)(typescript@5.0.4)
+    version: 11.1.1(rollup@3.23.0)(tslib@2.5.3)(typescript@5.1.3)
   '@types/mocha':
     specifier: ^10.0.1
     version: 10.0.1
@@ -111,8 +115,8 @@ devDependencies:
     specifier: ^6.2.1
     version: 6.2.1
   '@types/node':
-    specifier: ^20.2.3
-    version: 20.2.3
+    specifier: ^20.2.5
+    version: 20.2.5
   '@types/sinon':
     specifier: ^10.0.15
     version: 10.0.15
@@ -123,17 +127,20 @@ devDependencies:
     specifier: ^8.5.4
     version: 8.5.4
   '@typescript-eslint/eslint-plugin':
-    specifier: ^5.59.7
-    version: 5.59.7(@typescript-eslint/parser@5.59.7)(eslint@8.41.0)(typescript@5.0.4)
+    specifier: ^5.59.8
+    version: 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@5.1.3)
   '@typescript-eslint/parser':
-    specifier: ^5.59.7
-    version: 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+    specifier: ^5.59.8
+    version: 5.59.8(eslint@8.42.0)(typescript@5.1.3)
+  '@web/rollup-plugin-copy':
+    specifier: ^0.4.0
+    version: 0.4.0
   auto-changelog:
     specifier: ^2.4.0
     version: 2.4.0
   c8:
-    specifier: ^7.13.0
-    version: 7.13.0
+    specifier: ^7.14.0
+    version: 7.14.0
   clinic:
     specifier: ^12.1.0
     version: 12.1.0
@@ -141,26 +148,26 @@ devDependencies:
     specifier: ^7.0.3
     version: 7.0.3
   eslint:
-    specifier: ^8.41.0
-    version: 8.41.0
+    specifier: ^8.42.0
+    version: 8.42.0
   eslint-config-prettier:
     specifier: ^8.8.0
-    version: 8.8.0(eslint@8.41.0)
+    version: 8.8.0(eslint@8.42.0)
   eslint-import-resolver-typescript:
     specifier: ^3.5.5
-    version: 3.5.5(@typescript-eslint/parser@5.59.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0)
+    version: 3.5.5(@typescript-eslint/parser@5.59.8)(eslint-plugin-import@2.27.5)(eslint@8.42.0)
   eslint-plugin-import:
     specifier: ^2.27.5
-    version: 2.27.5(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
+    version: 2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
   eslint-plugin-jsdoc:
-    specifier: ^44.2.4
-    version: 44.2.4(eslint@8.41.0)
+    specifier: ^46.2.3
+    version: 46.2.3(eslint@8.42.0)
   eslint-plugin-n:
     specifier: ^16.0.0
-    version: 16.0.0(eslint@8.41.0)
+    version: 16.0.0(eslint@8.42.0)
   eslint-plugin-prettier:
     specifier: ^4.2.1
-    version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.41.0)(prettier@2.8.8)
+    version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8)
   eslint-plugin-tsdoc:
     specifier: ^0.2.17
     version: 0.2.17
@@ -183,8 +190,8 @@ devDependencies:
     specifier: ^2.8.8
     version: 2.8.8
   release-it:
-    specifier: ^15.10.3
-    version: 15.10.3
+    specifier: ^15.10.5
+    version: 15.10.5
   rimraf:
     specifier: ^5.0.1
     version: 5.0.1
@@ -197,9 +204,6 @@ devDependencies:
   rollup-plugin-analyzer:
     specifier: ^4.0.0
     version: 4.0.0
-  rollup-plugin-copy:
-    specifier: ^3.4.0
-    version: 3.4.0
   rollup-plugin-delete:
     specifier: ^2.0.0
     version: 2.0.0
@@ -211,10 +215,10 @@ devDependencies:
     version: 15.1.0
   ts-node:
     specifier: ^10.9.1
-    version: 10.9.1(@types/node@20.2.3)(typescript@5.0.4)
+    version: 10.9.1(@types/node@20.2.5)(typescript@5.1.3)
   typescript:
-    specifier: ^5.0.4
-    version: 5.0.4
+    specifier: ^5.1.3
+    version: 5.1.3
 
 packages:
 
@@ -322,8 +326,8 @@ packages:
       chalk: 4.1.2
       lodash.debounce: 4.0.8
       loose-envify: 1.4.0
-      postcss: 8.4.23
-      postcss-import: 13.0.0(postcss@8.4.23)
+      postcss: 8.4.24
+      postcss-import: 13.0.0(postcss@8.4.24)
       stream-template: 0.0.10
       webfontloader: 1.6.28
     dev: true
@@ -421,13 +425,13 @@ packages:
     resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
     engines: {node: '>=0.1.90'}
 
-  /@commitlint/cli@17.6.3:
-    resolution: {integrity: sha512-ItSz2fd4F+CujgIbQOfNNerDF1eFlsBGEfp9QcCb1kxTYMuKTYZzA6Nu1YRRrIaaWwe2E7awUGpIMrPoZkOG3A==}
+  /@commitlint/cli@17.6.5:
+    resolution: {integrity: sha512-3PQrWr/uo6lzF5k7n5QuosCYnzaxP9qGBp3jhWP0Vmsa7XA6wrl9ccPqfQyXpSbQE3zBROVO3TDqgPKe4tfmLQ==}
     engines: {node: '>=v14'}
     hasBin: true
     dependencies:
       '@commitlint/format': 17.4.4
-      '@commitlint/lint': 17.6.3
+      '@commitlint/lint': 17.6.5
       '@commitlint/load': 17.5.0
       '@commitlint/read': 17.5.1
       '@commitlint/types': 17.4.4
@@ -441,8 +445,8 @@ packages:
       - '@swc/wasm'
     dev: true
 
-  /@commitlint/config-conventional@17.6.3:
-    resolution: {integrity: sha512-bLyHEjjRWqlLQWIgYFHmUPbEFMOOLXeF3QbUinDIJev/u9e769tkoTH9YPknEywiuIrAgZaVo+OfzAIsJP0fsw==}
+  /@commitlint/config-conventional@17.6.5:
+    resolution: {integrity: sha512-Xl9H9KLl86NZm5CYNTNF9dcz1xelE/EbvhWIWcYxG/rn3UWYWdWmmnX2q6ZduNdLFSGbOxzUpIx61j5zxbeXxg==}
     engines: {node: '>=v14'}
     dependencies:
       conventional-changelog-conventionalcommits: 5.0.0
@@ -481,21 +485,21 @@ packages:
       chalk: 4.1.2
     dev: true
 
-  /@commitlint/is-ignored@17.6.3:
-    resolution: {integrity: sha512-LQbNdnPbxrpbcrVKR5yf51SvquqktpyZJwqXx3lUMF6+nT9PHB8xn3wLy8pi2EQv5Zwba484JnUwDE1ygVYNQA==}
+  /@commitlint/is-ignored@17.6.5:
+    resolution: {integrity: sha512-CQvAPt9gX7cuUbMrIaIMKczfWJqqr6m8IlJs0F2zYwyyMTQ87QMHIj5jJ5HhOaOkaj6dvTMVGx8Dd1I4xgUuoQ==}
     engines: {node: '>=v14'}
     dependencies:
       '@commitlint/types': 17.4.4
       semver: 7.5.0
     dev: true
 
-  /@commitlint/lint@17.6.3:
-    resolution: {integrity: sha512-fBlXwt6SHJFgm3Tz+luuo3DkydAx9HNC5y4eBqcKuDuMVqHd2ugMNr+bQtx6riv9mXFiPoKp7nE4Xn/ls3iVDA==}
+  /@commitlint/lint@17.6.5:
+    resolution: {integrity: sha512-BSJMwkE4LWXrOsiP9KoHG+/heSDfvOL/Nd16+ojTS/DX8HZr8dNl8l3TfVr/d/9maWD8fSegRGtBtsyGuugFrw==}
     engines: {node: '>=v14'}
     dependencies:
-      '@commitlint/is-ignored': 17.6.3
-      '@commitlint/parse': 17.4.4
-      '@commitlint/rules': 17.6.1
+      '@commitlint/is-ignored': 17.6.5
+      '@commitlint/parse': 17.6.5
+      '@commitlint/rules': 17.6.5
       '@commitlint/types': 17.4.4
     dev: true
 
@@ -507,16 +511,16 @@ packages:
       '@commitlint/execute-rule': 17.4.0
       '@commitlint/resolve-extends': 17.4.4
       '@commitlint/types': 17.4.4
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       chalk: 4.1.2
       cosmiconfig: 8.1.3
-      cosmiconfig-typescript-loader: 4.3.0(@types/node@20.2.3)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.0.4)
+      cosmiconfig-typescript-loader: 4.3.0(@types/node@20.2.5)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.1.3)
       lodash.isplainobject: 4.0.6
       lodash.merge: 4.6.2
       lodash.uniq: 4.5.0
       resolve-from: 5.0.0
-      ts-node: 10.9.1(@types/node@20.2.3)(typescript@5.0.4)
-      typescript: 5.0.4
+      ts-node: 10.9.1(@types/node@20.2.5)(typescript@5.1.3)
+      typescript: 5.1.3
     transitivePeerDependencies:
       - '@swc/core'
       - '@swc/wasm'
@@ -527,8 +531,8 @@ packages:
     engines: {node: '>=v14'}
     dev: true
 
-  /@commitlint/parse@17.4.4:
-    resolution: {integrity: sha512-EKzz4f49d3/OU0Fplog7nwz/lAfXMaDxtriidyGF9PtR+SRbgv4FhsfF310tKxs6EPj8Y+aWWuX3beN5s+yqGg==}
+  /@commitlint/parse@17.6.5:
+    resolution: {integrity: sha512-0zle3bcn1Hevw5Jqpz/FzEWNo2KIzUbc1XyGg6WrWEoa6GH3A1pbqNF6MvE6rjuy6OY23c8stWnb4ETRZyN+Yw==}
     engines: {node: '>=v14'}
     dependencies:
       '@commitlint/types': 17.4.4
@@ -559,8 +563,8 @@ packages:
       resolve-global: 1.0.0
     dev: true
 
-  /@commitlint/rules@17.6.1:
-    resolution: {integrity: sha512-lUdHw6lYQ1RywExXDdLOKxhpp6857/4c95Dc/1BikrHgdysVUXz26yV0vp1GL7Gv+avx9WqZWTIVB7pNouxlfw==}
+  /@commitlint/rules@17.6.5:
+    resolution: {integrity: sha512-uTB3zSmnPyW2qQQH+Dbq2rekjlWRtyrjDo4aLFe63uteandgkI+cc0NhhbBAzcXShzVk0qqp8SlkQMu0mgHg/A==}
     engines: {node: '>=v14'}
     dependencies:
       '@commitlint/ensure': 17.4.4
@@ -613,13 +617,13 @@ packages:
       jsdoc-type-pratt-parser: 4.0.0
     dev: true
 
-  /@eslint-community/eslint-utils@4.4.0(eslint@8.41.0):
+  /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0):
     resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
     dependencies:
-      eslint: 8.41.0
+      eslint: 8.42.0
       eslint-visitor-keys: 3.4.1
     dev: true
 
@@ -645,8 +649,8 @@ packages:
       - supports-color
     dev: true
 
-  /@eslint/js@8.41.0:
-    resolution: {integrity: sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==}
+  /@eslint/js@8.42.0:
+    resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
@@ -654,8 +658,8 @@ packages:
     resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
     optional: true
 
-  /@humanwhocodes/config-array@0.11.8:
-    resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==}
+  /@humanwhocodes/config-array@0.11.10:
+    resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
     engines: {node: '>=10.10.0'}
     dependencies:
       '@humanwhocodes/object-schema': 1.2.1
@@ -684,7 +688,7 @@ packages:
     dependencies:
       string-width: 5.1.2
       string-width-cjs: /string-width@4.2.3
-      strip-ansi: 7.0.1
+      strip-ansi: 7.1.0
       strip-ansi-cjs: /strip-ansi@6.0.1
       wrap-ansi: 8.1.0
       wrap-ansi-cjs: /wrap-ansi@7.0.0
@@ -724,7 +728,7 @@ packages:
       '@jest/schemas': 29.4.3
       '@types/istanbul-lib-coverage': 2.0.4
       '@types/istanbul-reports': 3.0.1
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       '@types/yargs': 17.0.24
       chalk: 4.1.2
     dev: true
@@ -812,8 +816,8 @@ packages:
     resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==}
     dev: true
 
-  /@mikro-orm/cli@5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9):
-    resolution: {integrity: sha512-oeGY0X255k7BvrzR4YbOVtfygPdwfZ9fkoalPVV3VnGsGmjkckVDuIlUD7swpIkjKHtcbzOjhCxbM9OCwCeNdw==}
+  /@mikro-orm/cli@5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11):
+    resolution: {integrity: sha512-Xq380ItSARi8jG2Y6gQrd3msmioEfG3I5bHxF4aZR2LATO0r2zV6Am13CaGFnpS3EWeEUxGb7XUCjS7yoL9RzQ==}
     engines: {node: '>= 14.0.0'}
     hasBin: true
     peerDependencies:
@@ -850,10 +854,10 @@ packages:
         optional: true
     dependencies:
       '@jercle/yargonaut': 1.1.5
-      '@mikro-orm/core': 5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9)
-      '@mikro-orm/knex': 5.7.9(@mikro-orm/core@5.7.9)(sqlite3@5.1.6)
-      '@mikro-orm/mariadb': 5.7.9(@mikro-orm/core@5.7.9)
-      '@mikro-orm/sqlite': 5.7.9(@mikro-orm/core@5.7.9)
+      '@mikro-orm/core': 5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11)
+      '@mikro-orm/knex': 5.7.11(@mikro-orm/core@5.7.11)(sqlite3@5.1.6)
+      '@mikro-orm/mariadb': 5.7.11(@mikro-orm/core@5.7.11)
+      '@mikro-orm/sqlite': 5.7.11(@mikro-orm/core@5.7.11)
       fs-extra: 11.1.1
       tsconfig-paths: 4.2.0
       yargs: 17.7.2
@@ -869,8 +873,8 @@ packages:
       - tedious
     dev: true
 
-  /@mikro-orm/core@5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9):
-    resolution: {integrity: sha512-ydLs/9jimJcGiubawCc2icxtV7LKTfzmVJK9t7KUyf8LYkyrRm38sHc1aaeDkV2DN9lMVLY3gCqrNr1pBAZz0g==}
+  /@mikro-orm/core@5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11):
+    resolution: {integrity: sha512-4ZpqR+jEKFCOC5tX2zIYNvdQfhtdINzl3p3o2AJFeY1IcG/8PGw/6yFLg1hkGwgW7LPSa6djqBGEdm0GnmSsHw==}
     engines: {node: '>= 14.0.0'}
     peerDependencies:
       '@mikro-orm/better-sqlite': ^5.0.0
@@ -905,18 +909,18 @@ packages:
       '@mikro-orm/sqlite':
         optional: true
     dependencies:
-      '@mikro-orm/mariadb': 5.7.9(@mikro-orm/core@5.7.9)
-      '@mikro-orm/sqlite': 5.7.9(@mikro-orm/core@5.7.9)
+      '@mikro-orm/mariadb': 5.7.11(@mikro-orm/core@5.7.11)
+      '@mikro-orm/sqlite': 5.7.11(@mikro-orm/core@5.7.11)
       acorn-loose: 8.3.0
       acorn-walk: 8.2.0
-      dotenv: 16.0.3
+      dotenv: 16.1.3
       fs-extra: 11.1.1
       globby: 11.1.0
-      mikro-orm: 5.7.9
+      mikro-orm: 5.7.11
       reflect-metadata: 0.1.13
 
-  /@mikro-orm/knex@5.7.9(@mikro-orm/core@5.7.9)(sqlite3@5.1.6):
-    resolution: {integrity: sha512-2f3zIHbJIkO0ZGp36ebQQPfM04b3HthOWkfLRb5gAodj5VO2elZv6nvus0Evr8CkQGIILjAVVid9+loLrNau0w==}
+  /@mikro-orm/knex@5.7.11(@mikro-orm/core@5.7.11)(sqlite3@5.1.6):
+    resolution: {integrity: sha512-t2H3Dtrv0RaOn9vQGz7IPXN2L34H/RpTCN697lZXRVG2AgIJ4ImL52Ntqf+3L5dV4INSYvoKYm7ywBcfI990dQ==}
     engines: {node: '>= 14.0.0'}
     peerDependencies:
       '@mikro-orm/core': ^5.0.0
@@ -946,7 +950,7 @@ packages:
       sqlite3:
         optional: true
     dependencies:
-      '@mikro-orm/core': 5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9)
+      '@mikro-orm/core': 5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11)
       fs-extra: 11.1.1
       knex: 2.4.2(sqlite3@5.1.6)
       sqlite3: 5.1.6
@@ -956,8 +960,8 @@ packages:
       - supports-color
       - tedious
 
-  /@mikro-orm/mariadb@5.7.9(@mikro-orm/core@5.7.9):
-    resolution: {integrity: sha512-VaDrulfLxusXeWmok+faBADhFSvJ9rPzmMVPMHPgqqpsETAWpzDbkb9E8bNxsUW6EYI3rbaBjV/VamryrhQHZQ==}
+  /@mikro-orm/mariadb@5.7.11(@mikro-orm/core@5.7.11):
+    resolution: {integrity: sha512-swPBAbcgosrePKDXZ24He4vLeFzhtfpH1WpjQScN5ni8m4xflJenJGLd5ru/aEYZIcIjECJSawuH5ORtYcYJEA==}
     engines: {node: '>= 14.0.0'}
     peerDependencies:
       '@mikro-orm/core': ^5.0.0
@@ -972,8 +976,8 @@ packages:
       '@mikro-orm/seeder':
         optional: true
     dependencies:
-      '@mikro-orm/core': 5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9)
-      '@mikro-orm/knex': 5.7.9(@mikro-orm/core@5.7.9)(sqlite3@5.1.6)
+      '@mikro-orm/core': 5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11)
+      '@mikro-orm/knex': 5.7.11(@mikro-orm/core@5.7.11)(sqlite3@5.1.6)
       mariadb: 2.5.6
     transitivePeerDependencies:
       - better-sqlite3
@@ -986,19 +990,19 @@ packages:
       - supports-color
       - tedious
 
-  /@mikro-orm/reflection@5.7.9(@mikro-orm/core@5.7.9):
-    resolution: {integrity: sha512-WNqp/W4ginZI8c140oh2OYg5nOT/eXHNd43DFOYwN3ttOMaa4NSku6Njv/IiPkopP9hGzz/8StF0PduQbJQlKg==}
+  /@mikro-orm/reflection@5.7.11(@mikro-orm/core@5.7.11):
+    resolution: {integrity: sha512-dhPHxGj65L8/3XBOrN15TCwqcEZX9igoyGjWtmow3xHKaq4xZAw2q4gePMDYTfma2VI2I5Cs+hQGx68rZdCryA==}
     engines: {node: '>= 14.0.0'}
     peerDependencies:
       '@mikro-orm/core': ^5.0.0
     dependencies:
-      '@mikro-orm/core': 5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9)
+      '@mikro-orm/core': 5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11)
       globby: 11.1.0
       ts-morph: 18.0.0
     dev: false
 
-  /@mikro-orm/sqlite@5.7.9(@mikro-orm/core@5.7.9):
-    resolution: {integrity: sha512-r2VmfykRmLY5GdOCkZ2ycVrfkE53+ta6WjLOCyg9pbeA0DOyHRYz6Q+i7BEflGh7x2NfMJHnwHQHbHBG2jNqYA==}
+  /@mikro-orm/sqlite@5.7.11(@mikro-orm/core@5.7.11):
+    resolution: {integrity: sha512-r/z0/J5xt2KHT4QQTzB65rr/J/BExJM0z0Qj4z4wgGk46A49khKyNf0KQ8uezfh0d6gow77eoaradkgH1Ekx3A==}
     engines: {node: '>= 14.0.0'}
     peerDependencies:
       '@mikro-orm/core': ^5.0.0
@@ -1013,8 +1017,8 @@ packages:
       '@mikro-orm/seeder':
         optional: true
     dependencies:
-      '@mikro-orm/core': 5.7.9(@mikro-orm/mariadb@5.7.9)(@mikro-orm/sqlite@5.7.9)
-      '@mikro-orm/knex': 5.7.9(@mikro-orm/core@5.7.9)(sqlite3@5.1.6)
+      '@mikro-orm/core': 5.7.11(@mikro-orm/mariadb@5.7.11)(@mikro-orm/sqlite@5.7.11)
+      '@mikro-orm/knex': 5.7.11(@mikro-orm/core@5.7.11)(sqlite3@5.1.6)
       fs-extra: 11.1.1
       sqlite3: 5.1.6
       sqlstring-sqlite: 0.1.1
@@ -1171,8 +1175,8 @@ packages:
       - encoding
     dev: true
 
-  /@octokit/rest@19.0.7:
-    resolution: {integrity: sha512-HRtSfjrWmWVNp2uAkEpQnuGMJsu/+dBr47dRc5QVgsCbnIc1+GFEaoKBWkYG+zjrsHpSqcAElMio+n10c0b5JA==}
+  /@octokit/rest@19.0.11:
+    resolution: {integrity: sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==}
     engines: {node: '>= 14'}
     dependencies:
       '@octokit/core': 4.2.1
@@ -1200,8 +1204,8 @@ packages:
     dev: true
     optional: true
 
-  /@pkgr/utils@2.4.0:
-    resolution: {integrity: sha512-2OCURAmRtdlL8iUDTypMrrxfwe8frXTeXaxGsVOaYtc/wrUyk8Z/0OBetM7cdlsy7ZFWlMX72VogKeh+A4Xcjw==}
+  /@pkgr/utils@2.4.1:
+    resolution: {integrity: sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==}
     engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
     dependencies:
       cross-spawn: 7.0.3
@@ -1209,7 +1213,7 @@ packages:
       is-glob: 4.0.3
       open: 9.1.0
       picocolors: 1.0.0
-      tslib: 2.5.2
+      tslib: 2.5.3
     dev: true
 
   /@pnpm/config.env-replace@1.1.0:
@@ -1233,7 +1237,7 @@ packages:
       config-chain: 1.1.13
     dev: true
 
-  /@release-it/bumper@4.0.2(release-it@15.10.3):
+  /@release-it/bumper@4.0.2(release-it@15.10.5):
     resolution: {integrity: sha512-HjiFIBNvb67cLTbzdm6EqiSRwpB4MJY4TGJFY/ac5qnIxERWK5gx1zBnwbJZffDSoS46hJMugoXrDbITEfX4gA==}
     engines: {node: '>=14'}
     peerDependencies:
@@ -1247,7 +1251,7 @@ packages:
       lodash.castarray: 4.4.0
       lodash.get: 4.4.2
       lodash.set: 4.3.2
-      release-it: 15.10.3
+      release-it: 15.10.5
       semver: 7.5.1
     dev: true
 
@@ -1275,11 +1279,11 @@ packages:
     dependencies:
       rollup: 3.23.0
       serialize-javascript: 6.0.1
-      smob: 1.1.1
-      terser: 5.17.5
+      smob: 1.4.0
+      terser: 5.17.7
     dev: true
 
-  /@rollup/plugin-typescript@11.1.1(rollup@3.23.0)(tslib@2.5.2)(typescript@5.0.4):
+  /@rollup/plugin-typescript@11.1.1(rollup@3.23.0)(tslib@2.5.3)(typescript@5.1.3):
     resolution: {integrity: sha512-Ioir+x5Bejv72Lx2Zbz3/qGg7tvGbxQZALCLoJaGrkNXak/19+vKgKYJYM3i/fJxvsb23I9FuFQ8CUBEfsmBRg==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1295,8 +1299,8 @@ packages:
       '@rollup/pluginutils': 5.0.2(rollup@3.23.0)
       resolve: 1.22.2
       rollup: 3.23.0
-      tslib: 2.5.2
-      typescript: 5.0.4
+      tslib: 2.5.3
+      typescript: 5.1.3
     dev: true
 
   /@rollup/pluginutils@5.0.2(rollup@3.23.0):
@@ -1318,8 +1322,8 @@ packages:
     resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==}
     dev: true
 
-  /@sindresorhus/is@5.3.0:
-    resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==}
+  /@sindresorhus/is@5.4.1:
+    resolution: {integrity: sha512-axlrvsHlHlFmKKMEg4VyvMzFr93JWJj4eIfXY1STVuO2fsImCa7ncaiG5gC8HKOX590AW5RtRsC41/B+OfrSqw==}
     engines: {node: '>=14.16'}
     dev: true
 
@@ -1390,6 +1394,7 @@ packages:
   /@tootallnate/once@1.1.2:
     resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
     engines: {node: '>= 6'}
+    optional: true
 
   /@ts-morph/common@0.19.0:
     resolution: {integrity: sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==}
@@ -1420,12 +1425,6 @@ packages:
     resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==}
     dev: true
 
-  /@types/fs-extra@8.1.2:
-    resolution: {integrity: sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==}
-    dependencies:
-      '@types/node': 20.2.3
-    dev: true
-
   /@types/geojson@7946.0.10:
     resolution: {integrity: sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==}
 
@@ -1433,7 +1432,7 @@ packages:
     resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==}
     dependencies:
       '@types/minimatch': 5.1.2
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
     dev: true
 
   /@types/http-cache-semantics@4.0.1:
@@ -1456,8 +1455,8 @@ packages:
       '@types/istanbul-lib-report': 3.0.0
     dev: true
 
-  /@types/json-schema@7.0.11:
-    resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
+  /@types/json-schema@7.0.12:
+    resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
     dev: true
 
   /@types/json5@0.0.29:
@@ -1489,8 +1488,8 @@ packages:
   /@types/node@17.0.45:
     resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
 
-  /@types/node@20.2.3:
-    resolution: {integrity: sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==}
+  /@types/node@20.2.5:
+    resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==}
 
   /@types/normalize-package-data@2.4.1:
     resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
@@ -1525,7 +1524,7 @@ packages:
   /@types/tar@6.1.5:
     resolution: {integrity: sha512-qm2I/RlZij5RofuY7vohTpYNaYcrSQlN2MyjucQc7ZweDwaEWkdN/EeNh6e9zjK6uEm6PwjdMXkcj05BxZdX1Q==}
     dependencies:
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       minipass: 4.2.8
     dev: true
 
@@ -1544,14 +1543,14 @@ packages:
   /@types/whatwg-url@8.2.2:
     resolution: {integrity: sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==}
     dependencies:
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       '@types/webidl-conversions': 7.0.0
     dev: false
 
   /@types/ws@8.5.4:
     resolution: {integrity: sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg==}
     dependencies:
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
     dev: true
 
   /@types/yargs-parser@21.0.0:
@@ -1564,8 +1563,8 @@ packages:
       '@types/yargs-parser': 21.0.0
     dev: true
 
-  /@typescript-eslint/eslint-plugin@5.59.7(@typescript-eslint/parser@5.59.7)(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==}
+  /@typescript-eslint/eslint-plugin@5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       '@typescript-eslint/parser': ^5.0.0
@@ -1576,24 +1575,24 @@ packages:
         optional: true
     dependencies:
       '@eslint-community/regexpp': 4.5.1
-      '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
-      '@typescript-eslint/scope-manager': 5.59.7
-      '@typescript-eslint/type-utils': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
-      '@typescript-eslint/utils': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
+      '@typescript-eslint/scope-manager': 5.59.8
+      '@typescript-eslint/type-utils': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
+      '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       debug: 4.3.4(supports-color@8.1.1)
-      eslint: 8.41.0
+      eslint: 8.42.0
       grapheme-splitter: 1.0.4
       ignore: 5.2.4
       natural-compare-lite: 1.4.0
       semver: 7.5.1
-      tsutils: 3.21.0(typescript@5.0.4)
-      typescript: 5.0.4
+      tsutils: 3.21.0(typescript@5.1.3)
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/parser@5.59.7(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==}
+  /@typescript-eslint/parser@5.59.8(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@@ -1602,26 +1601,26 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/scope-manager': 5.59.7
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/typescript-estree': 5.59.7(typescript@5.0.4)
+      '@typescript-eslint/scope-manager': 5.59.8
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
       debug: 4.3.4(supports-color@8.1.1)
-      eslint: 8.41.0
-      typescript: 5.0.4
+      eslint: 8.42.0
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/scope-manager@5.59.7:
-    resolution: {integrity: sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==}
+  /@typescript-eslint/scope-manager@5.59.8:
+    resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/visitor-keys': 5.59.7
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/visitor-keys': 5.59.8
     dev: true
 
-  /@typescript-eslint/type-utils@5.59.7(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==}
+  /@typescript-eslint/type-utils@5.59.8(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '*'
@@ -1630,23 +1629,23 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 5.59.7(typescript@5.0.4)
-      '@typescript-eslint/utils': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
+      '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       debug: 4.3.4(supports-color@8.1.1)
-      eslint: 8.41.0
-      tsutils: 3.21.0(typescript@5.0.4)
-      typescript: 5.0.4
+      eslint: 8.42.0
+      tsutils: 3.21.0(typescript@5.1.3)
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/types@5.59.7:
-    resolution: {integrity: sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==}
+  /@typescript-eslint/types@5.59.8:
+    resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /@typescript-eslint/typescript-estree@5.59.7(typescript@5.0.4):
-    resolution: {integrity: sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==}
+  /@typescript-eslint/typescript-estree@5.59.8(typescript@5.1.3):
+    resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       typescript: '*'
@@ -1654,31 +1653,31 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/visitor-keys': 5.59.7
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/visitor-keys': 5.59.8
       debug: 4.3.4(supports-color@8.1.1)
       globby: 11.1.0
       is-glob: 4.0.3
       semver: 7.5.1
-      tsutils: 3.21.0(typescript@5.0.4)
-      typescript: 5.0.4
+      tsutils: 3.21.0(typescript@5.1.3)
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/utils@5.59.7(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==}
+  /@typescript-eslint/utils@5.59.8(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
-      '@types/json-schema': 7.0.11
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
+      '@types/json-schema': 7.0.12
       '@types/semver': 7.5.0
-      '@typescript-eslint/scope-manager': 5.59.7
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/typescript-estree': 5.59.7(typescript@5.0.4)
-      eslint: 8.41.0
+      '@typescript-eslint/scope-manager': 5.59.8
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
+      eslint: 8.42.0
       eslint-scope: 5.1.1
       semver: 7.5.1
     transitivePeerDependencies:
@@ -1686,14 +1685,21 @@ packages:
       - typescript
     dev: true
 
-  /@typescript-eslint/visitor-keys@5.59.7:
-    resolution: {integrity: sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==}
+  /@typescript-eslint/visitor-keys@5.59.8:
+    resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.59.7
+      '@typescript-eslint/types': 5.59.8
       eslint-visitor-keys: 3.4.1
     dev: true
 
+  /@web/rollup-plugin-copy@0.4.0:
+    resolution: {integrity: sha512-CSSx4j+WR0UNgT8GX8OTkLGOxWsCOxRDYHVo0WFqOwCnAeLtWJNQI0YamBEk9ozYSm9AW1YxKUBA79Rf+05tLQ==}
+    engines: {node: '>=16.0.0'}
+    dependencies:
+      glob: 7.2.3
+    dev: true
+
   /@webgpu/types@0.1.16:
     resolution: {integrity: sha512-9E61voMP4+Rze02jlTXud++Htpjyyk8vw5Hyw9FGRrmhHQg2GqbuOfwf5Klrb8vTxc2XWI3EfO7RUHMpxTj26A==}
     dev: true
@@ -1766,6 +1772,15 @@ packages:
     transitivePeerDependencies:
       - supports-color
 
+  /agent-base@7.1.0:
+    resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
+    engines: {node: '>= 14'}
+    dependencies:
+      debug: 4.3.4(supports-color@8.1.1)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /agentkeepalive@4.3.0:
     resolution: {integrity: sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==}
     engines: {node: '>= 8.0.0'}
@@ -1834,13 +1849,6 @@ packages:
       type-fest: 0.21.3
     dev: true
 
-  /ansi-escapes@6.2.0:
-    resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==}
-    engines: {node: '>=14.16'}
-    dependencies:
-      type-fest: 3.11.0
-    dev: true
-
   /ansi-regex@2.1.1:
     resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==}
     engines: {node: '>=0.10.0'}
@@ -2038,7 +2046,7 @@ packages:
     resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
     engines: {node: '>=4'}
     dependencies:
-      tslib: 2.5.2
+      tslib: 2.5.3
     dev: true
 
   /astral-regex@2.0.0:
@@ -2145,7 +2153,6 @@ packages:
   /basic-ftp@5.0.3:
     resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==}
     engines: {node: '>=10.0.0'}
-    dev: false
 
   /bcrypt-pbkdf@1.0.2:
     resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==}
@@ -2310,7 +2317,7 @@ packages:
     resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==}
     dependencies:
       cipher-base: 1.0.4
-      des.js: 1.0.1
+      des.js: 1.1.0
       inherits: 2.0.4
       safe-buffer: 5.2.1
     dev: true
@@ -2459,13 +2466,8 @@ packages:
       run-applescript: 5.0.0
     dev: true
 
-  /bytes@3.1.2:
-    resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
-    engines: {node: '>= 0.8'}
-    dev: true
-
-  /c8@7.13.0:
-    resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==}
+  /c8@7.14.0:
+    resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==}
     engines: {node: '>=10.12.0'}
     hasBin: true
     dependencies:
@@ -2839,10 +2841,6 @@ packages:
       color-string: 1.9.1
     dev: false
 
-  /colorette@1.4.0:
-    resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==}
-    dev: true
-
   /colorette@2.0.19:
     resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==}
 
@@ -3042,7 +3040,7 @@ packages:
     resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
     dev: true
 
-  /cosmiconfig-typescript-loader@4.3.0(@types/node@20.2.3)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.0.4):
+  /cosmiconfig-typescript-loader@4.3.0(@types/node@20.2.5)(cosmiconfig@8.1.3)(ts-node@10.9.1)(typescript@5.1.3):
     resolution: {integrity: sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==}
     engines: {node: '>=12', npm: '>=6'}
     peerDependencies:
@@ -3051,10 +3049,10 @@ packages:
       ts-node: '>=10'
       typescript: '>=3'
     dependencies:
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       cosmiconfig: 8.1.3
-      ts-node: 10.9.1(@types/node@20.2.3)(typescript@5.0.4)
-      typescript: 5.0.4
+      ts-node: 10.9.1(@types/node@20.2.5)(typescript@5.1.3)
+      typescript: 5.1.3
     dev: true
 
   /cosmiconfig@8.1.3:
@@ -3308,16 +3306,16 @@ packages:
       assert-plus: 1.0.0
     dev: true
 
-  /data-uri-to-buffer@3.0.1:
-    resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==}
-    engines: {node: '>= 6'}
-    dev: true
-
   /data-uri-to-buffer@4.0.1:
     resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
     engines: {node: '>= 12'}
     dev: true
 
+  /data-uri-to-buffer@5.0.1:
+    resolution: {integrity: sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==}
+    engines: {node: '>= 14'}
+    dev: true
+
   /dateformat@4.6.3:
     resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
     dev: true
@@ -3436,9 +3434,9 @@ packages:
     resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==}
     dev: true
 
-  /degenerator@3.0.4:
-    resolution: {integrity: sha512-Z66uPeBfHZAHVmue3HPfyKu2Q0rC2cRxbTOsvmU/po5fvvcx27W4mIu9n0PUlQih4oUYvcG1BsbtVv8x7KDOSw==}
-    engines: {node: '>= 6'}
+  /degenerator@4.0.2:
+    resolution: {integrity: sha512-HKwIFvZROUMfH3qI3gBpD61BYh7q3c3GXD5UGZzoVNJwVSYgZKvYl1fRMXc9ozoTxl/VZxKJ5v/bA+19tywFiw==}
+    engines: {node: '>= 14'}
     dependencies:
       ast-types: 0.13.4
       escodegen: 1.14.3
@@ -3475,6 +3473,7 @@ packages:
   /depd@2.0.0:
     resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
     engines: {node: '>= 0.8'}
+    optional: true
 
   /deprecation@2.3.1:
     resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==}
@@ -3490,8 +3489,8 @@ packages:
       through2: 2.0.5
     dev: true
 
-  /des.js@1.0.1:
-    resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==}
+  /des.js@1.1.0:
+    resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==}
     dependencies:
       inherits: 2.0.4
       minimalistic-assert: 1.0.1
@@ -3589,8 +3588,8 @@ packages:
       is-obj: 2.0.0
     dev: true
 
-  /dotenv@16.0.3:
-    resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==}
+  /dotenv@16.1.3:
+    resolution: {integrity: sha512-FYssxsmCTtKL72fGBSvb1K9dRz0/VZeWqFme/vSb7r7323x4CRaHu4LvQ5JG3+s6yt2YPbBrkpiEODktfyjI9A==}
     engines: {node: '>=12'}
 
   /dup@1.0.0:
@@ -3628,7 +3627,7 @@ packages:
     engines: {node: '>=0.10.0'}
     hasBin: true
     dependencies:
-      jake: 10.8.6
+      jake: 10.8.7
     dev: true
 
   /elliptic@6.5.4:
@@ -3677,8 +3676,8 @@ packages:
       inherits: 2.0.4
     dev: true
 
-  /enhanced-resolve@5.14.0:
-    resolution: {integrity: sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==}
+  /enhanced-resolve@5.14.1:
+    resolution: {integrity: sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==}
     engines: {node: '>=10.13.0'}
     dependencies:
       graceful-fs: 4.2.11
@@ -3884,13 +3883,13 @@ packages:
       source-map: 0.6.1
     dev: true
 
-  /eslint-config-prettier@8.8.0(eslint@8.41.0):
+  /eslint-config-prettier@8.8.0(eslint@8.42.0):
     resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
     hasBin: true
     peerDependencies:
       eslint: '>=7.0.0'
     dependencies:
-      eslint: 8.41.0
+      eslint: 8.42.0
     dev: true
 
   /eslint-import-resolver-node@0.3.7:
@@ -3903,7 +3902,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0):
+  /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.8)(eslint-plugin-import@2.27.5)(eslint@8.42.0):
     resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
@@ -3911,11 +3910,11 @@ packages:
       eslint-plugin-import: '*'
     dependencies:
       debug: 4.3.4(supports-color@8.1.1)
-      enhanced-resolve: 5.14.0
-      eslint: 8.41.0
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
-      get-tsconfig: 4.5.0
+      enhanced-resolve: 5.14.1
+      eslint: 8.42.0
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
+      get-tsconfig: 4.6.0
       globby: 13.1.4
       is-core-module: 2.12.1
       is-glob: 4.0.3
@@ -3927,7 +3926,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0):
+  /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0):
     resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -3948,27 +3947,27 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       debug: 3.2.7
-      eslint: 8.41.0
+      eslint: 8.42.0
       eslint-import-resolver-node: 0.3.7
-      eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0)
+      eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.8)(eslint-plugin-import@2.27.5)(eslint@8.42.0)
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /eslint-plugin-es-x@6.2.1(eslint@8.41.0):
+  /eslint-plugin-es-x@6.2.1(eslint@8.42.0):
     resolution: {integrity: sha512-uR34zUhZ9EBoiSD2DdV5kHLpydVEvwWqjteUr9sXRgJknwbKZJZhdJ7uFnaTtd+Nr/2G3ceJHnHXrFhJ67n3Tw==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=8'
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
       '@eslint-community/regexpp': 4.5.1
-      eslint: 8.41.0
+      eslint: 8.42.0
     dev: true
 
-  /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0):
+  /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0):
     resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -3978,15 +3977,15 @@ packages:
       '@typescript-eslint/parser':
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       array-includes: 3.1.6
       array.prototype.flat: 1.3.1
       array.prototype.flatmap: 1.3.1
       debug: 3.2.7
       doctrine: 2.1.0
-      eslint: 8.41.0
+      eslint: 8.42.0
       eslint-import-resolver-node: 0.3.7
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
       has: 1.0.3
       is-core-module: 2.12.1
       is-glob: 4.0.3
@@ -4001,8 +4000,8 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-plugin-jsdoc@44.2.4(eslint@8.41.0):
-    resolution: {integrity: sha512-/EMMxCyRh1SywhCb66gAqoGX4Yv6Xzc4bsSkF1AiY2o2+bQmGMQ05QZ5+JjHbdFTPDZY9pfn+DsSNP0a5yQpIg==}
+  /eslint-plugin-jsdoc@46.2.3(eslint@8.42.0):
+    resolution: {integrity: sha512-06s2RmIyichD2+CYQzSq4DH5YAaXdYm6WPe6C8daf7vr6MxzJiYJYOKxNYLDdQRTRE2JAW1kfU1OYRxvAxDzjA==}
     engines: {node: '>=16'}
     peerDependencies:
       eslint: ^7.0.0 || ^8.0.0
@@ -4012,7 +4011,7 @@ packages:
       comment-parser: 1.3.1
       debug: 4.3.4(supports-color@8.1.1)
       escape-string-regexp: 4.0.0
-      eslint: 8.41.0
+      eslint: 8.42.0
       esquery: 1.5.0
       semver: 7.5.1
       spdx-expression-parse: 3.0.1
@@ -4020,16 +4019,16 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-plugin-n@16.0.0(eslint@8.41.0):
+  /eslint-plugin-n@16.0.0(eslint@8.42.0):
     resolution: {integrity: sha512-akkZTE3hsHBrq6CwmGuYCzQREbVUrA855kzcHqe6i0FLBkeY7Y/6tThCVkjUnjhvRBAlc+8lILcSe5QvvDpeZQ==}
     engines: {node: '>=16.0.0'}
     peerDependencies:
       eslint: '>=7.0.0'
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
       builtins: 5.0.1
-      eslint: 8.41.0
-      eslint-plugin-es-x: 6.2.1(eslint@8.41.0)
+      eslint: 8.42.0
+      eslint-plugin-es-x: 6.2.1(eslint@8.42.0)
       ignore: 5.2.4
       is-core-module: 2.12.1
       minimatch: 3.1.2
@@ -4037,7 +4036,7 @@ packages:
       semver: 7.5.1
     dev: true
 
-  /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.41.0)(prettier@2.8.8):
+  /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8):
     resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
     engines: {node: '>=12.0.0'}
     peerDependencies:
@@ -4048,8 +4047,8 @@ packages:
       eslint-config-prettier:
         optional: true
     dependencies:
-      eslint: 8.41.0
-      eslint-config-prettier: 8.8.0(eslint@8.41.0)
+      eslint: 8.42.0
+      eslint-config-prettier: 8.8.0(eslint@8.42.0)
       prettier: 2.8.8
       prettier-linter-helpers: 1.0.0
     dev: true
@@ -4082,16 +4081,16 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /eslint@8.41.0:
-    resolution: {integrity: sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==}
+  /eslint@8.42.0:
+    resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     hasBin: true
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
       '@eslint-community/regexpp': 4.5.1
       '@eslint/eslintrc': 2.0.3
-      '@eslint/js': 8.41.0
-      '@humanwhocodes/config-array': 0.11.8
+      '@eslint/js': 8.42.0
+      '@humanwhocodes/config-array': 0.11.10
       '@humanwhocodes/module-importer': 1.0.1
       '@nodelib/fs.walk': 1.2.8
       ajv: 6.12.6
@@ -4380,11 +4379,6 @@ packages:
       moment: 2.29.4
     dev: false
 
-  /file-uri-to-path@2.0.0:
-    resolution: {integrity: sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==}
-    engines: {node: '>= 6'}
-    dev: true
-
   /filelist@1.0.4:
     resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==}
     dependencies:
@@ -4567,14 +4561,6 @@ packages:
     resolution: {integrity: sha512-xQVsnjJ/5pQtcKh+KjUoZGzVWn4uNkchxTF6Lwjr4Gf7nQr8fmUfhKJ62zE77+xQg9xnxi5KUps7XGs+VC986A==}
     dev: true
 
-  /ftp@0.3.10:
-    resolution: {integrity: sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==}
-    engines: {node: '>=0.8.0'}
-    dependencies:
-      readable-stream: 1.1.14
-      xregexp: 2.0.0
-    dev: true
-
   /function-bind@1.1.1:
     resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
 
@@ -4674,20 +4660,20 @@ packages:
       get-intrinsic: 1.2.1
     dev: true
 
-  /get-tsconfig@4.5.0:
-    resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==}
+  /get-tsconfig@4.6.0:
+    resolution: {integrity: sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg==}
+    dependencies:
+      resolve-pkg-maps: 1.0.0
     dev: true
 
-  /get-uri@3.0.2:
-    resolution: {integrity: sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==}
-    engines: {node: '>= 6'}
+  /get-uri@6.0.1:
+    resolution: {integrity: sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==}
+    engines: {node: '>= 14'}
     dependencies:
-      '@tootallnate/once': 1.1.2
-      data-uri-to-buffer: 3.0.1
+      basic-ftp: 5.0.3
+      data-uri-to-buffer: 5.0.1
       debug: 4.3.4(supports-color@8.1.1)
-      file-uri-to-path: 2.0.0
       fs-extra: 8.1.0
-      ftp: 0.3.10
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -4800,20 +4786,6 @@ packages:
       define-properties: 1.2.0
     dev: true
 
-  /globby@10.0.1:
-    resolution: {integrity: sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==}
-    engines: {node: '>=8'}
-    dependencies:
-      '@types/glob': 7.2.0
-      array-union: 2.1.0
-      dir-glob: 3.0.1
-      fast-glob: 3.2.12
-      glob: 7.2.3
-      ignore: 5.2.4
-      merge2: 1.4.1
-      slash: 3.0.0
-    dev: true
-
   /globby@10.0.2:
     resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==}
     engines: {node: '>=8'}
@@ -4856,11 +4828,11 @@ packages:
       get-intrinsic: 1.2.1
     dev: true
 
-  /got@12.6.0:
-    resolution: {integrity: sha512-WTcaQ963xV97MN3x0/CbAriXFZcXCfgxVp91I+Ze6pawQOa7SgzwSx2zIJJsX+kTajMnVs0xcFD1TxZKFqhdnQ==}
+  /got@12.6.1:
+    resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==}
     engines: {node: '>=14.16'}
     dependencies:
-      '@sindresorhus/is': 5.3.0
+      '@sindresorhus/is': 5.4.1
       '@szmarczak/http-timer': 5.0.1
       cacheable-lookup: 7.0.0
       cacheable-request: 10.2.10
@@ -5070,17 +5042,6 @@ packages:
   /http-cache-semantics@4.1.1:
     resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
 
-  /http-errors@2.0.0:
-    resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
-    engines: {node: '>= 0.8'}
-    dependencies:
-      depd: 2.0.0
-      inherits: 2.0.4
-      setprototypeof: 1.2.0
-      statuses: 2.0.1
-      toidentifier: 1.0.1
-    dev: true
-
   /http-parser-js@0.5.8:
     resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==}
     dev: true
@@ -5094,6 +5055,17 @@ packages:
       debug: 4.3.4(supports-color@8.1.1)
     transitivePeerDependencies:
       - supports-color
+    optional: true
+
+  /http-proxy-agent@7.0.0:
+    resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==}
+    engines: {node: '>= 14'}
+    dependencies:
+      agent-base: 7.1.0
+      debug: 4.3.4(supports-color@8.1.1)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
 
   /http-signature@1.2.0:
     resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==}
@@ -5129,6 +5101,16 @@ packages:
     transitivePeerDependencies:
       - supports-color
 
+  /https-proxy-agent@7.0.0:
+    resolution: {integrity: sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==}
+    engines: {node: '>= 14'}
+    dependencies:
+      agent-base: 7.1.0
+      debug: 4.3.4(supports-color@8.1.1)
+    transitivePeerDependencies:
+      - supports-color
+    dev: true
+
   /human-signals@1.1.1:
     resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==}
     engines: {node: '>=8.12.0'}
@@ -5276,25 +5258,25 @@ packages:
       through: 2.3.8
     dev: true
 
-  /inquirer@9.2.0:
-    resolution: {integrity: sha512-WWERbVqjsTXjXub1ZW0ZHDit1dyHqy0T9XIkky9TnmKAPrjU9Jkd59nZPK0dUuM3s73GZAZu2Jo4iFU3XSPVLA==}
+  /inquirer@9.2.6:
+    resolution: {integrity: sha512-y71l237eJJKS4rl7sQcEUiMhrR0pB/ZnRMMTxLpjJhWL4hdWCT03a6jJnC1w6qIPSRZWEozuieGt3v7XaEJYFw==}
     engines: {node: '>=14.18.0'}
     dependencies:
-      ansi-escapes: 6.2.0
+      ansi-escapes: 4.3.2
       chalk: 5.2.0
-      cli-cursor: 4.0.0
+      cli-cursor: 3.1.0
       cli-width: 4.0.0
       external-editor: 3.1.0
       figures: 5.0.0
       lodash: 4.17.21
       mute-stream: 1.0.0
-      ora: 6.3.0
-      run-async: 2.4.1
+      ora: 5.4.1
+      run-async: 3.0.0
       rxjs: 7.8.1
-      string-width: 5.1.2
-      strip-ansi: 7.0.1
+      string-width: 4.2.3
+      strip-ansi: 6.0.1
       through: 2.3.8
-      wrap-ansi: 8.1.0
+      wrap-ansi: 6.2.0
     dev: true
 
   /insert-module-globals@7.2.1:
@@ -5589,11 +5571,6 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
-  /is-plain-object@3.0.1:
-    resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==}
-    engines: {node: '>=0.10.0'}
-    dev: true
-
   /is-plain-object@5.0.0:
     resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
     engines: {node: '>=0.10.0'}
@@ -5781,8 +5758,8 @@ packages:
       '@pkgjs/parseargs': 0.11.0
     dev: true
 
-  /jake@10.8.6:
-    resolution: {integrity: sha512-G43Ub9IYEFfu72sua6rzooi8V8Gz2lkfk48rW20vEWCGizeaEPlKB1Kh8JIA84yQbiAEfqlPmSpGgCKKxH3rDA==}
+  /jake@10.8.7:
+    resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==}
     engines: {node: '>=10'}
     hasBin: true
     dependencies:
@@ -5837,7 +5814,7 @@ packages:
     engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
     dependencies:
       '@jest/types': 29.5.0
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       chalk: 4.1.2
       ci-info: 3.8.0
       graceful-fs: 4.2.11
@@ -6091,7 +6068,7 @@ packages:
       object-inspect: 1.12.3
       pidtree: 0.6.0
       string-argv: 0.3.2
-      yaml: 2.2.2
+      yaml: 2.3.1
     transitivePeerDependencies:
       - enquirer
       - supports-color
@@ -6297,20 +6274,19 @@ packages:
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     dev: true
 
-  /lru-cache@5.1.1:
-    resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
-    dependencies:
-      yallist: 3.1.1
-    dev: true
-
   /lru-cache@6.0.0:
     resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
     engines: {node: '>=10'}
     dependencies:
       yallist: 4.0.0
 
-  /lru-cache@9.1.1:
-    resolution: {integrity: sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==}
+  /lru-cache@7.18.3:
+    resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
+    engines: {node: '>=12'}
+    dev: true
+
+  /lru-cache@9.1.2:
+    resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==}
     engines: {node: 14 || >=16.14}
     dev: true
 
@@ -6453,8 +6429,8 @@ packages:
       braces: 3.0.2
       picomatch: 2.3.1
 
-  /mikro-orm@5.7.9:
-    resolution: {integrity: sha512-PD8gq2wGDfoydET+mL+bvNJmzmh6d3/8nA4z5+admjDEPzd8pd+x2QZOUPgkm2s0CChpoYCB2YaKqmxI82aCOQ==}
+  /mikro-orm@5.7.11:
+    resolution: {integrity: sha512-Cbg8cBqTgr+qPzeENPVHQ2L/SfDrkXjNa10ghQYp1W7Bt6jWYF4oukLAuo6GnPx/utPCbKRwTTB+cxHPppXh6Q==}
     engines: {node: '>= 14.0.0'}
 
   /miller-rabin@4.0.1:
@@ -6828,8 +6804,8 @@ packages:
       whatwg-url: 11.0.0
     dev: false
 
-  /mongodb@5.5.0:
-    resolution: {integrity: sha512-XgrkUgAAdfnZKQfk5AsYL8j7O99WHd4YXPxYxnh8dZxD+ekYWFRA3JktUsBnfg+455Smf75/+asoU/YLwNGoQQ==}
+  /mongodb@5.6.0:
+    resolution: {integrity: sha512-z8qVs9NfobHJm6uzK56XBZF8XwM9H294iRnB7wNjF0SnY93si5HPziIJn+qqvUR5QOff/4L0gCD6SShdR/GtVQ==}
     engines: {node: '>=14.20.1'}
     peerDependencies:
       '@aws-sdk/credential-providers': ^3.201.0
@@ -7319,8 +7295,8 @@ packages:
       wcwidth: 1.0.1
     dev: true
 
-  /ora@6.3.0:
-    resolution: {integrity: sha512-1/D8uRFY0ay2kgBpmAwmSA404w4OoPVhHMqRqtjvrcK/dnzcEZxMJ+V4DUbyICu8IIVRclHcOf5wlD1tMY4GUQ==}
+  /ora@6.3.1:
+    resolution: {integrity: sha512-ERAyNnZOfqM+Ao3RAvIXkYh5joP220yf59gVe2X/cI6SiCxIdi4c9HZKZD8R6q/RDXEje1THBju6iExiSsgJaQ==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
     dependencies:
       chalk: 5.2.0
@@ -7330,7 +7306,7 @@ packages:
       is-unicode-supported: 1.3.0
       log-symbols: 5.1.0
       stdin-discarder: 0.1.0
-      strip-ansi: 7.0.1
+      strip-ansi: 7.1.0
       wcwidth: 1.0.1
     dev: true
 
@@ -7417,28 +7393,26 @@ packages:
     engines: {node: '>=6'}
     dev: true
 
-  /pac-proxy-agent@5.0.0:
-    resolution: {integrity: sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==}
-    engines: {node: '>= 8'}
+  /pac-proxy-agent@6.0.3:
+    resolution: {integrity: sha512-5Hr1KgPDoc21Vn3rsXBirwwDnF/iac1jN/zkpsOYruyT+ZgsUhUOgVwq3v9+ukjZd/yGm/0nzO1fDfl7rkGoHQ==}
+    engines: {node: '>= 14'}
     dependencies:
-      '@tootallnate/once': 1.1.2
-      agent-base: 6.0.2
+      agent-base: 7.1.0
       debug: 4.3.4(supports-color@8.1.1)
-      get-uri: 3.0.2
-      http-proxy-agent: 4.0.1
-      https-proxy-agent: 5.0.1
-      pac-resolver: 5.0.1
-      raw-body: 2.5.2
-      socks-proxy-agent: 5.0.1
+      get-uri: 6.0.1
+      http-proxy-agent: 7.0.0
+      https-proxy-agent: 7.0.0
+      pac-resolver: 6.0.1
+      socks-proxy-agent: 8.0.1
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /pac-resolver@5.0.1:
-    resolution: {integrity: sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==}
-    engines: {node: '>= 8'}
+  /pac-resolver@6.0.1:
+    resolution: {integrity: sha512-dg497MhVT7jZegPRuOScQ/z0aV/5WR0gTdRu1md+Irs9J9o+ls5jIuxjo1WfaTG+eQQkxyn5HMGvWK+w7EIBkQ==}
+    engines: {node: '>= 14'}
     dependencies:
-      degenerator: 3.0.4
+      degenerator: 4.0.2
       ip: 1.1.8
       netmask: 2.0.2
     dev: true
@@ -7447,7 +7421,7 @@ packages:
     resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==}
     engines: {node: '>=8'}
     dependencies:
-      got: 12.6.0
+      got: 12.6.1
       registry-auth-token: 4.2.2
       registry-url: 5.1.0
       semver: 6.3.0
@@ -7457,7 +7431,7 @@ packages:
     resolution: {integrity: sha512-hySwcV8RAWeAfPsXb9/HGSPn8lwDnv6fabH+obUZKX169QknRkRhPxd1yMubpKDskLFATkl3jHpNtVtDPFA0Wg==}
     engines: {node: '>=14.16'}
     dependencies:
-      got: 12.6.0
+      got: 12.6.1
       registry-auth-token: 5.0.2
       registry-url: 6.0.1
       semver: 7.5.1
@@ -7562,7 +7536,7 @@ packages:
     resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==}
     engines: {node: '>=16 || 14 >=14.17'}
     dependencies:
-      lru-cache: 9.1.1
+      lru-cache: 9.1.2
       minipass: 6.0.2
     dev: true
 
@@ -7625,19 +7599,19 @@ packages:
     dependencies:
       semver-compare: 1.0.0
 
-  /poolifier@2.4.14:
-    resolution: {integrity: sha512-22cWUpyV/2B+e/UXUbf+rvr9s7EHsDrjpuIr8I4MO9JBru4gADIlxEUSEpzj4U2eAhayyMo6Xt4kINKdiGGETg==}
-    engines: {node: '>=16.0.0', pnpm: '>=8.0.0'}
+  /poolifier@2.5.3:
+    resolution: {integrity: sha512-L/0ka0p/9zvchXtwUjVSJ/wKCQFMhjzSqNdFXqJaTjcME50d4+VrlvgxdfOj9rmIJ/EHSpTVVc05eAD8rQ4DpQ==}
+    engines: {node: '>=16.14.0', pnpm: '>=8.6.0'}
     requiresBuild: true
     dev: false
 
-  /postcss-import@13.0.0(postcss@8.4.23):
+  /postcss-import@13.0.0(postcss@8.4.24):
     resolution: {integrity: sha512-LPUbm3ytpYopwQQjqgUH4S3EM/Gb9QsaSPP/5vnoi+oKVy3/mIk2sc0Paqw7RL57GpScm9MdIMUypw2znWiBpg==}
     engines: {node: '>=10.0.0'}
     peerDependencies:
       postcss: ^8.0.0
     dependencies:
-      postcss: 8.4.23
+      postcss: 8.4.24
       postcss-value-parser: 4.2.0
       read-cache: 1.0.0
       resolve: 1.22.2
@@ -7647,8 +7621,8 @@ packages:
     resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
     dev: true
 
-  /postcss@8.4.23:
-    resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==}
+  /postcss@8.4.24:
+    resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==}
     engines: {node: ^10 || ^12 || >=14}
     dependencies:
       nanoid: 3.3.6
@@ -7781,18 +7755,18 @@ packages:
     resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==}
     dev: true
 
-  /proxy-agent@5.0.0:
-    resolution: {integrity: sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==}
-    engines: {node: '>= 8'}
+  /proxy-agent@6.2.1:
+    resolution: {integrity: sha512-OIbBKlRAT+ycCm6wAYIzMwPejzRtjy8F3QiDX0eKOA3e4pe3U9F/IvzcHP42bmgQxVv97juG+J8/gx+JIeCX/Q==}
+    engines: {node: '>= 14'}
     dependencies:
-      agent-base: 6.0.2
+      agent-base: 7.1.0
       debug: 4.3.4(supports-color@8.1.1)
-      http-proxy-agent: 4.0.1
-      https-proxy-agent: 5.0.1
-      lru-cache: 5.1.1
-      pac-proxy-agent: 5.0.0
+      http-proxy-agent: 7.0.0
+      https-proxy-agent: 7.0.0
+      lru-cache: 7.18.3
+      pac-proxy-agent: 6.0.3
       proxy-from-env: 1.1.0
-      socks-proxy-agent: 5.0.1
+      socks-proxy-agent: 8.0.1
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -7928,16 +7902,6 @@ packages:
       safe-buffer: 5.2.1
     dev: true
 
-  /raw-body@2.5.2:
-    resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
-    engines: {node: '>= 0.8'}
-    dependencies:
-      bytes: 3.1.2
-      http-errors: 2.0.0
-      iconv-lite: 0.4.24
-      unpipe: 1.0.0
-    dev: true
-
   /rc@1.2.8:
     resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
     hasBin: true
@@ -7987,15 +7951,6 @@ packages:
       type-fest: 0.6.0
     dev: true
 
-  /readable-stream@1.1.14:
-    resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==}
-    dependencies:
-      core-util-is: 1.0.3
-      inherits: 2.0.4
-      isarray: 0.0.1
-      string_decoder: 0.10.31
-    dev: true
-
   /readable-stream@2.3.8:
     resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
     dependencies:
@@ -8088,21 +8043,21 @@ packages:
     resolution: {integrity: sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==}
     dev: true
 
-  /release-it@15.10.3:
-    resolution: {integrity: sha512-OSdHOg76gwkpLbSLBK09GZQj5XWXwBP+S6v//rSoQKkjqklaCLK04Gl5NkTwNrQOHHiihs4ToesDNh2+w55k3w==}
+  /release-it@15.10.5:
+    resolution: {integrity: sha512-6AWkcOYsEfCzegtAKvXekUG+CLjlFXztDwGzxFOGa8VJRuXbPONfM8rvaPYJX1hTlL5+KC4MWOEoKKzWhQ65gA==}
     engines: {node: '>=14.9'}
     hasBin: true
     dependencies:
       '@iarna/toml': 2.2.5
-      '@octokit/rest': 19.0.7
+      '@octokit/rest': 19.0.11
       async-retry: 1.3.3
       chalk: 5.2.0
       cosmiconfig: 8.1.3
       execa: 7.1.1
       git-url-parse: 13.1.0
       globby: 13.1.4
-      got: 12.6.0
-      inquirer: 9.2.0
+      got: 12.6.1
+      inquirer: 9.2.6
       is-ci: 3.0.1
       issue-parser: 6.0.0
       lodash: 4.17.21
@@ -8110,11 +8065,11 @@ packages:
       new-github-release-url: 2.0.0
       node-fetch: 3.3.1
       open: 9.1.0
-      ora: 6.3.0
+      ora: 6.3.1
       os-name: 5.1.0
       promise.allsettled: 1.0.6
-      proxy-agent: 5.0.0
-      semver: 7.5.0
+      proxy-agent: 6.2.1
+      semver: 7.5.1
       shelljs: 0.8.5
       update-notifier: 6.0.2
       url-join: 5.0.0
@@ -8189,6 +8144,10 @@ packages:
       global-dirs: 0.1.1
     dev: true
 
+  /resolve-pkg-maps@1.0.0:
+    resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+    dev: true
+
   /resolve@1.19.0:
     resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==}
     dependencies:
@@ -8298,17 +8257,6 @@ packages:
     engines: {node: '>=8.0.0'}
     dev: true
 
-  /rollup-plugin-copy@3.4.0:
-    resolution: {integrity: sha512-rGUmYYsYsceRJRqLVlE9FivJMxJ7X6jDlP79fmFkL8sJs7VVMSVyA2yfyL+PGyO/vJs4A87hwhgVfz61njI+uQ==}
-    engines: {node: '>=8.3'}
-    dependencies:
-      '@types/fs-extra': 8.1.2
-      colorette: 1.4.0
-      fs-extra: 8.1.0
-      globby: 10.0.1
-      is-plain-object: 3.0.1
-    dev: true
-
   /rollup-plugin-delete@2.0.0:
     resolution: {integrity: sha512-/VpLMtDy+8wwRlDANuYmDa9ss/knGsAgrDhM+tEwB1npHwNu4DYNmDfUL55csse/GHs9Q+SMT/rw9uiaZ3pnzA==}
     engines: {node: '>=10'}
@@ -8336,6 +8284,11 @@ packages:
     engines: {node: '>=0.12.0'}
     dev: true
 
+  /run-async@3.0.0:
+    resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==}
+    engines: {node: '>=0.12.0'}
+    dev: true
+
   /run-parallel@1.2.0:
     resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
     dependencies:
@@ -8351,7 +8304,7 @@ packages:
   /rxjs@7.8.1:
     resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
     dependencies:
-      tslib: 2.5.2
+      tslib: 2.5.3
     dev: true
 
   /safe-buffer@5.1.2:
@@ -8458,10 +8411,6 @@ packages:
   /set-blocking@2.0.0:
     resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
 
-  /setprototypeof@1.2.0:
-    resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
-    dev: true
-
   /sha.js@2.4.11:
     resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==}
     hasBin: true
@@ -8605,31 +8554,31 @@ packages:
     resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
     engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
 
-  /smob@1.1.1:
-    resolution: {integrity: sha512-i5aqEBPnDv9d77+NDxfjROtywxzNdAVNyaOr+RsLhM28Ts+Ar7luIp/Q+SBYa6wv/7BBcOpEkrhtDxsl2WA9Jg==}
+  /smob@1.4.0:
+    resolution: {integrity: sha512-MqR3fVulhjWuRNSMydnTlweu38UhQ0HXM4buStD/S3mc/BzX3CuM9OmhyQpmtYCvoYdl5ris6TI0ZqH355Ymqg==}
     dev: true
 
-  /socks-proxy-agent@5.0.1:
-    resolution: {integrity: sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==}
-    engines: {node: '>= 6'}
+  /socks-proxy-agent@6.2.1:
+    resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==}
+    engines: {node: '>= 10'}
     dependencies:
       agent-base: 6.0.2
       debug: 4.3.4(supports-color@8.1.1)
       socks: 2.7.1
     transitivePeerDependencies:
       - supports-color
-    dev: true
+    optional: true
 
-  /socks-proxy-agent@6.2.1:
-    resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==}
-    engines: {node: '>= 10'}
+  /socks-proxy-agent@8.0.1:
+    resolution: {integrity: sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ==}
+    engines: {node: '>= 14'}
     dependencies:
-      agent-base: 6.0.2
+      agent-base: 7.1.0
       debug: 4.3.4(supports-color@8.1.1)
       socks: 2.7.1
     transitivePeerDependencies:
       - supports-color
-    optional: true
+    dev: true
 
   /socks@2.7.1:
     resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==}
@@ -8794,11 +8743,6 @@ packages:
       through2: 2.0.5
     dev: true
 
-  /statuses@2.0.1:
-    resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
-    engines: {node: '>= 0.8'}
-    dev: true
-
   /stdin-discarder@0.1.0:
     resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==}
     engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -8913,7 +8857,7 @@ packages:
     dependencies:
       eastasianwidth: 0.2.0
       emoji-regex: 9.2.2
-      strip-ansi: 7.0.1
+      strip-ansi: 7.1.0
     dev: true
 
   /string.prototype.trim@1.2.7:
@@ -8941,10 +8885,6 @@ packages:
       es-abstract: 1.21.2
     dev: true
 
-  /string_decoder@0.10.31:
-    resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==}
-    dev: true
-
   /string_decoder@1.1.1:
     resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
     dependencies:
@@ -8983,8 +8923,8 @@ packages:
     dependencies:
       ansi-regex: 5.0.1
 
-  /strip-ansi@7.0.1:
-    resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==}
+  /strip-ansi@7.1.0:
+    resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
     engines: {node: '>=12'}
     dependencies:
       ansi-regex: 6.0.1
@@ -9065,8 +9005,8 @@ packages:
     resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
     engines: {node: ^14.18.0 || >=16.0.0}
     dependencies:
-      '@pkgr/utils': 2.4.0
-      tslib: 2.5.2
+      '@pkgr/utils': 2.4.1
+      tslib: 2.5.3
     dev: true
 
   /syntax-error@1.4.0:
@@ -9120,8 +9060,8 @@ packages:
       source-map-support: 0.5.21
     dev: true
 
-  /terser@5.17.5:
-    resolution: {integrity: sha512-NqFkzBX34WExkCbk3K5urmNCpEWqMPZnwGI1pMHwqvJ/zDlXC75u3NI7BrzoR8/pryy8Abx2e1i8ChrWkhH1Hg==}
+  /terser@5.17.7:
+    resolution: {integrity: sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==}
     engines: {node: '>=10'}
     hasBin: true
     dependencies:
@@ -9215,11 +9155,6 @@ packages:
     resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==}
     dev: true
 
-  /toidentifier@1.0.1:
-    resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
-    engines: {node: '>=0.6'}
-    dev: true
-
   /tough-cookie@2.5.0:
     resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==}
     engines: {node: '>=0.8'}
@@ -9276,7 +9211,7 @@ packages:
       code-block-writer: 12.0.0
     dev: false
 
-  /ts-node@10.9.1(@types/node@20.2.3)(typescript@5.0.4):
+  /ts-node@10.9.1(@types/node@20.2.5)(typescript@5.1.3):
     resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
     hasBin: true
     peerDependencies:
@@ -9295,14 +9230,14 @@ packages:
       '@tsconfig/node12': 1.0.11
       '@tsconfig/node14': 1.0.3
       '@tsconfig/node16': 1.0.4
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       acorn: 8.8.2
       acorn-walk: 8.2.0
       arg: 4.1.3
       create-require: 1.1.1
       diff: 4.0.2
       make-error: 1.3.6
-      typescript: 5.0.4
+      typescript: 5.1.3
       v8-compile-cache-lib: 3.0.1
       yn: 3.1.1
     dev: true
@@ -9329,17 +9264,17 @@ packages:
     resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
     dev: true
 
-  /tslib@2.5.2:
-    resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==}
+  /tslib@2.5.3:
+    resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==}
 
-  /tsutils@3.21.0(typescript@5.0.4):
+  /tsutils@3.21.0(typescript@5.1.3):
     resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
     engines: {node: '>= 6'}
     peerDependencies:
       typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
     dependencies:
       tslib: 1.14.1
-      typescript: 5.0.4
+      typescript: 5.1.3
     dev: true
 
   /ttest@3.0.0:
@@ -9427,11 +9362,6 @@ packages:
     engines: {node: '>=12.20'}
     dev: true
 
-  /type-fest@3.11.0:
-    resolution: {integrity: sha512-JaPw5U9ixP0XcpUbQoVSbxSDcK/K4nww20C3kjm9yE6cDRRhptU28AH60VWf9ltXmCrIfIbtt9J+2OUk2Uqiaw==}
-    engines: {node: '>=14.16'}
-    dev: true
-
   /type@1.2.0:
     resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==}
     dev: true
@@ -9465,9 +9395,9 @@ packages:
     resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
     dev: true
 
-  /typescript@5.0.4:
-    resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
-    engines: {node: '>=12.20'}
+  /typescript@5.1.3:
+    resolution: {integrity: sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==}
+    engines: {node: '>=14.17'}
     hasBin: true
     dev: true
 
@@ -9556,11 +9486,6 @@ packages:
     resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
     engines: {node: '>= 10.0.0'}
 
-  /unpipe@1.0.0:
-    resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
-    engines: {node: '>= 0.8'}
-    dev: true
-
   /untildify@4.0.0:
     resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
     engines: {node: '>=8'}
@@ -9841,7 +9766,7 @@ packages:
       execa: 5.1.1
     dev: true
 
-  /winston-daily-rotate-file@4.7.1(winston@3.8.2):
+  /winston-daily-rotate-file@4.7.1(winston@3.9.0):
     resolution: {integrity: sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA==}
     engines: {node: '>=8'}
     peerDependencies:
@@ -9850,7 +9775,7 @@ packages:
       file-stream-rotator: 0.6.1
       object-hash: 2.2.0
       triple-beam: 1.3.0
-      winston: 3.8.2
+      winston: 3.9.0
       winston-transport: 4.5.0
     dev: false
 
@@ -9863,8 +9788,8 @@ packages:
       triple-beam: 1.3.0
     dev: false
 
-  /winston@3.8.2:
-    resolution: {integrity: sha512-MsE1gRx1m5jdTTO9Ld/vND4krP2To+lgDoMEHGGa4HIlAUyXJtfc7CxQcGXVyz2IBpw5hbFkj2b/AtUdQwyRew==}
+  /winston@3.9.0:
+    resolution: {integrity: sha512-jW51iW/X95BCW6MMtZWr2jKQBP4hV5bIDq9QrIjfDk6Q9QuxvTKEAlpUNAzP+HYHFFCeENhph16s0zEunu4uuQ==}
     engines: {node: '>= 12.0.0'}
     dependencies:
       '@colors/colors': 1.5.0
@@ -9926,7 +9851,7 @@ packages:
     dependencies:
       ansi-styles: 6.2.1
       string-width: 5.1.2
-      strip-ansi: 7.0.1
+      strip-ansi: 7.1.0
     dev: true
 
   /wrappy@1.0.2:
@@ -9984,10 +9909,6 @@ packages:
     engines: {node: '>=12'}
     dev: true
 
-  /xregexp@2.0.0:
-    resolution: {integrity: sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==}
-    dev: true
-
   /xtend@4.0.2:
     resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
     engines: {node: '>=0.4'}
@@ -10002,15 +9923,11 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /yallist@3.1.1:
-    resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
-    dev: true
-
   /yallist@4.0.0:
     resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
 
-  /yaml@2.2.2:
-    resolution: {integrity: sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==}
+  /yaml@2.3.1:
+    resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==}
     engines: {node: '>= 14'}
     dev: true
 
index 8ca037fb9f24753c042ee475b786197d2c36d51e..1034ffc812825d1adcc7005ac13ce24f48b8f02d 100644 (file)
@@ -1,9 +1,11 @@
 /* eslint-disable n/no-unpublished-import */
+import { cpus } from 'node:os';
+
 import json from '@rollup/plugin-json';
 import terser from '@rollup/plugin-terser';
 import typescript from '@rollup/plugin-typescript';
+import { copy } from '@web/rollup-plugin-copy';
 import analyze from 'rollup-plugin-analyzer';
-import copy from 'rollup-plugin-copy';
 import del from 'rollup-plugin-delete';
 
 const isDevelopmentBuild = process.env.BUILD === 'development';
@@ -16,9 +18,8 @@ export default {
     {
       dir: 'dist',
       format: 'esm',
-      exports: 'auto',
-      ...(isDevelopmentBuild && { sourcemap: true }),
-      ...(!isDevelopmentBuild && { plugins: [terser({ maxWorkers: 2 })] }),
+      sourcemap: !!isDevelopmentBuild,
+      plugins: [terser({ maxWorkers: cpus().length / 2 })],
     },
   ],
   external: [
@@ -32,10 +33,12 @@ export default {
     'just-clone',
     'just-merge',
     'mnemonist/lru-map-with-delete.js',
+    'mnemonist/queue.js',
     'moment',
     'mongodb',
     'node:async_hooks',
     'node:crypto',
+    'node:events',
     'node:fs',
     'node:http',
     'node:path',
@@ -55,6 +58,9 @@ export default {
     json(),
     typescript({
       tsconfig: 'tsconfig.json',
+      compilerOptions: {
+        sourceMap: !!isDevelopmentBuild,
+      },
     }),
     del({
       targets: [
@@ -67,7 +73,15 @@ export default {
       ],
     }),
     copy({
-      targets: [{ src: 'src/assets', dest: 'dist/' }],
+      rootDir: 'src',
+      patterns: 'assets/**/*.json',
+      exclude: [
+        'assets/config-template.json',
+        'assets/*config[-_.]*.json',
+        'assets/idtags-template.json',
+        'assets/authorization-tags-template.json',
+        'assets/ui-protocol/**/*',
+      ],
     }),
     isAnalyzeBuild && analyze(),
   ],
index fc7665b4cc3893659d987826e4b4d583d51b12de..e511bf94878cfd9740a6b06667fed63a2ce5ae68 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
-sonar.projectVersion=1.2.13
+sonar.projectVersion=1.2.15
 
 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
 sonar.sources=src
index c5076adce7ca9a24f7c25ea50a45a1c916a355cf..0389526fd6a9400a90404903a360d8d607448fd6 100644 (file)
@@ -31,11 +31,15 @@ export class AutomaticTransactionGenerator extends AsyncResource {
 
   public readonly connectorsStatus: Map<number, Status>;
   public started: boolean;
+  private starting: boolean;
+  private stopping: boolean;
   private readonly chargingStation: ChargingStation;
 
   private constructor(chargingStation: ChargingStation) {
     super(moduleName);
     this.started = false;
+    this.starting = false;
+    this.stopping = false;
     this.chargingStation = chargingStation;
     this.connectorsStatus = new Map<number, Status>();
     this.initializeConnectorsStatus();
@@ -63,8 +67,14 @@ export class AutomaticTransactionGenerator extends AsyncResource {
       logger.warn(`${this.logPrefix()} is already started`);
       return;
     }
+    if (this.starting === true) {
+      logger.warn(`${this.logPrefix()} is already starting`);
+      return;
+    }
+    this.starting = true;
     this.startConnectors();
     this.started = true;
+    this.starting = false;
   }
 
   public stop(): void {
@@ -72,8 +82,14 @@ export class AutomaticTransactionGenerator extends AsyncResource {
       logger.warn(`${this.logPrefix()} is already stopped`);
       return;
     }
+    if (this.stopping === true) {
+      logger.warn(`${this.logPrefix()} is already stopping`);
+      return;
+    }
+    this.stopping = true;
     this.stopConnectors();
     this.started = false;
+    this.stopping = false;
   }
 
   public startConnector(connectorId: number): void {
@@ -316,45 +332,45 @@ export class AutomaticTransactionGenerator extends AsyncResource {
       for (const [evseId, evseStatus] of this.chargingStation.evses) {
         if (evseId > 0) {
           for (const connectorId of evseStatus.connectors.keys()) {
-            this.connectorsStatus.set(connectorId, {
-              start: false,
-              authorizeRequests: 0,
-              acceptedAuthorizeRequests: 0,
-              rejectedAuthorizeRequests: 0,
-              startTransactionRequests: 0,
-              acceptedStartTransactionRequests: 0,
-              rejectedStartTransactionRequests: 0,
-              stopTransactionRequests: 0,
-              acceptedStopTransactionRequests: 0,
-              rejectedStopTransactionRequests: 0,
-              skippedConsecutiveTransactions: 0,
-              skippedTransactions: 0,
-            });
+            this.connectorsStatus.set(connectorId, this.getConnectorStatus(connectorId));
           }
         }
       }
     } else {
       for (const connectorId of this.chargingStation.connectors.keys()) {
         if (connectorId > 0) {
-          this.connectorsStatus.set(connectorId, {
-            start: false,
-            authorizeRequests: 0,
-            acceptedAuthorizeRequests: 0,
-            rejectedAuthorizeRequests: 0,
-            startTransactionRequests: 0,
-            acceptedStartTransactionRequests: 0,
-            rejectedStartTransactionRequests: 0,
-            stopTransactionRequests: 0,
-            acceptedStopTransactionRequests: 0,
-            rejectedStopTransactionRequests: 0,
-            skippedConsecutiveTransactions: 0,
-            skippedTransactions: 0,
-          });
+          this.connectorsStatus.set(connectorId, this.getConnectorStatus(connectorId));
         }
       }
     }
   }
 
+  private getConnectorStatus(connectorId: number): Status {
+    const connectorStatus = Utils.cloneObject(
+      this.chargingStation.getAutomaticTransactionGeneratorStatuses()
+    )[connectorId];
+    delete connectorStatus?.startDate;
+    delete connectorStatus?.lastRunDate;
+    delete connectorStatus?.stopDate;
+    delete connectorStatus?.stoppedDate;
+    return (
+      connectorStatus ?? {
+        start: false,
+        authorizeRequests: 0,
+        acceptedAuthorizeRequests: 0,
+        rejectedAuthorizeRequests: 0,
+        startTransactionRequests: 0,
+        acceptedStartTransactionRequests: 0,
+        rejectedStartTransactionRequests: 0,
+        stopTransactionRequests: 0,
+        acceptedStopTransactionRequests: 0,
+        rejectedStopTransactionRequests: 0,
+        skippedConsecutiveTransactions: 0,
+        skippedTransactions: 0,
+      }
+    );
+  }
+
   private async startTransaction(
     connectorId: number
   ): Promise<StartTransactionResponse | undefined> {
index 3312224278521fe7e98fc128b58c2ad5bc887fb6..df0bb8e98cda7c85b30104ba9ed9fac37fceb610 100644 (file)
@@ -1,5 +1,6 @@
 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
 
+import { EventEmitter } from 'node:events';
 import path from 'node:path';
 import { fileURLToPath } from 'node:url';
 import { type Worker, isMainThread } from 'node:worker_threads';
@@ -17,10 +18,18 @@ import {
   type ChargingStationWorkerMessage,
   type ChargingStationWorkerMessageData,
   ChargingStationWorkerMessageEvents,
+  ProcedureName,
   type StationTemplateUrl,
   type Statistics,
 } from '../types';
-import { Configuration, ErrorUtils, Utils, logger } from '../utils';
+import {
+  Configuration,
+  Constants,
+  Utils,
+  handleUncaughtException,
+  handleUnhandledRejection,
+  logger,
+} from '../utils';
 import { type MessageHandler, type WorkerAbstract, WorkerFactory } from '../worker';
 
 const moduleName = 'Bootstrap';
@@ -30,7 +39,7 @@ enum exitCodes {
   noChargingStationTemplates = 2,
 }
 
-export class Bootstrap {
+export class Bootstrap extends EventEmitter {
   private static instance: Bootstrap | null = null;
   public numberOfChargingStations!: number;
   public numberOfChargingStationTemplates!: number;
@@ -41,14 +50,22 @@ export class Bootstrap {
   private readonly version: string = packageJson.version;
   private initializedCounters: boolean;
   private started: boolean;
+  private starting: boolean;
+  private stopping: boolean;
   private readonly workerScript: string;
 
   private constructor() {
+    super();
+    for (const signal of ['SIGINT', 'SIGQUIT', 'SIGTERM']) {
+      process.on(signal, this.gracefulShutdown);
+    }
     // Enable unconditionally for now
-    ErrorUtils.handleUnhandledRejection();
-    ErrorUtils.handleUncaughtException();
-    this.initializedCounters = false;
+    handleUnhandledRejection();
+    handleUncaughtException();
     this.started = false;
+    this.starting = false;
+    this.stopping = false;
+    this.initializedCounters = false;
     this.initializeCounters();
     this.workerImplementation = null;
     this.workerScript = path.join(
@@ -74,63 +91,90 @@ export class Bootstrap {
   }
 
   public async start(): Promise<void> {
-    if (isMainThread && this.started === false) {
-      this.initializeCounters();
-      this.initializeWorkerImplementation();
-      await this.workerImplementation?.start();
-      await this.storage?.open();
-      this.uiServer?.start();
-      // Start ChargingStation object instance in worker thread
-      for (const stationTemplateUrl of Configuration.getStationTemplateUrls()) {
-        try {
-          const nbStations = stationTemplateUrl.numberOfStations ?? 0;
-          for (let index = 1; index <= nbStations; index++) {
-            await this.startChargingStation(index, stationTemplateUrl);
+    if (!isMainThread) {
+      throw new Error('Cannot start charging stations simulator from worker thread');
+    }
+    if (this.started === false) {
+      if (this.starting === false) {
+        this.starting = true;
+        this.initializeCounters();
+        this.initializeWorkerImplementation();
+        await this.workerImplementation?.start();
+        await this.storage?.open();
+        this.uiServer?.start();
+        // Start ChargingStation object instance in worker thread
+        for (const stationTemplateUrl of Configuration.getStationTemplateUrls()) {
+          try {
+            const nbStations = stationTemplateUrl.numberOfStations ?? 0;
+            for (let index = 1; index <= nbStations; index++) {
+              await this.startChargingStation(index, stationTemplateUrl);
+            }
+          } catch (error) {
+            console.error(
+              chalk.red(
+                `Error at starting charging station with template file ${stationTemplateUrl.file}: `
+              ),
+              error
+            );
           }
-        } catch (error) {
-          console.error(
-            chalk.red(
-              `Error at starting charging station with template file ${stationTemplateUrl.file}: `
-            ),
-            error
-          );
         }
+        console.info(
+          chalk.green(
+            `Charging stations simulator ${
+              this.version
+            } started with ${this.numberOfChargingStations.toString()} charging station(s) from ${this.numberOfChargingStationTemplates.toString()} configured charging station template(s) and ${
+              Configuration.workerDynamicPoolInUse()
+                ? `${Configuration.getWorker().poolMinSize?.toString()}/`
+                : ''
+            }${this.workerImplementation?.size}${
+              Configuration.workerPoolInUse()
+                ? `/${Configuration.getWorker().poolMaxSize?.toString()}`
+                : ''
+            } worker(s) concurrently running in '${Configuration.getWorker().processType}' mode${
+              !Utils.isNullOrUndefined(this.workerImplementation?.maxElementsPerWorker)
+                ? ` (${this.workerImplementation?.maxElementsPerWorker} charging station(s) per worker)`
+                : ''
+            }`
+          )
+        );
+        this.started = true;
+        this.starting = false;
+      } else {
+        console.error(chalk.red('Cannot start an already starting charging stations simulator'));
       }
-      console.info(
-        chalk.green(
-          `Charging stations simulator ${
-            this.version
-          } started with ${this.numberOfChargingStations.toString()} charging station(s) from ${this.numberOfChargingStationTemplates.toString()} configured charging station template(s) and ${
-            Configuration.workerDynamicPoolInUse()
-              ? `${Configuration.getWorker().poolMinSize?.toString()}/`
-              : ''
-          }${this.workerImplementation?.size}${
-            Configuration.workerPoolInUse()
-              ? `/${Configuration.getWorker().poolMaxSize?.toString()}`
-              : ''
-          } worker(s) concurrently running in '${Configuration.getWorker().processType}' mode${
-            !Utils.isNullOrUndefined(this.workerImplementation?.maxElementsPerWorker)
-              ? ` (${this.workerImplementation?.maxElementsPerWorker} charging station(s) per worker)`
-              : ''
-          }`
-        )
-      );
-      this.started = true;
     } else {
       console.error(chalk.red('Cannot start an already started charging stations simulator'));
     }
   }
 
   public async stop(): Promise<void> {
-    if (isMainThread && this.started === true) {
-      await this.workerImplementation?.stop();
-      this.workerImplementation = null;
-      this.uiServer?.stop();
-      await this.storage?.close();
-      this.initializedCounters = false;
-      this.started = false;
+    if (!isMainThread) {
+      throw new Error('Cannot stop charging stations simulator from worker thread');
+    }
+    if (this.started === true) {
+      if (this.stopping === false) {
+        this.stopping = true;
+        await this.uiServer?.sendInternalRequest(
+          this.uiServer.buildProtocolRequest(
+            Utils.generateUUID(),
+            ProcedureName.STOP_CHARGING_STATION,
+            Constants.EMPTY_FREEZED_OBJECT
+          )
+        );
+        await this.waitForChargingStationsStopped();
+        await this.workerImplementation?.stop();
+        this.workerImplementation = null;
+        this.uiServer?.stop();
+        await this.storage?.close();
+        this.resetCounters();
+        this.initializedCounters = false;
+        this.started = false;
+        this.stopping = false;
+      } else {
+        console.error(chalk.red('Cannot stop an already stopping charging stations simulator'));
+      }
     } else {
-      console.error(chalk.red('Cannot stop a not started charging stations simulator'));
+      console.error(chalk.red('Cannot stop an already stopped charging stations simulator'));
     }
   }
 
@@ -172,15 +216,22 @@ export class Bootstrap {
       switch (msg.id) {
         case ChargingStationWorkerMessageEvents.started:
           this.workerEventStarted(msg.data as ChargingStationData);
+          this.emit(ChargingStationWorkerMessageEvents.started, msg.data as ChargingStationData);
           break;
         case ChargingStationWorkerMessageEvents.stopped:
           this.workerEventStopped(msg.data as ChargingStationData);
+          this.emit(ChargingStationWorkerMessageEvents.stopped, msg.data as ChargingStationData);
           break;
         case ChargingStationWorkerMessageEvents.updated:
           this.workerEventUpdated(msg.data as ChargingStationData);
+          this.emit(ChargingStationWorkerMessageEvents.updated, msg.data as ChargingStationData);
           break;
         case ChargingStationWorkerMessageEvents.performanceStatistics:
           this.workerEventPerformanceStatistics(msg.data as Statistics);
+          this.emit(
+            ChargingStationWorkerMessageEvents.performanceStatistics,
+            msg.data as Statistics
+          );
           break;
         default:
           throw new BaseError(
@@ -231,8 +282,7 @@ export class Bootstrap {
 
   private initializeCounters() {
     if (this.initializedCounters === false) {
-      this.numberOfChargingStationTemplates = 0;
-      this.numberOfChargingStations = 0;
+      this.resetCounters();
       const stationTemplateUrls = Configuration.getStationTemplateUrls();
       if (Utils.isNotEmptyArray(stationTemplateUrls)) {
         this.numberOfChargingStationTemplates = stationTemplateUrls.length;
@@ -251,11 +301,16 @@ export class Bootstrap {
         );
         process.exit(exitCodes.noChargingStationTemplates);
       }
-      this.numberOfStartedChargingStations = 0;
       this.initializedCounters = true;
     }
   }
 
+  private resetCounters(): void {
+    this.numberOfChargingStationTemplates = 0;
+    this.numberOfChargingStations = 0;
+    this.numberOfStartedChargingStations = 0;
+  }
+
   private async startChargingStation(
     index: number,
     stationTemplateUrl: StationTemplateUrl
@@ -271,6 +326,35 @@ export class Bootstrap {
     });
   }
 
+  private gracefulShutdown = (): void => {
+    console.info(`${chalk.green('Graceful shutdown')}`);
+    this.stop()
+      .then(() => {
+        process.exit(0);
+      })
+      .catch((error) => {
+        console.error(chalk.red('Error while shutdowning charging stations simulator: '), error);
+        process.exit(1);
+      });
+  };
+
+  private waitForChargingStationsStopped = async (
+    stoppedEventsToWait = this.numberOfStartedChargingStations
+  ): Promise<number> => {
+    return new Promise((resolve) => {
+      let stoppedEvents = 0;
+      if (stoppedEventsToWait === 0) {
+        resolve(stoppedEvents);
+      }
+      this.on(ChargingStationWorkerMessageEvents.stopped, () => {
+        ++stoppedEvents;
+        if (stoppedEvents === stoppedEventsToWait) {
+          resolve(stoppedEvents);
+        }
+      });
+    });
+  };
+
   private logPrefix = (): string => {
     return Utils.logPrefix(' Bootstrap |');
   };
index 82ed3b8c0da8ad579e767e6695010352a66b1343..a3f6769607c5b01bb9774bf614a71f31a80a5afe 100644 (file)
@@ -72,6 +72,7 @@ import {
   ReservationTerminationReason,
   type Response,
   StandardParametersKey,
+  type Status,
   type StatusNotificationRequest,
   type StatusNotificationResponse,
   StopTransactionReason,
@@ -91,14 +92,16 @@ import {
   Configuration,
   Constants,
   DCElectricUtils,
-  ErrorUtils,
-  FileUtils,
-  MessageChannelUtils,
   Utils,
   buildChargingStationAutomaticTransactionGeneratorConfiguration,
   buildConnectorsStatus,
   buildEvsesStatus,
+  buildStartedMessage,
+  buildStoppedMessage,
+  buildUpdatedMessage,
+  handleFileException,
   logger,
+  watchJsonFile,
 } from '../utils';
 
 export class ChargingStation {
@@ -655,7 +658,7 @@ export class ChargingStation {
         }
         this.openWSConnection();
         // Monitor charging station template file
-        this.templateFileWatcher = FileUtils.watchJsonFile(
+        this.templateFileWatcher = watchJsonFile(
           this.templateFile,
           FileType.ChargingStationTemplate,
           this.logPrefix(),
@@ -692,7 +695,7 @@ export class ChargingStation {
           }
         );
         this.started = true;
-        parentPort?.postMessage(MessageChannelUtils.buildStartedMessage(this));
+        parentPort?.postMessage(buildStartedMessage(this));
         this.starting = false;
       } else {
         logger.warn(`${this.logPrefix()} Charging station is already starting...`);
@@ -717,7 +720,7 @@ export class ChargingStation {
         delete this.bootNotificationResponse;
         this.started = false;
         this.saveConfiguration();
-        parentPort?.postMessage(MessageChannelUtils.buildStoppedMessage(this));
+        parentPort?.postMessage(buildStoppedMessage(this));
         this.stopping = false;
       } else {
         logger.warn(`${this.logPrefix()} Charging station is already stopping...`);
@@ -758,7 +761,7 @@ export class ChargingStation {
       terminateOpened: false,
     }
   ): void {
-    options.handshakeTimeout = options?.handshakeTimeout ?? this.getConnectionTimeout() * 1000;
+    options = { handshakeTimeout: this.getConnectionTimeout() * 1000, ...options };
     params = { ...{ closeOpened: false, terminateOpened: false }, ...params };
     if (this.started === false && this.starting === false) {
       logger.warn(
@@ -836,7 +839,10 @@ export class ChargingStation {
       | undefined;
     const automaticTransactionGeneratorConfigurationFromFile =
       this.getConfigurationFromFile()?.automaticTransactionGenerator;
-    if (automaticTransactionGeneratorConfigurationFromFile) {
+    if (
+      this.getAutomaticTransactionGeneratorPersistentConfiguration() &&
+      automaticTransactionGeneratorConfigurationFromFile
+    ) {
       automaticTransactionGeneratorConfiguration =
         automaticTransactionGeneratorConfigurationFromFile;
     } else {
@@ -849,6 +855,10 @@ export class ChargingStation {
     };
   }
 
+  public getAutomaticTransactionGeneratorStatuses(): Status[] | undefined {
+    return this.getConfigurationFromFile()?.automaticTransactionGeneratorStatuses;
+  }
+
   public startAutomaticTransactionGenerator(connectorIds?: number[]): void {
     this.automaticTransactionGenerator = AutomaticTransactionGenerator.getInstance(this);
     if (Utils.isNotEmptyArray(connectorIds)) {
@@ -858,8 +868,8 @@ export class ChargingStation {
     } else {
       this.automaticTransactionGenerator?.start();
     }
-    this.saveChargingStationAutomaticTransactionGeneratorConfiguration();
-    parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
+    this.saveAutomaticTransactionGeneratorConfiguration();
+    parentPort?.postMessage(buildUpdatedMessage(this));
   }
 
   public stopAutomaticTransactionGenerator(connectorIds?: number[]): void {
@@ -870,8 +880,8 @@ export class ChargingStation {
     } else {
       this.automaticTransactionGenerator?.stop();
     }
-    this.saveChargingStationAutomaticTransactionGeneratorConfiguration();
-    parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
+    this.saveAutomaticTransactionGeneratorConfiguration();
+    parentPort?.postMessage(buildUpdatedMessage(this));
   }
 
   public async stopTransactionOnConnector(
@@ -1161,7 +1171,7 @@ export class ChargingStation {
         this.templateFileHash = template.templateHash;
       }
     } catch (error) {
-      ErrorUtils.handleFileException(
+      handleFileException(
         this.templateFile,
         FileType.ChargingStationTemplate,
         error as NodeJS.ErrnoException,
@@ -1280,6 +1290,10 @@ export class ChargingStation {
     return this.stationInfo?.stationInfoPersistentConfiguration ?? true;
   }
 
+  private getAutomaticTransactionGeneratorPersistentConfiguration(): boolean {
+    return this.stationInfo?.automaticTransactionGeneratorPersistentConfiguration ?? true;
+  }
+
   private handleUnsupportedVersion(version: OCPPVersion) {
     const errorMsg = `Unsupported protocol version '${version}' configured
       in template file ${this.templateFile}`;
@@ -1295,9 +1309,8 @@ export class ChargingStation {
       `${ChargingStationUtils.getHashId(this.index, stationTemplate)}.json`
     );
     const chargingStationConfiguration = this.getConfigurationFromFile();
-    const featureFlag = false;
     if (
-      featureFlag &&
+      chargingStationConfiguration?.stationInfo?.templateHash === stationTemplate?.templateHash &&
       (chargingStationConfiguration?.connectorsStatus || chargingStationConfiguration?.evsesStatus)
     ) {
       this.initializeConnectorsOrEvsesFromFile(chargingStationConfiguration);
@@ -1680,7 +1693,7 @@ export class ChargingStation {
     if (stationTemplate?.Evses) {
       const evsesConfigHash = crypto
         .createHash(Constants.DEFAULT_HASH_ALGORITHM)
-        .update(`${JSON.stringify(stationTemplate?.Evses)}`)
+        .update(JSON.stringify(stationTemplate?.Evses))
         .digest('hex');
       const evsesConfigChanged =
         this.evses?.size !== 0 && this.evsesConfigurationHash !== evsesConfigHash;
@@ -1741,7 +1754,7 @@ export class ChargingStation {
           this.configurationFileHash = configuration.configurationHash;
         }
       } catch (error) {
-        ErrorUtils.handleFileException(
+        handleFileException(
           this.configurationFile,
           FileType.ChargingStationConfiguration,
           error as NodeJS.ErrnoException,
@@ -1752,8 +1765,10 @@ export class ChargingStation {
     return configuration;
   }
 
-  private saveChargingStationAutomaticTransactionGeneratorConfiguration(): void {
-    this.saveConfiguration();
+  private saveAutomaticTransactionGeneratorConfiguration(): void {
+    if (this.getAutomaticTransactionGeneratorPersistentConfiguration()) {
+      this.saveConfiguration();
+    }
   }
 
   private saveConnectorsStatus() {
@@ -1774,24 +1789,44 @@ export class ChargingStation {
           Utils.cloneObject<ChargingStationConfiguration>(this.getConfigurationFromFile()) ?? {};
         if (this.getStationInfoPersistentConfiguration() && this.stationInfo) {
           configurationData.stationInfo = this.stationInfo;
+        } else {
+          delete configurationData.stationInfo;
         }
         if (this.getOcppPersistentConfiguration() && this.ocppConfiguration?.configurationKey) {
           configurationData.configurationKey = this.ocppConfiguration.configurationKey;
+        } else {
+          delete configurationData.configurationKey;
         }
         configurationData = merge<ChargingStationConfiguration>(
           configurationData,
           buildChargingStationAutomaticTransactionGeneratorConfiguration(this)
         );
+        if (
+          !this.getAutomaticTransactionGeneratorPersistentConfiguration() ||
+          !this.getAutomaticTransactionGeneratorConfiguration()
+        ) {
+          delete configurationData.automaticTransactionGenerator;
+        }
         if (this.connectors.size > 0) {
           configurationData.connectorsStatus = buildConnectorsStatus(this);
+        } else {
+          delete configurationData.connectorsStatus;
         }
         if (this.evses.size > 0) {
           configurationData.evsesStatus = buildEvsesStatus(this);
+        } else {
+          delete configurationData.evsesStatus;
         }
         delete configurationData.configurationHash;
         const configurationHash = crypto
           .createHash(Constants.DEFAULT_HASH_ALGORITHM)
-          .update(JSON.stringify(configurationData))
+          .update(
+            JSON.stringify({
+              stationInfo: configurationData.stationInfo,
+              configurationKey: configurationData.configurationKey,
+              automaticTransactionGenerator: configurationData.automaticTransactionGenerator,
+            } as ChargingStationConfiguration)
+          )
           .digest('hex');
         if (this.configurationFileHash !== configurationHash) {
           AsyncLock.acquire(AsyncLockType.configuration)
@@ -1808,7 +1843,7 @@ export class ChargingStation {
               this.configurationFileHash = configurationHash;
             })
             .catch((error) => {
-              ErrorUtils.handleFileException(
+              handleFileException(
                 this.configurationFile,
                 FileType.ChargingStationConfiguration,
                 error as NodeJS.ErrnoException,
@@ -1826,7 +1861,7 @@ export class ChargingStation {
           );
         }
       } catch (error) {
-        ErrorUtils.handleFileException(
+        handleFileException(
           this.configurationFile,
           FileType.ChargingStationConfiguration,
           error as NodeJS.ErrnoException,
@@ -1901,7 +1936,7 @@ export class ChargingStation {
       }
       this.wsConnectionRestarted = false;
       this.autoReconnectRetryCount = 0;
-      parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
+      parentPort?.postMessage(buildUpdatedMessage(this));
     } else {
       logger.warn(
         `${this.logPrefix()} Connection to OCPP server through ${this.wsConnectionUrl.toString()} failed`
@@ -1931,7 +1966,7 @@ export class ChargingStation {
         this.started === true && (await this.reconnect());
         break;
     }
-    parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
+    parentPort?.postMessage(buildUpdatedMessage(this));
   }
 
   private getCachedRequest(messageType: MessageType, messageId: string): CachedRequest | undefined {
@@ -2041,7 +2076,7 @@ export class ChargingStation {
             logger.error(`${this.logPrefix()} ${errorMsg}`);
             throw new OCPPError(ErrorType.PROTOCOL_ERROR, errorMsg);
         }
-        parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
+        parentPort?.postMessage(buildUpdatedMessage(this));
       } else {
         throw new OCPPError(ErrorType.PROTOCOL_ERROR, 'Incoming message is not an array', null, {
           request,
index 24ee468c0a5cc1244cd52890fc279d07fde70df7..741449e3b63e9b8126e4440c9c143116b61156b7 100644 (file)
@@ -1,6 +1,7 @@
 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
 
-import { parentPort, workerData } from 'node:worker_threads';
+import { AsyncResource } from 'node:async_hooks';
+import { parentPort } from 'node:worker_threads';
 
 import { ThreadWorker } from 'poolifier';
 
@@ -9,38 +10,40 @@ import type { ChargingStationWorkerData } from '../types';
 import { Configuration } from '../utils';
 import { WorkerConstants, type WorkerMessage, WorkerMessageEvents } from '../worker';
 
+const moduleName = 'ChargingStationWorker';
+
 /**
  * Create and start a charging station instance
  *
  * @param data - workerData
  */
 const startChargingStation = (data: ChargingStationWorkerData): void => {
-  const station = new ChargingStation(data.index, data.templateFile);
-  station.start();
+  new ChargingStation(data.index, data.templateFile).start();
 };
 
-/**
- * Listen messages send by the main thread
- */
-const addMessageListener = (): void => {
-  parentPort?.on('message', (message: WorkerMessage<ChargingStationWorkerData>) => {
-    if (message.id === WorkerMessageEvents.startWorkerElement) {
-      startChargingStation(message.data);
-    }
-  });
-};
+class ChargingStationWorker extends AsyncResource {
+  constructor() {
+    super(moduleName);
+    // Add message listener to create and start charging station from the main thread
+    parentPort?.on('message', (message: WorkerMessage<ChargingStationWorkerData>) => {
+      if (message.id === WorkerMessageEvents.startWorkerElement) {
+        this.runInAsyncScope(
+          startChargingStation.bind(this) as (data: ChargingStationWorkerData) => void,
+          this,
+          message.data
+        );
+      }
+    });
+  }
+}
 
+export let chargingStationWorker: ChargingStationWorker;
 // Conditionally export ThreadWorker instance for pool usage
 export let threadWorker: ThreadWorker;
 if (Configuration.workerPoolInUse()) {
   threadWorker = new ThreadWorker<ChargingStationWorkerData>(startChargingStation, {
     maxInactiveTime: WorkerConstants.POOL_MAX_INACTIVE_TIME,
-    async: false,
   });
 } else {
-  // Add message listener to start charging station from main thread
-  addMessageListener();
-  if (workerData !== undefined) {
-    startChargingStation(workerData as ChargingStationWorkerData);
-  }
+  chargingStationWorker = new ChargingStationWorker();
 }
index ff5c49d9a6a2dba2fc2810b0e6a36fa54fbbb125..890ac1fbf12892a04c7afcde3e27d04f09845154 100644 (file)
@@ -3,7 +3,7 @@ import fs from 'node:fs';
 import type { ChargingStation } from './ChargingStation';
 import { ChargingStationUtils } from './ChargingStationUtils';
 import { FileType, IdTagDistribution } from '../types';
-import { ErrorUtils, FileUtils, Utils, logger } from '../utils';
+import { Utils, handleFileException, logger, watchJsonFile } from '../utils';
 
 type IdTagsCacheValueType = {
   idTags: string[];
@@ -31,9 +31,9 @@ export class IdTagsCache {
    * Get one idtag from the cache given the distribution
    * Must be called after checking the cache is not an empty array
    *
-   * @param distribution
-   * @param chargingStation
-   * @param connectorId
+   * @param distribution -
+   * @param chargingStation -
+   * @param connectorId -
    * @returns
    */
   public getIdTag(
@@ -59,7 +59,7 @@ export class IdTagsCache {
    * Get all idtags from the cache
    * Must be called after checking the cache is not an empty array
    *
-   * @param file
+   * @param file -
    * @returns
    */
   public getIdTags(file: string): string[] | undefined {
@@ -116,7 +116,7 @@ export class IdTagsCache {
   private setIdTagsCache(file: string, idTags: string[]) {
     return this.idTagsCaches.set(file, {
       idTags,
-      idTagsFileWatcher: FileUtils.watchJsonFile(
+      idTagsFileWatcher: watchJsonFile(
         file,
         FileType.Authorization,
         this.logPrefix(file),
@@ -130,7 +130,7 @@ export class IdTagsCache {
               this.deleteIdTagsCache(file);
               this.deleteIdTagsCacheIndexes(file);
             } catch (error) {
-              ErrorUtils.handleFileException(
+              handleFileException(
                 file,
                 FileType.Authorization,
                 error as NodeJS.ErrnoException,
@@ -172,7 +172,7 @@ export class IdTagsCache {
       try {
         return JSON.parse(fs.readFileSync(file, 'utf8')) as string[];
       } catch (error) {
-        ErrorUtils.handleFileException(
+        handleFileException(
           file,
           FileType.Authorization,
           error as NodeJS.ErrnoException,
index bfbe1232756dae8a34d456b8a6f62e417a71286e..27045c89617c023da1b85d17ee6b8c4b9713e95f 100644 (file)
@@ -49,7 +49,6 @@ import {
   type OCPP16ClearCacheRequest,
   type OCPP16DataTransferRequest,
   type OCPP16DataTransferResponse,
-  OCPP16DataTransferStatus,
   OCPP16DataTransferVendorId,
   OCPP16DiagnosticsStatus,
   type OCPP16DiagnosticsStatusNotificationRequest,
@@ -1512,13 +1511,9 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService {
   ): OCPP16DataTransferResponse {
     try {
       if (Object.values(OCPP16DataTransferVendorId).includes(commandPayload.vendorId)) {
-        return {
-          status: OCPP16DataTransferStatus.ACCEPTED,
-        };
+        return OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_ACCEPTED;
       }
-      return {
-        status: OCPP16DataTransferStatus.UNKNOWN_VENDOR_ID,
-      };
+      return OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_UNKNOWN_VENDOR_ID;
     } catch (error) {
       return this.handleIncomingRequestError(
         chargingStation,
index 543e2eda6e84e0a98dc8862c25c36c3d92b2dd93..9e8a2d5f7636a33aba59c198a8a7e337cea8f0bf 100644 (file)
@@ -51,7 +51,7 @@ import {
   type SetChargingProfileResponse,
   type UnlockConnectorResponse,
 } from '../../../types';
-import { Constants, MessageChannelUtils, Utils, logger } from '../../../utils';
+import { Constants, Utils, buildUpdatedMessage, logger } from '../../../utils';
 import { OCPPResponseService } from '../OCPPResponseService';
 
 const moduleName = 'OCPP16ResponseService';
@@ -659,7 +659,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
   ): Promise<void> {
     ChargingStationUtils.resetConnectorStatus(chargingStation.getConnectorStatus(connectorId));
     chargingStation.stopMeterValues(connectorId);
-    parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(chargingStation));
+    parentPort?.postMessage(buildUpdatedMessage(chargingStation));
     if (
       chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.Available
     ) {
@@ -725,7 +725,7 @@ export class OCPP16ResponseService extends OCPPResponseService {
       chargingStation.getConnectorStatus(transactionConnectorId)
     );
     chargingStation.stopMeterValues(transactionConnectorId);
-    parentPort?.postMessage(MessageChannelUtils.buildUpdatedMessage(chargingStation));
+    parentPort?.postMessage(buildUpdatedMessage(chargingStation));
     const logMsg = `${chargingStation.logPrefix()} Transaction with id ${requestPayload.transactionId.toString()} STOPPED on ${
       chargingStation.stationInfo.chargingStationId
     }#${transactionConnectorId?.toString()} with status '${
index 2d2a34a0a22a25afc95c8e2fd8fb7b5f6e46a3d2..b3f4dd3208315681d616f10cacfafa8bfb29ea77 100644 (file)
@@ -98,9 +98,17 @@ export class OCPPConstants {
     status: TriggerMessageStatus.NOT_IMPLEMENTED,
   });
 
+  static readonly OCPP_DATA_TRANSFER_RESPONSE_ACCEPTED = Object.freeze({
+    status: DataTransferStatus.ACCEPTED,
+  });
+
   static readonly OCPP_DATA_TRANSFER_RESPONSE_REJECTED = Object.freeze({
     status: DataTransferStatus.REJECTED,
   });
+  
+  static readonly OCPP_DATA_TRANSFER_RESPONSE_UNKNOWN_VENDOR_ID = Object.freeze({
+    status: DataTransferStatus.UNKNOWN_VENDOR_ID,
+  });
 
   static readonly OCPP_RESERVATION_RESPONSE_ACCEPTED = Object.freeze({
     status: ReservationStatus.ACCEPTED,
index 1206cede00d0493df941f54e73dc03cffedfc28c..2a304c31f118e138ab716150cc893d7ea0db9161 100644 (file)
@@ -15,7 +15,7 @@ import type {
   JsonType,
   OCPPVersion,
 } from '../../types';
-import { ErrorUtils, logger } from '../../utils';
+import { logger, setDefaultErrorParams } from '../../utils';
 
 const moduleName = 'OCPPIncomingRequestService';
 
@@ -62,7 +62,7 @@ export abstract class OCPPIncomingRequestService extends AsyncResource {
     error: Error,
     params: HandleErrorParams<T> = { throwError: true, consoleOut: false }
   ): T | undefined {
-    ErrorUtils.handleErrorParams(params);
+    setDefaultErrorParams(params);
     logger.error(
       `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`,
       error
index d2122a65ad2f281c7a9de9cd6b9afcbbeeb87a9d..a3b78ca63ec8e40d44a07c7a12f9689ed38eee63 100644 (file)
@@ -23,10 +23,16 @@ import {
   type ResponseCallback,
   type ResponseType,
 } from '../../types';
-import { Constants, ErrorUtils, Utils, logger } from '../../utils';
+import { Constants, Utils, handleSendMessageError, logger } from '../../utils';
 
 const moduleName = 'OCPPRequestService';
 
+const defaultRequestParams: RequestParams = {
+  skipBufferingOnError: false,
+  triggerMessage: false,
+  throwError: false,
+};
+
 export abstract class OCPPRequestService {
   private static instance: OCPPRequestService | null = null;
   private readonly version: OCPPVersion;
@@ -127,7 +133,7 @@ export abstract class OCPPRequestService {
         commandName
       );
     } catch (error) {
-      ErrorUtils.handleSendMessageError(chargingStation, commandName, error as Error, {
+      handleSendMessageError(chargingStation, commandName, error as Error, {
         throwError: true,
       });
     }
@@ -149,7 +155,7 @@ export abstract class OCPPRequestService {
         commandName
       );
     } catch (error) {
-      ErrorUtils.handleSendMessageError(chargingStation, commandName, error as Error);
+      handleSendMessageError(chargingStation, commandName, error as Error);
     }
   }
 
@@ -158,14 +164,10 @@ export abstract class OCPPRequestService {
     messageId: string,
     messagePayload: JsonType,
     commandName: RequestCommand,
-    params: RequestParams = {
-      skipBufferingOnError: false,
-      triggerMessage: false,
-      throwError: false,
-    }
+    params: RequestParams = defaultRequestParams
   ): Promise<ResponseType> {
     params = {
-      ...{ skipBufferingOnError: false, triggerMessage: false, throwError: false },
+      ...defaultRequestParams,
       ...params,
     };
     try {
@@ -178,7 +180,7 @@ export abstract class OCPPRequestService {
         params
       );
     } catch (error) {
-      ErrorUtils.handleSendMessageError(chargingStation, commandName, error as Error, {
+      handleSendMessageError(chargingStation, commandName, error as Error, {
         throwError: params.throwError,
       });
     }
@@ -264,14 +266,10 @@ export abstract class OCPPRequestService {
     messagePayload: JsonType | OCPPError,
     messageType: MessageType,
     commandName: RequestCommand | IncomingRequestCommand,
-    params: RequestParams = {
-      skipBufferingOnError: false,
-      triggerMessage: false,
-      throwError: false,
-    }
+    params: RequestParams = defaultRequestParams
   ): Promise<ResponseType> {
     params = {
-      ...{ skipBufferingOnError: false, triggerMessage: false, throwError: false },
+      ...defaultRequestParams,
       ...params,
     };
     if (
index c5387f33f9c693f41ff21f1b20d9f40d7c5cd514..078fa0a09551ca56e9e8d66bb94aad9cb2dab92c 100644 (file)
@@ -30,7 +30,7 @@ import {
   type StatusNotificationRequest,
   type StatusNotificationResponse,
 } from '../../types';
-import { Constants, ErrorUtils, Utils, logger } from '../../utils';
+import { Utils, handleFileException, logger } from '../../utils';
 
 export class OCPPServiceUtils {
   protected constructor() {
@@ -264,7 +264,7 @@ export class OCPPServiceUtils {
     try {
       return JSON.parse(fs.readFileSync(filePath, 'utf8')) as JSONSchemaType<T>;
     } catch (error) {
-      ErrorUtils.handleFileException(
+      handleFileException(
         filePath,
         FileType.JsonSchema,
         error as NodeJS.ErrnoException,
@@ -363,8 +363,13 @@ export class OCPPServiceUtils {
       unitMultiplier: 1,
     }
   ): number {
-    options.limitationEnabled = options?.limitationEnabled ?? true;
-    options.unitMultiplier = options?.unitMultiplier ?? 1;
+    options = {
+      ...{
+        limitationEnabled: true,
+        unitMultiplier: 1,
+      },
+      ...options,
+    };
     const parsedInt = parseInt(value);
     const numberValue = isNaN(parsedInt) ? Infinity : parsedInt;
     return options?.limitationEnabled
index 643b18831f2010c525844ccd5085f1a1a3a20ca8..e689441633b47e0c7a6b52cd4c90fb1de58221be 100644 (file)
@@ -11,7 +11,7 @@ import {
   type ProcedureName,
   type ProtocolRequest,
   type ProtocolResponse,
-  type ProtocolVersion,
+  ProtocolVersion,
   type RequestPayload,
   type ResponsePayload,
   type UIServerConfiguration,
@@ -46,6 +46,16 @@ export abstract class AbstractUIServer {
     this.chargingStations.clear();
   }
 
+  public async sendInternalRequest(request: ProtocolRequest): Promise<ProtocolResponse> {
+    const protocolVersion = ProtocolVersion['0.0.1'];
+    this.registerProtocolVersionUIService(protocolVersion);
+    return this.uiServices.get(protocolVersion)?.requestHandler(request);
+  }
+
+  public hasResponseHandler(id: string): boolean {
+    return this.responseHandlers.has(id);
+  }
+
   protected startHttpServer(): void {
     if (this.httpServer.listening === false) {
       this.httpServer.listen(this.uiServerConfiguration.options);
index b99ef36a80cf9ec223db9f1a77a0b32d1e095af6..159559df1f4cacb6eebaa1f67b8e6cca66ac030a 100644 (file)
@@ -44,7 +44,7 @@ export class UIHttpServer extends AbstractUIServer {
   public sendResponse(response: ProtocolResponse): void {
     const [uuid, payload] = response;
     try {
-      if (this.responseHandlers.has(uuid) === true) {
+      if (this.hasResponseHandler(uuid) === true) {
         const res = this.responseHandlers.get(uuid) as ServerResponse;
         res
           .writeHead(this.responseStatusToStatusCode(payload.status), {
@@ -125,6 +125,11 @@ export class UIHttpServer extends AbstractUIServer {
                   body ?? Constants.EMPTY_FREEZED_OBJECT
                 )
               )
+              .then((protocolResponse: ProtocolResponse) => {
+                if (!Utils.isNullOrUndefined(protocolResponse)) {
+                  this.sendResponse(protocolResponse);
+                }
+              })
               .catch(Constants.EMPTY_FUNCTION);
           });
       } else {
index cc00db13f233af42975062331f054992135ce510..dd5b6163576dc86b7bb22bb93c9cdb7223e31e91 100644 (file)
@@ -49,7 +49,15 @@ export class UIWebSocketServer extends AbstractUIServer {
         }
         const [requestId] = request as ProtocolRequest;
         this.responseHandlers.set(requestId, ws);
-        this.uiServices.get(version)?.requestHandler(request).catch(Constants.EMPTY_FUNCTION);
+        this.uiServices
+          .get(version)
+          ?.requestHandler(request)
+          .then((protocolResponse: ProtocolResponse) => {
+            if (!Utils.isNullOrUndefined(protocolResponse)) {
+              this.sendResponse(protocolResponse);
+            }
+          })
+          .catch(Constants.EMPTY_FUNCTION);
       });
       ws.on('error', (error) => {
         logger.error(`${this.logPrefix(moduleName, 'start.ws.onerror')} WebSocket error:`, error);
@@ -104,7 +112,7 @@ export class UIWebSocketServer extends AbstractUIServer {
   public sendResponse(response: ProtocolResponse): void {
     const responseId = response[0];
     try {
-      if (this.responseHandlers.has(responseId)) {
+      if (this.hasResponseHandler(responseId)) {
         const ws = this.responseHandlers.get(responseId) as WebSocket;
         if (ws?.readyState === WebSocket.OPEN) {
           ws.send(JSON.stringify(response));
index 71b057abe4a2f7369c1376d97ffcc55046eb0e89..1ec6cf93b20e77363f08ecbb79cb9c10ed9cf656 100644 (file)
@@ -5,6 +5,7 @@ import {
   ProcedureName,
   type ProtocolRequest,
   type ProtocolRequestHandler,
+  type ProtocolResponse,
   type ProtocolVersion,
   type RequestPayload,
   type ResponsePayload,
@@ -65,11 +66,11 @@ export abstract class AbstractUIService {
     this.broadcastChannelRequests = new Map<string, number>();
   }
 
-  public async requestHandler(request: ProtocolRequest): Promise<void> {
+  public async requestHandler(request: ProtocolRequest): Promise<ProtocolResponse | undefined> {
     let messageId: string;
     let command: ProcedureName;
     let requestPayload: RequestPayload | undefined;
-    let responsePayload: ResponsePayload;
+    let responsePayload: ResponsePayload | undefined;
     try {
       [messageId, command, requestPayload] = request;
 
@@ -87,7 +88,7 @@ export abstract class AbstractUIService {
       responsePayload = await this.requestHandlers.get(command)(messageId, command, requestPayload);
     } catch (error) {
       // Log
-      logger.error(`${this.logPrefix(moduleName, 'messageHandler')} Handle request error:`, error);
+      logger.error(`${this.logPrefix(moduleName, 'requestHandler')} Handle request error:`, error);
       responsePayload = {
         hashIds: requestPayload?.hashIds,
         status: ResponseStatus.FAILURE,
@@ -98,26 +99,26 @@ export abstract class AbstractUIService {
         errorStack: (error as Error).stack,
         errorDetails: (error as OCPPError).details,
       };
-    } finally {
-      // Send response for payload not forwarded to broadcast channel
-      if (!Utils.isNullOrUndefined(responsePayload)) {
-        this.sendResponse(messageId, responsePayload);
-      }
+    }
+    if (!Utils.isNullOrUndefined(responsePayload)) {
+      return this.uiServer.buildProtocolResponse(messageId, responsePayload);
     }
   }
 
-  public sendRequest(
-    messageId: string,
-    procedureName: ProcedureName,
-    requestPayload: RequestPayload
-  ): void {
-    this.uiServer.sendRequest(
-      this.uiServer.buildProtocolRequest(messageId, procedureName, requestPayload)
-    );
-  }
+  // public sendRequest(
+  //   messageId: string,
+  //   procedureName: ProcedureName,
+  //   requestPayload: RequestPayload
+  // ): void {
+  //   this.uiServer.sendRequest(
+  //     this.uiServer.buildProtocolRequest(messageId, procedureName, requestPayload)
+  //   );
+  // }
 
   public sendResponse(messageId: string, responsePayload: ResponsePayload): void {
-    this.uiServer.sendResponse(this.uiServer.buildProtocolResponse(messageId, responsePayload));
+    if (this.uiServer.hasResponseHandler(messageId)) {
+      this.uiServer.sendResponse(this.uiServer.buildProtocolResponse(messageId, responsePayload));
+    }
   }
 
   public logPrefix = (modName: string, methodName: string): string => {
index 61ef1b012946319ac1080fac1d9ca89b672fefd9..565ef6e7a2e4126a6fcc7e7e8e6c7c6f0f6cef8a 100644 (file)
@@ -15,9 +15,12 @@ import {
   CircularArray,
   Configuration,
   Constants,
-  MessageChannelUtils,
   Utils,
+  buildPerformanceStatisticsMessage,
   logger,
+  median,
+  nthPercentile,
+  stdDeviation,
 } from '../utils';
 
 export class PerformanceStatistics {
@@ -231,27 +234,25 @@ export class PerformanceStatistics {
             timestamp: entry.startTime,
             value: entry.duration,
           }));
-    this.statistics.statisticsData.get(entryName).medTimeMeasurement = Utils.median(
+    this.statistics.statisticsData.get(entryName).medTimeMeasurement = median(
       this.extractTimeSeriesValues(
         this.statistics.statisticsData.get(entryName).timeMeasurementSeries
       )
     );
     this.statistics.statisticsData.get(entryName).ninetyFiveThPercentileTimeMeasurement =
-      Utils.percentile(
+      nthPercentile(
         this.extractTimeSeriesValues(
           this.statistics.statisticsData.get(entryName).timeMeasurementSeries
         ),
         95
       );
-    this.statistics.statisticsData.get(entryName).stdDevTimeMeasurement = Utils.stdDeviation(
+    this.statistics.statisticsData.get(entryName).stdDevTimeMeasurement = stdDeviation(
       this.extractTimeSeriesValues(
         this.statistics.statisticsData.get(entryName).timeMeasurementSeries
       )
     );
     if (Configuration.getPerformanceStorage().enabled) {
-      parentPort?.postMessage(
-        MessageChannelUtils.buildPerformanceStatisticsMessage(this.statistics)
-      );
+      parentPort?.postMessage(buildPerformanceStatisticsMessage(this.statistics));
     }
   }
 
index 2a712a6008f61722ef21dddaac5acd2e3ba14d53..0fd29d0214f4ec6a138281f1e84d61011591ae03 100644 (file)
@@ -6,7 +6,7 @@ import path from 'node:path';
 import { Storage } from './Storage';
 import { BaseError } from '../../exception';
 import { FileType, type Statistics } from '../../types';
-import { AsyncLock, AsyncLockType, Constants, ErrorUtils, Utils } from '../../utils';
+import { AsyncLock, AsyncLockType, Constants, Utils, handleFileException } from '../../utils';
 
 export class JsonFileStorage extends Storage {
   private fd: number | null = null;
@@ -32,7 +32,7 @@ export class JsonFileStorage extends Storage {
         );
       })
       .catch((error) => {
-        ErrorUtils.handleFileException(
+        handleFileException(
           this.dbName,
           FileType.PerformanceRecords,
           error as NodeJS.ErrnoException,
@@ -53,7 +53,7 @@ export class JsonFileStorage extends Storage {
         this.fd = fs.openSync(this.dbName, 'a+');
       }
     } catch (error) {
-      ErrorUtils.handleFileException(
+      handleFileException(
         this.dbName,
         FileType.PerformanceRecords,
         error as NodeJS.ErrnoException,
@@ -69,7 +69,7 @@ export class JsonFileStorage extends Storage {
         this.fd = null;
       }
     } catch (error) {
-      ErrorUtils.handleFileException(
+      handleFileException(
         this.dbName,
         FileType.PerformanceRecords,
         error as NodeJS.ErrnoException,
index 9df2ebca63b5ae35ce3968959c2f6f23e0b5ede5..1360dabbad61aa2ec0feb3bde2fddfdd5d8b6d06 100644 (file)
@@ -9,7 +9,7 @@ import {
   type Statistics,
   StorageType,
 } from '../../types';
-import { ErrorUtils, Utils, logger } from '../../utils';
+import { Utils, logger, setDefaultErrorParams } from '../../utils';
 
 export abstract class Storage {
   protected readonly storageUri: URL;
@@ -27,7 +27,7 @@ export abstract class Storage {
     table?: string,
     params: HandleErrorParams<EmptyObject> = { throwError: false, consoleOut: false }
   ): void {
-    ErrorUtils.handleErrorParams(params, { throwError: false, consoleOut: false });
+    setDefaultErrorParams(params, { throwError: false, consoleOut: false });
     const inTableOrCollectionStr =
       (!Utils.isNullOrUndefined(table) || !table) && ` in table or collection '${table}'`;
     logger.error(
index fff8a1ad69e6805034807c9df1052bf4b560cf43..2f9a07fc9c13ac5637af0a73caae1b7ddb4c6e19 100644 (file)
@@ -1,15 +1,6 @@
 import type { ChargingStationTemplate } from './ChargingStationTemplate';
 import type { FirmwareStatus } from './ocpp/Requests';
 
-enum x509CertificateType {
-  V2GRootCertificate = 'V2GRootCertificate',
-  MORootCertificate = 'MORootCertificate',
-  CSMSRootCertificate = 'CSMSRootCertificate',
-  ManufacturerRootCertificate = 'ManufacturerRootCertificate',
-  ChargingStationCertificate = 'ChargingStationCertificate',
-  V2GCertificate = 'V2GCertificate',
-}
-
 export type ChargingStationInfo = Omit<
   ChargingStationTemplate,
   | 'AutomaticTransactionGenerator'
@@ -32,7 +23,6 @@ export type ChargingStationInfo = Omit<
   maximumPower?: number; // Always in Watt
   maximumAmperage?: number; // Always in Ampere
   firmwareStatus?: FirmwareStatus;
-  x509Certificates?: Record<x509CertificateType, string>;
 };
 
 export type ChargingStationInfoConfiguration = {
index e3594d02200701ce1502659300e265a8d07278fc..10f9733fbe2f595a684c5a460babb29be13c7ae5 100644 (file)
@@ -55,6 +55,15 @@ type CommandsSupport = {
   outgoingCommands?: Record<RequestCommand, boolean>;
 };
 
+enum x509CertificateType {
+  V2GRootCertificate = 'V2GRootCertificate',
+  MORootCertificate = 'MORootCertificate',
+  CSMSRootCertificate = 'CSMSRootCertificate',
+  ManufacturerRootCertificate = 'ManufacturerRootCertificate',
+  ChargingStationCertificate = 'ChargingStationCertificate',
+  V2GCertificate = 'V2GCertificate',
+}
+
 export type ChargingStationTemplate = {
   templateHash?: string;
   supervisionUrls?: string | string[];
@@ -67,6 +76,7 @@ export type ChargingStationTemplate = {
   ocppStrictCompliance?: boolean;
   ocppPersistentConfiguration?: boolean;
   stationInfoPersistentConfiguration?: boolean;
+  automaticTransactionGeneratorPersistentConfiguration?: boolean;
   wsOptions?: WsOptions;
   idTagsFile?: string;
   baseName: string;
@@ -115,4 +125,5 @@ export type ChargingStationTemplate = {
   AutomaticTransactionGenerator?: AutomaticTransactionGeneratorConfiguration;
   Evses?: Record<string, EvseTemplate>;
   Connectors?: Record<string, ConnectorStatus>;
+  x509Certificates?: Record<x509CertificateType, string>;
 };
index 276feabd0d8701191008289ac135bd9dc4658665..a23940cf330295cb609f28b7a3439ee05e26f6f6 100644 (file)
@@ -70,6 +70,8 @@ export type ConfigurationData = {
   /** @deprecated Moved to worker configuration section. */
   chargingStationsPerWorker?: number;
   logStatisticsInterval?: number;
+  logEnabled?: boolean;
+  logConsole?: boolean;
   logFormat?: string;
   logLevel?: string;
   logRotate?: boolean;
@@ -77,5 +79,4 @@ export type ConfigurationData = {
   logMaxSize?: number | string;
   logFile?: string;
   logErrorFile?: string;
-  logConsole?: boolean;
 };
index 229086fef1e8d2b45b9ae8f39ca77b867af0e2d5..16ad4f2b1cdcf53b44a90f6b6970858cff789e28 100644 (file)
@@ -1,38 +1,42 @@
 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
 
+import Queue from 'mnemonist/queue.js';
+
 export enum AsyncLockType {
   configuration = 'configuration',
   performance = 'performance',
 }
 
+type ResolveType = (value: void | PromiseLike<void>) => void;
+
 export class AsyncLock {
   private static readonly asyncLocks = new Map<AsyncLockType, AsyncLock>();
   private acquired: boolean;
-  private readonly resolveQueue: ((value: void | PromiseLike<void>) => void)[];
+  private readonly resolveQueue: Queue<ResolveType>;
 
   private constructor() {
     this.acquired = false;
-    this.resolveQueue = [];
+    this.resolveQueue = new Queue<ResolveType>();
   }
 
   public static async acquire(type: AsyncLockType): Promise<void> {
     const asyncLock = AsyncLock.getAsyncLock(type);
     if (!asyncLock.acquired) {
       asyncLock.acquired = true;
-    } else {
-      return new Promise((resolve) => {
-        asyncLock.resolveQueue.push(resolve);
-      });
+      return;
     }
+    return new Promise((resolve) => {
+      asyncLock.resolveQueue.enqueue(resolve);
+    });
   }
 
   public static async release(type: AsyncLockType): Promise<void> {
     const asyncLock = AsyncLock.getAsyncLock(type);
-    if (asyncLock.resolveQueue.length === 0 && asyncLock.acquired) {
+    if (asyncLock.resolveQueue.size === 0 && asyncLock.acquired) {
       asyncLock.acquired = false;
       return;
     }
-    const queuedResolve = asyncLock.resolveQueue.shift();
+    const queuedResolve = asyncLock.resolveQueue.dequeue();
     return new Promise((resolve) => {
       queuedResolve();
       resolve();
index 6f53ef3bd92e796d7f9be4fd049df4b88f8be6d9..b67afd447ae0f2ebc7a6f80f53bdfa5f57dfdf8f 100644 (file)
@@ -234,6 +234,12 @@ export class Configuration {
     return Configuration.getWorker().processType === WorkerProcessType.dynamicPool;
   }
 
+  public static getLogEnabled(): boolean | undefined {
+    return Utils.hasOwnProp(Configuration.getConfig(), 'logEnabled')
+      ? Configuration.getConfig()?.logEnabled
+      : true;
+  }
+
   public static getLogConsole(): boolean | undefined {
     Configuration.warnDeprecatedConfigurationKey(
       'consoleLog',
index 254bd9ecf4a821da81b0be440bbba16011b18511..b4f52ba894a9e57891a04954bbe066b6b1d40ad8 100644 (file)
@@ -12,84 +12,84 @@ import type {
   RequestCommand,
 } from '../types';
 
-export class ErrorUtils {
-  private constructor() {
-    // This is intentional
-  }
+const defaultErrorParams = {
+  throwError: true,
+  consoleOut: false,
+};
 
-  public static handleUncaughtException(): void {
-    process.on('uncaughtException', (error: Error) => {
-      console.error(chalk.red('Uncaught exception: '), error);
-    });
-  }
+export const handleUncaughtException = (): void => {
+  process.on('uncaughtException', (error: Error) => {
+    console.error(chalk.red('Uncaught exception: '), error);
+  });
+};
 
-  public static handleUnhandledRejection(): void {
-    process.on('unhandledRejection', (reason: unknown) => {
-      console.error(chalk.red('Unhandled rejection: '), reason);
-    });
-  }
+export const handleUnhandledRejection = (): void => {
+  process.on('unhandledRejection', (reason: unknown) => {
+    console.error(chalk.red('Unhandled rejection: '), reason);
+  });
+};
 
-  public static handleFileException(
-    file: string,
-    fileType: FileType,
-    error: NodeJS.ErrnoException,
-    logPrefix: string,
-    params: HandleErrorParams<EmptyObject> = { throwError: true, consoleOut: false }
-  ): void {
-    ErrorUtils.handleErrorParams(params);
-    const prefix = Utils.isNotEmptyString(logPrefix) ? `${logPrefix} ` : '';
-    let logMsg: string;
-    switch (error.code) {
-      case 'ENOENT':
-        logMsg = `${fileType} file ${file} not found:`;
-        break;
-      case 'EEXIST':
-        logMsg = `${fileType} file ${file} already exists:`;
-        break;
-      case 'EACCES':
-        logMsg = `${fileType} file ${file} access denied:`;
-        break;
-      case 'EPERM':
-        logMsg = `${fileType} file ${file} permission denied:`;
-        break;
-      default:
-        logMsg = `${fileType} file ${file} error:`;
-    }
-    if (params?.consoleOut === true) {
-      if (params?.throwError) {
-        console.error(`${chalk.green(prefix)}${chalk.red(`${logMsg} `)}`, error);
-      } else {
-        console.warn(`${chalk.green(prefix)}${chalk.yellow(`${logMsg} `)}`, error);
-      }
-    } else if (params?.consoleOut === false) {
-      if (params?.throwError) {
-        logger.error(`${prefix}${logMsg}`, error);
-      } else {
-        logger.warn(`${prefix}${logMsg}`, error);
-      }
+export const handleFileException = (
+  file: string,
+  fileType: FileType,
+  error: NodeJS.ErrnoException,
+  logPrefix: string,
+  params: HandleErrorParams<EmptyObject> = defaultErrorParams
+): void => {
+  setDefaultErrorParams(params);
+  const prefix = Utils.isNotEmptyString(logPrefix) ? `${logPrefix} ` : '';
+  let logMsg: string;
+  switch (error.code) {
+    case 'ENOENT':
+      logMsg = `${fileType} file ${file} not found:`;
+      break;
+    case 'EEXIST':
+      logMsg = `${fileType} file ${file} already exists:`;
+      break;
+    case 'EACCES':
+      logMsg = `${fileType} file ${file} access denied:`;
+      break;
+    case 'EPERM':
+      logMsg = `${fileType} file ${file} permission denied:`;
+      break;
+    default:
+      logMsg = `${fileType} file ${file} error:`;
+  }
+  if (params?.consoleOut === true) {
+    if (params?.throwError) {
+      console.error(`${chalk.green(prefix)}${chalk.red(`${logMsg} `)}`, error);
+    } else {
+      console.warn(`${chalk.green(prefix)}${chalk.yellow(`${logMsg} `)}`, error);
     }
+  } else if (params?.consoleOut === false) {
     if (params?.throwError) {
-      throw error;
+      logger.error(`${prefix}${logMsg}`, error);
+    } else {
+      logger.warn(`${prefix}${logMsg}`, error);
     }
   }
-
-  public static handleSendMessageError(
-    chargingStation: ChargingStation,
-    commandName: RequestCommand | IncomingRequestCommand,
-    error: Error,
-    params: HandleErrorParams<EmptyObject> = { throwError: false, consoleOut: false }
-  ): void {
-    ErrorUtils.handleErrorParams(params, { throwError: false, consoleOut: false });
-    logger.error(`${chargingStation.logPrefix()} Request command '${commandName}' error:`, error);
-    if (params?.throwError === true) {
-      throw error;
-    }
+  if (params?.throwError) {
+    throw error;
   }
+};
 
-  public static handleErrorParams<T extends JsonType>(
-    params: HandleErrorParams<T>,
-    defaultParams: HandleErrorParams<T> = { throwError: true, consoleOut: false }
-  ): HandleErrorParams<T> {
-    return { ...defaultParams, ...params };
+export const handleSendMessageError = (
+  chargingStation: ChargingStation,
+  commandName: RequestCommand | IncomingRequestCommand,
+  error: Error,
+  params: HandleErrorParams<EmptyObject> = { throwError: false, consoleOut: false }
+): void => {
+  setDefaultErrorParams(params, { throwError: false, consoleOut: false });
+  logger.error(`${chargingStation.logPrefix()} Request command '${commandName}' error:`, error);
+  if (params?.throwError === true) {
+    throw error;
   }
-}
+};
+
+export const setDefaultErrorParams = <T extends JsonType>(
+  params: HandleErrorParams<T>,
+  defaultParams: HandleErrorParams<T> = defaultErrorParams
+): HandleErrorParams<T> => {
+  params = { ...defaultParams, ...params };
+  return params;
+};
index 4e556a4bc1c3d642c8c9edecbb92049d5e880044..51871884ccc38e7c7b6d09c7d6cd37c1a6ad3192 100644 (file)
@@ -1,49 +1,37 @@
 import fs from 'node:fs';
 
-import { ErrorUtils } from './ErrorUtils';
+import { handleFileException } from './ErrorUtils';
 import { logger } from './Logger';
 import { Utils } from './Utils';
 import type { FileType, JsonType } from '../types';
 
-export class FileUtils {
-  private constructor() {
-    // This is intentional
-  }
-
-  public static watchJsonFile<T extends JsonType>(
-    file: string,
-    fileType: FileType,
-    logPrefix: string,
-    refreshedVariable?: T,
-    listener: fs.WatchListener<string> = (event, filename) => {
-      if (Utils.isNotEmptyString(filename) && event === 'change') {
-        try {
-          logger.debug(`${logPrefix} ${fileType} file ${file} have changed, reload`);
-          refreshedVariable && (refreshedVariable = JSON.parse(fs.readFileSync(file, 'utf8')) as T);
-        } catch (error) {
-          ErrorUtils.handleFileException(
-            file,
-            fileType,
-            error as NodeJS.ErrnoException,
-            logPrefix,
-            {
-              throwError: false,
-            }
-          );
-        }
-      }
-    }
-  ): fs.FSWatcher | undefined {
-    if (Utils.isNotEmptyString(file)) {
+export const watchJsonFile = <T extends JsonType>(
+  file: string,
+  fileType: FileType,
+  logPrefix: string,
+  refreshedVariable?: T,
+  listener: fs.WatchListener<string> = (event, filename) => {
+    if (Utils.isNotEmptyString(filename) && event === 'change') {
       try {
-        return fs.watch(file, listener);
+        logger.debug(`${logPrefix} ${fileType} file ${file} have changed, reload`);
+        refreshedVariable && (refreshedVariable = JSON.parse(fs.readFileSync(file, 'utf8')) as T);
       } catch (error) {
-        ErrorUtils.handleFileException(file, fileType, error as NodeJS.ErrnoException, logPrefix, {
+        handleFileException(file, fileType, error as NodeJS.ErrnoException, logPrefix, {
           throwError: false,
         });
       }
-    } else {
-      logger.info(`${logPrefix} No ${fileType} file to watch given. Not monitoring its changes`);
     }
   }
-}
+): fs.FSWatcher | undefined => {
+  if (Utils.isNotEmptyString(file)) {
+    try {
+      return fs.watch(file, listener);
+    } catch (error) {
+      handleFileException(file, fileType, error as NodeJS.ErrnoException, logPrefix, {
+        throwError: false,
+      });
+    }
+  } else {
+    logger.info(`${logPrefix} No ${fileType} file to watch given. Not monitoring its changes`);
+  }
+};
index 9bb195a3c65db0841776cb0c5bd38308f94e3443..637beb5bd533bffe6f0fb91cc8124bef730ce381 100644 (file)
@@ -1,5 +1,5 @@
 import type { FormatWrap } from 'logform';
-import { type Logger, createLogger, format, type transport } from 'winston';
+import { createLogger, format, type transport } from 'winston';
 import TransportType from 'winston/lib/winston/transports/index.js';
 import DailyRotateFile from 'winston-daily-rotate-file';
 
@@ -38,7 +38,8 @@ if (Configuration.getLogRotate() === true) {
   ];
 }
 
-const logger: Logger = createLogger({
+export const logger = createLogger({
+  silent: !Configuration.getLogEnabled(),
   level: Configuration.getLogLevel(),
   format: format.combine(format.splat(), (format[Configuration.getLogFormat()] as FormatWrap)()),
   transports,
@@ -58,5 +59,3 @@ if (Configuration.getLogConsole()) {
     })
   );
 }
-
-export { logger };
index 3fcdbb20921f1135db9c1dd0c3f8024f6f90668a..2bb43a961ccfa11686896321a52c02b5b0f74eb9 100644 (file)
@@ -12,62 +12,54 @@ import {
   type Statistics,
 } from '../types';
 
-export class MessageChannelUtils {
-  private constructor() {
-    // This is intentional
-  }
+export const buildStartedMessage = (
+  chargingStation: ChargingStation
+): ChargingStationWorkerMessage<ChargingStationData> => {
+  return {
+    id: ChargingStationWorkerMessageEvents.started,
+    data: buildChargingStationDataPayload(chargingStation),
+  };
+};
 
-  public static buildStartedMessage(
-    chargingStation: ChargingStation
-  ): ChargingStationWorkerMessage<ChargingStationData> {
-    return {
-      id: ChargingStationWorkerMessageEvents.started,
-      data: MessageChannelUtils.buildChargingStationDataPayload(chargingStation),
-    };
-  }
+export const buildStoppedMessage = (
+  chargingStation: ChargingStation
+): ChargingStationWorkerMessage<ChargingStationData> => {
+  return {
+    id: ChargingStationWorkerMessageEvents.stopped,
+    data: buildChargingStationDataPayload(chargingStation),
+  };
+};
 
-  public static buildStoppedMessage(
-    chargingStation: ChargingStation
-  ): ChargingStationWorkerMessage<ChargingStationData> {
-    return {
-      id: ChargingStationWorkerMessageEvents.stopped,
-      data: MessageChannelUtils.buildChargingStationDataPayload(chargingStation),
-    };
-  }
+export const buildUpdatedMessage = (
+  chargingStation: ChargingStation
+): ChargingStationWorkerMessage<ChargingStationData> => {
+  return {
+    id: ChargingStationWorkerMessageEvents.updated,
+    data: buildChargingStationDataPayload(chargingStation),
+  };
+};
 
-  public static buildUpdatedMessage(
-    chargingStation: ChargingStation
-  ): ChargingStationWorkerMessage<ChargingStationData> {
-    return {
-      id: ChargingStationWorkerMessageEvents.updated,
-      data: MessageChannelUtils.buildChargingStationDataPayload(chargingStation),
-    };
-  }
+export const buildPerformanceStatisticsMessage = (
+  statistics: Statistics
+): ChargingStationWorkerMessage<Statistics> => {
+  return {
+    id: ChargingStationWorkerMessageEvents.performanceStatistics,
+    data: statistics,
+  };
+};
 
-  public static buildPerformanceStatisticsMessage(
-    statistics: Statistics
-  ): ChargingStationWorkerMessage<Statistics> {
-    return {
-      id: ChargingStationWorkerMessageEvents.performanceStatistics,
-      data: statistics,
-    };
-  }
-
-  private static buildChargingStationDataPayload(
-    chargingStation: ChargingStation
-  ): ChargingStationData {
-    return {
-      started: chargingStation.started,
-      stationInfo: chargingStation.stationInfo,
-      connectors: buildConnectorsStatus(chargingStation),
-      evses: buildEvsesStatus(chargingStation, OutputFormat.worker),
-      ocppConfiguration: chargingStation.ocppConfiguration,
-      wsState: chargingStation?.wsConnection?.readyState,
-      bootNotificationResponse: chargingStation.bootNotificationResponse,
-      ...(chargingStation.automaticTransactionGenerator && {
-        automaticTransactionGenerator:
-          buildChargingStationAutomaticTransactionGeneratorConfiguration(chargingStation),
-      }),
-    };
-  }
-}
+const buildChargingStationDataPayload = (chargingStation: ChargingStation): ChargingStationData => {
+  return {
+    started: chargingStation.started,
+    stationInfo: chargingStation.stationInfo,
+    connectors: buildConnectorsStatus(chargingStation),
+    evses: buildEvsesStatus(chargingStation, OutputFormat.worker),
+    ocppConfiguration: chargingStation.ocppConfiguration,
+    wsState: chargingStation?.wsConnection?.readyState,
+    bootNotificationResponse: chargingStation.bootNotificationResponse,
+    ...(chargingStation.automaticTransactionGenerator && {
+      automaticTransactionGenerator:
+        buildChargingStationAutomaticTransactionGeneratorConfiguration(chargingStation),
+    }),
+  };
+};
diff --git a/src/utils/StatisticUtils.ts b/src/utils/StatisticUtils.ts
new file mode 100644 (file)
index 0000000..bb9a847
--- /dev/null
@@ -0,0 +1,55 @@
+import { Utils } from './Utils';
+
+export const median = (dataSet: number[]): number => {
+  if (Utils.isEmptyArray(dataSet)) {
+    return 0;
+  }
+  if (Array.isArray(dataSet) === true && dataSet.length === 1) {
+    return dataSet[0];
+  }
+  const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
+  return (
+    (sortedDataSet[(sortedDataSet.length - 1) >> 1] + sortedDataSet[sortedDataSet.length >> 1]) / 2
+  );
+};
+
+// TODO: use order statistics tree https://en.wikipedia.org/wiki/Order_statistic_tree
+export const nthPercentile = (dataSet: number[], percentile: number): number => {
+  if (percentile < 0 && percentile > 100) {
+    throw new RangeError('Percentile is not between 0 and 100');
+  }
+  if (Utils.isEmptyArray(dataSet)) {
+    return 0;
+  }
+  const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
+  if (percentile === 0 || sortedDataSet.length === 1) {
+    return sortedDataSet[0];
+  }
+  if (percentile === 100) {
+    return sortedDataSet[sortedDataSet.length - 1];
+  }
+  const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1);
+  const percentileIndexInteger = Math.floor(percentileIndexBase);
+  if (!Utils.isNullOrUndefined(sortedDataSet[percentileIndexInteger + 1])) {
+    return (
+      sortedDataSet[percentileIndexInteger] +
+      (percentileIndexBase - percentileIndexInteger) *
+        (sortedDataSet[percentileIndexInteger + 1] - sortedDataSet[percentileIndexInteger])
+    );
+  }
+  return sortedDataSet[percentileIndexInteger];
+};
+
+export const stdDeviation = (dataSet: number[]): number => {
+  let totalDataSet = 0;
+  for (const data of dataSet) {
+    totalDataSet += data;
+  }
+  const dataSetMean = totalDataSet / dataSet.length;
+  let totalGeometricDeviation = 0;
+  for (const data of dataSet) {
+    const deviation = data - dataSetMean;
+    totalGeometricDeviation += deviation * deviation;
+  }
+  return Math.sqrt(totalGeometricDeviation / dataSet.length);
+};
index 3d8c73bdf0cdbeec9516dd079832587a0696ebba..c86afecaf71984b36378c12e3f6c9b02b964c7dc 100644 (file)
@@ -334,59 +334,4 @@ export class Utils {
     }
     return '(Unknown)';
   }
-
-  public static median(dataSet: number[]): number {
-    if (Utils.isEmptyArray(dataSet)) {
-      return 0;
-    }
-    if (Array.isArray(dataSet) === true && dataSet.length === 1) {
-      return dataSet[0];
-    }
-    const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
-    return (
-      (sortedDataSet[(sortedDataSet.length - 1) >> 1] + sortedDataSet[sortedDataSet.length >> 1]) /
-      2
-    );
-  }
-
-  // TODO: use order statistics tree https://en.wikipedia.org/wiki/Order_statistic_tree
-  public static percentile(dataSet: number[], percentile: number): number {
-    if (percentile < 0 && percentile > 100) {
-      throw new RangeError('Percentile is not between 0 and 100');
-    }
-    if (Utils.isEmptyArray(dataSet)) {
-      return 0;
-    }
-    const sortedDataSet = dataSet.slice().sort((a, b) => a - b);
-    if (percentile === 0 || sortedDataSet.length === 1) {
-      return sortedDataSet[0];
-    }
-    if (percentile === 100) {
-      return sortedDataSet[sortedDataSet.length - 1];
-    }
-    const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1);
-    const percentileIndexInteger = Math.floor(percentileIndexBase);
-    if (!Utils.isNullOrUndefined(sortedDataSet[percentileIndexInteger + 1])) {
-      return (
-        sortedDataSet[percentileIndexInteger] +
-        (percentileIndexBase - percentileIndexInteger) *
-          (sortedDataSet[percentileIndexInteger + 1] - sortedDataSet[percentileIndexInteger])
-      );
-    }
-    return sortedDataSet[percentileIndexInteger];
-  }
-
-  public static stdDeviation(dataSet: number[]): number {
-    let totalDataSet = 0;
-    for (const data of dataSet) {
-      totalDataSet += data;
-    }
-    const dataSetMean = totalDataSet / dataSet.length;
-    let totalGeometricDeviation = 0;
-    for (const data of dataSet) {
-      const deviation = data - dataSetMean;
-      totalGeometricDeviation += deviation * deviation;
-    }
-    return Math.sqrt(totalGeometricDeviation / dataSet.length);
-  }
 }
index b034c9a28f26b93b1ae5c6fa94a07213023ee1af..b2374d7361e6ee0c0d3d4f0a74edeb8259eea1e9 100644 (file)
@@ -9,8 +9,20 @@ export {
 export { CircularArray } from './CircularArray';
 export { Configuration } from './Configuration';
 export { Constants } from './Constants';
-export { ErrorUtils } from './ErrorUtils';
-export { FileUtils } from './FileUtils';
-export { MessageChannelUtils } from './MessageChannelUtils';
+export {
+  handleFileException,
+  handleUncaughtException,
+  handleUnhandledRejection,
+  handleSendMessageError,
+  setDefaultErrorParams,
+} from './ErrorUtils';
+export { watchJsonFile } from './FileUtils';
+export {
+  buildPerformanceStatisticsMessage,
+  buildUpdatedMessage,
+  buildStartedMessage,
+  buildStoppedMessage,
+} from './MessageChannelUtils';
 export { Utils } from './Utils';
+export { median, nthPercentile, stdDeviation } from './StatisticUtils';
 export { logger } from './Logger';
index 16d566bde2ae60049fe401c7f13f830af4ce17dd..d42f629db3ff0b5ced69039c28c2b180dab7731b 100644 (file)
@@ -1,13 +1,18 @@
+import type EventEmitterAsyncResource from 'node:events';
 import fs from 'node:fs';
 
+import type { PoolInfo } from 'poolifier';
+
 import { WorkerConstants } from './WorkerConstants';
-import type { WorkerData, WorkerOptions } from './WorkerTypes';
+import type { SetInfo, WorkerData, WorkerOptions } from './WorkerTypes';
 
 export abstract class WorkerAbstract<T extends WorkerData> {
   protected readonly workerScript: string;
   protected readonly workerOptions: WorkerOptions;
+  public abstract readonly info: PoolInfo | SetInfo;
   public abstract readonly size: number;
   public abstract readonly maxElementsPerWorker: number | undefined;
+  public abstract readonly emitter: EventEmitterAsyncResource | undefined;
 
   /**
    * `WorkerAbstract` constructor.
@@ -40,7 +45,18 @@ export abstract class WorkerAbstract<T extends WorkerData> {
     this.workerOptions = workerOptions;
   }
 
+  /**
+   * Start the worker pool/set.
+   */
   public abstract start(): Promise<void>;
+  /**
+   * Stop the worker pool/set.
+   */
   public abstract stop(): Promise<void>;
+  /**
+   * Add a task element to the worker pool/set.
+   *
+   * @param elementData -
+   */
   public abstract addElement(elementData: T): Promise<void>;
 }
index ff80bfcbdf5a082b885620e025fd335db3696947..38d85aea06d0252531076338382cf161e447d991 100644 (file)
@@ -1,10 +1,11 @@
+import type EventEmitterAsyncResource from 'node:events';
 import type { Worker } from 'node:worker_threads';
 
-import { DynamicThreadPool, type ErrorHandler, type ExitHandler } from 'poolifier';
+import { DynamicThreadPool, type ErrorHandler, type ExitHandler, type PoolInfo } from 'poolifier';
 
 import { WorkerAbstract } from './WorkerAbstract';
 import type { WorkerData, WorkerOptions } from './WorkerTypes';
-import { WorkerUtils } from './WorkerUtils';
+import { defaultErrorHandler, defaultExitHandler, sleep } from './WorkerUtils';
 
 export class WorkerDynamicPool extends WorkerAbstract<WorkerData> {
   private readonly pool: DynamicThreadPool<WorkerData>;
@@ -18,10 +19,10 @@ export class WorkerDynamicPool extends WorkerAbstract<WorkerData> {
   constructor(workerScript: string, workerOptions?: WorkerOptions) {
     super(workerScript, workerOptions);
     this.workerOptions.poolOptions.errorHandler = (
-      this.workerOptions?.poolOptions?.errorHandler ?? WorkerUtils.defaultErrorHandler
+      this.workerOptions?.poolOptions?.errorHandler ?? defaultErrorHandler
     ).bind(this) as ErrorHandler<Worker>;
     this.workerOptions.poolOptions.exitHandler = (
-      this.workerOptions?.poolOptions?.exitHandler ?? WorkerUtils.defaultExitHandler
+      this.workerOptions?.poolOptions?.exitHandler ?? defaultExitHandler
     ).bind(this) as ExitHandler<Worker>;
     this.workerOptions.poolOptions.messageHandler.bind(this);
     this.pool = new DynamicThreadPool<WorkerData>(
@@ -32,42 +33,36 @@ export class WorkerDynamicPool extends WorkerAbstract<WorkerData> {
     );
   }
 
+  get info(): PoolInfo {
+    return this.pool.info;
+  }
+
   get size(): number {
-    return this.pool.workerNodes.length;
+    return this.pool.info.workerNodes;
   }
 
   get maxElementsPerWorker(): number | undefined {
     return undefined;
   }
 
-  /**
-   *
-   * @returns
-   * @public
-   */
+  get emitter(): EventEmitterAsyncResource | undefined {
+    return this.pool?.emitter;
+  }
+
+  /** @inheritDoc */
   public async start(): Promise<void> {
     // This is intentional
   }
 
-  /**
-   *
-   * @returns
-   * @public
-   */
+  /** @inheritDoc */
   public async stop(): Promise<void> {
     return this.pool.destroy();
   }
 
-  /**
-   *
-   * @param elementData -
-   * @returns
-   * @public
-   */
+  /** @inheritDoc */
   public async addElement(elementData: WorkerData): Promise<void> {
     await this.pool.execute(elementData);
     // Start element sequentially to optimize memory at startup
-    this.workerOptions.elementStartDelay > 0 &&
-      (await WorkerUtils.sleep(this.workerOptions.elementStartDelay));
+    this.workerOptions.elementStartDelay > 0 && (await sleep(this.workerOptions.elementStartDelay));
   }
 }
index 513efb506f7a8f6f5cddaba641ec8e771fc10955..681609585de1d388fe59135fb778fcf39fccc384 100644 (file)
@@ -1,19 +1,22 @@
 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
 
+import EventEmitterAsyncResource from 'node:events';
 import { Worker } from 'node:worker_threads';
 
 import { WorkerAbstract } from './WorkerAbstract';
 import { WorkerConstants } from './WorkerConstants';
 import {
   type MessageHandler,
+  type SetInfo,
   type WorkerData,
   WorkerMessageEvents,
   type WorkerOptions,
   type WorkerSetElement,
 } from './WorkerTypes';
-import { WorkerUtils } from './WorkerUtils';
+import { defaultErrorHandler, defaultExitHandler, sleep } from './WorkerUtils';
 
 export class WorkerSet extends WorkerAbstract<WorkerData> {
+  public readonly emitter: EventEmitterAsyncResource;
   private readonly workerSet: Set<WorkerSetElement>;
 
   /**
@@ -25,6 +28,18 @@ export class WorkerSet extends WorkerAbstract<WorkerData> {
   constructor(workerScript: string, workerOptions?: WorkerOptions) {
     super(workerScript, workerOptions);
     this.workerSet = new Set<WorkerSetElement>();
+    this.emitter = new EventEmitterAsyncResource();
+  }
+
+  get info(): SetInfo {
+    return {
+      size: this.size,
+      runningElements: [...this.workerSet].reduce(
+        (accumulator, workerSetElement) => accumulator + workerSetElement.numberOfWorkerElements,
+        0
+      ),
+      elementsPerWorker: this.maxElementsPerWorker,
+    };
   }
 
   get size(): number {
@@ -35,58 +50,42 @@ export class WorkerSet extends WorkerAbstract<WorkerData> {
     return this.workerOptions.elementsPerWorker;
   }
 
-  /**
-   *
-   * @param elementData -
-   * @returns
-   * @public
-   */
+  /** @inheritDoc */
+  public async start(): Promise<void> {
+    this.addWorkerSetElement();
+    // Add worker set element sequentially to optimize memory at startup
+    this.workerOptions.workerStartDelay > 0 && (await sleep(this.workerOptions.workerStartDelay));
+  }
+
+  /** @inheritDoc */
+  public async stop(): Promise<void> {
+    for (const workerSetElement of this.workerSet) {
+      await workerSetElement.worker.terminate();
+    }
+    this.workerSet.clear();
+  }
+
+  /** @inheritDoc */
   public async addElement(elementData: WorkerData): Promise<void> {
     if (!this.workerSet) {
       throw new Error("Cannot add a WorkerSet element: workers' set does not exist");
     }
-    if (
-      this.workerSet.size === 0 ||
-      this.getLastWorkerSetElement().numberOfWorkerElements >= this.workerOptions.elementsPerWorker
-    ) {
-      await this.startWorker();
-    }
-    this.getLastWorker().postMessage({
+    const workerSetElement = await this.getWorkerSetElement();
+    workerSetElement.worker.postMessage({
       id: WorkerMessageEvents.startWorkerElement,
       data: elementData,
     });
-    ++this.getLastWorkerSetElement().numberOfWorkerElements;
-    // Start element sequentially to optimize memory at startup
+    ++workerSetElement.numberOfWorkerElements;
+    // Add element sequentially to optimize memory at startup
     if (this.workerOptions.elementStartDelay > 0) {
-      await WorkerUtils.sleep(this.workerOptions.elementStartDelay);
-    }
-  }
-
-  /**
-   *
-   * @returns
-   * @public
-   */
-  public async start(): Promise<void> {
-    await this.startWorker();
-  }
-
-  /**
-   *
-   * @returns
-   * @public
-   */
-  public async stop(): Promise<void> {
-    for (const workerSetElement of this.workerSet) {
-      await workerSetElement.worker.terminate();
+      await sleep(this.workerOptions.elementStartDelay);
     }
-    this.workerSet.clear();
   }
 
   /**
-   * Start a new `Worker`.
+   * Add a new `WorkerSetElement`.
    */
-  private async startWorker(): Promise<void> {
+  private addWorkerSetElement(): WorkerSetElement {
     const worker = new Worker(this.workerScript);
     worker.on(
       'message',
@@ -94,30 +93,35 @@ export class WorkerSet extends WorkerAbstract<WorkerData> {
         this
       ) as MessageHandler<Worker>
     );
-    worker.on('error', WorkerUtils.defaultErrorHandler.bind(this) as (err: Error) => void);
-    worker.on('exit', (code) => {
-      WorkerUtils.defaultExitHandler(code);
-      this.workerSet.delete(this.getWorkerSetElementByWorker(worker));
+    worker.on('error', defaultErrorHandler.bind(this) as (err: Error) => void);
+    worker.on('error', (error) => {
+      this.emitter.emit('error', error);
+      this.addWorkerSetElement();
     });
-    this.workerSet.add({ worker, numberOfWorkerElements: 0 });
-    // Start worker sequentially to optimize memory at startup
-    this.workerOptions.workerStartDelay > 0 &&
-      (await WorkerUtils.sleep(this.workerOptions.workerStartDelay));
-  }
-
-  private getLastWorkerSetElement(): WorkerSetElement {
-    let workerSetElement: WorkerSetElement;
-    for (workerSetElement of this.workerSet) {
-      /* This is intentional */
-    }
+    worker.on('exit', defaultExitHandler.bind(this) as (exitCode: number) => void);
+    worker.on('exit', () => this.workerSet.delete(this.getWorkerSetElementByWorker(worker)));
+    const workerSetElement: WorkerSetElement = { worker, numberOfWorkerElements: 0 };
+    this.workerSet.add(workerSetElement);
     return workerSetElement;
   }
 
-  private getLastWorker(): Worker {
-    return this.getLastWorkerSetElement().worker;
+  private async getWorkerSetElement(): Promise<WorkerSetElement> {
+    let chosenWorkerSetElement: WorkerSetElement;
+    for (const workerSetElement of this.workerSet) {
+      if (workerSetElement.numberOfWorkerElements < this.workerOptions.elementsPerWorker) {
+        chosenWorkerSetElement = workerSetElement;
+        break;
+      }
+    }
+    if (!chosenWorkerSetElement) {
+      chosenWorkerSetElement = this.addWorkerSetElement();
+      // Add worker set element sequentially to optimize memory at startup
+      this.workerOptions.workerStartDelay > 0 && (await sleep(this.workerOptions.workerStartDelay));
+    }
+    return chosenWorkerSetElement;
   }
 
-  private getWorkerSetElementByWorker(worker: Worker): WorkerSetElement {
+  private getWorkerSetElementByWorker(worker: Worker): WorkerSetElement | undefined {
     let workerSetElt: WorkerSetElement;
     for (const workerSetElement of this.workerSet) {
       if (workerSetElement.worker.threadId === worker.threadId) {
index de1f5b29cfb89aebc39240584f9ed045ee6b1efb..f5c2a6e89f60658dc0e30082d4aea62ad8e0ad62 100644 (file)
@@ -1,10 +1,11 @@
+import type EventEmitterAsyncResource from 'node:events';
 import type { Worker } from 'node:worker_threads';
 
-import { type ErrorHandler, type ExitHandler, FixedThreadPool } from 'poolifier';
+import { type ErrorHandler, type ExitHandler, FixedThreadPool, type PoolInfo } from 'poolifier';
 
 import { WorkerAbstract } from './WorkerAbstract';
 import type { WorkerData, WorkerOptions } from './WorkerTypes';
-import { WorkerUtils } from './WorkerUtils';
+import { defaultErrorHandler, defaultExitHandler, sleep } from './WorkerUtils';
 
 export class WorkerStaticPool extends WorkerAbstract<WorkerData> {
   private readonly pool: FixedThreadPool<WorkerData>;
@@ -18,10 +19,10 @@ export class WorkerStaticPool extends WorkerAbstract<WorkerData> {
   constructor(workerScript: string, workerOptions?: WorkerOptions) {
     super(workerScript, workerOptions);
     this.workerOptions.poolOptions.errorHandler = (
-      this.workerOptions?.poolOptions?.errorHandler ?? WorkerUtils.defaultErrorHandler
+      this.workerOptions?.poolOptions?.errorHandler ?? defaultErrorHandler
     ).bind(this) as ErrorHandler<Worker>;
     this.workerOptions.poolOptions.exitHandler = (
-      this.workerOptions?.poolOptions?.exitHandler ?? WorkerUtils.defaultExitHandler
+      this.workerOptions?.poolOptions?.exitHandler ?? defaultExitHandler
     ).bind(this) as ExitHandler<Worker>;
     this.workerOptions.poolOptions.messageHandler.bind(this);
     this.pool = new FixedThreadPool(
@@ -31,42 +32,36 @@ export class WorkerStaticPool extends WorkerAbstract<WorkerData> {
     );
   }
 
+  get info(): PoolInfo {
+    return this.pool.info;
+  }
+
   get size(): number {
-    return this.pool.workerNodes.length;
+    return this.pool.info.workerNodes;
   }
 
   get maxElementsPerWorker(): number | undefined {
     return undefined;
   }
 
-  /**
-   *
-   * @returns
-   * @public
-   */
+  get emitter(): EventEmitterAsyncResource | undefined {
+    return this.pool?.emitter;
+  }
+
+  /** @inheritDoc */
   public async start(): Promise<void> {
     // This is intentional
   }
 
-  /**
-   *
-   * @returns
-   * @public
-   */
+  /** @inheritDoc */
   public async stop(): Promise<void> {
     return this.pool.destroy();
   }
 
-  /**
-   *
-   * @param elementData -
-   * @returns
-   * @public
-   */
+  /** @inheritDoc */
   public async addElement(elementData: WorkerData): Promise<void> {
     await this.pool.execute(elementData);
     // Start element sequentially to optimize memory at startup
-    this.workerOptions.elementStartDelay > 0 &&
-      (await WorkerUtils.sleep(this.workerOptions.elementStartDelay));
+    this.workerOptions.elementStartDelay > 0 && (await sleep(this.workerOptions.elementStartDelay));
   }
 }
index 1b7cbb300cf95a7ac5c9ba22bc4e8ac4a622afe6..6f780bce30dc6c6f274578a38972f7b28844adb3 100644 (file)
@@ -8,6 +8,12 @@ export enum WorkerProcessType {
   staticPool = 'staticPool',
 }
 
+export type SetInfo = {
+  size: number;
+  runningElements: number;
+  elementsPerWorker: number;
+};
+
 export type MessageHandler<T> = (this: T, message: unknown) => void;
 
 export type WorkerOptions = {
index 7c72ff3e57fcac90ed51150f7780727a754df808..368d64f20585e0dfd737748bb64a6306e0e12405 100644 (file)
@@ -1,21 +1,19 @@
 import chalk from 'chalk';
 
-export class WorkerUtils {
-  private constructor() {
-    // This is intentional
-  }
+export const sleep = async (milliSeconds: number): Promise<NodeJS.Timeout> => {
+  return new Promise((resolve) => setTimeout(resolve as () => void, milliSeconds));
+};
 
-  public static async sleep(milliSeconds: number): Promise<NodeJS.Timeout> {
-    return new Promise((resolve) => setTimeout(resolve as () => void, milliSeconds));
+export const defaultExitHandler = (code: number): void => {
+  if (code === 0) {
+    console.info(chalk.green('Worker exited successfully'));
+  } else if (code === 1) {
+    console.info(chalk.green('Worker terminated successfully'));
+  } else if (code > 1) {
+    console.error(chalk.red(`Worker exited with exit code: ${code.toString()}`));
   }
+};
 
-  public static defaultExitHandler = (code: number): void => {
-    if (code !== 0) {
-      console.error(chalk.red(`Worker exited with error exit code: ${code.toString()}`));
-    }
-  };
-
-  public static defaultErrorHandler = (error: Error): void => {
-    console.error(chalk.red('Worker errored: ', error));
-  };
-}
+export const defaultErrorHandler = (error: Error): void => {
+  console.error(chalk.red('Worker errored: ', error));
+};
similarity index 99%
rename from test/utils/CircularArrayTest.ts
rename to test/utils/CircularArray.test.ts
index 0a2609c0a2d19b65878647531b2a214e711a0b77..720ca68de3c4e006c7739ffed7f61f0f6523b70f 100644 (file)
@@ -2,7 +2,7 @@ import { expect } from 'expect';
 
 import { CircularArray } from '../../src/utils/CircularArray';
 
-describe('Circular array test suite', () => {
+describe('CircularArray test suite', () => {
   it('Verify that circular array can be instantiated', () => {
     const circularArray = new CircularArray();
     expect(circularArray).toBeInstanceOf(CircularArray);
diff --git a/test/utils/StatisticUtils.test.ts b/test/utils/StatisticUtils.test.ts
new file mode 100644 (file)
index 0000000..2910c32
--- /dev/null
@@ -0,0 +1,29 @@
+import { expect } from 'expect';
+
+import { median, nthPercentile, stdDeviation } from '../../src/utils/StatisticUtils';
+
+describe('StatisticUtils test suite', () => {
+  it('Verify median()', () => {
+    expect(median([])).toBe(0);
+    expect(median([0.08])).toBe(0.08);
+    expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05);
+    expect(median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535);
+  });
+
+  it('Verify nthPercentile()', () => {
+    expect(nthPercentile([], 25)).toBe(0);
+    expect(nthPercentile([0.08], 50)).toBe(0.08);
+    const array0 = [0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03];
+    expect(nthPercentile(array0, 0)).toBe(0.25);
+    expect(nthPercentile(array0, 50)).toBe(3.05);
+    expect(nthPercentile(array0, 80)).toBe(4.974);
+    expect(nthPercentile(array0, 85)).toBe(5.131);
+    expect(nthPercentile(array0, 90)).toBe(5.434);
+    expect(nthPercentile(array0, 95)).toBe(5.736999999999999);
+    expect(nthPercentile(array0, 100)).toBe(6.04);
+  });
+
+  it('Verify stdDeviation()', () => {
+    expect(stdDeviation([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(2.0256064851429216);
+  });
+});
similarity index 93%
rename from test/utils/UtilsTest.ts
rename to test/utils/Utils.test.ts
index f5e1259db9a95200eafc188116977a2b4aca03b8..5732e57ed316673e1cbc538d9b853a0c33d90665 100644 (file)
@@ -329,28 +329,4 @@ describe('Utils test suite', () => {
     expect(Utils.isEmptyObject(new WeakMap())).toBe(false);
     expect(Utils.isEmptyObject(new WeakSet())).toBe(false);
   });
-
-  it('Verify median()', () => {
-    expect(Utils.median([])).toBe(0);
-    expect(Utils.median([0.08])).toBe(0.08);
-    expect(Utils.median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(3.05);
-    expect(Utils.median([0.25, 4.75, 3.05, 6.04, 1.01, 2.02])).toBe(2.535);
-  });
-
-  it('Verify percentile()', () => {
-    expect(Utils.percentile([], 25)).toBe(0);
-    expect(Utils.percentile([0.08], 50)).toBe(0.08);
-    const array0 = [0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03];
-    expect(Utils.percentile(array0, 0)).toBe(0.25);
-    expect(Utils.percentile(array0, 50)).toBe(3.05);
-    expect(Utils.percentile(array0, 80)).toBe(4.974);
-    expect(Utils.percentile(array0, 85)).toBe(5.131);
-    expect(Utils.percentile(array0, 90)).toBe(5.434);
-    expect(Utils.percentile(array0, 95)).toBe(5.736999999999999);
-    expect(Utils.percentile(array0, 100)).toBe(6.04);
-  });
-
-  it('Verify stdDeviation()', () => {
-    expect(Utils.stdDeviation([0.25, 4.75, 3.05, 6.04, 1.01, 2.02, 5.03])).toBe(2.0256064851429216);
-  });
 });
index 28e4186cc7a46108190920667ad2534c1c322ea6..658bfcfcb007f0d91129deff97701f59d30f3698 100644 (file)
@@ -15,7 +15,7 @@
     // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
     // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
     // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
-    "sourceMap": true,                        /* Generates corresponding '.map' file. */
+    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
     // "outFile": "./",                       /* Concatenate and emit output to single file. */
     "outDir": "./dist",                       /* Redirect output structure to the directory. */
     "rootDir": "./",                          /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
index 2c7b284162f4cafdbef8875c7ae7cb517c8e7abd..7bf0a6cb021be91e7c31854ac53abbb24d981259 100644 (file)
@@ -1,6 +1,8 @@
 {
-  "extends": "./tsconfig.json",
+  "extends": "./tsconfig-base.json",
   "compilerOptions": {
-    "module": "commonjs"
+    "module": "commonjs",
+    "sourceMap": true,
+    "verbatimModuleSyntax": true
   }
 }
index a1fb929529f217533cb7b620743b5bce1f695a36..a8b359e11c79dbc32921a894482b32ede140a9d4 100644 (file)
@@ -4,11 +4,11 @@
   "readme": "README.md",
   "engines": {
     "node": ">=16.9.0",
-    "pnpm": ">=8.0.0"
+    "pnpm": ">=8.6.0"
   },
   "volta": {
     "node": "20.2.0",
-    "pnpm": "8.5.1"
+    "pnpm": "8.6.0"
   },
   "scripts": {
     "preinstall": "npx --yes only-allow pnpm",
     "finalhandler": "^1.2.0",
     "serve-static": "^1.15.0",
     "vue": "^3.3.4",
-    "vue-router": "^4.2.1"
+    "vue-router": "^4.2.2"
   },
   "devDependencies": {
     "@tsconfig/node20": "^1.0.1",
     "@types/jsdom": "^21.1.1",
-    "@types/node": "^20.2.3",
-    "@typescript-eslint/eslint-plugin": "^5.59.7",
-    "@typescript-eslint/parser": "^5.59.7",
+    "@types/node": "^20.2.5",
+    "@typescript-eslint/eslint-plugin": "^5.59.8",
+    "@typescript-eslint/parser": "^5.59.8",
     "@vitejs/plugin-vue": "^4.2.3",
     "@vitejs/plugin-vue-jsx": "^3.0.1",
-    "@vitest/coverage-c8": "^0.31.1",
+    "@vitest/coverage-c8": "^0.31.4",
     "@vue/eslint-config-prettier": "^7.1.0",
     "@vue/eslint-config-typescript": "^11.0.3",
     "@vue/test-utils": "^2.3.2",
     "@vue/tsconfig": "^0.4.0",
     "cross-env": "^7.0.3",
-    "eslint": "^8.41.0",
+    "eslint": "^8.42.0",
     "eslint-define-config": "^1.20.0",
     "eslint-import-resolver-typescript": "^3.5.5",
     "eslint-plugin-import": "^2.27.5",
-    "eslint-plugin-vue": "^9.14.0",
-    "jsdom": "^22.0.0",
+    "eslint-plugin-vue": "^9.14.1",
+    "jsdom": "^22.1.0",
     "prettier": "^2.8.8",
     "rimraf": "^5.0.1",
-    "typescript": "~5.0.4",
-    "vite": "^4.3.8",
-    "vitest": "^0.31.1"
+    "typescript": "~5.1.3",
+    "vite": "^4.3.9",
+    "vitest": "^0.31.4"
   },
   "_id": "webui@0.1.1"
 }
index 2ca83507b0a954bafdda59f9ef62507c30c311f4..e6ebaeeeaa56129ae150c498cd1c241df304ed7a 100644 (file)
@@ -1,4 +1,8 @@
-lockfileVersion: '6.0'
+lockfileVersion: '6.1'
+
+settings:
+  autoInstallPeers: true
+  excludeLinksFromLockfile: false
 
 dependencies:
   finalhandler:
@@ -11,8 +15,8 @@ dependencies:
     specifier: ^3.3.4
     version: 3.3.4
   vue-router:
-    specifier: ^4.2.1
-    version: 4.2.1(vue@3.3.4)
+    specifier: ^4.2.2
+    version: 4.2.2(vue@3.3.4)
 
 devDependencies:
   '@tsconfig/node20':
@@ -22,29 +26,29 @@ devDependencies:
     specifier: ^21.1.1
     version: 21.1.1
   '@types/node':
-    specifier: ^20.2.3
-    version: 20.2.3
+    specifier: ^20.2.5
+    version: 20.2.5
   '@typescript-eslint/eslint-plugin':
-    specifier: ^5.59.7
-    version: 5.59.7(@typescript-eslint/parser@5.59.7)(eslint@8.41.0)(typescript@5.0.4)
+    specifier: ^5.59.8
+    version: 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@5.1.3)
   '@typescript-eslint/parser':
-    specifier: ^5.59.7
-    version: 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+    specifier: ^5.59.8
+    version: 5.59.8(eslint@8.42.0)(typescript@5.1.3)
   '@vitejs/plugin-vue':
     specifier: ^4.2.3
-    version: 4.2.3(vite@4.3.8)(vue@3.3.4)
+    version: 4.2.3(vite@4.3.9)(vue@3.3.4)
   '@vitejs/plugin-vue-jsx':
     specifier: ^3.0.1
-    version: 3.0.1(vite@4.3.8)(vue@3.3.4)
+    version: 3.0.1(vite@4.3.9)(vue@3.3.4)
   '@vitest/coverage-c8':
-    specifier: ^0.31.1
-    version: 0.31.1(vitest@0.31.1)
+    specifier: ^0.31.4
+    version: 0.31.4(vitest@0.31.4)
   '@vue/eslint-config-prettier':
     specifier: ^7.1.0
-    version: 7.1.0(eslint@8.41.0)(prettier@2.8.8)
+    version: 7.1.0(eslint@8.42.0)(prettier@2.8.8)
   '@vue/eslint-config-typescript':
     specifier: ^11.0.3
-    version: 11.0.3(eslint-plugin-vue@9.14.0)(eslint@8.41.0)(typescript@5.0.4)
+    version: 11.0.3(eslint-plugin-vue@9.14.1)(eslint@8.42.0)(typescript@5.1.3)
   '@vue/test-utils':
     specifier: ^2.3.2
     version: 2.3.2(vue@3.3.4)
@@ -55,23 +59,23 @@ devDependencies:
     specifier: ^7.0.3
     version: 7.0.3
   eslint:
-    specifier: ^8.41.0
-    version: 8.41.0
+    specifier: ^8.42.0
+    version: 8.42.0
   eslint-define-config:
     specifier: ^1.20.0
     version: 1.20.0
   eslint-import-resolver-typescript:
     specifier: ^3.5.5
-    version: 3.5.5(@typescript-eslint/parser@5.59.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0)
+    version: 3.5.5(@typescript-eslint/parser@5.59.8)(eslint-plugin-import@2.27.5)(eslint@8.42.0)
   eslint-plugin-import:
     specifier: ^2.27.5
-    version: 2.27.5(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
+    version: 2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
   eslint-plugin-vue:
-    specifier: ^9.14.0
-    version: 9.14.0(eslint@8.41.0)
+    specifier: ^9.14.1
+    version: 9.14.1(eslint@8.42.0)
   jsdom:
-    specifier: ^22.0.0
-    version: 22.0.0
+    specifier: ^22.1.0
+    version: 22.1.0
   prettier:
     specifier: ^2.8.8
     version: 2.8.8
@@ -79,14 +83,14 @@ devDependencies:
     specifier: ^5.0.1
     version: 5.0.1
   typescript:
-    specifier: ~5.0.4
-    version: 5.0.4
+    specifier: ~5.1.3
+    version: 5.1.3
   vite:
-    specifier: ^4.3.8
-    version: 4.3.8(@types/node@20.2.3)
+    specifier: ^4.3.9
+    version: 4.3.9(@types/node@20.2.5)
   vitest:
-    specifier: ^0.31.1
-    version: 0.31.1(jsdom@22.0.0)
+    specifier: ^0.31.4
+    version: 0.31.4(jsdom@22.1.0)
 
 packages:
 
@@ -105,25 +109,25 @@ packages:
       '@babel/highlight': 7.18.6
     dev: true
 
-  /@babel/compat-data@7.21.9:
-    resolution: {integrity: sha512-FUGed8kfhyWvbYug/Un/VPJD41rDIgoVVcR+FuzhzOYyRz5uED+Gd3SLZml0Uw2l2aHFb7ZgdW5mGA3G2cCCnQ==}
+  /@babel/compat-data@7.22.3:
+    resolution: {integrity: sha512-aNtko9OPOwVESUFp3MZfD8Uzxl7JzSeJpd7npIoxCasU37PFbAQRpKglkaKwlHOyeJdrREpo8TW8ldrkYWwvIQ==}
     engines: {node: '>=6.9.0'}
     dev: true
 
-  /@babel/core@7.21.8:
-    resolution: {integrity: sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==}
+  /@babel/core@7.22.1:
+    resolution: {integrity: sha512-Hkqu7J4ynysSXxmAahpN1jjRwVJ+NdpraFLIWflgjpVob3KNyK3/tIUc7Q7szed8WMp0JNa7Qtd1E9Oo22F9gA==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@ampproject/remapping': 2.2.1
       '@babel/code-frame': 7.21.4
-      '@babel/generator': 7.21.9
-      '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8)
-      '@babel/helper-module-transforms': 7.21.5
-      '@babel/helpers': 7.21.5
-      '@babel/parser': 7.21.9
+      '@babel/generator': 7.22.3
+      '@babel/helper-compilation-targets': 7.22.1(@babel/core@7.22.1)
+      '@babel/helper-module-transforms': 7.22.1
+      '@babel/helpers': 7.22.3
+      '@babel/parser': 7.22.4
       '@babel/template': 7.21.9
-      '@babel/traverse': 7.21.5
-      '@babel/types': 7.21.5
+      '@babel/traverse': 7.22.4
+      '@babel/types': 7.22.4
       convert-source-map: 1.9.0
       debug: 4.3.4
       gensync: 1.0.0-beta.2
@@ -133,11 +137,11 @@ packages:
       - supports-color
     dev: true
 
-  /@babel/generator@7.21.9:
-    resolution: {integrity: sha512-F3fZga2uv09wFdEjEQIJxXALXfz0+JaOb7SabvVMmjHxeVTuGW8wgE8Vp1Hd7O+zMTYtcfEISGRzPkeiaPPsvg==}
+  /@babel/generator@7.22.3:
+    resolution: {integrity: sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
       '@jridgewell/gen-mapping': 0.3.3
       '@jridgewell/trace-mapping': 0.3.18
       jsesc: 2.5.2
@@ -147,36 +151,36 @@ packages:
     resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
-  /@babel/helper-compilation-targets@7.21.5(@babel/core@7.21.8):
-    resolution: {integrity: sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==}
+  /@babel/helper-compilation-targets@7.22.1(@babel/core@7.22.1):
+    resolution: {integrity: sha512-Rqx13UM3yVB5q0D/KwQ8+SPfX/+Rnsy1Lw1k/UwOC4KC6qrzIQoY3lYnBu5EHKBlEHHcj0M0W8ltPSkD8rqfsQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/compat-data': 7.21.9
-      '@babel/core': 7.21.8
+      '@babel/compat-data': 7.22.3
+      '@babel/core': 7.22.1
       '@babel/helper-validator-option': 7.21.0
-      browserslist: 4.21.5
+      browserslist: 4.21.7
       lru-cache: 5.1.1
       semver: 6.3.0
     dev: true
 
-  /@babel/helper-create-class-features-plugin@7.21.8(@babel/core@7.21.8):
-    resolution: {integrity: sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==}
+  /@babel/helper-create-class-features-plugin@7.22.1(@babel/core@7.22.1):
+    resolution: {integrity: sha512-SowrZ9BWzYFgzUMwUmowbPSGu6CXL5MSuuCkG3bejahSpSymioPmuLdhPxNOc9MjuNGjy7M/HaXvJ8G82Lywlw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0
     dependencies:
-      '@babel/core': 7.21.8
+      '@babel/core': 7.22.1
       '@babel/helper-annotate-as-pure': 7.18.6
-      '@babel/helper-environment-visitor': 7.21.5
+      '@babel/helper-environment-visitor': 7.22.1
       '@babel/helper-function-name': 7.21.0
-      '@babel/helper-member-expression-to-functions': 7.21.5
+      '@babel/helper-member-expression-to-functions': 7.22.3
       '@babel/helper-optimise-call-expression': 7.18.6
-      '@babel/helper-replace-supers': 7.21.5
+      '@babel/helper-replace-supers': 7.22.1
       '@babel/helper-skip-transparent-expression-wrappers': 7.20.0
       '@babel/helper-split-export-declaration': 7.18.6
       semver: 6.3.0
@@ -184,8 +188,8 @@ packages:
       - supports-color
     dev: true
 
-  /@babel/helper-environment-visitor@7.21.5:
-    resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==}
+  /@babel/helper-environment-visitor@7.22.1:
+    resolution: {integrity: sha512-Z2tgopurB/kTbidvzeBrc2To3PUP/9i5MUe+fU6QJCQDyPwSH2oRapkLw3KGECDYSjhQZCNxEvNvZlLw8JjGwA==}
     engines: {node: '>=6.9.0'}
     dev: true
 
@@ -194,42 +198,42 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/template': 7.21.9
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
   /@babel/helper-hoist-variables@7.18.6:
     resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
-  /@babel/helper-member-expression-to-functions@7.21.5:
-    resolution: {integrity: sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==}
+  /@babel/helper-member-expression-to-functions@7.22.3:
+    resolution: {integrity: sha512-Gl7sK04b/2WOb6OPVeNy9eFKeD3L6++CzL3ykPOWqTn08xgYYK0wz4TUh2feIImDXxcVW3/9WQ1NMKY66/jfZA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
   /@babel/helper-module-imports@7.21.4:
     resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
-  /@babel/helper-module-transforms@7.21.5:
-    resolution: {integrity: sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==}
+  /@babel/helper-module-transforms@7.22.1:
+    resolution: {integrity: sha512-dxAe9E7ySDGbQdCVOY/4+UcD8M9ZFqZcZhSPsPacvCG4M+9lwtDDQfI2EoaSvmf7W/8yCBkGU0m7Pvt1ru3UZw==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-environment-visitor': 7.21.5
+      '@babel/helper-environment-visitor': 7.22.1
       '@babel/helper-module-imports': 7.21.4
       '@babel/helper-simple-access': 7.21.5
       '@babel/helper-split-export-declaration': 7.18.6
       '@babel/helper-validator-identifier': 7.19.1
       '@babel/template': 7.21.9
-      '@babel/traverse': 7.21.5
-      '@babel/types': 7.21.5
+      '@babel/traverse': 7.22.4
+      '@babel/types': 7.22.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -238,7 +242,7 @@ packages:
     resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
   /@babel/helper-plugin-utils@7.21.5:
@@ -246,16 +250,16 @@ packages:
     engines: {node: '>=6.9.0'}
     dev: true
 
-  /@babel/helper-replace-supers@7.21.5:
-    resolution: {integrity: sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==}
+  /@babel/helper-replace-supers@7.22.1:
+    resolution: {integrity: sha512-ut4qrkE4AuSfrwHSps51ekR1ZY/ygrP1tp0WFm8oVq6nzc/hvfV/22JylndIbsf2U2M9LOMwiSddr6y+78j+OQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/helper-environment-visitor': 7.21.5
-      '@babel/helper-member-expression-to-functions': 7.21.5
+      '@babel/helper-environment-visitor': 7.22.1
+      '@babel/helper-member-expression-to-functions': 7.22.3
       '@babel/helper-optimise-call-expression': 7.18.6
       '@babel/template': 7.21.9
-      '@babel/traverse': 7.21.5
-      '@babel/types': 7.21.5
+      '@babel/traverse': 7.22.4
+      '@babel/types': 7.22.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -264,21 +268,21 @@ packages:
     resolution: {integrity: sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
   /@babel/helper-skip-transparent-expression-wrappers@7.20.0:
     resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
   /@babel/helper-split-export-declaration@7.18.6:
     resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
     engines: {node: '>=6.9.0'}
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
     dev: true
 
   /@babel/helper-string-parser@7.21.5:
@@ -294,13 +298,13 @@ packages:
     engines: {node: '>=6.9.0'}
     dev: true
 
-  /@babel/helpers@7.21.5:
-    resolution: {integrity: sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==}
+  /@babel/helpers@7.22.3:
+    resolution: {integrity: sha512-jBJ7jWblbgr7r6wYZHMdIqKc73ycaTcCaWRq4/2LpuPHcx7xMlZvpGQkOYc9HeSjn6rcx15CPlgVcBtZ4WZJ2w==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/template': 7.21.9
-      '@babel/traverse': 7.21.5
-      '@babel/types': 7.21.5
+      '@babel/traverse': 7.22.4
+      '@babel/types': 7.22.4
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -314,44 +318,44 @@ packages:
       js-tokens: 4.0.0
     dev: true
 
-  /@babel/parser@7.21.9:
-    resolution: {integrity: sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==}
+  /@babel/parser@7.22.4:
+    resolution: {integrity: sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==}
     engines: {node: '>=6.0.0'}
     hasBin: true
     dependencies:
-      '@babel/types': 7.21.5
+      '@babel/types': 7.22.4
 
-  /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.21.8):
+  /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.22.1):
     resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.21.8
+      '@babel/core': 7.22.1
       '@babel/helper-plugin-utils': 7.21.5
     dev: true
 
-  /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.21.8):
+  /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.22.1):
     resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.21.8
+      '@babel/core': 7.22.1
       '@babel/helper-plugin-utils': 7.21.5
     dev: true
 
-  /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.21.8):
-    resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==}
+  /@babel/plugin-transform-typescript@7.22.3(@babel/core@7.22.1):
+    resolution: {integrity: sha512-pyjnCIniO5PNaEuGxT28h0HbMru3qCVrMqVgVOz/krComdIrY9W6FCLBq9NWHY8HDGaUlan+UhmZElDENIfCcw==}
     engines: {node: '>=6.9.0'}
     peerDependencies:
       '@babel/core': ^7.0.0-0
     dependencies:
-      '@babel/core': 7.21.8
+      '@babel/core': 7.22.1
       '@babel/helper-annotate-as-pure': 7.18.6
-      '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.21.8)
+      '@babel/helper-create-class-features-plugin': 7.22.1(@babel/core@7.22.1)
       '@babel/helper-plugin-utils': 7.21.5
-      '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.21.8)
+      '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.22.1)
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -361,30 +365,30 @@ packages:
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/code-frame': 7.21.4
-      '@babel/parser': 7.21.9
-      '@babel/types': 7.21.5
+      '@babel/parser': 7.22.4
+      '@babel/types': 7.22.4
     dev: true
 
-  /@babel/traverse@7.21.5:
-    resolution: {integrity: sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==}
+  /@babel/traverse@7.22.4:
+    resolution: {integrity: sha512-Tn1pDsjIcI+JcLKq1AVlZEr4226gpuAQTsLMorsYg9tuS/kG7nuwwJ4AB8jfQuEgb/COBwR/DqJxmoiYFu5/rQ==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/code-frame': 7.21.4
-      '@babel/generator': 7.21.9
-      '@babel/helper-environment-visitor': 7.21.5
+      '@babel/generator': 7.22.3
+      '@babel/helper-environment-visitor': 7.22.1
       '@babel/helper-function-name': 7.21.0
       '@babel/helper-hoist-variables': 7.18.6
       '@babel/helper-split-export-declaration': 7.18.6
-      '@babel/parser': 7.21.9
-      '@babel/types': 7.21.5
+      '@babel/parser': 7.22.4
+      '@babel/types': 7.22.4
       debug: 4.3.4
       globals: 11.12.0
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@babel/types@7.21.5:
-    resolution: {integrity: sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==}
+  /@babel/types@7.22.4:
+    resolution: {integrity: sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==}
     engines: {node: '>=6.9.0'}
     dependencies:
       '@babel/helper-string-parser': 7.21.5
@@ -593,13 +597,13 @@ packages:
     dev: true
     optional: true
 
-  /@eslint-community/eslint-utils@4.4.0(eslint@8.41.0):
+  /@eslint-community/eslint-utils@4.4.0(eslint@8.42.0):
     resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
     dependencies:
-      eslint: 8.41.0
+      eslint: 8.42.0
       eslint-visitor-keys: 3.4.1
     dev: true
 
@@ -625,13 +629,13 @@ packages:
       - supports-color
     dev: true
 
-  /@eslint/js@8.41.0:
-    resolution: {integrity: sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==}
+  /@eslint/js@8.42.0:
+    resolution: {integrity: sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /@humanwhocodes/config-array@0.11.8:
-    resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==}
+  /@humanwhocodes/config-array@0.11.10:
+    resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==}
     engines: {node: '>=10.10.0'}
     dependencies:
       '@humanwhocodes/object-schema': 1.2.1
@@ -656,7 +660,7 @@ packages:
     dependencies:
       string-width: 5.1.2
       string-width-cjs: /string-width@4.2.3
-      strip-ansi: 7.0.1
+      strip-ansi: 7.1.0
       strip-ansi-cjs: /strip-ansi@6.0.1
       wrap-ansi: 8.1.0
       wrap-ansi-cjs: /wrap-ansi@7.0.0
@@ -728,8 +732,8 @@ packages:
     dev: true
     optional: true
 
-  /@pkgr/utils@2.4.0:
-    resolution: {integrity: sha512-2OCURAmRtdlL8iUDTypMrrxfwe8frXTeXaxGsVOaYtc/wrUyk8Z/0OBetM7cdlsy7ZFWlMX72VogKeh+A4Xcjw==}
+  /@pkgr/utils@2.4.1:
+    resolution: {integrity: sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==}
     engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
     dependencies:
       cross-spawn: 7.0.3
@@ -737,7 +741,7 @@ packages:
       is-glob: 4.0.3
       open: 9.1.0
       picocolors: 1.0.0
-      tslib: 2.5.2
+      tslib: 2.5.3
     dev: true
 
   /@tootallnate/once@2.0.0:
@@ -766,21 +770,21 @@ packages:
   /@types/jsdom@21.1.1:
     resolution: {integrity: sha512-cZFuoVLtzKP3gmq9eNosUL1R50U+USkbLtUQ1bYVgl/lKp0FZM7Cq4aIHAL8oIvQ17uSHi7jXPtfDOdjPwBE7A==}
     dependencies:
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       '@types/tough-cookie': 4.0.2
       parse5: 7.1.2
     dev: true
 
-  /@types/json-schema@7.0.11:
-    resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
+  /@types/json-schema@7.0.12:
+    resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==}
     dev: true
 
   /@types/json5@0.0.29:
     resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
     dev: true
 
-  /@types/node@20.2.3:
-    resolution: {integrity: sha512-pg9d0yC4rVNWQzX8U7xb4olIOFuuVL9za3bzMT2pu2SU0SNEi66i2qrvhE2qt0HvkhuCaWJu7pLNOt/Pj8BIrw==}
+  /@types/node@20.2.5:
+    resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==}
     dev: true
 
   /@types/semver@7.5.0:
@@ -791,8 +795,8 @@ packages:
     resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==}
     dev: true
 
-  /@typescript-eslint/eslint-plugin@5.59.7(@typescript-eslint/parser@5.59.7)(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-BL+jYxUFIbuYwy+4fF86k5vdT9lT0CNJ6HtwrIvGh0PhH8s0yy5rjaKH2fDCrz5ITHy07WCzVGNvAmjJh4IJFA==}
+  /@typescript-eslint/eslint-plugin@5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-JDMOmhXteJ4WVKOiHXGCoB96ADWg9q7efPWHRViT/f09bA8XOMLAVHHju3l0MkZnG1izaWXYmgvQcUjTRcpShQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       '@typescript-eslint/parser': ^5.0.0
@@ -803,24 +807,24 @@ packages:
         optional: true
     dependencies:
       '@eslint-community/regexpp': 4.5.1
-      '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
-      '@typescript-eslint/scope-manager': 5.59.7
-      '@typescript-eslint/type-utils': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
-      '@typescript-eslint/utils': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
+      '@typescript-eslint/scope-manager': 5.59.8
+      '@typescript-eslint/type-utils': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
+      '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       debug: 4.3.4
-      eslint: 8.41.0
+      eslint: 8.42.0
       grapheme-splitter: 1.0.4
       ignore: 5.2.4
       natural-compare-lite: 1.4.0
       semver: 7.5.1
-      tsutils: 3.21.0(typescript@5.0.4)
-      typescript: 5.0.4
+      tsutils: 3.21.0(typescript@5.1.3)
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/parser@5.59.7(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==}
+  /@typescript-eslint/parser@5.59.8(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-AnR19RjJcpjoeGojmwZtCwBX/RidqDZtzcbG3xHrmz0aHHoOcbWnpDllenRDmDvsV0RQ6+tbb09/kyc+UT9Orw==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
@@ -829,26 +833,26 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/scope-manager': 5.59.7
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/typescript-estree': 5.59.7(typescript@5.0.4)
+      '@typescript-eslint/scope-manager': 5.59.8
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
       debug: 4.3.4
-      eslint: 8.41.0
-      typescript: 5.0.4
+      eslint: 8.42.0
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/scope-manager@5.59.7:
-    resolution: {integrity: sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==}
+  /@typescript-eslint/scope-manager@5.59.8:
+    resolution: {integrity: sha512-/w08ndCYI8gxGf+9zKf1vtx/16y8MHrZs5/tnjHhMLNSixuNcJavSX4wAiPf4aS5x41Es9YPCn44MIe4cxIlig==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/visitor-keys': 5.59.7
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/visitor-keys': 5.59.8
     dev: true
 
-  /@typescript-eslint/type-utils@5.59.7(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-ozuz/GILuYG7osdY5O5yg0QxXUAEoI4Go3Do5xeu+ERH9PorHBPSdvD3Tjp2NN2bNLh1NJQSsQu2TPu/Ly+HaQ==}
+  /@typescript-eslint/type-utils@5.59.8(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-+5M518uEIHFBy3FnyqZUF3BMP+AXnYn4oyH8RF012+e7/msMY98FhGL5SrN29NQ9xDgvqCgYnsOiKp1VjZ/fpA==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '*'
@@ -857,23 +861,23 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/typescript-estree': 5.59.7(typescript@5.0.4)
-      '@typescript-eslint/utils': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
+      '@typescript-eslint/utils': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       debug: 4.3.4
-      eslint: 8.41.0
-      tsutils: 3.21.0(typescript@5.0.4)
-      typescript: 5.0.4
+      eslint: 8.42.0
+      tsutils: 3.21.0(typescript@5.1.3)
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/types@5.59.7:
-    resolution: {integrity: sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==}
+  /@typescript-eslint/types@5.59.8:
+    resolution: {integrity: sha512-+uWuOhBTj/L6awoWIg0BlWy0u9TyFpCHrAuQ5bNfxDaZ1Ppb3mx6tUigc74LHcbHpOHuOTOJrBoAnhdHdaea1w==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /@typescript-eslint/typescript-estree@5.59.7(typescript@5.0.4):
-    resolution: {integrity: sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==}
+  /@typescript-eslint/typescript-estree@5.59.8(typescript@5.1.3):
+    resolution: {integrity: sha512-Jy/lPSDJGNow14vYu6IrW790p7HIf/SOV1Bb6lZ7NUkLc2iB2Z9elESmsaUtLw8kVqogSbtLH9tut5GCX1RLDg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       typescript: '*'
@@ -881,31 +885,31 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/visitor-keys': 5.59.7
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/visitor-keys': 5.59.8
       debug: 4.3.4
       globby: 11.1.0
       is-glob: 4.0.3
       semver: 7.5.1
-      tsutils: 3.21.0(typescript@5.0.4)
-      typescript: 5.0.4
+      tsutils: 3.21.0(typescript@5.1.3)
+      typescript: 5.1.3
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@typescript-eslint/utils@5.59.7(eslint@8.41.0)(typescript@5.0.4):
-    resolution: {integrity: sha512-yCX9WpdQKaLufz5luG4aJbOpdXf/fjwGMcLFXZVPUz3QqLirG5QcwwnIHNf8cjLjxK4qtzTO8udUtMQSAToQnQ==}
+  /@typescript-eslint/utils@5.59.8(eslint@8.42.0)(typescript@5.1.3):
+    resolution: {integrity: sha512-Tr65630KysnNn9f9G7ROF3w1b5/7f6QVCJ+WK9nhIocWmx9F+TmCAcglF26Vm7z8KCTwoKcNEBZrhlklla3CKg==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
-      '@types/json-schema': 7.0.11
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
+      '@types/json-schema': 7.0.12
       '@types/semver': 7.5.0
-      '@typescript-eslint/scope-manager': 5.59.7
-      '@typescript-eslint/types': 5.59.7
-      '@typescript-eslint/typescript-estree': 5.59.7(typescript@5.0.4)
-      eslint: 8.41.0
+      '@typescript-eslint/scope-manager': 5.59.8
+      '@typescript-eslint/types': 5.59.8
+      '@typescript-eslint/typescript-estree': 5.59.8(typescript@5.1.3)
+      eslint: 8.42.0
       eslint-scope: 5.1.1
       semver: 7.5.1
     transitivePeerDependencies:
@@ -913,87 +917,87 @@ packages:
       - typescript
     dev: true
 
-  /@typescript-eslint/visitor-keys@5.59.7:
-    resolution: {integrity: sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==}
+  /@typescript-eslint/visitor-keys@5.59.8:
+    resolution: {integrity: sha512-pJhi2ms0x0xgloT7xYabil3SGGlojNNKjK/q6dB3Ey0uJLMjK2UDGJvHieiyJVW/7C3KI+Z4Q3pEHkm4ejA+xQ==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dependencies:
-      '@typescript-eslint/types': 5.59.7
+      '@typescript-eslint/types': 5.59.8
       eslint-visitor-keys: 3.4.1
     dev: true
 
-  /@vitejs/plugin-vue-jsx@3.0.1(vite@4.3.8)(vue@3.3.4):
+  /@vitejs/plugin-vue-jsx@3.0.1(vite@4.3.9)(vue@3.3.4):
     resolution: {integrity: sha512-+Jb7ggL48FSPS1uhPnJbJwWa9Sr90vQ+d0InW+AhBM22n+cfuYqJZDckBc+W3QSHe1WDvewMZfa4wZOtk5pRgw==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       vite: ^4.0.0
       vue: ^3.0.0
     dependencies:
-      '@babel/core': 7.21.8
-      '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.21.8)
-      '@vue/babel-plugin-jsx': 1.1.1(@babel/core@7.21.8)
-      vite: 4.3.8(@types/node@20.2.3)
+      '@babel/core': 7.22.1
+      '@babel/plugin-transform-typescript': 7.22.3(@babel/core@7.22.1)
+      '@vue/babel-plugin-jsx': 1.1.1(@babel/core@7.22.1)
+      vite: 4.3.9(@types/node@20.2.5)
       vue: 3.3.4
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /@vitejs/plugin-vue@4.2.3(vite@4.3.8)(vue@3.3.4):
+  /@vitejs/plugin-vue@4.2.3(vite@4.3.9)(vue@3.3.4):
     resolution: {integrity: sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
       vite: ^4.0.0
       vue: ^3.2.25
     dependencies:
-      vite: 4.3.8(@types/node@20.2.3)
+      vite: 4.3.9(@types/node@20.2.5)
       vue: 3.3.4
     dev: true
 
-  /@vitest/coverage-c8@0.31.1(vitest@0.31.1):
-    resolution: {integrity: sha512-6TkjQpmgYez7e3dbAUoYdRXxWN81BojCmUILJwgCy39uZFG33DsQ0rSRSZC9beAEdCZTpxR63nOvd9hxDQcJ0g==}
+  /@vitest/coverage-c8@0.31.4(vitest@0.31.4):
+    resolution: {integrity: sha512-VPx368m4DTcpA/P0v3YdVxl4QOSh1DbUcXURLRvDShrIB5KxOgfzw4Bn2R8AhAe/GyiWW/FIsJ/OJdYXCCiC1w==}
     peerDependencies:
       vitest: '>=0.30.0 <1'
     dependencies:
       '@ampproject/remapping': 2.2.1
-      c8: 7.13.0
+      c8: 7.14.0
       magic-string: 0.30.0
       picocolors: 1.0.0
       std-env: 3.3.3
-      vitest: 0.31.1(jsdom@22.0.0)
+      vitest: 0.31.4(jsdom@22.1.0)
     dev: true
 
-  /@vitest/expect@0.31.1:
-    resolution: {integrity: sha512-BV1LyNvhnX+eNYzJxlHIGPWZpwJFZaCcOIzp2CNG0P+bbetenTupk6EO0LANm4QFt0TTit+yqx7Rxd1qxi/SQA==}
+  /@vitest/expect@0.31.4:
+    resolution: {integrity: sha512-tibyx8o7GUyGHZGyPgzwiaPaLDQ9MMuCOrc03BYT0nryUuhLbL7NV2r/q98iv5STlwMgaKuFJkgBW/8iPKwlSg==}
     dependencies:
-      '@vitest/spy': 0.31.1
-      '@vitest/utils': 0.31.1
+      '@vitest/spy': 0.31.4
+      '@vitest/utils': 0.31.4
       chai: 4.3.7
     dev: true
 
-  /@vitest/runner@0.31.1:
-    resolution: {integrity: sha512-imWuc82ngOtxdCUpXwtEzZIuc1KMr+VlQ3Ondph45VhWoQWit5yvG/fFcldbnCi8DUuFi+NmNx5ehMUw/cGLUw==}
+  /@vitest/runner@0.31.4:
+    resolution: {integrity: sha512-Wgm6UER+gwq6zkyrm5/wbpXGF+g+UBB78asJlFkIOwyse0pz8lZoiC6SW5i4gPnls/zUcPLWS7Zog0LVepXnpg==}
     dependencies:
-      '@vitest/utils': 0.31.1
+      '@vitest/utils': 0.31.4
       concordance: 5.0.4
       p-limit: 4.0.0
-      pathe: 1.1.0
+      pathe: 1.1.1
     dev: true
 
-  /@vitest/snapshot@0.31.1:
-    resolution: {integrity: sha512-L3w5uU9bMe6asrNzJ8WZzN+jUTX4KSgCinEJPXyny0o90fG4FPQMV0OWsq7vrCWfQlAilMjDnOF9nP8lidsJ+g==}
+  /@vitest/snapshot@0.31.4:
+    resolution: {integrity: sha512-LemvNumL3NdWSmfVAMpXILGyaXPkZbG5tyl6+RQSdcHnTj6hvA49UAI8jzez9oQyE/FWLKRSNqTGzsHuk89LRA==}
     dependencies:
       magic-string: 0.30.0
-      pathe: 1.1.0
+      pathe: 1.1.1
       pretty-format: 27.5.1
     dev: true
 
-  /@vitest/spy@0.31.1:
-    resolution: {integrity: sha512-1cTpt2m9mdo3hRLDyCG2hDQvRrePTDgEJBFQQNz1ydHHZy03EiA6EpFxY+7ODaY7vMRCie+WlFZBZ0/dQWyssQ==}
+  /@vitest/spy@0.31.4:
+    resolution: {integrity: sha512-3ei5ZH1s3aqbEyftPAzSuunGICRuhE+IXOmpURFdkm5ybUADk+viyQfejNk6q8M5QGX8/EVKw+QWMEP3DTJDag==}
     dependencies:
-      tinyspy: 2.1.0
+      tinyspy: 2.1.1
     dev: true
 
-  /@vitest/utils@0.31.1:
-    resolution: {integrity: sha512-yFyRD5ilwojsZfo3E0BnH72pSVSuLg2356cN1tCEe/0RtDzxTPYwOomIC+eQbot7m6DRy4tPZw+09mB7NkbMmA==}
+  /@vitest/utils@0.31.4:
+    resolution: {integrity: sha512-DobZbHacWznoGUfYU8XDPY78UubJxXfMNY1+SUdOp1NsI34eopSA6aZMeaGu10waSOeYwE8lxrd/pLfT0RMxjQ==}
     dependencies:
       concordance: 5.0.4
       loupe: 2.3.6
@@ -1004,14 +1008,14 @@ packages:
     resolution: {integrity: sha512-hz4R8tS5jMn8lDq6iD+yWL6XNB699pGIVLk7WSJnn1dbpjaazsjZQkieJoRX6gW5zpYSCFqQ7jUquPNY65tQYA==}
     dev: true
 
-  /@vue/babel-plugin-jsx@1.1.1(@babel/core@7.21.8):
+  /@vue/babel-plugin-jsx@1.1.1(@babel/core@7.22.1):
     resolution: {integrity: sha512-j2uVfZjnB5+zkcbc/zsOc0fSNGCMMjaEXP52wdwdIfn0qjFfEYpYZBFKFg+HHnQeJCVrjOeO0YxgaL7DMrym9w==}
     dependencies:
       '@babel/helper-module-imports': 7.21.4
-      '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.8)
+      '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.1)
       '@babel/template': 7.21.9
-      '@babel/traverse': 7.21.5
-      '@babel/types': 7.21.5
+      '@babel/traverse': 7.22.4
+      '@babel/types': 7.22.4
       '@vue/babel-helper-vue-transform-on': 1.0.2
       camelcase: 6.3.0
       html-tags: 3.3.1
@@ -1024,7 +1028,7 @@ packages:
   /@vue/compiler-core@3.3.4:
     resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==}
     dependencies:
-      '@babel/parser': 7.21.9
+      '@babel/parser': 7.22.4
       '@vue/shared': 3.3.4
       estree-walker: 2.0.2
       source-map-js: 1.0.2
@@ -1038,7 +1042,7 @@ packages:
   /@vue/compiler-sfc@3.3.4:
     resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==}
     dependencies:
-      '@babel/parser': 7.21.9
+      '@babel/parser': 7.22.4
       '@vue/compiler-core': 3.3.4
       '@vue/compiler-dom': 3.3.4
       '@vue/compiler-ssr': 3.3.4
@@ -1046,7 +1050,7 @@ packages:
       '@vue/shared': 3.3.4
       estree-walker: 2.0.2
       magic-string: 0.30.0
-      postcss: 8.4.23
+      postcss: 8.4.24
       source-map-js: 1.0.2
 
   /@vue/compiler-ssr@3.3.4:
@@ -1059,19 +1063,19 @@ packages:
     resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==}
     dev: false
 
-  /@vue/eslint-config-prettier@7.1.0(eslint@8.41.0)(prettier@2.8.8):
+  /@vue/eslint-config-prettier@7.1.0(eslint@8.42.0)(prettier@2.8.8):
     resolution: {integrity: sha512-Pv/lVr0bAzSIHLd9iz0KnvAr4GKyCEl+h52bc4e5yWuDVtLgFwycF7nrbWTAQAS+FU6q1geVd07lc6EWfJiWKQ==}
     peerDependencies:
       eslint: '>= 7.28.0'
       prettier: '>= 2.0.0'
     dependencies:
-      eslint: 8.41.0
-      eslint-config-prettier: 8.8.0(eslint@8.41.0)
-      eslint-plugin-prettier: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.41.0)(prettier@2.8.8)
+      eslint: 8.42.0
+      eslint-config-prettier: 8.8.0(eslint@8.42.0)
+      eslint-plugin-prettier: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8)
       prettier: 2.8.8
     dev: true
 
-  /@vue/eslint-config-typescript@11.0.3(eslint-plugin-vue@9.14.0)(eslint@8.41.0)(typescript@5.0.4):
+  /@vue/eslint-config-typescript@11.0.3(eslint-plugin-vue@9.14.1)(eslint@8.42.0)(typescript@5.1.3):
     resolution: {integrity: sha512-dkt6W0PX6H/4Xuxg/BlFj5xHvksjpSlVjtkQCpaYJBIEuKj2hOVU7r+TIe+ysCwRYFz/lGqvklntRkCAibsbPw==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
@@ -1082,12 +1086,12 @@ packages:
       typescript:
         optional: true
     dependencies:
-      '@typescript-eslint/eslint-plugin': 5.59.7(@typescript-eslint/parser@5.59.7)(eslint@8.41.0)(typescript@5.0.4)
-      '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
-      eslint: 8.41.0
-      eslint-plugin-vue: 9.14.0(eslint@8.41.0)
-      typescript: 5.0.4
-      vue-eslint-parser: 9.3.0(eslint@8.41.0)
+      '@typescript-eslint/eslint-plugin': 5.59.8(@typescript-eslint/parser@5.59.8)(eslint@8.42.0)(typescript@5.1.3)
+      '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
+      eslint: 8.42.0
+      eslint-plugin-vue: 9.14.1(eslint@8.42.0)
+      typescript: 5.1.3
+      vue-eslint-parser: 9.3.0(eslint@8.42.0)
     transitivePeerDependencies:
       - supports-color
     dev: true
@@ -1095,7 +1099,7 @@ packages:
   /@vue/reactivity-transform@3.3.4:
     resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==}
     dependencies:
-      '@babel/parser': 7.21.9
+      '@babel/parser': 7.22.4
       '@vue/compiler-core': 3.3.4
       '@vue/shared': 3.3.4
       estree-walker: 2.0.2
@@ -1330,15 +1334,15 @@ packages:
       fill-range: 7.0.1
     dev: true
 
-  /browserslist@4.21.5:
-    resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==}
+  /browserslist@4.21.7:
+    resolution: {integrity: sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA==}
     engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
     hasBin: true
     dependencies:
-      caniuse-lite: 1.0.30001489
-      electron-to-chromium: 1.4.404
-      node-releases: 2.0.11
-      update-browserslist-db: 1.0.11(browserslist@4.21.5)
+      caniuse-lite: 1.0.30001494
+      electron-to-chromium: 1.4.419
+      node-releases: 2.0.12
+      update-browserslist-db: 1.0.11(browserslist@4.21.7)
     dev: true
 
   /bundle-name@3.0.0:
@@ -1348,8 +1352,8 @@ packages:
       run-applescript: 5.0.0
     dev: true
 
-  /c8@7.13.0:
-    resolution: {integrity: sha512-/NL4hQTv1gBL6J6ei80zu3IiTrmePDKXKXOTLpHvcIWZTVYQlDhVWjjWvkhICylE8EwwnMVzDZugCvdx0/DIIA==}
+  /c8@7.14.0:
+    resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==}
     engines: {node: '>=10.12.0'}
     hasBin: true
     dependencies:
@@ -1389,8 +1393,8 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /caniuse-lite@1.0.30001489:
-    resolution: {integrity: sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==}
+  /caniuse-lite@1.0.30001494:
+    resolution: {integrity: sha512-sY2B5Qyl46ZzfYDegrl8GBCzdawSLT4ThM9b9F+aDYUrAG2zCOyMbd2Tq34mS1g4ZKBfjRlzOohQMxx28x6wJg==}
     dev: true
 
   /chai@4.3.7:
@@ -1686,8 +1690,8 @@ packages:
     resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
     dev: false
 
-  /electron-to-chromium@1.4.404:
-    resolution: {integrity: sha512-te57sWvQdpxmyd1GiswaodKdXdPgn9cN4ht8JlNa04QgtrfnUdWEo1261rY2vaC6TKaiHn0E7QerJWPKFCvMVw==}
+  /electron-to-chromium@1.4.419:
+    resolution: {integrity: sha512-jdie3RiEgygvDTyS2sgjq71B36q2cDSBfPlwzUyuOrfYTNoYWyBxxjGJV/HAu3A2hB0Y+HesvCVkVAFoCKwCSw==}
     dev: true
 
   /emoji-regex@8.0.0:
@@ -1703,8 +1707,8 @@ packages:
     engines: {node: '>= 0.8'}
     dev: false
 
-  /enhanced-resolve@5.14.0:
-    resolution: {integrity: sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==}
+  /enhanced-resolve@5.14.1:
+    resolution: {integrity: sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==}
     engines: {node: '>=10.13.0'}
     dependencies:
       graceful-fs: 4.2.11
@@ -1829,13 +1833,13 @@ packages:
     engines: {node: '>=10'}
     dev: true
 
-  /eslint-config-prettier@8.8.0(eslint@8.41.0):
+  /eslint-config-prettier@8.8.0(eslint@8.42.0):
     resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==}
     hasBin: true
     peerDependencies:
       eslint: '>=7.0.0'
     dependencies:
-      eslint: 8.41.0
+      eslint: 8.42.0
     dev: true
 
   /eslint-define-config@1.20.0:
@@ -1853,7 +1857,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0):
+  /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@5.59.8)(eslint-plugin-import@2.27.5)(eslint@8.42.0):
     resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==}
     engines: {node: ^14.18.0 || >=16.0.0}
     peerDependencies:
@@ -1861,11 +1865,11 @@ packages:
       eslint-plugin-import: '*'
     dependencies:
       debug: 4.3.4
-      enhanced-resolve: 5.14.0
-      eslint: 8.41.0
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
-      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
-      get-tsconfig: 4.5.0
+      enhanced-resolve: 5.14.1
+      eslint: 8.42.0
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
+      eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
+      get-tsconfig: 4.6.0
       globby: 13.1.4
       is-core-module: 2.12.1
       is-glob: 4.0.3
@@ -1877,7 +1881,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0):
+  /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0):
     resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -1898,16 +1902,16 @@ packages:
       eslint-import-resolver-webpack:
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       debug: 3.2.7
-      eslint: 8.41.0
+      eslint: 8.42.0
       eslint-import-resolver-node: 0.3.7
-      eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.7)(eslint-plugin-import@2.27.5)(eslint@8.41.0)
+      eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@5.59.8)(eslint-plugin-import@2.27.5)(eslint@8.42.0)
     transitivePeerDependencies:
       - supports-color
     dev: true
 
-  /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0):
+  /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0):
     resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==}
     engines: {node: '>=4'}
     peerDependencies:
@@ -1917,15 +1921,15 @@ packages:
       '@typescript-eslint/parser':
         optional: true
     dependencies:
-      '@typescript-eslint/parser': 5.59.7(eslint@8.41.0)(typescript@5.0.4)
+      '@typescript-eslint/parser': 5.59.8(eslint@8.42.0)(typescript@5.1.3)
       array-includes: 3.1.6
       array.prototype.flat: 1.3.1
       array.prototype.flatmap: 1.3.1
       debug: 3.2.7
       doctrine: 2.1.0
-      eslint: 8.41.0
+      eslint: 8.42.0
       eslint-import-resolver-node: 0.3.7
-      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.7)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.41.0)
+      eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.8)(eslint-import-resolver-node@0.3.7)(eslint-import-resolver-typescript@3.5.5)(eslint@8.42.0)
       has: 1.0.3
       is-core-module: 2.12.1
       is-glob: 4.0.3
@@ -1940,7 +1944,7 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.41.0)(prettier@2.8.8):
+  /eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.42.0)(prettier@2.8.8):
     resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
     engines: {node: '>=12.0.0'}
     peerDependencies:
@@ -1951,25 +1955,25 @@ packages:
       eslint-config-prettier:
         optional: true
     dependencies:
-      eslint: 8.41.0
-      eslint-config-prettier: 8.8.0(eslint@8.41.0)
+      eslint: 8.42.0
+      eslint-config-prettier: 8.8.0(eslint@8.42.0)
       prettier: 2.8.8
       prettier-linter-helpers: 1.0.0
     dev: true
 
-  /eslint-plugin-vue@9.14.0(eslint@8.41.0):
-    resolution: {integrity: sha512-4O7EuiqPGVQA1wYCzLvCzsBTv9JIPHLHhrf0k55DLzbwtmJbSw2TKS0G/l7pOwi9RWMSkjIT7ftChU5gZpgnJw==}
+  /eslint-plugin-vue@9.14.1(eslint@8.42.0):
+    resolution: {integrity: sha512-LQazDB1qkNEKejLe/b5a9VfEbtbczcOaui5lQ4Qw0tbRBbQYREyxxOV5BQgNDTqGPs9pxqiEpbMi9ywuIaF7vw==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: ^6.2.0 || ^7.0.0 || ^8.0.0
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
-      eslint: 8.41.0
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
+      eslint: 8.42.0
       natural-compare: 1.4.0
       nth-check: 2.1.1
       postcss-selector-parser: 6.0.13
       semver: 7.5.1
-      vue-eslint-parser: 9.3.0(eslint@8.41.0)
+      vue-eslint-parser: 9.3.0(eslint@8.42.0)
       xml-name-validator: 4.0.0
     transitivePeerDependencies:
       - supports-color
@@ -1996,16 +2000,16 @@ packages:
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     dev: true
 
-  /eslint@8.41.0:
-    resolution: {integrity: sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==}
+  /eslint@8.42.0:
+    resolution: {integrity: sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
     hasBin: true
     dependencies:
-      '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0)
+      '@eslint-community/eslint-utils': 4.4.0(eslint@8.42.0)
       '@eslint-community/regexpp': 4.5.1
       '@eslint/eslintrc': 2.0.3
-      '@eslint/js': 8.41.0
-      '@humanwhocodes/config-array': 0.11.8
+      '@eslint/js': 8.42.0
+      '@humanwhocodes/config-array': 0.11.10
       '@humanwhocodes/module-importer': 1.0.1
       '@nodelib/fs.walk': 1.2.8
       ajv: 6.12.6
@@ -2304,8 +2308,10 @@ packages:
       get-intrinsic: 1.2.1
     dev: true
 
-  /get-tsconfig@4.5.0:
-    resolution: {integrity: sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==}
+  /get-tsconfig@4.6.0:
+    resolution: {integrity: sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg==}
+    dependencies:
+      resolve-pkg-maps: 1.0.0
     dev: true
 
   /glob-parent@5.1.2:
@@ -2793,8 +2799,8 @@ packages:
       argparse: 2.0.1
     dev: true
 
-  /jsdom@22.0.0:
-    resolution: {integrity: sha512-p5ZTEb5h+O+iU02t0GfEjAnkdYPrQSkfuTSMkMYyIoMvUNEHsbG0bHHbfXIcfTqD2UfvjQX7mmgiFsyRwGscVw==}
+  /jsdom@22.1.0:
+    resolution: {integrity: sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==}
     engines: {node: '>=16'}
     peerDependencies:
       canvas: ^2.5.0
@@ -2812,7 +2818,7 @@ packages:
       http-proxy-agent: 5.0.0
       https-proxy-agent: 5.0.1
       is-potential-custom-element-name: 1.0.1
-      nwsapi: 2.2.4
+      nwsapi: 2.2.5
       parse5: 7.1.2
       rrweb-cssom: 0.6.0
       saxes: 6.0.0
@@ -2916,8 +2922,8 @@ packages:
       yallist: 4.0.0
     dev: true
 
-  /lru-cache@9.1.1:
-    resolution: {integrity: sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==}
+  /lru-cache@9.1.2:
+    resolution: {integrity: sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==}
     engines: {node: 14 || >=16.14}
     dev: true
 
@@ -3015,11 +3021,11 @@ packages:
     engines: {node: '>=16 || 14 >=14.17'}
     dev: true
 
-  /mlly@1.2.1:
-    resolution: {integrity: sha512-1aMEByaWgBPEbWV2BOPEMySRrzl7rIHXmQxam4DM8jVjalTQDjpN2ZKOLUrwyhfZQO7IXHml2StcHMhooDeEEQ==}
+  /mlly@1.3.0:
+    resolution: {integrity: sha512-HT5mcgIQKkOrZecOjOX3DJorTikWXwsBfpcr/MGBkhfWcjiqvnaL/9ppxvIUXfjT6xt4DVIAsN9fMUz1ev4bIw==}
     dependencies:
       acorn: 8.8.2
-      pathe: 1.1.0
+      pathe: 1.1.1
       pkg-types: 1.0.3
       ufo: 1.1.2
     dev: true
@@ -3048,8 +3054,8 @@ packages:
     resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
     dev: true
 
-  /node-releases@2.0.11:
-    resolution: {integrity: sha512-+M0PwXeU80kRohZ3aT4J/OnR+l9/KD2nVLNNoRgFtnf+umQVFdGBAO2N8+nCnEi0xlh/Wk3zOGC+vNNx+uM79Q==}
+  /node-releases@2.0.12:
+    resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==}
     dev: true
 
   /nopt@6.0.0:
@@ -3080,8 +3086,8 @@ packages:
       boolbase: 1.0.0
     dev: true
 
-  /nwsapi@2.2.4:
-    resolution: {integrity: sha512-NHj4rzRo0tQdijE9ZqAx6kYDcoRwYwSYzCA8MY3JzfxlrvEU0jhnhJT9BhqhJs7I/dKcrDm6TyulaRqZPIhN5g==}
+  /nwsapi@2.2.5:
+    resolution: {integrity: sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ==}
     dev: true
 
   /object-inspect@1.12.3:
@@ -3228,7 +3234,7 @@ packages:
     resolution: {integrity: sha512-qSDLy2aGFPm8i4rsbHd4MNyTcrzHFsLQykrtbuGRknZZCBBVXSv2tSCDN2Cg6Rt/GFRw8GoW9y9Ecw5rIPG1sg==}
     engines: {node: '>=16 || 14 >=14.17'}
     dependencies:
-      lru-cache: 9.1.1
+      lru-cache: 9.1.2
       minipass: 6.0.2
     dev: true
 
@@ -3237,8 +3243,8 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
-  /pathe@1.1.0:
-    resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==}
+  /pathe@1.1.1:
+    resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==}
     dev: true
 
   /pathval@1.1.1:
@@ -3257,8 +3263,8 @@ packages:
     resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==}
     dependencies:
       jsonc-parser: 3.2.0
-      mlly: 1.2.1
-      pathe: 1.1.0
+      mlly: 1.3.0
+      pathe: 1.1.1
     dev: true
 
   /postcss-selector-parser@6.0.13:
@@ -3269,8 +3275,8 @@ packages:
       util-deprecate: 1.0.2
     dev: true
 
-  /postcss@8.4.23:
-    resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==}
+  /postcss@8.4.24:
+    resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==}
     engines: {node: ^10 || ^12 || >=14}
     dependencies:
       nanoid: 3.3.6
@@ -3361,6 +3367,10 @@ packages:
     engines: {node: '>=4'}
     dev: true
 
+  /resolve-pkg-maps@1.0.0:
+    resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
+    dev: true
+
   /resolve@1.22.2:
     resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==}
     hasBin: true
@@ -3568,7 +3578,7 @@ packages:
     dependencies:
       eastasianwidth: 0.2.0
       emoji-regex: 9.2.2
-      strip-ansi: 7.0.1
+      strip-ansi: 7.1.0
     dev: true
 
   /string.prototype.trim@1.2.7:
@@ -3603,8 +3613,8 @@ packages:
       ansi-regex: 5.0.1
     dev: true
 
-  /strip-ansi@7.0.1:
-    resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==}
+  /strip-ansi@7.1.0:
+    resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
     engines: {node: '>=12'}
     dependencies:
       ansi-regex: 6.0.1
@@ -3667,8 +3677,8 @@ packages:
     resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==}
     engines: {node: ^14.18.0 || >=16.0.0}
     dependencies:
-      '@pkgr/utils': 2.4.0
-      tslib: 2.5.2
+      '@pkgr/utils': 2.4.1
+      tslib: 2.5.3
     dev: true
 
   /tapable@2.2.1:
@@ -3703,8 +3713,8 @@ packages:
     engines: {node: '>=14.0.0'}
     dev: true
 
-  /tinyspy@2.1.0:
-    resolution: {integrity: sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==}
+  /tinyspy@2.1.1:
+    resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==}
     engines: {node: '>=14.0.0'}
     dev: true
 
@@ -3759,18 +3769,18 @@ packages:
     resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
     dev: true
 
-  /tslib@2.5.2:
-    resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==}
+  /tslib@2.5.3:
+    resolution: {integrity: sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==}
     dev: true
 
-  /tsutils@3.21.0(typescript@5.0.4):
+  /tsutils@3.21.0(typescript@5.1.3):
     resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
     engines: {node: '>= 6'}
     peerDependencies:
       typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
     dependencies:
       tslib: 1.14.1
-      typescript: 5.0.4
+      typescript: 5.1.3
     dev: true
 
   /type-check@0.4.0:
@@ -3798,9 +3808,9 @@ packages:
       is-typed-array: 1.1.10
     dev: true
 
-  /typescript@5.0.4:
-    resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
-    engines: {node: '>=12.20'}
+  /typescript@5.1.3:
+    resolution: {integrity: sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==}
+    engines: {node: '>=14.17'}
     hasBin: true
     dev: true
 
@@ -3832,13 +3842,13 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
-  /update-browserslist-db@1.0.11(browserslist@4.21.5):
+  /update-browserslist-db@1.0.11(browserslist@4.21.7):
     resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
     hasBin: true
     peerDependencies:
       browserslist: '>= 4.21.0'
     dependencies:
-      browserslist: 4.21.5
+      browserslist: 4.21.7
       escalade: 3.1.1
       picocolors: 1.0.0
     dev: true
@@ -3869,17 +3879,17 @@ packages:
       convert-source-map: 1.9.0
     dev: true
 
-  /vite-node@0.31.1(@types/node@20.2.3):
-    resolution: {integrity: sha512-BajE/IsNQ6JyizPzu9zRgHrBwczkAs0erQf/JRpgTIESpKvNj9/Gd0vxX905klLkb0I0SJVCKbdrl5c6FnqYKA==}
+  /vite-node@0.31.4(@types/node@20.2.5):
+    resolution: {integrity: sha512-uzL377GjJtTbuc5KQxVbDu2xfU/x0wVjUtXQR2ihS21q/NK6ROr4oG0rsSkBBddZUVCwzfx22in76/0ZZHXgkQ==}
     engines: {node: '>=v14.18.0'}
     hasBin: true
     dependencies:
       cac: 6.7.14
       debug: 4.3.4
-      mlly: 1.2.1
-      pathe: 1.1.0
+      mlly: 1.3.0
+      pathe: 1.1.1
       picocolors: 1.0.0
-      vite: 4.3.8(@types/node@20.2.3)
+      vite: 4.3.9(@types/node@20.2.5)
     transitivePeerDependencies:
       - '@types/node'
       - less
@@ -3890,8 +3900,8 @@ packages:
       - terser
     dev: true
 
-  /vite@4.3.8(@types/node@20.2.3):
-    resolution: {integrity: sha512-uYB8PwN7hbMrf4j1xzGDk/lqjsZvCDbt/JC5dyfxc19Pg8kRm14LinK/uq+HSLNswZEoKmweGdtpbnxRtrAXiQ==}
+  /vite@4.3.9(@types/node@20.2.5):
+    resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==}
     engines: {node: ^14.18.0 || >=16.0.0}
     hasBin: true
     peerDependencies:
@@ -3915,16 +3925,16 @@ packages:
       terser:
         optional: true
     dependencies:
-      '@types/node': 20.2.3
+      '@types/node': 20.2.5
       esbuild: 0.17.19
-      postcss: 8.4.23
+      postcss: 8.4.24
       rollup: 3.23.0
     optionalDependencies:
       fsevents: 2.3.2
     dev: true
 
-  /vitest@0.31.1(jsdom@22.0.0):
-    resolution: {integrity: sha512-/dOoOgzoFk/5pTvg1E65WVaobknWREN15+HF+0ucudo3dDG/vCZoXTQrjIfEaWvQXmqScwkRodrTbM/ScMpRcQ==}
+  /vitest@0.31.4(jsdom@22.1.0):
+    resolution: {integrity: sha512-GoV0VQPmWrUFOZSg3RpQAPN+LPmHg2/gxlMNJlyxJihkz6qReHDV6b0pPDcqFLNEPya4tWJ1pgwUNP9MLmUfvQ==}
     engines: {node: '>=v14.18.0'}
     hasBin: true
     peerDependencies:
@@ -3956,29 +3966,29 @@ packages:
     dependencies:
       '@types/chai': 4.3.5
       '@types/chai-subset': 1.3.3
-      '@types/node': 20.2.3
-      '@vitest/expect': 0.31.1
-      '@vitest/runner': 0.31.1
-      '@vitest/snapshot': 0.31.1
-      '@vitest/spy': 0.31.1
-      '@vitest/utils': 0.31.1
+      '@types/node': 20.2.5
+      '@vitest/expect': 0.31.4
+      '@vitest/runner': 0.31.4
+      '@vitest/snapshot': 0.31.4
+      '@vitest/spy': 0.31.4
+      '@vitest/utils': 0.31.4
       acorn: 8.8.2
       acorn-walk: 8.2.0
       cac: 6.7.14
       chai: 4.3.7
       concordance: 5.0.4
       debug: 4.3.4
-      jsdom: 22.0.0
+      jsdom: 22.1.0
       local-pkg: 0.4.3
       magic-string: 0.30.0
-      pathe: 1.1.0
+      pathe: 1.1.1
       picocolors: 1.0.0
       std-env: 3.3.3
       strip-literal: 1.0.1
       tinybench: 2.5.0
       tinypool: 0.5.0
-      vite: 4.3.8(@types/node@20.2.3)
-      vite-node: 0.31.1(@types/node@20.2.3)
+      vite: 4.3.9(@types/node@20.2.5)
+      vite-node: 0.31.4(@types/node@20.2.5)
       why-is-node-running: 2.2.2
     transitivePeerDependencies:
       - less
@@ -3989,14 +3999,14 @@ packages:
       - terser
     dev: true
 
-  /vue-eslint-parser@9.3.0(eslint@8.41.0):
+  /vue-eslint-parser@9.3.0(eslint@8.42.0):
     resolution: {integrity: sha512-48IxT9d0+wArT1+3wNIy0tascRoywqSUe2E1YalIC1L8jsUGe5aJQItWfRok7DVFGz3UYvzEI7n5wiTXsCMAcQ==}
     engines: {node: ^14.17.0 || >=16.0.0}
     peerDependencies:
       eslint: '>=6.0.0'
     dependencies:
       debug: 4.3.4
-      eslint: 8.41.0
+      eslint: 8.42.0
       eslint-scope: 7.2.0
       eslint-visitor-keys: 3.4.1
       espree: 9.5.2
@@ -4007,8 +4017,8 @@ packages:
       - supports-color
     dev: true
 
-  /vue-router@4.2.1(vue@3.3.4):
-    resolution: {integrity: sha512-nW28EeifEp8Abc5AfmAShy5ZKGsGzjcnZ3L1yc2DYUo+MqbBClrRP9yda3dIekM4I50/KnEwo1wkBLf7kHH5Cw==}
+  /vue-router@4.2.2(vue@3.3.4):
+    resolution: {integrity: sha512-cChBPPmAflgBGmy3tBsjeoe3f3VOSG6naKyY5pjtrqLGbNEXdzCigFUHgBvp9e3ysAtFtEx7OLqcSDh/1Cq2TQ==}
     peerDependencies:
       vue: ^3.2.0
     dependencies:
@@ -4121,7 +4131,7 @@ packages:
     dependencies:
       ansi-styles: 6.2.1
       string-width: 5.1.2
-      strip-ansi: 7.0.1
+      strip-ansi: 7.1.0
     dev: true
 
   /wrappy@1.0.2: