From c3b9c1ef98e638c3bc16cca6fb67a7171c9950a1 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 16 Sep 2025 14:52:30 +0200 Subject: [PATCH 01/19] revert commit 4b2468d61 to fix wifi issue with tasmota core --- src/ESP32React/MqttSettingsService.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ESP32React/MqttSettingsService.cpp b/src/ESP32React/MqttSettingsService.cpp index 395f5a421..fc1c065a3 100644 --- a/src/ESP32React/MqttSettingsService.cpp +++ b/src/ESP32React/MqttSettingsService.cpp @@ -33,9 +33,9 @@ void MqttSettingsService::begin() { void MqttSettingsService::startClient() { static bool isSecure = false; - if (_mqttClient != nullptr) { + if (_mqttClient) { // do we need to change the client? - if (_state.enabled && ((isSecure && _state.enableTLS) || (!isSecure && !_state.enableTLS))) { + if ((isSecure && _state.enableTLS) || (!isSecure && !_state.enableTLS)) { return; } delete _mqttClient; @@ -79,9 +79,6 @@ void MqttSettingsService::startClient() { } void MqttSettingsService::loop() { - if (!_state.enabled || _mqttClient == nullptr || emsesp::EMSESP::system_.systemStatus() != 0) { - return; - } if (_reconfigureMqtt || (_disconnectedAt && static_cast(uuid::get_uptime() - _disconnectedAt) >= MQTT_RECONNECTION_DELAY)) { // reconfigure MQTT client _disconnectedAt = configureMqtt() ? 0 : uuid::get_uptime(); From 61c3b47269bfcb7f6bef1c9c688e8e7587840b29 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 25 Sep 2025 17:11:21 +0200 Subject: [PATCH 02/19] fix display partition name, remove double quotes in shuntingyard --- platformio.ini | 4 ++-- src/core/shuntingYard.hpp | 22 ++++++++++++++++++---- src/core/system.cpp | 2 +- src/web/WebSchedulerService.cpp | 2 +- src/web/WebStatusService.cpp | 2 +- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/platformio.ini b/platformio.ini index 31748ace1..c1ee00bf0 100644 --- a/platformio.ini +++ b/platformio.ini @@ -108,8 +108,8 @@ build_type = release board_build.filesystem = littlefs lib_deps = bblanchon/ArduinoJson @ 7.4.2 - ESP32Async/AsyncTCP @ 3.4.7 - ESP32Async/ESPAsyncWebServer @ 3.8.0 + ESP32Async/AsyncTCP @ 3.4.8 + ESP32Async/ESPAsyncWebServer @ 3.8.1 https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8 ; diff --git a/src/core/shuntingYard.hpp b/src/core/shuntingYard.hpp index 14a993e19..256fa97c2 100644 --- a/src/core/shuntingYard.hpp +++ b/src/core/shuntingYard.hpp @@ -67,7 +67,12 @@ std::deque exprToTokens(const std::string & expr) { if (*p) { ++p; } - const auto s = std::string(b, p); + auto s = std::string(b, p); + auto n = s.find("\"\""); + while (n != std::string::npos) { + s.erase(n, 2); + n = s.find("\"\""); + } tokens.emplace_back(Token::Type::String, s, -3); if (*p == '\0') { --p; @@ -360,8 +365,8 @@ bool isnum(const std::string & s) { std::string commands(std::string & expr, bool quotes = true) { auto expr_new = emsesp::Helpers::toLower(expr); for (uint8_t device = 0; device < emsesp::EMSdevice::DeviceType::UNKNOWN; device++) { - const char * d = emsesp::EMSdevice::device_type_2_device_name(device); - auto f = expr_new.find(d); + std::string d = (std::string)emsesp::EMSdevice::device_type_2_device_name(device) + "/"; + auto f = expr_new.find(d); while (f != std::string::npos) { // entity names are alphanumeric or _ auto e = expr_new.find_first_not_of("/._abcdefghijklmnopqrstuvwxyz0123456789", f); @@ -401,6 +406,14 @@ std::string commands(std::string & expr, bool quotes = true) { f = expr_new.find(d, e); } } + if (quotes) { + // remove double quotes + auto f = expr.find("\"\""); + while (f != std::string::npos) { + expr.erase(f, 2); + f = expr.find("\"\""); + } + } return expr; } @@ -442,7 +455,7 @@ std::string to_hex(uint32_t i) { // RPN calculator std::string calculate(const std::string & expr) { std::string expr_new = expr; - commands(expr_new); + // commands(expr_new); const auto tokens = exprToTokens(expr_new); if (tokens.empty()) { @@ -679,6 +692,7 @@ std::string calculate(const std::string & expr) { // check for multiple instances of ? : std::string compute(const std::string & expr) { std::string expr_new = expr; + commands(expr_new); // replace ems-esp commands with values // search json with url: auto f = expr_new.find_first_of('{'); diff --git a/src/core/system.cpp b/src/core/system.cpp index 064fd2f7e..ef7564a5b 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1572,7 +1572,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject output node["freeCaps"] = heap_caps_get_free_size(MALLOC_CAP_8BIT) / 1024; // includes heap and psram node["usedApp"] = EMSESP::system_.appUsed(); // kilobytes node["freeApp"] = EMSESP::system_.appFree(); // kilobytes - node["partition"] = esp_ota_get_running_partition()->label; // active partition + node["partition"] = (const char *)esp_ota_get_running_partition()->label; // active partition node["flash_chip_size"] = ESP.getFlashChipSize() / 1024; // kilobytes #endif node["resetReason"] = EMSESP::system_.reset_reason(0) + " / " + EMSESP::system_.reset_reason(1); diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index 06f317fc2..c325a7036 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -351,7 +351,7 @@ bool WebSchedulerService::command(const char * name, const std::string & command } std::string value = doc["value"] | data.c_str(); // extract value if its in the command, or take the data std::string method = doc["method"] | "GET"; // default GET - + commands(value, false); // if there is data, force a POST int httpResult = 0; if (value.length() || method == "post") { // we have all lowercase diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 0431479b8..a13d99303 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -115,7 +115,7 @@ void WebStatusService::systemStatus(AsyncWebServerRequest * request) { root["max_alloc_heap"] = EMSESP::system_.getMaxAllocMem(); root["arduino_version"] = ARDUINO_VERSION; root["sdk_version"] = ESP.getSdkVersion(); - root["partition"] = esp_ota_get_running_partition()->label; // active partition + root["partition"] = (const char *)esp_ota_get_running_partition()->label; // active partition root["flash_chip_size"] = ESP.getFlashChipSize() / 1024; root["flash_chip_speed"] = ESP.getFlashChipSpeed(); root["app_used"] = EMSESP::system_.appUsed(); From ae26754bc83367290573fb3014e4d0377c7a9825 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 26 Sep 2025 08:44:58 +0200 Subject: [PATCH 03/19] update pkg --- interface/package.json | 30 +- interface/pnpm-lock.yaml | 1180 +++++++++++++++++++------------------- 2 files changed, 614 insertions(+), 596 deletions(-) diff --git a/interface/package.json b/interface/package.json index be2f62a37..b3a599de4 100644 --- a/interface/package.json +++ b/interface/package.json @@ -25,43 +25,43 @@ "@alova/adapter-xhr": "2.2.1", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", - "@mui/icons-material": "^7.3.1", - "@mui/material": "^7.3.1", + "@mui/icons-material": "^7.3.2", + "@mui/material": "^7.3.2", "@table-library/react-table-library": "4.1.15", "alova": "3.3.4", "async-validator": "^4.2.5", "formidable": "^3.5.4", "jwt-decode": "^4.0.0", - "magic-string": "^0.30.18", + "magic-string": "^0.30.19", "mime-types": "^3.0.1", - "preact": "^10.27.1", + "preact": "^10.27.2", "react": "^19.1.1", "react-dom": "^19.1.1", "react-icons": "^5.5.0", - "react-router": "^7.8.2", + "react-router": "^7.9.2", "react-toastify": "^11.0.5", "typesafe-i18n": "^5.26.2", "typescript": "^5.9.2" }, "devDependencies": { - "@babel/core": "^7.28.3", - "@eslint/js": "^9.34.0", + "@babel/core": "^7.28.4", + "@eslint/js": "^9.36.0", "@preact/compat": "^18.3.1", "@preact/preset-vite": "^2.10.2", "@trivago/prettier-plugin-sort-imports": "^5.2.2", - "@types/node": "^24.3.0", - "@types/react": "^19.1.12", - "@types/react-dom": "^19.1.8", + "@types/node": "^24.5.2", + "@types/react": "^19.1.13", + "@types/react-dom": "^19.1.9", "concurrently": "^9.2.1", - "eslint": "^9.34.0", + "eslint": "^9.36.0", "eslint-config-prettier": "^10.1.8", "prettier": "^3.6.2", "rollup-plugin-visualizer": "^6.0.3", - "terser": "^5.43.1", - "typescript-eslint": "^8.41.0", - "vite": "^7.1.3", + "terser": "^5.44.0", + "typescript-eslint": "^8.44.1", + "vite": "^7.1.7", "vite-plugin-imagemin": "^0.6.1", "vite-tsconfig-paths": "^5.1.4" }, - "packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b" + "packageManager": "pnpm@10.17.1" } diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index 6efc6f8e2..516685851 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -13,19 +13,19 @@ importers: version: 2.2.1(alova@3.3.4) '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.1.12)(react@19.1.1) + version: 11.14.0(@types/react@19.1.13)(react@19.1.1) '@emotion/styled': specifier: ^11.14.1 - version: 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + version: 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) '@mui/icons-material': - specifier: ^7.3.1 - version: 7.3.1(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + specifier: ^7.3.2 + version: 7.3.2(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) '@mui/material': - specifier: ^7.3.1 - version: 7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^7.3.2 + version: 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@table-library/react-table-library': specifier: 4.1.15 - version: 4.1.15(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 4.1.15(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1) alova: specifier: 3.3.4 version: 3.3.4 @@ -39,14 +39,14 @@ importers: specifier: ^4.0.0 version: 4.0.0 magic-string: - specifier: ^0.30.18 - version: 0.30.18 + specifier: ^0.30.19 + version: 0.30.19 mime-types: specifier: ^3.0.1 version: 3.0.1 preact: - specifier: ^10.27.1 - version: 10.27.1 + specifier: ^10.27.2 + version: 10.27.2 react: specifier: ^19.1.1 version: 19.1.1 @@ -57,8 +57,8 @@ importers: specifier: ^5.5.0 version: 5.5.0(react@19.1.1) react-router: - specifier: ^7.8.2 - version: 7.8.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + specifier: ^7.9.2 + version: 7.9.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react-toastify: specifier: ^11.0.5 version: 11.0.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) @@ -70,59 +70,59 @@ importers: version: 5.9.2 devDependencies: '@babel/core': - specifier: ^7.28.3 - version: 7.28.3 + specifier: ^7.28.4 + version: 7.28.4 '@eslint/js': - specifier: ^9.34.0 - version: 9.34.0 + specifier: ^9.36.0 + version: 9.36.0 '@preact/compat': specifier: ^18.3.1 - version: 18.3.1(preact@10.27.1) + version: 18.3.1(preact@10.27.2) '@preact/preset-vite': specifier: ^2.10.2 - version: 2.10.2(@babel/core@7.28.3)(preact@10.27.1)(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)) + version: 2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) '@trivago/prettier-plugin-sort-imports': specifier: ^5.2.2 version: 5.2.2(prettier@3.6.2) '@types/node': - specifier: ^24.3.0 - version: 24.3.0 + specifier: ^24.5.2 + version: 24.5.2 '@types/react': - specifier: ^19.1.12 - version: 19.1.12 + specifier: ^19.1.13 + version: 19.1.13 '@types/react-dom': - specifier: ^19.1.8 - version: 19.1.8(@types/react@19.1.12) + specifier: ^19.1.9 + version: 19.1.9(@types/react@19.1.13) concurrently: specifier: ^9.2.1 version: 9.2.1 eslint: - specifier: ^9.34.0 - version: 9.34.0 + specifier: ^9.36.0 + version: 9.36.0 eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.34.0) + version: 10.1.8(eslint@9.36.0) prettier: specifier: ^3.6.2 version: 3.6.2 rollup-plugin-visualizer: specifier: ^6.0.3 - version: 6.0.3(rollup@4.49.0) + version: 6.0.3(rollup@4.52.2) terser: - specifier: ^5.43.1 - version: 5.43.1 + specifier: ^5.44.0 + version: 5.44.0 typescript-eslint: - specifier: ^8.41.0 - version: 8.41.0(eslint@9.34.0)(typescript@5.9.2) + specifier: ^8.44.1 + version: 8.44.1(eslint@9.36.0)(typescript@5.9.2) vite: - specifier: ^7.1.3 - version: 7.1.3(@types/node@24.3.0)(terser@5.43.1) + specifier: ^7.1.7 + version: 7.1.7(@types/node@24.5.2)(terser@5.44.0) vite-plugin-imagemin: specifier: ^0.6.1 - version: 0.6.1(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)) + version: 0.6.1(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.2)(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)) + version: 5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) packages: @@ -134,20 +134,16 @@ packages: '@alova/shared@1.3.1': resolution: {integrity: sha512-ijSOaFLUFcVzMKSY3avoEE5C03/p9atjMDPBwvNkwnzaCrhv6/m4A121NdadF8YlHCRuifyYfz90IyEdMXTsJg==} - '@ampproject/remapping@2.3.0': - resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} - engines: {node: '>=6.0.0'} - '@babel/code-frame@7.27.1': resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.28.0': - resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} + '@babel/compat-data@7.28.4': + resolution: {integrity: sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==} engines: {node: '>=6.9.0'} - '@babel/core@7.28.3': - resolution: {integrity: sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==} + '@babel/core@7.28.4': + resolution: {integrity: sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==} engines: {node: '>=6.9.0'} '@babel/generator@7.28.3': @@ -192,12 +188,12 @@ packages: resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.28.3': - resolution: {integrity: sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==} + '@babel/helpers@7.28.4': + resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -219,20 +215,20 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.28.3': - resolution: {integrity: sha512-9uIQ10o0WGdpP6GDhXcdOJPJuDgFtIDtN/9+ArJQ2NAfAmiuhTQdzkaTGR33v43GYS2UrSA0eX2pPPHoFVvpxA==} + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} '@emotion/babel-plugin@11.13.5': @@ -244,8 +240,8 @@ packages: '@emotion/hash@0.9.2': resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} - '@emotion/is-prop-valid@1.3.1': - resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} + '@emotion/is-prop-valid@1.4.0': + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} '@emotion/memoize@0.9.0': resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} @@ -289,68 +285,68 @@ packages: '@emotion/weak-memoize@0.4.0': resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} - '@esbuild/aix-ppc64@0.25.9': - resolution: {integrity: sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==} + '@esbuild/aix-ppc64@0.25.10': + resolution: {integrity: sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.25.9': - resolution: {integrity: sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==} + '@esbuild/android-arm64@0.25.10': + resolution: {integrity: sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.25.9': - resolution: {integrity: sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==} + '@esbuild/android-arm@0.25.10': + resolution: {integrity: sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.25.9': - resolution: {integrity: sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==} + '@esbuild/android-x64@0.25.10': + resolution: {integrity: sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.25.9': - resolution: {integrity: sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==} + '@esbuild/darwin-arm64@0.25.10': + resolution: {integrity: sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.25.9': - resolution: {integrity: sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==} + '@esbuild/darwin-x64@0.25.10': + resolution: {integrity: sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.25.9': - resolution: {integrity: sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==} + '@esbuild/freebsd-arm64@0.25.10': + resolution: {integrity: sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.9': - resolution: {integrity: sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==} + '@esbuild/freebsd-x64@0.25.10': + resolution: {integrity: sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.25.9': - resolution: {integrity: sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==} + '@esbuild/linux-arm64@0.25.10': + resolution: {integrity: sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.25.9': - resolution: {integrity: sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==} + '@esbuild/linux-arm@0.25.10': + resolution: {integrity: sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.25.9': - resolution: {integrity: sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==} + '@esbuild/linux-ia32@0.25.10': + resolution: {integrity: sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -361,98 +357,98 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.9': - resolution: {integrity: sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==} + '@esbuild/linux-loong64@0.25.10': + resolution: {integrity: sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.25.9': - resolution: {integrity: sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==} + '@esbuild/linux-mips64el@0.25.10': + resolution: {integrity: sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.25.9': - resolution: {integrity: sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==} + '@esbuild/linux-ppc64@0.25.10': + resolution: {integrity: sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.25.9': - resolution: {integrity: sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==} + '@esbuild/linux-riscv64@0.25.10': + resolution: {integrity: sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.25.9': - resolution: {integrity: sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==} + '@esbuild/linux-s390x@0.25.10': + resolution: {integrity: sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.25.9': - resolution: {integrity: sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==} + '@esbuild/linux-x64@0.25.10': + resolution: {integrity: sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.9': - resolution: {integrity: sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==} + '@esbuild/netbsd-arm64@0.25.10': + resolution: {integrity: sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.9': - resolution: {integrity: sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==} + '@esbuild/netbsd-x64@0.25.10': + resolution: {integrity: sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.25.9': - resolution: {integrity: sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==} + '@esbuild/openbsd-arm64@0.25.10': + resolution: {integrity: sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.9': - resolution: {integrity: sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==} + '@esbuild/openbsd-x64@0.25.10': + resolution: {integrity: sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.25.9': - resolution: {integrity: sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==} + '@esbuild/openharmony-arm64@0.25.10': + resolution: {integrity: sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.25.9': - resolution: {integrity: sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==} + '@esbuild/sunos-x64@0.25.10': + resolution: {integrity: sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.25.9': - resolution: {integrity: sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==} + '@esbuild/win32-arm64@0.25.10': + resolution: {integrity: sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.25.9': - resolution: {integrity: sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==} + '@esbuild/win32-ia32@0.25.10': + resolution: {integrity: sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.25.9': - resolution: {integrity: sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==} + '@esbuild/win32-x64@0.25.10': + resolution: {integrity: sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -477,8 +473,8 @@ packages: resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.34.0': - resolution: {integrity: sha512-EoyvqQnBNsV1CWaEJ559rxXL4c8V92gxirbawSmVUOWXlsRxxQXl6LmCpdUblgxgSkDIqKnhzba2SjRTI/A5Rw==} + '@eslint/js@9.36.0': + resolution: {integrity: sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -493,18 +489,14 @@ packages: resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} @@ -520,6 +512,9 @@ packages: '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} @@ -530,30 +525,30 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - '@jridgewell/trace-mapping@0.3.30': - resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@mui/core-downloads-tracker@7.3.1': - resolution: {integrity: sha512-+mIK1Z0BhOaQ0vCgOkT1mSrIpEHLo338h4/duuL4TBLXPvUMit732mnwJY3W40Avy30HdeSfwUAAGRkKmwRaEQ==} + '@mui/core-downloads-tracker@7.3.2': + resolution: {integrity: sha512-AOyfHjyDKVPGJJFtxOlept3EYEdLoar/RvssBTWVAvDJGIE676dLi2oT/Kx+FoVXFoA/JdV7DEMq/BVWV3KHRw==} - '@mui/icons-material@7.3.1': - resolution: {integrity: sha512-upzCtG6awpL6noEZlJ5Z01khZ9VnLNLaj7tb6iPbN6G97eYfUTs8e9OyPKy3rEms3VQWmVBfri7jzeaRxdFIzA==} + '@mui/icons-material@7.3.2': + resolution: {integrity: sha512-TZWazBjWXBjR6iGcNkbKklnwodcwj0SrChCNHc9BhD9rBgET22J1eFhHsEmvSvru9+opDy3umqAimQjokhfJlQ==} engines: {node: '>=14.0.0'} peerDependencies: - '@mui/material': ^7.3.1 + '@mui/material': ^7.3.2 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/material@7.3.1': - resolution: {integrity: sha512-Xf6Shbo03YmcBedZMwSpEFOwpYDtU7tC+rhAHTrA9FHk0FpsDqiQ9jUa1j/9s3HLs7KWb5mDcGnlwdh9Q9KAag==} + '@mui/material@7.3.2': + resolution: {integrity: sha512-qXvbnawQhqUVfH1LMgMaiytP+ZpGoYhnGl7yYq2x57GYzcFL/iPzSZ3L30tlbwEjSVKNYcbiKO8tANR1tadjUg==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 '@emotion/styled': ^11.3.0 - '@mui/material-pigment-css': ^7.3.1 + '@mui/material-pigment-css': ^7.3.2 '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -567,8 +562,8 @@ packages: '@types/react': optional: true - '@mui/private-theming@7.3.1': - resolution: {integrity: sha512-WU3YLkKXii/x8ZEKnrLKsPwplCVE11yZxUvlaaZSIzCcI3x2OdFC8eMlNy74hVeUsYQvzzX1Es/k4ARPlFvpPQ==} + '@mui/private-theming@7.3.2': + resolution: {integrity: sha512-ha7mFoOyZGJr75xeiO9lugS3joRROjc8tG1u4P50dH0KR7bwhHznVMcYg7MouochUy0OxooJm/OOSpJ7gKcMvg==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -577,8 +572,8 @@ packages: '@types/react': optional: true - '@mui/styled-engine@7.3.1': - resolution: {integrity: sha512-Nqo6OHjvJpXJ1+9TekTE//+8RybgPQUKwns2Lh0sq+8rJOUSUKS3KALv4InSOdHhIM9Mdi8/L7LTF1/Ky6D6TQ==} + '@mui/styled-engine@7.3.2': + resolution: {integrity: sha512-PkJzW+mTaek4e0nPYZ6qLnW5RGa0KN+eRTf5FA2nc7cFZTeM+qebmGibaTLrgQBy3UpcpemaqfzToBNkzuxqew==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.4.1 @@ -590,8 +585,8 @@ packages: '@emotion/styled': optional: true - '@mui/system@7.3.1': - resolution: {integrity: sha512-mIidecvcNVpNJMdPDmCeoSL5zshKBbYPcphjuh6ZMjhybhqhZ4mX6k9zmIWh6XOXcqRQMg5KrcjnO0QstrNj3w==} + '@mui/system@7.3.2': + resolution: {integrity: sha512-9d8JEvZW+H6cVkaZ+FK56R53vkJe3HsTpcjMUtH8v1xK6Y1TjzHdZ7Jck02mGXJsE6MQGWVs3ogRHTQmS9Q/rA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': ^11.5.0 @@ -606,16 +601,16 @@ packages: '@types/react': optional: true - '@mui/types@7.4.5': - resolution: {integrity: sha512-ZPwlAOE3e8C0piCKbaabwrqZbW4QvWz0uapVPWya7fYj6PeDkl5sSJmomT7wjOcZGPB48G/a6Ubidqreptxz4g==} + '@mui/types@7.4.6': + resolution: {integrity: sha512-NVBbIw+4CDMMppNamVxyTccNv0WxtDb7motWDlMeSC8Oy95saj1TIZMGynPpFLePt3yOD8TskzumeqORCgRGWw==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 peerDependenciesMeta: '@types/react': optional: true - '@mui/utils@7.3.1': - resolution: {integrity: sha512-/31y4wZqVWa0jzMnzo6JPjxwP6xXy4P3+iLbosFg/mJQowL1KIou0LC+lquWW60FKVbKz5ZUWBg2H3jausa0pw==} + '@mui/utils@7.3.2': + resolution: {integrity: sha512-4DMWQGenOdLnM3y/SdFQFwKsCLM+mqxzvoWp9+x2XdEzXapkznauHLiXtSohHs/mc0+5/9UACt1GdugCX2te5g==} engines: {node: '>=14.0.0'} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -678,103 +673,113 @@ packages: resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} - '@rollup/rollup-android-arm-eabi@4.49.0': - resolution: {integrity: sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==} + '@rollup/rollup-android-arm-eabi@4.52.2': + resolution: {integrity: sha512-o3pcKzJgSGt4d74lSZ+OCnHwkKBeAbFDmbEm5gg70eA8VkyCuC/zV9TwBnmw6VjDlRdF4Pshfb+WE9E6XY1PoQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.49.0': - resolution: {integrity: sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==} + '@rollup/rollup-android-arm64@4.52.2': + resolution: {integrity: sha512-cqFSWO5tX2vhC9hJTK8WAiPIm4Q8q/cU8j2HQA0L3E1uXvBYbOZMhE2oFL8n2pKB5sOCHY6bBuHaRwG7TkfJyw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.49.0': - resolution: {integrity: sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==} + '@rollup/rollup-darwin-arm64@4.52.2': + resolution: {integrity: sha512-vngduywkkv8Fkh3wIZf5nFPXzWsNsVu1kvtLETWxTFf/5opZmflgVSeLgdHR56RQh71xhPhWoOkEBvbehwTlVA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.49.0': - resolution: {integrity: sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==} + '@rollup/rollup-darwin-x64@4.52.2': + resolution: {integrity: sha512-h11KikYrUCYTrDj6h939hhMNlqU2fo/X4NB0OZcys3fya49o1hmFaczAiJWVAFgrM1NCP6RrO7lQKeVYSKBPSQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.49.0': - resolution: {integrity: sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==} + '@rollup/rollup-freebsd-arm64@4.52.2': + resolution: {integrity: sha512-/eg4CI61ZUkLXxMHyVlmlGrSQZ34xqWlZNW43IAU4RmdzWEx0mQJ2mN/Cx4IHLVZFL6UBGAh+/GXhgvGb+nVxw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.49.0': - resolution: {integrity: sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==} + '@rollup/rollup-freebsd-x64@4.52.2': + resolution: {integrity: sha512-QOWgFH5X9+p+S1NAfOqc0z8qEpJIoUHf7OWjNUGOeW18Mx22lAUOiA9b6r2/vpzLdfxi/f+VWsYjUOMCcYh0Ng==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.49.0': - resolution: {integrity: sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==} + '@rollup/rollup-linux-arm-gnueabihf@4.52.2': + resolution: {integrity: sha512-kDWSPafToDd8LcBYd1t5jw7bD5Ojcu12S3uT372e5HKPzQt532vW+rGFFOaiR0opxePyUkHrwz8iWYEyH1IIQA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.49.0': - resolution: {integrity: sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==} + '@rollup/rollup-linux-arm-musleabihf@4.52.2': + resolution: {integrity: sha512-gKm7Mk9wCv6/rkzwCiUC4KnevYhlf8ztBrDRT9g/u//1fZLapSRc+eDZj2Eu2wpJ+0RzUKgtNijnVIB4ZxyL+w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.49.0': - resolution: {integrity: sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==} + '@rollup/rollup-linux-arm64-gnu@4.52.2': + resolution: {integrity: sha512-66lA8vnj5mB/rtDNwPgrrKUOtCLVQypkyDa2gMfOefXK6rcZAxKLO9Fy3GkW8VkPnENv9hBkNOFfGLf6rNKGUg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.49.0': - resolution: {integrity: sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==} + '@rollup/rollup-linux-arm64-musl@4.52.2': + resolution: {integrity: sha512-s+OPucLNdJHvuZHuIz2WwncJ+SfWHFEmlC5nKMUgAelUeBUnlB4wt7rXWiyG4Zn07uY2Dd+SGyVa9oyLkVGOjA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.49.0': - resolution: {integrity: sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==} + '@rollup/rollup-linux-loong64-gnu@4.52.2': + resolution: {integrity: sha512-8wTRM3+gVMDLLDdaT6tKmOE3lJyRy9NpJUS/ZRWmLCmOPIJhVyXwjBo+XbrrwtV33Em1/eCTd5TuGJm4+DmYjw==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-ppc64-gnu@4.49.0': - resolution: {integrity: sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==} + '@rollup/rollup-linux-ppc64-gnu@4.52.2': + resolution: {integrity: sha512-6yqEfgJ1anIeuP2P/zhtfBlDpXUb80t8DpbYwXQ3bQd95JMvUaqiX+fKqYqUwZXqdJDd8xdilNtsHM2N0cFm6A==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.49.0': - resolution: {integrity: sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==} + '@rollup/rollup-linux-riscv64-gnu@4.52.2': + resolution: {integrity: sha512-sshYUiYVSEI2B6dp4jMncwxbrUqRdNApF2c3bhtLAU0qA8Lrri0p0NauOsTWh3yCCCDyBOjESHMExonp7Nzc0w==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.49.0': - resolution: {integrity: sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==} + '@rollup/rollup-linux-riscv64-musl@4.52.2': + resolution: {integrity: sha512-duBLgd+3pqC4MMwBrKkFxaZerUxZcYApQVC5SdbF5/e/589GwVvlRUnyqMFbM8iUSb1BaoX/3fRL7hB9m2Pj8Q==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.49.0': - resolution: {integrity: sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==} + '@rollup/rollup-linux-s390x-gnu@4.52.2': + resolution: {integrity: sha512-tzhYJJidDUVGMgVyE+PmxENPHlvvqm1KILjjZhB8/xHYqAGeizh3GBGf9u6WdJpZrz1aCpIIHG0LgJgH9rVjHQ==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.49.0': - resolution: {integrity: sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==} + '@rollup/rollup-linux-x64-gnu@4.52.2': + resolution: {integrity: sha512-opH8GSUuVcCSSyHHcl5hELrmnk4waZoVpgn/4FDao9iyE4WpQhyWJ5ryl5M3ocp4qkRuHfyXnGqg8M9oKCEKRA==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.49.0': - resolution: {integrity: sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==} + '@rollup/rollup-linux-x64-musl@4.52.2': + resolution: {integrity: sha512-LSeBHnGli1pPKVJ79ZVJgeZWWZXkEe/5o8kcn23M8eMKCUANejchJbF/JqzM4RRjOJfNRhKJk8FuqL1GKjF5oQ==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.49.0': - resolution: {integrity: sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==} + '@rollup/rollup-openharmony-arm64@4.52.2': + resolution: {integrity: sha512-uPj7MQ6/s+/GOpolavm6BPo+6CbhbKYyZHUDvZ/SmJM7pfDBgdGisFX3bY/CBDMg2ZO4utfhlApkSfZ92yXw7Q==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.52.2': + resolution: {integrity: sha512-Z9MUCrSgIaUeeHAiNkm3cQyst2UhzjPraR3gYYfOjAuZI7tcFRTOD+4cHLPoS/3qinchth+V56vtqz1Tv+6KPA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.49.0': - resolution: {integrity: sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==} + '@rollup/rollup-win32-ia32-msvc@4.52.2': + resolution: {integrity: sha512-+GnYBmpjldD3XQd+HMejo+0gJGwYIOfFeoBQv32xF/RUIvccUz20/V6Otdv+57NE70D5pa8W/jVGDoGq0oON4A==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.49.0': - resolution: {integrity: sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==} + '@rollup/rollup-win32-x64-gnu@4.52.2': + resolution: {integrity: sha512-ApXFKluSB6kDQkAqZOKXBjiaqdF1BlKi+/eqnYe9Ee7U2K3pUDKsIyr8EYm/QDHTJIM+4X+lI0gJc3TTRhd+dA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.52.2': + resolution: {integrity: sha512-ARz+Bs8kY6FtitYM96PqPEVvPXqEZmPZsSkXvyX19YzDqkCaIlhCieLLMI5hxO9SRZ2XtCtm8wxhy0iJ2jxNfw==} cpu: [x64] os: [win32] @@ -846,8 +851,8 @@ packages: resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - '@types/node@24.3.0': - resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} + '@types/node@24.5.2': + resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -855,8 +860,8 @@ packages: '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} - '@types/react-dom@19.1.8': - resolution: {integrity: sha512-xG7xaBMJCpcK0RpN8jDbAACQo54ycO6h4dSSmgv8+fu6ZIAdANkx/WsawASUjVXYfy+J9AbUpRMNNEsXCDfDBQ==} + '@types/react-dom@19.1.9': + resolution: {integrity: sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==} peerDependencies: '@types/react': ^19.0.0 @@ -865,8 +870,8 @@ packages: peerDependencies: '@types/react': '*' - '@types/react@19.1.12': - resolution: {integrity: sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==} + '@types/react@19.1.13': + resolution: {integrity: sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -874,63 +879,63 @@ packages: '@types/svgo@2.6.4': resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} - '@typescript-eslint/eslint-plugin@8.41.0': - resolution: {integrity: sha512-8fz6oa6wEKZrhXWro/S3n2eRJqlRcIa6SlDh59FXJ5Wp5XRZ8B9ixpJDcjadHq47hMx0u+HW6SNa6LjJQ6NLtw==} + '@typescript-eslint/eslint-plugin@8.44.1': + resolution: {integrity: sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.41.0 + '@typescript-eslint/parser': ^8.44.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.41.0': - resolution: {integrity: sha512-gTtSdWX9xiMPA/7MV9STjJOOYtWwIJIYxkQxnSV1U3xcE+mnJSH3f6zI0RYP+ew66WSlZ5ed+h0VCxsvdC1jJg==} + '@typescript-eslint/parser@8.44.1': + resolution: {integrity: sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.41.0': - resolution: {integrity: sha512-b8V9SdGBQzQdjJ/IO3eDifGpDBJfvrNTp2QD9P2BeqWTGrRibgfgIlBSw6z3b6R7dPzg752tOs4u/7yCLxksSQ==} + '@typescript-eslint/project-service@8.44.1': + resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.41.0': - resolution: {integrity: sha512-n6m05bXn/Cd6DZDGyrpXrELCPVaTnLdPToyhBoFkLIMznRUQUEQdSp96s/pcWSQdqOhrgR1mzJ+yItK7T+WPMQ==} + '@typescript-eslint/scope-manager@8.44.1': + resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.41.0': - resolution: {integrity: sha512-TDhxYFPUYRFxFhuU5hTIJk+auzM/wKvWgoNYOPcOf6i4ReYlOoYN8q1dV5kOTjNQNJgzWN3TUUQMtlLOcUgdUw==} + '@typescript-eslint/tsconfig-utils@8.44.1': + resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.41.0': - resolution: {integrity: sha512-63qt1h91vg3KsjVVonFJWjgSK7pZHSQFKH6uwqxAH9bBrsyRhO6ONoKyXxyVBzG1lJnFAJcKAcxLS54N1ee1OQ==} + '@typescript-eslint/type-utils@8.44.1': + resolution: {integrity: sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.41.0': - resolution: {integrity: sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==} + '@typescript-eslint/types@8.44.1': + resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.41.0': - resolution: {integrity: sha512-D43UwUYJmGhuwHfY7MtNKRZMmfd8+p/eNSfFe6tH5mbVDto+VQCayeAt35rOx3Cs6wxD16DQtIKw/YXxt5E0UQ==} + '@typescript-eslint/typescript-estree@8.44.1': + resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.41.0': - resolution: {integrity: sha512-udbCVstxZ5jiPIXrdH+BZWnPatjlYwJuJkDA4Tbo3WyYLh8NvB+h/bKeSZHDOFKfphsZYJQqaFtLeXEqurQn1A==} + '@typescript-eslint/utils@8.44.1': + resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.41.0': - resolution: {integrity: sha512-+GeGMebMCy0elMNg67LRNoVnUFPIm37iu5CmHESVx56/9Jsfdpsvbv605DQ81Pi/x11IdKUsS5nzgTYbCQU9fg==} + '@typescript-eslint/visitor-keys@8.44.1': + resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -1009,6 +1014,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.7: + resolution: {integrity: sha512-bxxN2M3a4d1CRoQC//IqsR5XrLh0IJ8TCv2x6Y9N0nckNz/rTjZB3//GGscZziZOxmjP55rzxg/ze7usFI9FqQ==} + hasBin: true + bin-build@3.0.0: resolution: {integrity: sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA==} engines: {node: '>=4'} @@ -1045,8 +1054,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.25.3: - resolution: {integrity: sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==} + browserslist@4.26.2: + resolution: {integrity: sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1095,8 +1104,8 @@ packages: resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} engines: {node: '>=0.10.0'} - caniuse-lite@1.0.30001737: - resolution: {integrity: sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==} + caniuse-lite@1.0.30001745: + resolution: {integrity: sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ==} caw@2.0.1: resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==} @@ -1215,8 +1224,8 @@ packages: engines: {node: '>=10'} hasBin: true - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1315,8 +1324,8 @@ packages: duplexer3@0.1.5: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} - electron-to-chromium@1.5.211: - resolution: {integrity: sha512-IGBvimJkotaLzFnwIVgW9/UD/AOJ2tByUmeOrtqBfACSbAw5b1G0XpvdaieKyc7ULmbwXVx+4e4Be8pOPBrYkw==} + electron-to-chromium@1.5.223: + resolution: {integrity: sha512-qKm55ic6nbEmagFlTFczML33rF90aU+WtrJ9MdTCThrcvDNdUHN4p6QfVN78U06ZmguqXIyMPyYhw2TrbDUwPQ==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1331,8 +1340,8 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} @@ -1471,8 +1480,8 @@ packages: engines: {node: '>=12'} hasBin: true - esbuild@0.25.9: - resolution: {integrity: sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==} + esbuild@0.25.10: + resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==} engines: {node: '>=18'} hasBin: true @@ -1506,8 +1515,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.34.0: - resolution: {integrity: sha512-RNCHRX5EwdrESy3Jc9o8ie8Bog+PeYvvSR8sDGoZxNFTvZ4dlxUB3WzQ3bQMztFrSRODGrLLj8g6OFuGY/aiQg==} + eslint@9.36.0: + resolution: {integrity: sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2137,8 +2146,8 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - magic-string@0.30.18: - resolution: {integrity: sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} make-dir@1.3.0: resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} @@ -2229,8 +2238,8 @@ packages: node-html-parser@6.1.13: resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + node-releases@2.0.21: + resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -2431,8 +2440,8 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - preact@10.27.1: - resolution: {integrity: sha512-V79raXEWch/rbqoNc7nT9E4ep7lu+mI3+sBmfRD4i1M73R3WLYcCtdI0ibxGVf4eQL8ZIz2nFacqEC+rmnOORQ==} + preact@10.27.2: + resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -2496,8 +2505,8 @@ packages: react-is@19.1.1: resolution: {integrity: sha512-tr41fA15Vn8p4X9ntI+yCyeGSf1TlYaY5vlTZfQmeLBrFo3psOPX6HhTDnFNL9uj3EhP0KAQ80cugCl4b4BERA==} - react-router@7.8.2: - resolution: {integrity: sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==} + react-router@7.9.2: + resolution: {integrity: sha512-i2TPp4dgaqrOqiRGLZmqh2WXmbdFknUyiCRmSKs0hf6fWXkTKg5h56b+9F22NbGRAMxjYfqQnpi63egzD2SuZA==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -2596,8 +2605,8 @@ packages: rollup: optional: true - rollup@4.49.0: - resolution: {integrity: sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==} + rollup@4.52.2: + resolution: {integrity: sha512-I25/2QgoROE1vYV+NQ1En9T9UFB9Cmfm2CJ83zZOlaDpvz29wGQSZXWKw7MiNXau7wYgB/T9fVIdIuEQ+KbiiA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2819,8 +2828,8 @@ packages: resolution: {integrity: sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA==} engines: {node: '>=4'} - terser@5.43.1: - resolution: {integrity: sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==} + terser@5.44.0: + resolution: {integrity: sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==} engines: {node: '>=10'} hasBin: true @@ -2831,12 +2840,12 @@ packages: resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} engines: {node: '>=0.10.0'} - tinyglobby@0.2.14: - resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} - to-buffer@1.2.1: - resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} engines: {node: '>= 0.4'} to-regex-range@5.0.1: @@ -2895,8 +2904,8 @@ packages: peerDependencies: typescript: '>=3.5.1' - typescript-eslint@8.41.0: - resolution: {integrity: sha512-n66rzs5OBXW3SFSnZHr2T685q1i4ODm2nulFJhMZBotaTavsS8TrI3d7bDlRSs9yWo7HmyWrN9qDu14Qv7Y0Dw==} + typescript-eslint@8.44.1: + resolution: {integrity: sha512-0ws8uWGrUVTjEeN2OM4K1pLKHK/4NiNP/vz6ns+LjT/6sqpaYzIVFajZb1fj/IDwpsrrHb3Jy0Qm5u9CPcKaeg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -2910,8 +2919,8 @@ packages: unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} - undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} @@ -2954,8 +2963,8 @@ packages: peerDependencies: vite: '>=2.0.0' - vite-prerender-plugin@0.5.11: - resolution: {integrity: sha512-xWOhb8Ef2zoJIiinYVunIf3omRfUbEXcPEvrkQcrDpJ2yjDokxhvQ26eSJbkthRhymntWx6816jpATrJphh+ug==} + vite-prerender-plugin@0.5.12: + resolution: {integrity: sha512-EiwhbMn+flg14EysbLTmZSzq8NGTxhytgK3bf4aGRF1evWLGwZiHiUJ1KZDvbxgKbMf2pG6fJWGEa3UZXOnR1g==} peerDependencies: vite: 5.x || 6.x || 7.x @@ -2967,8 +2976,8 @@ packages: vite: optional: true - vite@7.1.3: - resolution: {integrity: sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==} + vite@7.1.7: + resolution: {integrity: sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3073,33 +3082,28 @@ snapshots: '@alova/shared@1.3.1': {} - '@ampproject/remapping@2.3.0': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 - '@babel/code-frame@7.27.1': dependencies: '@babel/helper-validator-identifier': 7.27.1 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.28.0': {} + '@babel/compat-data@7.28.4': {} - '@babel/core@7.28.3': + '@babel/core@7.28.4': dependencies: - '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.3) - '@babel/helpers': 7.28.3 - '@babel/parser': 7.28.3 + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.4) + '@babel/helpers': 7.28.4 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 + '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -3108,21 +3112,21 @@ snapshots: '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.28.0 + '@babel/compat-data': 7.28.4 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.25.3 + browserslist: 4.26.2 lru-cache: 5.1.1 semver: 6.3.1 @@ -3130,17 +3134,17 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.3)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -3152,59 +3156,59 @@ snapshots: '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.28.3': + '@babel/helpers@7.28.4': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 - '@babel/parser@7.28.3': + '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) + '@babel/core': 7.28.4 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.3)': + '@babel/plugin-transform-react-jsx@7.27.1(@babel/core@7.28.4)': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/types': 7.28.2 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color - '@babel/runtime@7.28.3': {} + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 - '@babel/traverse@7.28.3': + '@babel/traverse@7.28.4': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 + '@babel/types': 7.28.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -3212,7 +3216,7 @@ snapshots: '@emotion/babel-plugin@11.13.5': dependencies: '@babel/helper-module-imports': 7.27.1 - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@emotion/hash': 0.9.2 '@emotion/memoize': 0.9.0 '@emotion/serialize': 1.3.3 @@ -3235,15 +3239,15 @@ snapshots: '@emotion/hash@0.9.2': {} - '@emotion/is-prop-valid@1.3.1': + '@emotion/is-prop-valid@1.4.0': dependencies: '@emotion/memoize': 0.9.0 '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1)': + '@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 @@ -3253,7 +3257,7 @@ snapshots: hoist-non-react-statics: 3.3.2 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 transitivePeerDependencies: - supports-color @@ -3267,18 +3271,18 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@emotion/babel-plugin': 11.13.5 - '@emotion/is-prop-valid': 1.3.1 - '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) + '@emotion/is-prop-valid': 1.4.0 + '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.1) '@emotion/utils': 1.4.2 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 transitivePeerDependencies: - supports-color @@ -3292,90 +3296,90 @@ snapshots: '@emotion/weak-memoize@0.4.0': {} - '@esbuild/aix-ppc64@0.25.9': + '@esbuild/aix-ppc64@0.25.10': optional: true - '@esbuild/android-arm64@0.25.9': + '@esbuild/android-arm64@0.25.10': optional: true - '@esbuild/android-arm@0.25.9': + '@esbuild/android-arm@0.25.10': optional: true - '@esbuild/android-x64@0.25.9': + '@esbuild/android-x64@0.25.10': optional: true - '@esbuild/darwin-arm64@0.25.9': + '@esbuild/darwin-arm64@0.25.10': optional: true - '@esbuild/darwin-x64@0.25.9': + '@esbuild/darwin-x64@0.25.10': optional: true - '@esbuild/freebsd-arm64@0.25.9': + '@esbuild/freebsd-arm64@0.25.10': optional: true - '@esbuild/freebsd-x64@0.25.9': + '@esbuild/freebsd-x64@0.25.10': optional: true - '@esbuild/linux-arm64@0.25.9': + '@esbuild/linux-arm64@0.25.10': optional: true - '@esbuild/linux-arm@0.25.9': + '@esbuild/linux-arm@0.25.10': optional: true - '@esbuild/linux-ia32@0.25.9': + '@esbuild/linux-ia32@0.25.10': optional: true '@esbuild/linux-loong64@0.14.54': optional: true - '@esbuild/linux-loong64@0.25.9': + '@esbuild/linux-loong64@0.25.10': optional: true - '@esbuild/linux-mips64el@0.25.9': + '@esbuild/linux-mips64el@0.25.10': optional: true - '@esbuild/linux-ppc64@0.25.9': + '@esbuild/linux-ppc64@0.25.10': optional: true - '@esbuild/linux-riscv64@0.25.9': + '@esbuild/linux-riscv64@0.25.10': optional: true - '@esbuild/linux-s390x@0.25.9': + '@esbuild/linux-s390x@0.25.10': optional: true - '@esbuild/linux-x64@0.25.9': + '@esbuild/linux-x64@0.25.10': optional: true - '@esbuild/netbsd-arm64@0.25.9': + '@esbuild/netbsd-arm64@0.25.10': optional: true - '@esbuild/netbsd-x64@0.25.9': + '@esbuild/netbsd-x64@0.25.10': optional: true - '@esbuild/openbsd-arm64@0.25.9': + '@esbuild/openbsd-arm64@0.25.10': optional: true - '@esbuild/openbsd-x64@0.25.9': + '@esbuild/openbsd-x64@0.25.10': optional: true - '@esbuild/openharmony-arm64@0.25.9': + '@esbuild/openharmony-arm64@0.25.10': optional: true - '@esbuild/sunos-x64@0.25.9': + '@esbuild/sunos-x64@0.25.10': optional: true - '@esbuild/win32-arm64@0.25.9': + '@esbuild/win32-arm64@0.25.10': optional: true - '@esbuild/win32-ia32@0.25.9': + '@esbuild/win32-ia32@0.25.10': optional: true - '@esbuild/win32-x64@0.25.9': + '@esbuild/win32-x64@0.25.10': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.34.0)': + '@eslint-community/eslint-utils@4.9.0(eslint@9.36.0)': dependencies: - eslint: 9.34.0 + eslint: 9.36.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -3383,7 +3387,7 @@ snapshots: '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -3397,7 +3401,7 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -3408,7 +3412,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.34.0': {} + '@eslint/js@9.36.0': {} '@eslint/object-schema@2.1.6': {} @@ -3419,15 +3423,13 @@ snapshots: '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.6': + '@humanfs/node@0.16.7': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.3 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} '@isaacs/balanced-match@4.0.1': {} @@ -3439,41 +3441,46 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/resolve-uri@3.1.2': {} '@jridgewell/source-map@0.3.11': dependencies: '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.30 + '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/sourcemap-codec@1.5.5': {} - '@jridgewell/trace-mapping@0.3.30': + '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@mui/core-downloads-tracker@7.3.1': {} + '@mui/core-downloads-tracker@7.3.2': {} - '@mui/icons-material@7.3.1(@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.12)(react@19.1.1)': + '@mui/icons-material@7.3.2(@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 - '@mui/material': 7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@babel/runtime': 7.28.4 + '@mui/material': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1) react: 19.1.1 optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 - '@mui/material@7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@mui/material@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 - '@mui/core-downloads-tracker': 7.3.1 - '@mui/system': 7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) - '@mui/types': 7.4.5(@types/react@19.1.12) - '@mui/utils': 7.3.1(@types/react@19.1.12)(react@19.1.1) + '@babel/runtime': 7.28.4 + '@mui/core-downloads-tracker': 7.3.2 + '@mui/system': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) + '@mui/types': 7.4.6(@types/react@19.1.13) + '@mui/utils': 7.3.2(@types/react@19.1.13)(react@19.1.1) '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@19.1.12) + '@types/react-transition-group': 4.4.12(@types/react@19.1.13) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 @@ -3482,22 +3489,22 @@ snapshots: react-is: 19.1.1 react-transition-group: 4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) - '@types/react': 19.1.12 + '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) + '@types/react': 19.1.13 - '@mui/private-theming@7.3.1(@types/react@19.1.12)(react@19.1.1)': + '@mui/private-theming@7.3.2(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 - '@mui/utils': 7.3.1(@types/react@19.1.12)(react@19.1.1) + '@babel/runtime': 7.28.4 + '@mui/utils': 7.3.2(@types/react@19.1.13)(react@19.1.1) prop-types: 15.8.1 react: 19.1.1 optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 - '@mui/styled-engine@7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(react@19.1.1)': + '@mui/styled-engine@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 '@emotion/sheet': 1.4.0 @@ -3505,42 +3512,42 @@ snapshots: prop-types: 15.8.1 react: 19.1.1 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) - '@mui/system@7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1)': + '@mui/system@7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 - '@mui/private-theming': 7.3.1(@types/react@19.1.12)(react@19.1.1) - '@mui/styled-engine': 7.3.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1))(react@19.1.1) - '@mui/types': 7.4.5(@types/react@19.1.12) - '@mui/utils': 7.3.1(@types/react@19.1.12)(react@19.1.1) + '@babel/runtime': 7.28.4 + '@mui/private-theming': 7.3.2(@types/react@19.1.13)(react@19.1.1) + '@mui/styled-engine': 7.3.2(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1))(react@19.1.1) + '@mui/types': 7.4.6(@types/react@19.1.13) + '@mui/utils': 7.3.2(@types/react@19.1.13)(react@19.1.1) clsx: 2.1.1 csstype: 3.1.3 prop-types: 15.8.1 react: 19.1.1 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(@types/react@19.1.12)(react@19.1.1) - '@types/react': 19.1.12 + '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(@types/react@19.1.13)(react@19.1.1) + '@types/react': 19.1.13 - '@mui/types@7.4.5(@types/react@19.1.12)': + '@mui/types@7.4.6(@types/react@19.1.13)': dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 - '@mui/utils@7.3.1(@types/react@19.1.12)(react@19.1.1)': + '@mui/utils@7.3.2(@types/react@19.1.13)(react@19.1.1)': dependencies: - '@babel/runtime': 7.28.3 - '@mui/types': 7.4.5(@types/react@19.1.12) + '@babel/runtime': 7.28.4 + '@mui/types': 7.4.6(@types/react@19.1.13) '@types/prop-types': 15.7.15 clsx: 2.1.1 prop-types: 15.8.1 react: 19.1.1 react-is: 19.1.1 optionalDependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 '@noble/hashes@1.8.0': {} @@ -3562,43 +3569,43 @@ snapshots: '@popperjs/core@2.11.8': {} - '@preact/compat@18.3.1(preact@10.27.1)': + '@preact/compat@18.3.1(preact@10.27.2)': dependencies: - preact: 10.27.1 + preact: 10.27.2 - '@preact/preset-vite@2.10.2(@babel/core@7.28.3)(preact@10.27.1)(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1))': + '@preact/preset-vite@2.10.2(@babel/core@7.28.4)(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0))': dependencies: - '@babel/core': 7.28.3 - '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.3) - '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.3) - '@prefresh/vite': 2.4.10(preact@10.27.1)(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)) + '@babel/core': 7.28.4 + '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.4) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.4) + '@prefresh/vite': 2.4.10(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) '@rollup/pluginutils': 4.2.1 - babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.3) - debug: 4.4.1 + babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.4) + debug: 4.4.3 picocolors: 1.1.1 - vite: 7.1.3(@types/node@24.3.0)(terser@5.43.1) - vite-prerender-plugin: 0.5.11(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)) + vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) + vite-prerender-plugin: 0.5.12(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)) transitivePeerDependencies: - preact - supports-color '@prefresh/babel-plugin@0.5.2': {} - '@prefresh/core@1.5.7(preact@10.27.1)': + '@prefresh/core@1.5.7(preact@10.27.2)': dependencies: - preact: 10.27.1 + preact: 10.27.2 '@prefresh/utils@1.2.1': {} - '@prefresh/vite@2.4.10(preact@10.27.1)(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1))': + '@prefresh/vite@2.4.10(preact@10.27.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0))': dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 '@prefresh/babel-plugin': 0.5.2 - '@prefresh/core': 1.5.7(preact@10.27.1) + '@prefresh/core': 1.5.7(preact@10.27.2) '@prefresh/utils': 1.2.1 '@rollup/pluginutils': 4.2.1 - preact: 10.27.1 - vite: 7.1.3(@types/node@24.3.0)(terser@5.43.1) + preact: 10.27.2 + vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) transitivePeerDependencies: - supports-color @@ -3607,71 +3614,77 @@ snapshots: estree-walker: 2.0.2 picomatch: 2.3.1 - '@rollup/rollup-android-arm-eabi@4.49.0': + '@rollup/rollup-android-arm-eabi@4.52.2': optional: true - '@rollup/rollup-android-arm64@4.49.0': + '@rollup/rollup-android-arm64@4.52.2': optional: true - '@rollup/rollup-darwin-arm64@4.49.0': + '@rollup/rollup-darwin-arm64@4.52.2': optional: true - '@rollup/rollup-darwin-x64@4.49.0': + '@rollup/rollup-darwin-x64@4.52.2': optional: true - '@rollup/rollup-freebsd-arm64@4.49.0': + '@rollup/rollup-freebsd-arm64@4.52.2': optional: true - '@rollup/rollup-freebsd-x64@4.49.0': + '@rollup/rollup-freebsd-x64@4.52.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.49.0': + '@rollup/rollup-linux-arm-gnueabihf@4.52.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.49.0': + '@rollup/rollup-linux-arm-musleabihf@4.52.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.49.0': + '@rollup/rollup-linux-arm64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.49.0': + '@rollup/rollup-linux-arm64-musl@4.52.2': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.49.0': + '@rollup/rollup-linux-loong64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.49.0': + '@rollup/rollup-linux-ppc64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.49.0': + '@rollup/rollup-linux-riscv64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-riscv64-musl@4.49.0': + '@rollup/rollup-linux-riscv64-musl@4.52.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.49.0': + '@rollup/rollup-linux-s390x-gnu@4.52.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.49.0': + '@rollup/rollup-linux-x64-gnu@4.52.2': optional: true - '@rollup/rollup-linux-x64-musl@4.49.0': + '@rollup/rollup-linux-x64-musl@4.52.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.49.0': + '@rollup/rollup-openharmony-arm64@4.52.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.49.0': + '@rollup/rollup-win32-arm64-msvc@4.52.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.49.0': + '@rollup/rollup-win32-ia32-msvc@4.52.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.52.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.52.2': optional: true '@sindresorhus/is@0.7.0': {} - '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.1.12)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.1.13)(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.1.12)(react@19.1.1) + '@emotion/react': 11.14.0(@types/react@19.1.13)(react@19.1.1) clsx: 1.1.1 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) @@ -3681,9 +3694,9 @@ snapshots: '@trivago/prettier-plugin-sort-imports@5.2.2(prettier@3.6.2)': dependencies: '@babel/generator': 7.28.3 - '@babel/parser': 7.28.3 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 javascript-natural-sort: 0.7.1 lodash: 4.17.21 prettier: 3.6.2 @@ -3697,7 +3710,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 24.3.0 + '@types/node': 24.5.2 '@types/imagemin-gifsicle@7.0.4': dependencies: @@ -3726,55 +3739,55 @@ snapshots: '@types/imagemin@7.0.1': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 '@types/json-schema@7.0.15': {} '@types/keyv@3.1.4': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 '@types/minimatch@6.0.0': dependencies: minimatch: 10.0.3 - '@types/node@24.3.0': + '@types/node@24.5.2': dependencies: - undici-types: 7.10.0 + undici-types: 7.12.0 '@types/parse-json@4.0.2': {} '@types/prop-types@15.7.15': {} - '@types/react-dom@19.1.8(@types/react@19.1.12)': + '@types/react-dom@19.1.9(@types/react@19.1.13)': dependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 - '@types/react-transition-group@4.4.12(@types/react@19.1.12)': + '@types/react-transition-group@4.4.12(@types/react@19.1.13)': dependencies: - '@types/react': 19.1.12 + '@types/react': 19.1.13 - '@types/react@19.1.12': + '@types/react@19.1.13': dependencies: csstype: 3.1.3 '@types/responselike@1.0.3': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 '@types/svgo@2.6.4': dependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 - '@typescript-eslint/eslint-plugin@8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/type-utils': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.41.0 - eslint: 9.34.0 + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/type-utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 + eslint: 9.36.0 graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -3783,57 +3796,57 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@5.9.2)': + '@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.41.0 - debug: 4.4.1 - eslint: 9.34.0 + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.44.1 + debug: 4.4.3 + eslint: 9.36.0 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.41.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.2) - '@typescript-eslint/types': 8.41.0 - debug: 4.4.1 + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + debug: 4.4.3 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.41.0': + '@typescript-eslint/scope-manager@8.44.1': dependencies: - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/visitor-keys': 8.41.0 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 - '@typescript-eslint/tsconfig-utils@8.41.0(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.41.0(eslint@9.34.0)(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - debug: 4.4.1 - eslint: 9.34.0 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + debug: 4.4.3 + eslint: 9.36.0 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.41.0': {} + '@typescript-eslint/types@8.44.1': {} - '@typescript-eslint/typescript-estree@8.41.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.41.0(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.41.0(typescript@5.9.2) - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/visitor-keys': 8.41.0 - debug: 4.4.1 + '@typescript-eslint/project-service': 8.44.1(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.2) + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/visitor-keys': 8.44.1 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -3843,20 +3856,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.41.0(eslint@9.34.0)(typescript@5.9.2)': + '@typescript-eslint/utils@8.44.1(eslint@9.36.0)(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) - '@typescript-eslint/scope-manager': 8.41.0 - '@typescript-eslint/types': 8.41.0 - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - eslint: 9.34.0 + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) + '@typescript-eslint/scope-manager': 8.44.1 + '@typescript-eslint/types': 8.44.1 + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + eslint: 9.36.0 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.41.0': + '@typescript-eslint/visitor-keys@8.44.1': dependencies: - '@typescript-eslint/types': 8.41.0 + '@typescript-eslint/types': 8.44.1 eslint-visitor-keys: 4.2.1 acorn-jsx@5.3.2(acorn@8.15.0): @@ -3909,18 +3922,20 @@ snapshots: babel-plugin-macros@3.1.0: dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 cosmiconfig: 7.1.0 resolve: 1.22.10 - babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.3): + babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.4): dependencies: - '@babel/core': 7.28.3 + '@babel/core': 7.28.4 balanced-match@1.0.2: {} base64-js@1.5.1: {} + baseline-browser-mapping@2.8.7: {} + bin-build@3.0.0: dependencies: decompress: 4.2.1 @@ -3974,12 +3989,13 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.25.3: + browserslist@4.26.2: dependencies: - caniuse-lite: 1.0.30001737 - electron-to-chromium: 1.5.211 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.3) + baseline-browser-mapping: 2.8.7 + caniuse-lite: 1.0.30001745 + electron-to-chromium: 1.5.223 + node-releases: 2.0.21 + update-browserslist-db: 1.1.3(browserslist@4.26.2) buffer-alloc-unsafe@1.1.0: {} @@ -4035,7 +4051,7 @@ snapshots: camelcase@2.1.1: {} - caniuse-lite@1.0.30001737: {} + caniuse-lite@1.0.30001745: {} caw@2.0.1: dependencies: @@ -4177,7 +4193,7 @@ snapshots: bin-build: 3.0.0 bin-wrapper: 4.1.0 - debug@4.4.1: + debug@4.4.3: dependencies: ms: 2.1.3 @@ -4248,7 +4264,7 @@ snapshots: dom-helpers@5.2.1: dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 csstype: 3.1.3 dom-serializer@1.4.1: @@ -4322,7 +4338,7 @@ snapshots: duplexer3@0.1.5: {} - electron-to-chromium@1.5.211: {} + electron-to-chromium@1.5.223: {} emoji-regex@8.0.0: {} @@ -4334,7 +4350,7 @@ snapshots: entities@4.5.0: {} - error-ex@1.3.2: + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -4430,34 +4446,34 @@ snapshots: esbuild-windows-64: 0.14.54 esbuild-windows-arm64: 0.14.54 - esbuild@0.25.9: + esbuild@0.25.10: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.9 - '@esbuild/android-arm': 0.25.9 - '@esbuild/android-arm64': 0.25.9 - '@esbuild/android-x64': 0.25.9 - '@esbuild/darwin-arm64': 0.25.9 - '@esbuild/darwin-x64': 0.25.9 - '@esbuild/freebsd-arm64': 0.25.9 - '@esbuild/freebsd-x64': 0.25.9 - '@esbuild/linux-arm': 0.25.9 - '@esbuild/linux-arm64': 0.25.9 - '@esbuild/linux-ia32': 0.25.9 - '@esbuild/linux-loong64': 0.25.9 - '@esbuild/linux-mips64el': 0.25.9 - '@esbuild/linux-ppc64': 0.25.9 - '@esbuild/linux-riscv64': 0.25.9 - '@esbuild/linux-s390x': 0.25.9 - '@esbuild/linux-x64': 0.25.9 - '@esbuild/netbsd-arm64': 0.25.9 - '@esbuild/netbsd-x64': 0.25.9 - '@esbuild/openbsd-arm64': 0.25.9 - '@esbuild/openbsd-x64': 0.25.9 - '@esbuild/openharmony-arm64': 0.25.9 - '@esbuild/sunos-x64': 0.25.9 - '@esbuild/win32-arm64': 0.25.9 - '@esbuild/win32-ia32': 0.25.9 - '@esbuild/win32-x64': 0.25.9 + '@esbuild/aix-ppc64': 0.25.10 + '@esbuild/android-arm': 0.25.10 + '@esbuild/android-arm64': 0.25.10 + '@esbuild/android-x64': 0.25.10 + '@esbuild/darwin-arm64': 0.25.10 + '@esbuild/darwin-x64': 0.25.10 + '@esbuild/freebsd-arm64': 0.25.10 + '@esbuild/freebsd-x64': 0.25.10 + '@esbuild/linux-arm': 0.25.10 + '@esbuild/linux-arm64': 0.25.10 + '@esbuild/linux-ia32': 0.25.10 + '@esbuild/linux-loong64': 0.25.10 + '@esbuild/linux-mips64el': 0.25.10 + '@esbuild/linux-ppc64': 0.25.10 + '@esbuild/linux-riscv64': 0.25.10 + '@esbuild/linux-s390x': 0.25.10 + '@esbuild/linux-x64': 0.25.10 + '@esbuild/netbsd-arm64': 0.25.10 + '@esbuild/netbsd-x64': 0.25.10 + '@esbuild/openbsd-arm64': 0.25.10 + '@esbuild/openbsd-x64': 0.25.10 + '@esbuild/openharmony-arm64': 0.25.10 + '@esbuild/sunos-x64': 0.25.10 + '@esbuild/win32-arm64': 0.25.10 + '@esbuild/win32-ia32': 0.25.10 + '@esbuild/win32-x64': 0.25.10 escalade@3.2.0: {} @@ -4465,9 +4481,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.34.0): + eslint-config-prettier@10.1.8(eslint@9.36.0): dependencies: - eslint: 9.34.0 + eslint: 9.36.0 eslint-scope@8.4.0: dependencies: @@ -4478,17 +4494,17 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.34.0: + eslint@9.36.0: dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.34.0) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.36.0) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.34.0 + '@eslint/js': 9.36.0 '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.6 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -4496,7 +4512,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -5161,7 +5177,7 @@ snapshots: dependencies: yallist: 3.1.1 - magic-string@0.30.18: + magic-string@0.30.19: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -5245,7 +5261,7 @@ snapshots: css-select: 5.2.2 he: 1.2.0 - node-releases@2.0.19: {} + node-releases@2.0.21: {} normalize-package-data@2.5.0: dependencies: @@ -5361,12 +5377,12 @@ snapshots: parse-json@2.2.0: dependencies: - error-ex: 1.3.2 + error-ex: 1.3.4 parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 + error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -5428,7 +5444,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - preact@10.27.1: {} + preact@10.27.2: {} prelude-ls@1.2.1: {} @@ -5480,7 +5496,7 @@ snapshots: react-is@19.1.1: {} - react-router@7.8.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): + react-router@7.9.2(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: cookie: 1.0.2 react: 19.1.1 @@ -5496,7 +5512,7 @@ snapshots: react-transition-group@4.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -5510,7 +5526,7 @@ snapshots: react-window@1.8.11(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: - '@babel/runtime': 7.28.3 + '@babel/runtime': 7.28.4 memoize-one: 5.2.1 react: 19.1.1 react-dom: 19.1.1(react@19.1.1) @@ -5569,39 +5585,41 @@ snapshots: dependencies: glob: 7.2.3 - rollup-plugin-visualizer@6.0.3(rollup@4.49.0): + rollup-plugin-visualizer@6.0.3(rollup@4.52.2): dependencies: open: 8.4.2 picomatch: 4.0.3 source-map: 0.7.6 yargs: 17.7.2 optionalDependencies: - rollup: 4.49.0 + rollup: 4.52.2 - rollup@4.49.0: + rollup@4.52.2: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.49.0 - '@rollup/rollup-android-arm64': 4.49.0 - '@rollup/rollup-darwin-arm64': 4.49.0 - '@rollup/rollup-darwin-x64': 4.49.0 - '@rollup/rollup-freebsd-arm64': 4.49.0 - '@rollup/rollup-freebsd-x64': 4.49.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.49.0 - '@rollup/rollup-linux-arm-musleabihf': 4.49.0 - '@rollup/rollup-linux-arm64-gnu': 4.49.0 - '@rollup/rollup-linux-arm64-musl': 4.49.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.49.0 - '@rollup/rollup-linux-ppc64-gnu': 4.49.0 - '@rollup/rollup-linux-riscv64-gnu': 4.49.0 - '@rollup/rollup-linux-riscv64-musl': 4.49.0 - '@rollup/rollup-linux-s390x-gnu': 4.49.0 - '@rollup/rollup-linux-x64-gnu': 4.49.0 - '@rollup/rollup-linux-x64-musl': 4.49.0 - '@rollup/rollup-win32-arm64-msvc': 4.49.0 - '@rollup/rollup-win32-ia32-msvc': 4.49.0 - '@rollup/rollup-win32-x64-msvc': 4.49.0 + '@rollup/rollup-android-arm-eabi': 4.52.2 + '@rollup/rollup-android-arm64': 4.52.2 + '@rollup/rollup-darwin-arm64': 4.52.2 + '@rollup/rollup-darwin-x64': 4.52.2 + '@rollup/rollup-freebsd-arm64': 4.52.2 + '@rollup/rollup-freebsd-x64': 4.52.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.2 + '@rollup/rollup-linux-arm-musleabihf': 4.52.2 + '@rollup/rollup-linux-arm64-gnu': 4.52.2 + '@rollup/rollup-linux-arm64-musl': 4.52.2 + '@rollup/rollup-linux-loong64-gnu': 4.52.2 + '@rollup/rollup-linux-ppc64-gnu': 4.52.2 + '@rollup/rollup-linux-riscv64-gnu': 4.52.2 + '@rollup/rollup-linux-riscv64-musl': 4.52.2 + '@rollup/rollup-linux-s390x-gnu': 4.52.2 + '@rollup/rollup-linux-x64-gnu': 4.52.2 + '@rollup/rollup-linux-x64-musl': 4.52.2 + '@rollup/rollup-openharmony-arm64': 4.52.2 + '@rollup/rollup-win32-arm64-msvc': 4.52.2 + '@rollup/rollup-win32-ia32-msvc': 4.52.2 + '@rollup/rollup-win32-x64-gnu': 4.52.2 + '@rollup/rollup-win32-x64-msvc': 4.52.2 fsevents: 2.3.3 run-parallel@1.2.0: @@ -5791,7 +5809,7 @@ snapshots: end-of-stream: 1.4.5 fs-constants: 1.0.0 readable-stream: 2.3.8 - to-buffer: 1.2.1 + to-buffer: 1.2.2 xtend: 4.0.2 temp-dir@1.0.0: {} @@ -5801,7 +5819,7 @@ snapshots: temp-dir: 1.0.0 uuid: 3.4.0 - terser@5.43.1: + terser@5.44.0: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.15.0 @@ -5812,12 +5830,12 @@ snapshots: timed-out@4.0.1: {} - tinyglobby@0.2.14: + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - to-buffer@1.2.1: + to-buffer@1.2.2: dependencies: isarray: 2.0.5 safe-buffer: 5.2.1 @@ -5865,13 +5883,13 @@ snapshots: dependencies: typescript: 5.9.2 - typescript-eslint@8.41.0(eslint@9.34.0)(typescript@5.9.2): + typescript-eslint@8.44.1(eslint@9.36.0)(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.41.0(@typescript-eslint/parser@8.41.0(eslint@9.34.0)(typescript@5.9.2))(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/parser': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - '@typescript-eslint/typescript-estree': 8.41.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.41.0(eslint@9.34.0)(typescript@5.9.2) - eslint: 9.34.0 + '@typescript-eslint/eslint-plugin': 8.44.1(@typescript-eslint/parser@8.44.1(eslint@9.36.0)(typescript@5.9.2))(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/parser': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.2) + '@typescript-eslint/utils': 8.44.1(eslint@9.36.0)(typescript@5.9.2) + eslint: 9.36.0 typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -5883,13 +5901,13 @@ snapshots: buffer: 5.7.1 through: 2.3.8 - undici-types@7.10.0: {} + undici-types@7.12.0: {} universalify@2.0.1: {} - update-browserslist-db@1.1.3(browserslist@4.25.3): + update-browserslist-db@1.1.3(browserslist@4.26.2): dependencies: - browserslist: 4.25.3 + browserslist: 4.26.2 escalade: 3.2.0 picocolors: 1.1.1 @@ -5916,7 +5934,7 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-plugin-imagemin@0.6.1(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)): + vite-plugin-imagemin@0.6.1(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)): dependencies: '@types/imagemin': 7.0.1 '@types/imagemin-gifsicle': 7.0.4 @@ -5927,7 +5945,7 @@ snapshots: '@types/imagemin-webp': 7.0.3 '@types/svgo': 2.6.4 chalk: 4.1.2 - debug: 4.4.1 + debug: 4.4.3 esbuild: 0.14.54 fs-extra: 10.1.0 gifsicle: 5.2.0 @@ -5941,43 +5959,43 @@ snapshots: imagemin-webp: 6.1.0 jpegtran-bin: 6.0.1 pathe: 0.2.0 - vite: 7.1.3(@types/node@24.3.0)(terser@5.43.1) + vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) transitivePeerDependencies: - supports-color - vite-prerender-plugin@0.5.11(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)): + vite-prerender-plugin@0.5.12(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)): dependencies: kolorist: 1.8.0 - magic-string: 0.30.18 + magic-string: 0.30.19 node-html-parser: 6.1.13 simple-code-frame: 1.3.0 source-map: 0.7.6 stack-trace: 1.0.0-pre2 - vite: 7.1.3(@types/node@24.3.0)(terser@5.43.1) + vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) - vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.3(@types/node@24.3.0)(terser@5.43.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.7(@types/node@24.5.2)(terser@5.44.0)): dependencies: - debug: 4.4.1 + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.2) optionalDependencies: - vite: 7.1.3(@types/node@24.3.0)(terser@5.43.1) + vite: 7.1.7(@types/node@24.5.2)(terser@5.44.0) transitivePeerDependencies: - supports-color - typescript - vite@7.1.3(@types/node@24.3.0)(terser@5.43.1): + vite@7.1.7(@types/node@24.5.2)(terser@5.44.0): dependencies: - esbuild: 0.25.9 + esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 - rollup: 4.49.0 - tinyglobby: 0.2.14 + rollup: 4.52.2 + tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.2 fsevents: 2.3.3 - terser: 5.43.1 + terser: 5.44.0 which-typed-array@1.1.19: dependencies: From b1d6ab3c962fcd027c409d483518ad5491299c43 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 26 Sep 2025 08:46:11 +0200 Subject: [PATCH 04/19] ventilation bypass state from 0x55C, #1197 --- src/devices/ventilation.cpp | 10 ++++++---- src/devices/ventilation.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/devices/ventilation.cpp b/src/devices/ventilation.cpp index 8dcdf6605..6b41fb8d8 100644 --- a/src/devices/ventilation.cpp +++ b/src/devices/ventilation.cpp @@ -30,7 +30,7 @@ Ventilation::Ventilation(uint8_t device_type, uint8_t device_id, uint8_t product register_telegram_type(0x583, "VentilationMonitor", false, MAKE_PF_CB(process_MonitorMessage)); register_telegram_type(0x5D9, "Airquality", false, MAKE_PF_CB(process_VOCMessage)); register_telegram_type(0x587, "Bypass", false, MAKE_PF_CB(process_BypassMessage)); - // register_telegram_type(0x5, "VentilationSet", true, MAKE_PF_CB(process_SetMessage)); + register_telegram_type(0x55C, "VentilationSet", true, MAKE_PF_CB(process_SetMessage)); register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &outFresh_, @@ -50,8 +50,9 @@ Ventilation::Ventilation(uint8_t device_type, uint8_t device_id, uint8_t product register_device_value(DeviceValueTAG::TAG_DEVICE_DATA, &bypass_, DeviceValueType::BOOL, FL_(airbypass), DeviceValueUOM::NONE, MAKE_CF_CB(set_bypass)); } -// message +// message 0x055C, data: 08 01 11 17 void Ventilation::process_SetMessage(std::shared_ptr telegram) { + has_update(telegram, bypass_, 1); } // message 583 @@ -85,9 +86,10 @@ void Ventilation::process_ModeMessage(std::shared_ptr telegram) has_enumupdate(telegram, mode_, 0, -1); } -// message 0x0587, data: 01 00 +// message 0x0587, data: 00 00 64 00 64 0A 00 01 54 01 00 01 00 00 00 46 00 00 00 02 00 A3 00 A3 void Ventilation::process_BypassMessage(std::shared_ptr telegram) { - has_update(telegram, bypass_, 1); + // has_update(telegram, bypass_closing, 0); + // has_update(telegram, bypass_opening, 1); } bool Ventilation::set_ventMode(const char * value, const int8_t id) { diff --git a/src/devices/ventilation.h b/src/devices/ventilation.h index f76fc7185..d01dcd6a0 100644 --- a/src/devices/ventilation.h +++ b/src/devices/ventilation.h @@ -41,7 +41,7 @@ class Ventilation : public EMSdevice { uint8_t ventOutSpeed_; // handlers: 0x056B 0x0575 0x0583 0x0585 0x0586 0x0587 0x0588 0x058D 0x058E 0x058F 0x0590 0x05CF 0x05D9 0x05E3 - void process_SetMessage(std::shared_ptr telegram); + void process_SetMessage(std::shared_ptr telegram); // 0x55C void process_MonitorMessage(std::shared_ptr telegram); void process_ModeMessage(std::shared_ptr telegram); // 0x56B void process_BlowerMessage(std::shared_ptr telegram); // 0x56B From 4cfcba18ee6d81483d9d35a5f4ba90243be30a9f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 26 Sep 2025 08:47:31 +0200 Subject: [PATCH 05/19] analogsensors pulse output #2624 and frequncy input #2631 --- interface/src/app/main/Sensors.tsx | 3 +- .../src/app/main/SensorsAnalogDialog.tsx | 40 +++++++- interface/src/app/main/types.ts | 18 +++- src/core/analogsensor.cpp | 91 ++++++++++++++++--- src/core/analogsensor.h | 13 ++- src/core/emsdevicevalue.cpp | 8 +- src/core/emsdevicevalue.h | 3 +- src/core/locale_common.h | 4 +- src/web/WebDataService.cpp | 5 +- 9 files changed, 159 insertions(+), 26 deletions(-) diff --git a/interface/src/app/main/Sensors.tsx b/interface/src/app/main/Sensors.tsx index 8332f42c5..c8a37fd91 100644 --- a/interface/src/app/main/Sensors.tsx +++ b/interface/src/app/main/Sensors.tsx @@ -439,7 +439,8 @@ const Sensors = () => { {a.n} {AnalogTypeNames[a.t]} {(a.t === AnalogType.DIGITAL_OUT && a.g !== 25 && a.g !== 26) || - a.t === AnalogType.DIGITAL_IN ? ( + a.t === AnalogType.DIGITAL_IN || + a.t === AnalogType.PULSE ? ( {a.v ? LL.ON() : LL.OFF()} ) : ( {a.t ? formatValue(a.v, a.u) : ''} diff --git a/interface/src/app/main/SensorsAnalogDialog.tsx b/interface/src/app/main/SensorsAnalogDialog.tsx index 6ee9e17e3..719505aa3 100644 --- a/interface/src/app/main/SensorsAnalogDialog.tsx +++ b/interface/src/app/main/SensorsAnalogDialog.tsx @@ -132,7 +132,9 @@ const SensorsAnalogDialog = ({ ))} - {editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE && ( + {((editItem.t >= AnalogType.COUNTER && editItem.t <= AnalogType.RATE) || + (editItem.t >= AnalogType.FREQ_0 && + editItem.t <= AnalogType.FREQ_2)) && ( )} + {editItem.t === AnalogType.PULSE && ( + <> + + + {LL.ACTIVEHIGH()} + {LL.ACTIVELOW()} + + + + s + ) + }, + htmlInput: { min: '0', max: '10000', step: '0.1' } + }} + /> + + + )} diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index 924d57a5a..5c86daf4f 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -188,7 +188,8 @@ export enum DeviceValueUOM { VOLTS, MBAR, LH, - CTKWH + CTKWH, + HZ } export const DeviceValueUOM_s = [ @@ -218,7 +219,8 @@ export const DeviceValueUOM_s = [ 'V', 'mbar', 'l/h', - 'ct/kWh' + 'ct/kWh', + 'Hz' ]; export enum AnalogType { @@ -234,7 +236,11 @@ export enum AnalogType { PWM_1 = 8, PWM_2 = 9, NTC = 10, - RGB = 11 + RGB = 11, + PULSE = 12, + FREQ_0 = 13, + FREQ_1 = 14, + FREQ_2 = 15 } export const AnalogTypeNames = [ @@ -249,7 +255,11 @@ export const AnalogTypeNames = [ 'PWM 1', 'PWM 2', 'NTC Temp.', - 'RGB Led' + 'RGB Led', + 'Pulse', + 'Freq 0', + 'Freq 1', + 'Freq 2' ]; type BoardProfiles = Record; diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index dadebe4e4..c7acd095a 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -23,6 +23,29 @@ namespace emsesp { uuid::log::Logger AnalogSensor::logger_{F_(analogsensor), uuid::log::Facility::DAEMON}; +portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; +unsigned long AnalogSensor::edge[] = {0, 0, 0}; +unsigned long AnalogSensor::edgecnt[] = {0, 0, 0}; + +void IRAM_ATTR AnalogSensor::freqIrq0() { + portENTER_CRITICAL_ISR(&mux); + edgecnt[0]++; + edge[0] = micros(); + portEXIT_CRITICAL_ISR(&mux); +} +void IRAM_ATTR AnalogSensor::freqIrq1() { + portENTER_CRITICAL_ISR(&mux); + edgecnt[1]++; + edge[1] = micros(); + portEXIT_CRITICAL_ISR(&mux); +} +void IRAM_ATTR AnalogSensor::freqIrq2() { + portENTER_CRITICAL_ISR(&mux); + edgecnt[2]++; + edge[2] = micros(); + portEXIT_CRITICAL_ISR(&mux); +} + void AnalogSensor::start(const bool factory_settings) { // if (factory_settings && EMSESP::nvs_.getString("boot").equals("E32V2_2") && EMSESP::nvs_.getString("hwrevision").equals("3.0")) { if (factory_settings && analogReadMilliVolts(39) > 700) { // core voltage > 2.6V @@ -92,7 +115,7 @@ void AnalogSensor::reload(bool get_nvs) { for (const auto & sensor : settings.analogCustomizations) { // search customlist if (sensor_.gpio() == sensor.gpio) { // for output sensors set value to new start-value - if (sensor.type >= AnalogType::DIGITAL_OUT + if (sensor.type >= AnalogType::DIGITAL_OUT && sensor.type <= AnalogType::PWM_2 && (sensor_.type() != sensor.type || sensor_.offset() != sensor.offset || sensor_.factor() != sensor.factor)) { sensor_.set_value(sensor.offset); } @@ -134,7 +157,7 @@ void AnalogSensor::reload(bool get_nvs) { } } if (sensor.type == AnalogType::COUNTER || (sensor.type >= AnalogType::DIGITAL_OUT && sensor.type <= AnalogType::PWM_2) - || sensor.type == AnalogType::RGB) { + || sensor.type == AnalogType::RGB || sensor.type == AnalogType::PULSE) { Command::add( EMSdevice::DeviceType::ANALOGSENSOR, sensor.name.c_str(), @@ -142,6 +165,7 @@ void AnalogSensor::reload(bool get_nvs) { sensor.type == AnalogType::COUNTER ? FL_(counter) : sensor.type == AnalogType::DIGITAL_OUT ? FL_(digital_out) : sensor.type == AnalogType::RGB ? FL_(RGB) + : sensor.type == AnalogType::PULSE ? FL_(pulse) : FL_(pwm), CommandFlag::ADMIN_ONLY); } @@ -204,6 +228,16 @@ void AnalogSensor::reload(bool get_nvs) { sensor.set_offset(0); sensor.set_value(0); publish_sensor(sensor); + } else if (sensor.type() >= AnalogType::FREQ_0 && sensor.type() <= AnalogType::FREQ_2) { + LOG_DEBUG("Frequency on GPIO %02d", sensor.gpio()); + pinMode(sensor.gpio(), INPUT_PULLUP); + sensor.set_offset(0); + sensor.set_value(0); + publish_sensor(sensor); + auto index = sensor.type() - AnalogType::FREQ_0; + attachInterrupt(sensor.gpio(), index == 0 ? freqIrq0 : index == 1 ? freqIrq1 : freqIrq2, FALLING); + lastedge[index] = edge[index] = micros(); + edgecnt[index] = 0; } else if (sensor.type() == AnalogType::DIGITAL_IN) { LOG_DEBUG("Digital Read on GPIO %02d", sensor.gpio()); pinMode(sensor.gpio(), INPUT_PULLUP); @@ -260,6 +294,11 @@ void AnalogSensor::reload(bool get_nvs) { sensor.set_value(sensor.offset()); } publish_sensor(sensor); + } else if (sensor.type() == AnalogType::PULSE) { + LOG_DEBUG("Pulse on GPIO %02d", sensor.gpio()); + pinMode(sensor.gpio(), OUTPUT); + digitalWrite(sensor.gpio(), (sensor.offset() == 1) ^ (sensor.value() == 1)); + sensor.polltime_ = sensor.value() != 0 ? uuid::get_uptime() + (sensor.factor() * 1000) : 0; } else if (sensor.type() >= AnalogType::PWM_0 && sensor.type() <= AnalogType::PWM_2) { LOG_DEBUG("PWM output on GPIO %02d", sensor.gpio()); #if ESP_IDF_VERSION_MAJOR >= 5 @@ -330,6 +369,23 @@ void AnalogSensor::measure() { changed_ = true; publish_sensor(sensor); } + } else if (sensor.type() >= AnalogType::FREQ_0 && sensor.type() <= AnalogType::FREQ_2) { + auto index = sensor.type() - AnalogType::FREQ_0; + auto oldval = sensor.value(); + if (edge[index] != lastedge[index] && edgecnt[index] > 0) { + portENTER_CRITICAL_ISR(&mux); + auto t = (edge[index] - lastedge[index]) / edgecnt[index]; + lastedge[index] = edge[index]; + edgecnt[index] = 0; + portEXIT_CRITICAL_ISR(&mux); + sensor.set_value(sensor.factor() * 1000000.0 / t); + } else if (micros() - edge[index] > 10000000ul && sensor.value() > 0) { + sensor.set_value(0); + } + if (sensor.value() != oldval) { + changed_ = true; + publish_sensor(sensor); + } } } } @@ -337,9 +393,9 @@ void AnalogSensor::measure() { // poll digital io every time with debounce // go through the list of digital sensors for (auto & sensor : sensors_) { + auto old_value = sensor.value(); // remember current value before reading if (sensor.type() == AnalogType::DIGITAL_IN || sensor.type() == AnalogType::COUNTER || sensor.type() == AnalogType::TIMER || sensor.type() == AnalogType::RATE) { - auto old_value = sensor.value(); // remember current value before reading auto current_reading = digitalRead(sensor.gpio()); if (sensor.poll_ != current_reading) { // check for pinchange sensor.polltime_ = uuid::get_uptime(); // remember time of pinchange @@ -362,13 +418,17 @@ void AnalogSensor::measure() { sensor.last_polltime_ = sensor.polltime_; } } - - // see if there is a change and increment # reads - if (old_value != sensor.value()) { - sensorreads_++; - changed_ = true; - publish_sensor(sensor); - } + } + if (sensor.type() == AnalogType::PULSE && sensor.value() && sensor.polltime_ && sensor.polltime_ < uuid::get_uptime()) { + sensor.set_value(0); + digitalWrite(sensor.gpio(), sensor.offset()); + sensor.polltime_ = 0; + } + // see if there is a change and increment # reads + if (old_value != sensor.value()) { + sensorreads_++; + changed_ = true; + publish_sensor(sensor); } } @@ -562,6 +622,9 @@ void AnalogSensor::publish_values(const bool force) { case AnalogType::PWM_0: case AnalogType::PWM_1: case AnalogType::PWM_2: + case AnalogType::FREQ_0: + case AnalogType::FREQ_1: + case AnalogType::FREQ_2: case AnalogType::RGB: case AnalogType::NTC: dataSensor["value"] = serialized(Helpers::render_value(s, sensor.value(), 2)); // double @@ -762,7 +825,7 @@ void AnalogSensor::get_value_json(JsonObject output, const Sensor & sensor) { output["analog"] = FL_(list_sensortype)[sensor.type()]; output["value"] = sensor.value(); output["readable"] = true; - output["writeable"] = sensor.type() == AnalogType::COUNTER || sensor.type() >= AnalogType::RGB + output["writeable"] = sensor.type() == AnalogType::COUNTER || sensor.type() == AnalogType::RGB || sensor.type() == AnalogType::PULSE || (sensor.type() >= AnalogType::DIGITAL_OUT && sensor.type() <= AnalogType::PWM_2); output["visible"] = true; if (sensor.type() == AnalogType::COUNTER) { @@ -842,6 +905,12 @@ bool AnalogSensor::command_setvalue(const char * value, const int8_t gpio) { rgbLedWrite(sensor.gpio(), 2 * r, 2 * g, 2 * b); #endif LOG_DEBUG("RGB set to %d, %d, %d", r, g, b); + } else if (sensor.type() == AnalogType::PULSE) { + uint8_t v = val; + sensor.set_value(v); + pinMode(sensor.gpio(), OUTPUT); + digitalWrite(sensor.gpio(), (sensor.offset() != 0) ^ (sensor.value() != 0)); + sensor.polltime_ = sensor.value() != 0 ? uuid::get_uptime() + (sensor.factor() * 1000) : 0; } else if (sensor.type() == AnalogType::DIGITAL_OUT) { uint8_t v = val; #if CONFIG_IDF_TARGET_ESP32 diff --git a/src/core/analogsensor.h b/src/core/analogsensor.h index 32b31a0e6..18b400a1f 100644 --- a/src/core/analogsensor.h +++ b/src/core/analogsensor.h @@ -124,7 +124,11 @@ class AnalogSensor { PWM_1 = 8, PWM_2 = 9, NTC = 10, - RGB = 11 + RGB = 11, + PULSE = 12, + FREQ_0 = 13, + FREQ_1 = 14, + FREQ_2 = 15 }; void start(const bool factory_settings = false); @@ -190,6 +194,13 @@ class AnalogSensor { bool changed_ = true; // this will force a publish of all sensors when initialising uint32_t sensorfails_ = 0; uint32_t sensorreads_ = 0; + + static void IRAM_ATTR freqIrq0(); + static void IRAM_ATTR freqIrq1(); + static void IRAM_ATTR freqIrq2(); + static unsigned long edge[3]; + static unsigned long edgecnt[3]; + unsigned long lastedge[3] = {0, 0, 0}; }; } // namespace emsesp diff --git a/src/core/emsdevicevalue.cpp b/src/core/emsdevicevalue.cpp index 82bb45732..d62ca4628 100644 --- a/src/core/emsdevicevalue.cpp +++ b/src/core/emsdevicevalue.cpp @@ -108,10 +108,10 @@ DeviceValue::DeviceValue(uint8_t device_type, const char * DeviceValue::DeviceValueUOM_s[] = { F_(uom_blank), // 0 - F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0], - FL_(minutes)[0], F_(uom_ua), F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0], - F_(uom_dbm), F_(uom_fahrenheit), F_(uom_mv), F_(uom_sqm), F_(uom_m3), F_(uom_l), F_(uom_kmin), - F_(uom_k), F_(uom_volts), F_(uom_mbar), F_(uom_lh), F_(uom_ctkwh), F_(uom_blank) + F_(uom_degrees), F_(uom_degrees), F_(uom_percent), F_(uom_lmin), F_(uom_kwh), F_(uom_wh), FL_(hours)[0], FL_(minutes)[0], + F_(uom_ua), F_(uom_bar), F_(uom_kw), F_(uom_w), F_(uom_kb), FL_(seconds)[0], F_(uom_dbm), F_(uom_fahrenheit), + F_(uom_mv), F_(uom_sqm), F_(uom_m3), F_(uom_l), F_(uom_kmin), F_(uom_k), F_(uom_volts), F_(uom_mbar), + F_(uom_lh), F_(uom_ctkwh), F_(uom_hz), F_(uom_blank) }; diff --git a/src/core/emsdevicevalue.h b/src/core/emsdevicevalue.h index ec4bf4e76..49d509e8b 100644 --- a/src/core/emsdevicevalue.h +++ b/src/core/emsdevicevalue.h @@ -75,7 +75,8 @@ class DeviceValue { MBAR, // 24 - mbar LH, // 25 - l/h CTKWH, // 26 - ct/kWh - CONNECTIVITY // 27 - used in HA + HZ, // 27 - Hz + CONNECTIVITY // 28 - used in HA }; // TAG mapping - maps to DeviceValueTAG_s in emsdevicevalue.cpp diff --git a/src/core/locale_common.h b/src/core/locale_common.h index 36a072937..f83cac0d0 100644 --- a/src/core/locale_common.h +++ b/src/core/locale_common.h @@ -264,6 +264,7 @@ MAKE_WORD_CUSTOM(uom_volts, "V") MAKE_WORD_CUSTOM(uom_mbar, "mbar") MAKE_WORD_CUSTOM(uom_lh, "l/h") MAKE_WORD_CUSTOM(uom_ctkwh, "ct/kWh") +MAKE_WORD_CUSTOM(uom_hz, "Hz") // MQTT topics and prefixes MAKE_WORD_CUSTOM(heating_active, "heating_active") @@ -277,7 +278,8 @@ MAKE_ENUM_FIXED(list_syslog_level, "off", "emerg", "alert", "crit", "error", "wa MAKE_ENUM_FIXED(counter, "counter") MAKE_ENUM_FIXED(digital_out, "digital_out") MAKE_ENUM_FIXED(RGB, "RGB") -MAKE_ENUM_FIXED(list_sensortype, "disabled", "digital in", "counter", "adc", "timer", "rate", "digital out", "pwm 0", "pwm 1", "pwm 2", "NTC Temp", "RGB Led") +MAKE_ENUM_FIXED(pulse, "pulse") +MAKE_ENUM_FIXED(list_sensortype, "disabled", "digital in", "counter", "adc", "timer", "rate", "digital out", "pwm 0", "pwm 1", "pwm 2", "NTC Temp", "RGB Led", "pulse", "freq 0", "freq 1", "freq 2") // watch MAKE_ENUM_FIXED(list_watch, "off", "on", "raw", "unknown") diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 13489e7c8..735a35182 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -436,7 +436,8 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { obj["v"] = Helpers::transformNumFloat(sensor.value()); } else #endif - if (sensor.type() == AnalogSensor::AnalogType::DIGITAL_OUT || sensor.type() == AnalogSensor::AnalogType::DIGITAL_IN) { + if (sensor.type() == AnalogSensor::AnalogType::DIGITAL_OUT || sensor.type() == AnalogSensor::AnalogType::DIGITAL_IN + || sensor.type() == AnalogSensor::AnalogType::PULSE) { char s[12]; dv["v"] = Helpers::render_boolean(s, sensor.value() != 0, true); JsonArray l = dv["l"].to(); @@ -448,7 +449,7 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { } if (sensor.type() == AnalogSensor::AnalogType::COUNTER || (sensor.type() >= AnalogSensor::AnalogType::DIGITAL_OUT && sensor.type() <= AnalogSensor::AnalogType::PWM_2) - || sensor.type() == AnalogSensor::AnalogType::RGB) { + || sensor.type() == AnalogSensor::AnalogType::RGB || sensor.type() == AnalogSensor::AnalogType::PULSE) { dv["c"] = sensor.name(); } } From 419fe8ef5d554ca96fcbe2f505b1e386951dcb5c Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Fri, 26 Sep 2025 08:47:48 +0200 Subject: [PATCH 06/19] dev 18, changelog --- CHANGELOG_LATEST.md | 8 +++++--- src/emsesp_version.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index d5a58947c..4b7a95412 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -18,11 +18,12 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/). - disinfection command [#2601](https://github.com/emsesp/EMS-ESP32/issues/2601) - added new board profile for upcoming BBQKees E32V2.2 - set differential pressure entity in Mixer device -- set set climate action cooling/heating in HA +- set set climate action cooling/heating in HA [#2583](https://github.com/emsesp/EMS-ESP32/issues/2583) - Internal sensors of E32V2_2 -- FW200 display options -- CR11 mode settings OFF/MANUAL depends on selTemp +- FW200 display options [#2610](https://github.com/emsesp/EMS-ESP32/discussions/2610) +- CR11 mode settings OFF/MANUAL depends on selTemp [#2437](https://github.com/emsesp/EMS-ESP32/issues/3437) - Fuse settings for BBQKees boards +- Analogsensors for pulse output [#2624](https://github.com/emsesp/EMS-ESP32/discussions/2624) and frequency input [#2631](https://github.com/emsesp/EMS-ESP32/discussions/2631) ## Fixed @@ -39,6 +40,7 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/). - Add pulsed water meter input to V1.3 gateway with Lilygo S3 [#2550](https://github.com/emsesp/EMS-ESP32/issues/2550) - fix missing long 10-second press of Button to perform a factory reset - fix wwMaxPower on Junkers ZBS14 [#2609](https://github.com/emsesp/EMS-ESP32/issues/2609) +- ventilation bypass state from telegram 0x55C [#1197](https://github.com/emsesp/EMS-ESP32/issues/1197) ## Changed diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 42e3d4969..453758804 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.3-dev.17" +#define EMSESP_APP_VERSION "3.7.3-dev.18" From 59d07e81d652ca6e19264c710dfcd34ea58426ca Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 29 Sep 2025 12:47:08 +0200 Subject: [PATCH 07/19] test SRC Plus implementation, #2636 --- src/core/emsesp.cpp | 6 +- src/core/locale_translations.h | 3 + src/devices/connect.cpp | 130 +++++++++++++++++++++++++++++++++ src/devices/connect.h | 32 ++++++++ 4 files changed, 170 insertions(+), 1 deletion(-) diff --git a/src/core/emsesp.cpp b/src/core/emsesp.cpp index 42806141b..829ffc631 100644 --- a/src/core/emsesp.cpp +++ b/src/core/emsesp.cpp @@ -1307,7 +1307,11 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const default_name = "Wireless sensor base"; } } - + // map MX400 also to RF Base + if (device_id == EMSdevice::EMS_DEVICE_ID_RFBASE) { + device_type = DeviceType::CONNECT; + default_name = "Wireless base"; + } if ((device_id >= EMSdevice::EMS_DEVICE_ID_DHW1 && device_id <= EMSdevice::EMS_DEVICE_ID_DHW8) || device_id == EMSdevice::EMS_DEVICE_ID_IPM_DHW) { device_type = DeviceType::WATER; } diff --git a/src/core/locale_translations.h b/src/core/locale_translations.h index fe3f131e6..46747b3e1 100644 --- a/src/core/locale_translations.h +++ b/src/core/locale_translations.h @@ -915,6 +915,9 @@ MAKE_TRANSLATION(status, "status", "status", "Status", "Status", "Status", "stat // RF sensor, id 0x40, telegram 0x435 MAKE_TRANSLATION(RFTemp, "rftemp", "RF room temperature sensor", "RF Raumtemperatursensor", "RF ruimtetemperatuur sensor", "RF Rumsgivare Temperatur", "bezprzewodowy czujnik temperatury pomieszczenia", "RF romsgiver temp", "capteur de température de pièce RF", "RF oda sıcaklık sensörü", "Sensore di temperatura ambiente RF", "RF snímač izbovej teploty", "RF senzor teploty místnosti") +// gateway thermostat +MAKE_TRANSLATION(name, "name", "name", "Name") + // ventilation MAKE_TRANSLATION(outFresh, "outfresh", "outdoor fresh air", "Außenlufttemp.", "temperatuur buitenlucht", "Utelufttemperatur", "świeże powietrze z zewnątrz", "", "", "dış ortam taze hava", "aria fresca esterna", "čerstvý vzduch vonku", "venkovní čerstvý vzduch") // TODO translate MAKE_TRANSLATION(inFresh, "infresh", "indoor fresh air", "Zulufttemp.", "temperatuur aanvoer", "Tillufttemperatur", "nawiew", "", "", "iç ortam taze hava", "aria fresca interna", "čerstvý vzduch v interiéri", "vnitřní čerstvý vzduch") // TODO translate diff --git a/src/devices/connect.cpp b/src/devices/connect.cpp index 03303b257..123b0b88a 100644 --- a/src/devices/connect.cpp +++ b/src/devices/connect.cpp @@ -32,6 +32,20 @@ Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, con DeviceValueNumOp::DV_NUMOP_DIV10, FL_(outdoorTemp), DeviceValueUOM::DEGREES); + // Roomthermostats + for (uint8_t i = 0; i < 16; i++) { + register_telegram_type(0x0BDD + i, "Room", false, MAKE_PF_CB(process_roomThermostat)); + register_telegram_type(0x0B3D + i, "Roomname", true, MAKE_PF_CB(process_roomThermostatName)); + register_telegram_type(0x0BB5 + i, "Roomsettings", true, MAKE_PF_CB(process_roomThermostatMode)); + + // 1230..123F read, unknown, 16 bytes long? + // register_telegram_type(0x1230 + i, "unknown", true, MAKE_PF_CB(process_unknown)); + // 1244..1253 broadcast, unknown, 14 bytes long + } + // register_telegram_type(0xDB65, "Roomschedule", true, MAKE_PF_CB(process_roomSchedule)); + // 0x2040, broadcast 36 bytes: + // data: 0E 60 00 DF 0D AF 0A 46 0A 46 02 9A 1C 53 1C 53 12 AD 12 AD 00 00 13 C2 + // data: 1F 37 1F 37 00 00 00 00 18 97 11 27 (offset 24) } } /* @@ -46,6 +60,122 @@ void Connect::process_OutdoorTemp(std::shared_ptr telegram) { (0x0880), data: 01 04 (0x0889), data: 00 80 80 01 */ +void Connect::register_device_values_room(std::shared_ptr room) { + auto tag = DeviceValueTAG::TAG_HS1 + room->room(); + register_device_value(tag, &room->temp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(roomTemp), DeviceValueUOM::DEGREES); + register_device_value(tag, &room->humidity_, DeviceValueType::UINT8, FL_(airHumidity), DeviceValueUOM::PERCENT); + register_device_value(tag, &room->seltemp_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(seltemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_seltemp)); + register_device_value(tag, &room->mode_, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); + register_device_value(tag, &room->name_, DeviceValueType::STRING, FL_(name), DeviceValueUOM::NONE, MAKE_CF_CB(set_name)); +} + +std::shared_ptr Connect::room_circuit(const uint8_t num, const bool create) { + // check for existing circuit + for (const auto & room_circuit : room_circuits_) { + if (room_circuit->room() == num) { + return room_circuit; + } + } + if (!create) { + return nullptr; + } + // create a new circuit object and add to the list + auto new_room = std::make_shared(num); + room_circuits_.push_back(new_room); + // register the device values + register_device_values_room(new_room); + + return new_room; // return back point to new HC object +} + +// gateway(0x50) B all(0x00), ?(0x0BDD), data: 00 E6 36 2A +void Connect::process_roomThermostat(std::shared_ptr telegram) { + auto rc = room_circuit(telegram->type_id - 0xBDD, true); + uint8_t humidity = EMS_VALUE_UINT8_NOTSET; + uint8_t seltemp = EMS_VALUE_UINT8_NOTSET; + has_update(telegram, rc->temp_, 0); + if (Helpers::hasValue(rc->temp_)) { + telegram->read_value(humidity, 2); + telegram->read_value(seltemp, 3); + } + has_update(rc->humidity_, humidity); + has_update(rc->seltemp_, seltemp); +} + +// gateway(0x48) W gateway(0x50), ?(0x0B42), data: 01 +// gateway(0x48) W gateway(0x50), ?(0x0B42), data: 00 4B 00 FC 00 63 00 68 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (offset 1) +void Connect::process_roomThermostatName(std::shared_ptr telegram) { + auto rc = room_circuit(telegram->type_id - 0xB3D); + if (rc == nullptr) { + return; + } + if (telegram->offset > 1 || telegram->message_length < 3) { + return; + } + std::string s; + char c; + uint8_t i = 3 - telegram->offset; + while ((i < telegram->message_length) && ((c = telegram->message_data[i]) != 0)) { + s += c; + i += 2; + } + if (s.length()) { + has_update(rc->name_, s.c_str(), s.length()); + } +} + +// settings 0-mode, 1-tempautotemp, 3 - manualtemp, 6,7 - ? +void Connect::process_roomThermostatMode(std::shared_ptr telegram) { + auto rc = room_circuit(telegram->type_id - 0xBB5); + if (rc == nullptr) { + return; + } + has_enumupdate(telegram, rc->mode_, 0, {3, 1, 0}); +} + +// Settings: + +bool Connect::set_mode(const char * value, const int8_t id) { + auto rc = room_circuit(id - DeviceValueTAG::TAG_HS1); + if (rc == nullptr) { + return false; + } + uint8_t v; + if (Helpers::value2enum(value, v, FL_(enum_mode2), {3, 1, 0})) { + write_command(0xBB5 + rc->room(), 0, v); // no validate, mode change is broadcasted + return true; + } + return false; +} + +bool Connect::set_seltemp(const char * value, const int8_t id) { + auto rc = room_circuit(id - DeviceValueTAG::TAG_HS1); + if (rc == nullptr) { + return false; + } + float v; + if (Helpers::value2float(value, v)) { + write_command(0xBB5 + rc->room(), rc->mode_ == 2 ? 1 : 3, v * 2); + return true; + } + return false; +} + +bool Connect::set_name(const char * value, const int8_t id) { + auto rc = room_circuit(id - DeviceValueTAG::TAG_HS1); + if (rc == nullptr || value == nullptr || strlen(value) > 12) { + return false; + } + uint8_t data[strlen(value) * 2]; + uint8_t * d = data; + const char * c = value; + while (*c != 0) { + *d++ = 0; + *d++ = *c++; + } + write_command(0x0B3D + rc->room(), 1, data, sizeof(data), 0x0B3D + rc->room()); + return true; +} } // namespace emsesp diff --git a/src/devices/connect.h b/src/devices/connect.h index 5db2e11d3..e20e74315 100644 --- a/src/devices/connect.h +++ b/src/devices/connect.h @@ -27,7 +27,39 @@ class Connect : public EMSdevice { public: Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, const char * version, const char * name, uint8_t flags, uint8_t brand); + class RoomCircuit { + public: + RoomCircuit(const uint8_t num) + : room_(num) { + } + ~RoomCircuit() = default; + int16_t temp_; + uint8_t humidity_; + uint8_t seltemp_; + uint8_t mode_; + char name_[25]; + + uint8_t room() { + return room_; + } + + private: + uint8_t room_; // dhw circuit number 0..10 + }; + private: + std::shared_ptr room_circuit(const uint8_t num, const bool create = false); + + void register_device_values_room(std::shared_ptr room); + void process_roomThermostat(std::shared_ptr telegram); + void process_roomThermostatName(std::shared_ptr telegram); + void process_roomThermostatMode(std::shared_ptr telegram); + bool set_mode(const char * value, const int8_t id); + bool set_seltemp(const char * value, const int8_t id); + bool set_name(const char * value, const int8_t id); + + std::vector> room_circuits_; + void process_OutdoorTemp(std::shared_ptr telegram); int16_t outdoorTemp_; }; From d88513d7898d470f713765f27ded8313810babdc Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 30 Sep 2025 08:48:56 +0200 Subject: [PATCH 08/19] SRC thermostat test, update1 --- src/core/locale_common.h | 1 + src/devices/connect.cpp | 64 ++++++++++++++++++++++++---------------- src/devices/connect.h | 15 ++++++---- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/core/locale_common.h b/src/core/locale_common.h index f83cac0d0..f3c5cdbd0 100644 --- a/src/core/locale_common.h +++ b/src/core/locale_common.h @@ -339,6 +339,7 @@ MAKE_ENUM(enum_mode4, FL_(nofrost), FL_(eco), FL_(heat), FL_(auto)) // JUNKERS MAKE_ENUM(enum_mode5, FL_(auto), FL_(off)) // CRF MAKE_ENUM(enum_mode6, FL_(nofrost), FL_(night), FL_(day)) // RC10 MAKE_ENUM(enum_mode7, FL_(off), FL_(manual)) // CR11 +MAKE_ENUM(enum_mode8, FL_(auto), FL_(heat), FL_(cool), FL_(off)) // SRC room thermostats MAKE_ENUM(enum_mode_ha, FL_(off), FL_(heat), FL_(auto)) // HA climate MAKE_ENUM(enum_modetype, FL_(eco), FL_(comfort)) diff --git a/src/devices/connect.cpp b/src/devices/connect.cpp index 123b0b88a..79eef43a3 100644 --- a/src/devices/connect.cpp +++ b/src/devices/connect.cpp @@ -37,10 +37,8 @@ Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, con register_telegram_type(0x0BDD + i, "Room", false, MAKE_PF_CB(process_roomThermostat)); register_telegram_type(0x0B3D + i, "Roomname", true, MAKE_PF_CB(process_roomThermostatName)); register_telegram_type(0x0BB5 + i, "Roomsettings", true, MAKE_PF_CB(process_roomThermostatMode)); - - // 1230..123F read, unknown, 16 bytes long? - // register_telegram_type(0x1230 + i, "unknown", true, MAKE_PF_CB(process_unknown)); - // 1244..1253 broadcast, unknown, 14 bytes long + register_telegram_type(0x1230 + i, "Roomparams", true, MAKE_PF_CB(process_roomThermostatParam)); + register_telegram_type(0x1244 + i, "Roomdata", false, MAKE_PF_CB(process_roomThermostatData)); } // register_telegram_type(0xDB65, "Roomschedule", true, MAKE_PF_CB(process_roomSchedule)); // 0x2040, broadcast 36 bytes: @@ -63,9 +61,11 @@ void Connect::process_OutdoorTemp(std::shared_ptr telegram) { void Connect::register_device_values_room(std::shared_ptr room) { auto tag = DeviceValueTAG::TAG_HS1 + room->room(); register_device_value(tag, &room->temp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(roomTemp), DeviceValueUOM::DEGREES); - register_device_value(tag, &room->humidity_, DeviceValueType::UINT8, FL_(airHumidity), DeviceValueUOM::PERCENT); - register_device_value(tag, &room->seltemp_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(seltemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_seltemp)); - register_device_value(tag, &room->mode_, DeviceValueType::ENUM, FL_(enum_mode2), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); + register_device_value(tag, &room->humidity_, DeviceValueType::INT8, FL_(airHumidity), DeviceValueUOM::PERCENT); + register_device_value(tag, &room->dewtemp_, DeviceValueType::INT16, DeviceValueNumOp::DV_NUMOP_DIV10, FL_(dewTemperature), DeviceValueUOM::DEGREES); + register_device_value( + tag, &room->seltemp_, DeviceValueType::UINT8, DeviceValueNumOp::DV_NUMOP_DIV2, FL_(seltemp), DeviceValueUOM::DEGREES, MAKE_CF_CB(set_seltemp)); + register_device_value(tag, &room->mode_, DeviceValueType::ENUM, FL_(enum_mode8), FL_(mode), DeviceValueUOM::NONE, MAKE_CF_CB(set_mode)); register_device_value(tag, &room->name_, DeviceValueType::STRING, FL_(name), DeviceValueUOM::NONE, MAKE_CF_CB(set_name)); } @@ -90,16 +90,22 @@ std::shared_ptr Connect::room_circuit(const uint8_t num, c // gateway(0x50) B all(0x00), ?(0x0BDD), data: 00 E6 36 2A void Connect::process_roomThermostat(std::shared_ptr telegram) { - auto rc = room_circuit(telegram->type_id - 0xBDD, true); - uint8_t humidity = EMS_VALUE_UINT8_NOTSET; - uint8_t seltemp = EMS_VALUE_UINT8_NOTSET; - has_update(telegram, rc->temp_, 0); - if (Helpers::hasValue(rc->temp_)) { - telegram->read_value(humidity, 2); - telegram->read_value(seltemp, 3); + bool create = telegram->offset == 0 && telegram->message_data[0] < 0x80; + auto rc = room_circuit(telegram->type_id - 0xBDD, create); + if (rc == nullptr) { + return; } - has_update(rc->humidity_, humidity); - has_update(rc->seltemp_, seltemp); + has_update(telegram, rc->temp_, 0); + has_update(telegram, rc->humidity_, 2); // could show -3 if not set + has_update(telegram, rc->seltemp_, 3); + + // calculate dew temperature + const float k2 = 17.62; + const float k3 = 243.12; + const float t = (float)rc->temp_ / 10; + const float h = (float)rc->humidity_ / 100; + int16_t dt = (10 * k3 * (((k2 * t) / (k3 + t)) + log(h)) / (((k2 * k3) / (k3 + t)) - log(h))); + has_update(rc->dewtemp_, dt); } // gateway(0x48) W gateway(0x50), ?(0x0B42), data: 01 @@ -113,14 +119,11 @@ void Connect::process_roomThermostatName(std::shared_ptr telegra return; } std::string s; - char c; - uint8_t i = 3 - telegram->offset; - while ((i < telegram->message_length) && ((c = telegram->message_data[i]) != 0)) { - s += c; - i += 2; + for (uint8_t i = 2 - telegram->offset; (i < telegram->message_length) && (telegram->message_data[i] != 0); i += 2) { + s += (char)telegram->message_data[i]; } if (s.length()) { - has_update(rc->name_, s.c_str(), s.length()); + has_update(rc->name_, s.c_str(), s.length() + 1); } } @@ -130,7 +133,14 @@ void Connect::process_roomThermostatMode(std::shared_ptr telegra if (rc == nullptr) { return; } - has_enumupdate(telegram, rc->mode_, 0, {3, 1, 0}); + // has_enumupdate(telegram, rc->mode_, 0, {3, 1, 0}); + has_update(telegram, rc->mode_, 0); +} + +void Connect::process_roomThermostatParam(std::shared_ptr telegram) { +} + +void Connect::process_roomThermostatData(std::shared_ptr telegram) { } // Settings: @@ -141,7 +151,8 @@ bool Connect::set_mode(const char * value, const int8_t id) { return false; } uint8_t v; - if (Helpers::value2enum(value, v, FL_(enum_mode2), {3, 1, 0})) { + // if (Helpers::value2enum(value, v, FL_(enum_mode2), {3, 1, 0})) { + if (Helpers::value2enum(value, v, FL_(enum_mode8))) { write_command(0xBB5 + rc->room(), 0, v); // no validate, mode change is broadcasted return true; } @@ -155,7 +166,8 @@ bool Connect::set_seltemp(const char * value, const int8_t id) { } float v; if (Helpers::value2float(value, v)) { - write_command(0xBB5 + rc->room(), rc->mode_ == 2 ? 1 : 3, v * 2); + // write_command(0xBB5 + rc->room(), rc->mode_ == 2 ? 1 : 3, v == -1 ? 0xFF : uint8_t(v * 2)); + write_command(0xBB5 + rc->room(), rc->mode_ == 0 ? 1 : 3, v == -1 ? 0xFF : uint8_t(v * 2)); return true; } return false; @@ -166,7 +178,7 @@ bool Connect::set_name(const char * value, const int8_t id) { if (rc == nullptr || value == nullptr || strlen(value) > 12) { return false; } - uint8_t data[strlen(value) * 2]; + uint8_t data[strlen(value) * 2]; uint8_t * d = data; const char * c = value; while (*c != 0) { diff --git a/src/devices/connect.h b/src/devices/connect.h index e20e74315..877a4b824 100644 --- a/src/devices/connect.h +++ b/src/devices/connect.h @@ -33,13 +33,14 @@ class Connect : public EMSdevice { : room_(num) { } ~RoomCircuit() = default; - int16_t temp_; - uint8_t humidity_; - uint8_t seltemp_; - uint8_t mode_; - char name_[25]; + int16_t temp_; + int8_t humidity_; + uint8_t seltemp_; + uint8_t mode_; + char name_[25]; + int16_t dewtemp_; - uint8_t room() { + uint8_t room() { return room_; } @@ -54,6 +55,8 @@ class Connect : public EMSdevice { void process_roomThermostat(std::shared_ptr telegram); void process_roomThermostatName(std::shared_ptr telegram); void process_roomThermostatMode(std::shared_ptr telegram); + void process_roomThermostatParam(std::shared_ptr telegram); + void process_roomThermostatData(std::shared_ptr telegram); bool set_mode(const char * value, const int8_t id); bool set_seltemp(const char * value, const int8_t id); bool set_name(const char * value, const int8_t id); From f782eac0cf3dca6830ad8583a9ccb19719b42180 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Thu, 2 Oct 2025 11:49:53 +0200 Subject: [PATCH 09/19] rename HA dev_i, SRC: do not fetch inactive circuits, long names, HA climated --- src/core/emsdevice.cpp | 7 ++++- src/core/mqtt.cpp | 63 ++++++++++++++++++++++------------------- src/devices/connect.cpp | 59 ++++++++++++++++++++++++-------------- src/devices/connect.h | 2 +- 4 files changed, 78 insertions(+), 53 deletions(-) diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index fe6b8de0a..08faa425b 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -1896,7 +1896,12 @@ void EMSdevice::mqtt_ha_entity_config_create() { create_device_config = false; // only create the main config once count++; } -#ifndef EMSESP_STANDALONE + // SRC thermostats mapped to connect/hs1/... + if (dv.tag >= DeviceValueTAG::TAG_HS1 && !strcmp(dv.short_name, FL_(roomtemp)[0])) { + Mqtt::publish_ha_climate_config(dv.tag, true, false, dv.min, dv.max); + } + + #ifndef EMSESP_STANDALONE // always create minimum one config if (count && (heap_caps_get_free_size(MALLOC_CAP_8BIT) < 65 * 1024)) { // checks free Heap+PSRAM break; diff --git a/src/core/mqtt.cpp b/src/core/mqtt.cpp index 03b579342..f440cb432 100644 --- a/src/core/mqtt.cpp +++ b/src/core/mqtt.cpp @@ -528,8 +528,8 @@ void Mqtt::ha_status() { strcpy(uniq, "system_status"); } - doc["uniq_id"] = uniq; - doc["obj_id"] = uniq; + doc["uniq_id"] = uniq; + doc["default_entity_id"] = uniq; doc["stat_t"] = Mqtt::base() + "/status"; doc["name"] = "System status"; @@ -827,7 +827,7 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev snprintf(entity_with_tag, sizeof(entity_with_tag), "%s", entity); } - // build unique identifier also used as object_id which also becomes the Entity ID in HA + // build unique identifier also used as default_entity_id which also becomes the Entity ID in HA char uniq_id[80]; // list of boiler entities that need conversion for 3.6 compatibility, add ww suffix @@ -980,8 +980,8 @@ bool Mqtt::publish_ha_sensor_config(uint8_t type, // EMSdev // build the full payload JsonDocument doc; - doc["uniq_id"] = uniq_id; - doc["obj_id"] = uniq_id; // same as unique_id + doc["uniq_id"] = uniq_id; + doc["default_entity_id"] = uniq_id; // same as unique_id char sample_val[30] = "0"; // sample, correct(!) entity value, used only to prevent warning/error in HA if real value is not published yet @@ -1235,7 +1235,9 @@ void Mqtt::add_ha_classes(JsonObject doc, const uint8_t device_type, const uint8 } bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, const bool remove, const int16_t min, const uint32_t max) { - uint8_t hc_num = tag; + uint8_t hc_num = tag < DeviceValueTAG::TAG_HS1 ? tag : tag - DeviceValueTAG::TAG_HS1 + 1; + const char * devicename = tag < DeviceValueTAG::TAG_HS1 ? "thermostat" : "connect"; + const char * tagname = tag < DeviceValueTAG::TAG_HS1 ? "hc" : "hs"; char topic[Mqtt::MQTT_TOPIC_MAX_SIZE]; char topic_t[Mqtt::MQTT_TOPIC_MAX_SIZE]; @@ -1253,21 +1255,21 @@ bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, char min_s[10]; char max_s[10]; - snprintf(topic, sizeof(topic), "climate/%s/thermostat_hc%d/config", Mqtt::basename().c_str(), hc_num); + snprintf(topic, sizeof(topic), "climate/%s/%s_%s%d/config", Mqtt::basename().c_str(), devicename, tagname, hc_num); if (remove) { return queue_remove_topic(topic); // publish empty payload with retain flag } if (Mqtt::is_nested()) { // nested format - snprintf(hc_mode_s, sizeof(hc_mode_s), "value_json.hc%d.mode", hc_num); - snprintf(hc_mode_cond, sizeof(hc_mode_cond), "value_json.hc%d is undefined or %s is undefined", hc_num, hc_mode_s); - snprintf(seltemp_s, sizeof(seltemp_s), "value_json.hc%d.seltemp", hc_num); - snprintf(seltemp_cond, sizeof(seltemp_cond), "value_json.hc%d is defined and %s is defined", hc_num, seltemp_s); + snprintf(hc_mode_s, sizeof(hc_mode_s), "value_json.%s%d.mode", tagname, hc_num); + snprintf(hc_mode_cond, sizeof(hc_mode_cond), "value_json.%s%d is undefined or %s is undefined", tagname, hc_num, hc_mode_s); + snprintf(seltemp_s, sizeof(seltemp_s), "value_json.%s%d.seltemp", tagname, hc_num); + snprintf(seltemp_cond, sizeof(seltemp_cond), "value_json.%s%d is defined and %s is defined", tagname, hc_num, seltemp_s); if (has_roomtemp) { - snprintf(currtemp_s, sizeof(currtemp_s), "value_json.hc%d.currtemp", hc_num); - snprintf(currtemp_cond, sizeof(currtemp_cond), "value_json.hc%d is defined and %s is defined", hc_num, currtemp_s); + snprintf(currtemp_s, sizeof(currtemp_s), "value_json.%s%d.currtemp", tagname, hc_num); + snprintf(currtemp_cond, sizeof(currtemp_cond), "value_json.%s%d is defined and %s is defined", tagname, hc_num, currtemp_s); } snprintf(topic_t, sizeof(topic_t), "~/%s", Mqtt::tag_to_topic(EMSdevice::DeviceType::THERMOSTAT, DeviceValueTAG::TAG_NONE).c_str()); } else { @@ -1281,7 +1283,10 @@ bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, snprintf(currtemp_s, sizeof(currtemp_s), "value_json.currtemp"); snprintf(currtemp_cond, sizeof(currtemp_cond), "%s is defined", currtemp_s); } - snprintf(topic_t, sizeof(topic_t), "~/%s", Mqtt::tag_to_topic(EMSdevice::DeviceType::THERMOSTAT, DeviceValueTAG::TAG_HC1 + hc_num - 1).c_str()); + snprintf(topic_t, + sizeof(topic_t), + "~/%s", + Mqtt::tag_to_topic(tag < DeviceValueTAG::TAG_HS1 ? EMSdevice::DeviceType::THERMOSTAT : EMSdevice::DeviceType::CONNECT, tag).c_str()); } snprintf(mode_str_tpl, @@ -1297,28 +1302,28 @@ bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, hc_mode_s, Helpers::translated_word(FL_(off))); - snprintf(name_s, sizeof(name_s), "Hc%d", hc_num); + snprintf(name_s, sizeof(name_s), "%s%d", tag < DeviceValueTAG::TAG_HS1 ? "Hc" : "Hs", hc_num); if (Mqtt::entity_format() == entityFormat::MULTI_SHORT) { - snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_thermostat_hc%d", Mqtt::basename().c_str(), hc_num); // add basename + snprintf(uniq_id_s, sizeof(uniq_id_s), "%s_%s%s%d", Mqtt::basename().c_str(), devicename, tagname, hc_num); // add basename } else { - snprintf(uniq_id_s, sizeof(uniq_id_s), "thermostat_hc%d", hc_num); // backward compatible with v3.4 + snprintf(uniq_id_s, sizeof(uniq_id_s), "%s%d", devicename, hc_num); // backward compatible with v3.4 } - snprintf(temp_cmd_s, sizeof(temp_cmd_s), "~/thermostat/hc%d/seltemp", hc_num); - snprintf(mode_cmd_s, sizeof(mode_cmd_s), "~/thermostat/hc%d/mode", hc_num); + snprintf(temp_cmd_s, sizeof(temp_cmd_s), "~/%s/%s%d/seltemp", devicename, tagname, hc_num); + snprintf(mode_cmd_s, sizeof(mode_cmd_s), "~/%s/%s%d/mode", devicename, tagname, hc_num); JsonDocument doc; - doc["~"] = Mqtt::base(); - doc["uniq_id"] = uniq_id_s; - doc["obj_id"] = uniq_id_s; // same as uniq_id - doc["name"] = name_s; - doc["mode_stat_t"] = topic_t; - doc["mode_stat_tpl"] = mode_str_tpl; - doc["temp_cmd_t"] = temp_cmd_s; - doc["temp_stat_t"] = topic_t; - doc["temp_stat_tpl"] = (std::string) "{{" + seltemp_s + " if " + seltemp_cond + " else 0}}"; + doc["~"] = Mqtt::base(); + doc["uniq_id"] = uniq_id_s; + doc["default_entity_id"] = uniq_id_s; // same as uniq_id + doc["name"] = name_s; + doc["mode_stat_t"] = topic_t; + doc["mode_stat_tpl"] = mode_str_tpl; + doc["temp_cmd_t"] = temp_cmd_s; + doc["temp_stat_t"] = topic_t; + doc["temp_stat_tpl"] = (std::string) "{{" + seltemp_s + " if " + seltemp_cond + " else 0}}"; if (has_roomtemp) { doc["curr_temp_t"] = topic_t; @@ -1341,7 +1346,7 @@ bool Mqtt::publish_ha_climate_config(const int8_t tag, const bool has_roomtemp, modes.add("heat"); modes.add("off"); - add_ha_dev_section(doc.as(), "thermostat", nullptr, nullptr, nullptr, false); // add dev section + add_ha_dev_section(doc.as(), devicename, nullptr, nullptr, nullptr, false); // add dev section add_ha_avail_section(doc.as(), topic_t, false, seltemp_cond, has_roomtemp ? currtemp_cond : nullptr, hc_mode_cond); // add availability section return queue_ha(topic, doc.as()); // publish the config payload with retain flag diff --git a/src/devices/connect.cpp b/src/devices/connect.cpp index 79eef43a3..c72aa6954 100644 --- a/src/devices/connect.cpp +++ b/src/devices/connect.cpp @@ -34,11 +34,11 @@ Connect::Connect(uint8_t device_type, uint8_t device_id, uint8_t product_id, con DeviceValueUOM::DEGREES); // Roomthermostats for (uint8_t i = 0; i < 16; i++) { - register_telegram_type(0x0BDD + i, "Room", false, MAKE_PF_CB(process_roomThermostat)); - register_telegram_type(0x0B3D + i, "Roomname", true, MAKE_PF_CB(process_roomThermostatName)); - register_telegram_type(0x0BB5 + i, "Roomsettings", true, MAKE_PF_CB(process_roomThermostatMode)); - register_telegram_type(0x1230 + i, "Roomparams", true, MAKE_PF_CB(process_roomThermostatParam)); - register_telegram_type(0x1244 + i, "Roomdata", false, MAKE_PF_CB(process_roomThermostatData)); + register_telegram_type(0x0BDD + i, "Room", false, MAKE_PF_CB(process_roomThermostat)); // broadcasted + register_telegram_type(0x0B3D + i, "Roomname", false, MAKE_PF_CB(process_roomThermostatName)); // fetch for active circuits + register_telegram_type(0x0BB5 + i, "Roomsettings", false, MAKE_PF_CB(process_roomThermostatMode)); // fetch for active circuits + register_telegram_type(0x1230 + i, "Roomparams", false, MAKE_PF_CB(process_roomThermostatParam)); // fetch for active circuits + register_telegram_type(0x1244 + i, "Roomdata", false, MAKE_PF_CB(process_roomThermostatData)); // broadcasted } // register_telegram_type(0xDB65, "Roomschedule", true, MAKE_PF_CB(process_roomSchedule)); // 0x2040, broadcast 36 bytes: @@ -84,6 +84,9 @@ std::shared_ptr Connect::room_circuit(const uint8_t num, c room_circuits_.push_back(new_room); // register the device values register_device_values_room(new_room); + toggle_fetch(0x0B3D + num, true); // name + toggle_fetch(0x0BB5 + num, true); // mode + toggle_fetch(0x1230 + num, true); // unknown return new_room; // return back point to new HC object } @@ -115,16 +118,13 @@ void Connect::process_roomThermostatName(std::shared_ptr telegra if (rc == nullptr) { return; } - if (telegram->offset > 1 || telegram->message_length < 3) { - return; - } - std::string s; - for (uint8_t i = 2 - telegram->offset; (i < telegram->message_length) && (telegram->message_data[i] != 0); i += 2) { - s += (char)telegram->message_data[i]; - } - if (s.length()) { - has_update(rc->name_, s.c_str(), s.length() + 1); + + for (uint8_t i = telegram->offset; i < telegram->message_length + telegram->offset && i < 100; i++) { + if ((i > 1) && (i % 2) == 0) { + rc->name_[(i - 2) / 2] = telegram->message_data[i]; + } } + rc->name_[50] = ' \0'; // make sure name is terminated } // settings 0-mode, 1-tempautotemp, 3 - manualtemp, 6,7 - ? @@ -137,10 +137,20 @@ void Connect::process_roomThermostatMode(std::shared_ptr telegra has_update(telegram, rc->mode_, 0); } +// unknown telegrams, needs fetch void Connect::process_roomThermostatParam(std::shared_ptr telegram) { + auto rc = room_circuit(telegram->type_id - 0x1230); + if (rc == nullptr) { + return; + } } +// unknown broadcasted telegrams void Connect::process_roomThermostatData(std::shared_ptr telegram) { + auto rc = room_circuit(telegram->type_id - 0x1244); + if (rc == nullptr) { + return; + } } // Settings: @@ -175,17 +185,22 @@ bool Connect::set_seltemp(const char * value, const int8_t id) { bool Connect::set_name(const char * value, const int8_t id) { auto rc = room_circuit(id - DeviceValueTAG::TAG_HS1); - if (rc == nullptr || value == nullptr || strlen(value) > 12) { + if (rc == nullptr || value == nullptr || strlen(value) > 50) { return false; } - uint8_t data[strlen(value) * 2]; - uint8_t * d = data; - const char * c = value; - while (*c != 0) { - *d++ = 0; - *d++ = *c++; + uint8_t len = strlen(value) * 2 + 2; + uint8_t data[len]; + for (uint8_t i = 0; i < strlen(value) + 1; i++) { // include terminating '\0' + data[2 * i] = 0; + data[2 * i + 1] = value[i]; + } + uint8_t ofs = 0; + while (len > 0) { + uint8_t part = len > 25 ? 25 : len; + write_command(0x0B3D + rc->room(), ofs + 1, &data[ofs], part, 0); + ofs += part; + len -= part; } - write_command(0x0B3D + rc->room(), 1, data, sizeof(data), 0x0B3D + rc->room()); return true; } diff --git a/src/devices/connect.h b/src/devices/connect.h index 877a4b824..3c1b48713 100644 --- a/src/devices/connect.h +++ b/src/devices/connect.h @@ -37,7 +37,7 @@ class Connect : public EMSdevice { int8_t humidity_; uint8_t seltemp_; uint8_t mode_; - char name_[25]; + char name_[51]; int16_t dewtemp_; uint8_t room() { From 391a312f0c7eb63c392dd6bb6d3a4703c37d2760 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sat, 4 Oct 2025 09:53:41 +0200 Subject: [PATCH 10/19] add CR11 calinttemp --- src/devices/boiler.cpp | 3 ++- src/devices/thermostat.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 130133672..485c17206 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -2419,7 +2419,8 @@ bool Boiler::set_flow_temp(const char * value, const int8_t id) { // no verify if value is unchanged, put it to end of tx-queue, no priority // see https://github.com/emsesp/EMS-ESP32/issues/654, https://github.com/emsesp/EMS-ESP32/issues/954 if (v == selFlowTemp_) { - EMSESP::txservice_.add(Telegram::Operation::TX_WRITE, device_id(), EMS_TYPE_UBASetPoints, 0, (uint8_t *)&v, 1, 0, false); + uint8_t v1 = v; + EMSESP::txservice_.add(Telegram::Operation::TX_WRITE, device_id(), EMS_TYPE_UBASetPoints, 0, &v1, 1, 0, false); return true; } diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 00eb431d1..97f1925df 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2010,7 +2010,7 @@ bool Thermostat::set_calinttemp(const char * value, const int8_t id) { write_command(0xB0, 0, t, 0xB0); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 1, t, EMS_TYPE_RC30Settings); - } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100H) { + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100H || model() == EMSdevice::EMS_DEVICE_FLAG_CR11) { write_command(0x273, 0, t, 0x273); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { write_command(0x241, 7, t, 0x241); From 689a3a9a6950661719859d35f505db02b6a9393f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Sun, 5 Oct 2025 09:22:46 +0200 Subject: [PATCH 11/19] selflowtemp and forceheatingoff for ems+ telegrams (2E0 command) --- src/devices/boiler.cpp | 48 ++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 485c17206..66da87ef0 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -1208,8 +1208,13 @@ void Boiler::check_active() { static uint32_t lastSendHeatingOff = 0; if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && (uuid::get_uptime_sec() - lastSendHeatingOff) >= 60) { lastSendHeatingOff = uuid::get_uptime_sec(); - uint8_t data[] = {0, 0, 0, 0}; - write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); + if (has_telegram_id(0xE4)) { + uint8_t data[] = {1, 0, 0, 1, 1}; + write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0); + } else { + uint8_t data[] = {0, 0, 0, 0}; + write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); + } } // calculate energy for boiler 0x08 from stored modulation an time in units of 0.01 Wh @@ -1841,8 +1846,13 @@ void Boiler::process_UBASetPoints(std::shared_ptr telegram) { // overwrite other settings on receive? if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && telegram->dest == 0x08 && (setFlowTemp_ + setBurnPow_ + wwSetBurnPow_) != 0) { - uint8_t data[] = {0, 0, 0, 0}; - write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); + if (has_telegram_id(0xE4)) { + uint8_t data[] = {1, 0, 0, 1, 1}; + write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0); + } else { + uint8_t data[] = {0, 0, 0, 0}; + write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); + } } } @@ -2420,12 +2430,16 @@ bool Boiler::set_flow_temp(const char * value, const int8_t id) { // see https://github.com/emsesp/EMS-ESP32/issues/654, https://github.com/emsesp/EMS-ESP32/issues/954 if (v == selFlowTemp_) { uint8_t v1 = v; - EMSESP::txservice_.add(Telegram::Operation::TX_WRITE, device_id(), EMS_TYPE_UBASetPoints, 0, &v1, 1, 0, false); + if (has_telegram_id(0xE4)) { + EMSESP::txservice_.add(Telegram::Operation::TX_WRITE, device_id(), EMS_TYPE_UBASetPoints2, 1, &v1, 1, 0, false); + } else { + EMSESP::txservice_.add(Telegram::Operation::TX_WRITE, device_id(), EMS_TYPE_UBASetPoints, 0, &v1, 1, 0, false); + } return true; } if (has_telegram_id(0xE4)) { - write_command(EMS_TYPE_UBASetPoints, 0, v, 0xE4); + write_command(EMS_TYPE_UBASetPoints2, 1, v, 0xE4); } else { write_command(EMS_TYPE_UBASetPoints, 0, v, 0x18); } @@ -2439,8 +2453,11 @@ bool Boiler::set_burn_power(const char * value, const int8_t id) { return false; } - write_command(EMS_TYPE_UBASetPoints, 1, v, EMS_TYPE_UBASetPoints); - + if (has_telegram_id(0xE4)) { + write_command(EMS_TYPE_UBASetPoints2, 2, v); + } else { + write_command(EMS_TYPE_UBASetPoints, 1, v); + } return true; } @@ -3418,11 +3435,16 @@ bool Boiler::set_forceHeatingOff(const char * value, const int8_t id) { if (Helpers::value2bool(value, v)) { has_update(forceHeatingOff_, v); if (!v && Helpers::hasValue(heatingTemp_)) { - uint8_t data[] = {heatingTemp_, - (Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100), - (Helpers::hasValue(pumpModMax_) ? pumpModMax_ : (uint8_t)0), - 0}; - write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); + if (has_telegram_id(0xE4)) { + uint8_t data[] = {1, heatingTemp_, (Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100), 1, 1}; + write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0); + } else { + uint8_t data[] = {heatingTemp_, + (Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100), + (Helpers::hasValue(pumpModMax_) ? pumpModMax_ : (uint8_t)0), + 0}; + write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); + } } return true; } From e9e7162bcdce52a7f429337a54bf97b73bef7436 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 6 Oct 2025 08:59:16 +0200 Subject: [PATCH 12/19] typos, update --- platformio.ini | 2 +- src/core/emsdevice.cpp | 5 ++++- src/devices/connect.cpp | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/platformio.ini b/platformio.ini index c1ee00bf0..8303e8c9a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -108,7 +108,7 @@ build_type = release board_build.filesystem = littlefs lib_deps = bblanchon/ArduinoJson @ 7.4.2 - ESP32Async/AsyncTCP @ 3.4.8 + ESP32Async/AsyncTCP @ 3.4.9 ESP32Async/ESPAsyncWebServer @ 3.8.1 https://github.com/emsesp/EMS-ESP-Modules.git @ 1.0.8 diff --git a/src/core/emsdevice.cpp b/src/core/emsdevice.cpp index 08faa425b..fa42a91cb 100644 --- a/src/core/emsdevice.cpp +++ b/src/core/emsdevice.cpp @@ -258,6 +258,9 @@ uint8_t EMSdevice::device_name_2_device_type(const char * topic) { if (!strcmp(lowtopic, F_(pool))) { return DeviceType::POOL; } + if (!strcmp(lowtopic, F_(connect))) { + return DeviceType::CONNECT; + } // non EMS if (!strcmp(lowtopic, F_(custom))) { @@ -1901,7 +1904,7 @@ void EMSdevice::mqtt_ha_entity_config_create() { Mqtt::publish_ha_climate_config(dv.tag, true, false, dv.min, dv.max); } - #ifndef EMSESP_STANDALONE +#ifndef EMSESP_STANDALONE // always create minimum one config if (count && (heap_caps_get_free_size(MALLOC_CAP_8BIT) < 65 * 1024)) { // checks free Heap+PSRAM break; diff --git a/src/devices/connect.cpp b/src/devices/connect.cpp index c72aa6954..0579d0f70 100644 --- a/src/devices/connect.cpp +++ b/src/devices/connect.cpp @@ -124,7 +124,7 @@ void Connect::process_roomThermostatName(std::shared_ptr telegra rc->name_[(i - 2) / 2] = telegram->message_data[i]; } } - rc->name_[50] = ' \0'; // make sure name is terminated + rc->name_[50] = '\0'; // make sure name is terminated } // settings 0-mode, 1-tempautotemp, 3 - manualtemp, 6,7 - ? From b29f02e5dddba822881105092dfb2bf459a7e8ba Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 6 Oct 2025 18:22:12 +0200 Subject: [PATCH 13/19] remove scan deep --- src/core/console.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/console.cpp b/src/core/console.cpp index 08b400dd6..a7dd705b6 100644 --- a/src/core/console.cpp +++ b/src/core/console.cpp @@ -364,6 +364,10 @@ static void setup_commands(std::shared_ptr const & commands) { // EMS device commands // + commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, {F_(scan)}, [](Shell & shell, const std::vector & arguments) { + EMSESP::scan_devices(); + }); + /* removed scan deep commands->add_command(ShellContext::MAIN, CommandFlags::ADMIN, {F_(scan)}, {F_(deep_optional)}, [](Shell & shell, const std::vector & arguments) { if (arguments.empty()) { EMSESP::scan_devices(); @@ -379,7 +383,7 @@ static void setup_commands(std::shared_ptr const & commands) { } } }); - + */ // read [offset] [length] commands->add_command(ShellContext::MAIN, CommandFlags::USER, From 7c5351f15f69de04b54c2d79b40dd00f1235de91 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Mon, 6 Oct 2025 18:28:14 +0200 Subject: [PATCH 14/19] add Greenstar 2000 boiler #2645 --- CHANGELOG_LATEST.md | 9 +++++++-- src/core/device_library.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index 4b7a95412..e4b753d59 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -21,9 +21,12 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/). - set set climate action cooling/heating in HA [#2583](https://github.com/emsesp/EMS-ESP32/issues/2583) - Internal sensors of E32V2_2 - FW200 display options [#2610](https://github.com/emsesp/EMS-ESP32/discussions/2610) -- CR11 mode settings OFF/MANUAL depends on selTemp [#2437](https://github.com/emsesp/EMS-ESP32/issues/3437) +- CR11 mode settings OFF/MANUAL depends on selTemp [#2437](https://github.com/emsesp/EMS-ESP32/issues/2437) - Fuse settings for BBQKees boards -- Analogsensors for pulse output [#2624](https://github.com/emsesp/EMS-ESP32/discussions/2624) and frequency input [#2631](https://github.com/emsesp/EMS-ESP32/discussions/2631) +- Analogsensors for pulse output [#2624](https://github.com/emsesp/EMS-ESP32/discussions/2624) +- Analogsensors frequency input [#2631](https://github.com/emsesp/EMS-ESP32/discussions/2631) +- SRC plus thermostats [#2636](https://github.com/emsesp/EMS-ESP32/issues/2636) +- Greenstar 2000 [#2645](https://github.com/emsesp/EMS-ESP32/issues/2645) ## Fixed @@ -41,9 +44,11 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/). - fix missing long 10-second press of Button to perform a factory reset - fix wwMaxPower on Junkers ZBS14 [#2609](https://github.com/emsesp/EMS-ESP32/issues/2609) - ventilation bypass state from telegram 0x55C [#1197](https://github.com/emsesp/EMS-ESP32/issues/1197) +- set selflowtemp for ems+ boilers [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641) ## Changed - show console log with ISO date/time [#2533](https://github.com/emsesp/EMS-ESP32/discussions/2533) - remove ESP32 CPU temperature - updated core libraries like AsyncTCP, AsyncWebServer and Modbus +- remove command `scan deep` diff --git a/src/core/device_library.h b/src/core/device_library.h index 1d5fc2e77..917b9f6ae 100644 --- a/src/core/device_library.h +++ b/src/core/device_library.h @@ -25,6 +25,7 @@ // Boilers - 0x08 { 8, DeviceType::BOILER, "CS5800i, CS6800i, WLW176i, WLW186i", DeviceFlags::EMS_DEVICE_FLAG_CS6800}, +{ 11, DeviceType::BOILER, "Greenstar 2000", DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 12, DeviceType::BOILER, "C1200W", DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 16, DeviceType::BOILER, "CS5800iG", DeviceFlags::EMS_DEVICE_FLAG_NONE}, { 64, DeviceType::BOILER, "BK13/BK15, Smartline, GB1*2", DeviceFlags::EMS_DEVICE_FLAG_NONE}, From 4cfd9b699cfcf58c274c09bba6079d2fd8037f00 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Oct 2025 07:23:27 +0200 Subject: [PATCH 15/19] fix misuse of forceheatingoff --- src/devices/boiler.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index 66da87ef0..c61ddfe90 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -3433,6 +3433,9 @@ bool Boiler::set_wwAltOpPrio(const char * value, const int8_t id) { bool Boiler::set_forceHeatingOff(const char * value, const int8_t id) { bool v; if (Helpers::value2bool(value, v)) { + if (v == (forceHeatingOff_ > 0)) { // no change, ignore + return true; + } has_update(forceHeatingOff_, v); if (!v && Helpers::hasValue(heatingTemp_)) { if (has_telegram_id(0xE4)) { From 015110a72eeffec6633998310985cf5eb954c441 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Oct 2025 09:00:27 +0200 Subject: [PATCH 16/19] changelog, dev19 --- CHANGELOG_LATEST.md | 1 + src/emsesp_version.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md index e4b753d59..6ce0bf3fc 100644 --- a/CHANGELOG_LATEST.md +++ b/CHANGELOG_LATEST.md @@ -52,3 +52,4 @@ For more details go to [docs.emsesp.org](https://docs.emsesp.org/). - remove ESP32 CPU temperature - updated core libraries like AsyncTCP, AsyncWebServer and Modbus - remove command `scan deep` +- ignore repeated `forceheatingoff` commands [#2641](https://github.com/emsesp/EMS-ESP32/discussions/2641) diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 453758804..096657251 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.7.3-dev.18" +#define EMSESP_APP_VERSION "3.7.3-dev.19" From 8411ea6773af11e74130f60ff25afd80beba7404 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Oct 2025 09:35:53 +0200 Subject: [PATCH 17/19] fix forceheatingoff ems+ --- src/devices/boiler.cpp | 46 +++++++++++++++++++++++++----------------- src/devices/boiler.h | 1 + 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/src/devices/boiler.cpp b/src/devices/boiler.cpp index c61ddfe90..acef3e50e 100644 --- a/src/devices/boiler.cpp +++ b/src/devices/boiler.cpp @@ -66,6 +66,7 @@ Boiler::Boiler(uint8_t device_type, int8_t device_id, uint8_t product_id, const register_telegram_type(0xE9, "UBAMonitorWWPlus", false, MAKE_PF_CB(process_UBAMonitorWWPlus)); register_telegram_type(0xEA, "UBAParameterWWPlus", true, MAKE_PF_CB(process_UBAParameterWWPlus)); register_telegram_type(0x28, "WeatherComp", true, MAKE_PF_CB(process_WeatherComp)); + register_telegram_type(0x2E0, "UBASetPoints", false, MAKE_PF_CB(process_UBASetPoints2)); } if (isHeatPump()) { @@ -1837,22 +1838,31 @@ void Boiler::process_UBAOutdoorTemp(std::shared_ptr telegram) { // UBASetPoint 0x1A void Boiler::process_UBASetPoints(std::shared_ptr telegram) { - uint8_t setFlowTemp_ = 0; - uint8_t setBurnPow_ = 0; - uint8_t wwSetBurnPow_ = 0; + uint8_t setFlowTemp_ = 0; + uint8_t setBurnPow_ = 0; + uint8_t setPumpMod_ = 0; telegram->read_value(setFlowTemp_, 0); telegram->read_value(setBurnPow_, 1); - telegram->read_value(wwSetBurnPow_, 2); + telegram->read_value(setPumpMod_, 2); - // overwrite other settings on receive? - if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && telegram->dest == 0x08 && (setFlowTemp_ + setBurnPow_ + wwSetBurnPow_) != 0) { - if (has_telegram_id(0xE4)) { - uint8_t data[] = {1, 0, 0, 1, 1}; - write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0); - } else { - uint8_t data[] = {0, 0, 0, 0}; - write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); - } + // forceHeatingOff overwrite to zero + if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && telegram->dest == 0x08 && (setFlowTemp_ + setBurnPow_ + setPumpMod_) != 0) { + uint8_t data[] = {0, 0, 0, 0}; + write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); + } +} + +// UBASetPoints ems+ 0x2E0 +void Boiler::process_UBASetPoints2(std::shared_ptr telegram) { + uint8_t setFlowTemp_ = 0; + uint8_t setBurnPow_ = 0; + telegram->read_value(setFlowTemp_, 0); + telegram->read_value(setBurnPow_, 1); + + // forceHeatingOff overwrite to zero + if (forceHeatingOff_ == EMS_VALUE_BOOL_ON && telegram->dest == 0x08 && (setFlowTemp_ + setBurnPow_) != 0) { + uint8_t data[] = {1, 0, 0, 1, 1}; + write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0); } } @@ -3433,22 +3443,20 @@ bool Boiler::set_wwAltOpPrio(const char * value, const int8_t id) { bool Boiler::set_forceHeatingOff(const char * value, const int8_t id) { bool v; if (Helpers::value2bool(value, v)) { - if (v == (forceHeatingOff_ > 0)) { // no change, ignore - return true; - } - has_update(forceHeatingOff_, v); - if (!v && Helpers::hasValue(heatingTemp_)) { + // set only on change on->off + if (!v && forceHeatingOff_ && Helpers::hasValue(heatingTemp_)) { if (has_telegram_id(0xE4)) { uint8_t data[] = {1, heatingTemp_, (Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100), 1, 1}; write_command(EMS_TYPE_UBASetPoints2, 0, data, sizeof(data), 0); } else { uint8_t data[] = {heatingTemp_, (Helpers::hasValue(burnMaxPower_) ? burnMaxPower_ : (uint8_t)100), - (Helpers::hasValue(pumpModMax_) ? pumpModMax_ : (uint8_t)0), + (Helpers::hasValue(pumpModMax_) ? pumpModMax_ : (uint8_t)100), 0}; write_command(EMS_TYPE_UBASetPoints, 0, data, sizeof(data), 0); } } + has_update(forceHeatingOff_, v); return true; } return false; diff --git a/src/devices/boiler.h b/src/devices/boiler.h index 3ff03cf76..aeee7b4e4 100644 --- a/src/devices/boiler.h +++ b/src/devices/boiler.h @@ -354,6 +354,7 @@ class Boiler : public EMSdevice { void process_UBAParameterWWPlus(std::shared_ptr telegram); void process_UBAOutdoorTemp(std::shared_ptr telegram); void process_UBASetPoints(std::shared_ptr telegram); + void process_UBASetPoints2(std::shared_ptr telegram); void process_UBAFlags(std::shared_ptr telegram); void process_MC110Status(std::shared_ptr telegram); void process_UBAMaintenanceStatus(std::shared_ptr telegram); From eb14e89c35d1774e46596972a88d808e16f6274e Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Oct 2025 10:36:48 +0200 Subject: [PATCH 18/19] fix writing calIntTemp for remote thermostats #2646 --- src/devices/thermostat.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index 97f1925df..c4e5ba166 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -2006,12 +2006,12 @@ bool Thermostat::set_calinttemp(const char * value, const int8_t id) { auto t = (int8_t)(ct * 10); LOG_DEBUG("Calibrating internal temperature to %d.%d C", t / 10, t < 0 ? -t % 10 : t % 10); - if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { + if (device_id() >= 0x38 && device_id() <= 0x3F) { // remote thermostats RC100H, CR10, ... + write_command(0x273 + device_id() - 0x38, 0, t, 0x273 + device_id() - 0x38); + } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC10) { write_command(0xB0, 0, t, 0xB0); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC30) { write_command(EMS_TYPE_RC30Settings, 1, t, EMS_TYPE_RC30Settings); - } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100H || model() == EMSdevice::EMS_DEVICE_FLAG_CR11) { - write_command(0x273, 0, t, 0x273); } else if (model() == EMSdevice::EMS_DEVICE_FLAG_RC100) { write_command(0x241, 7, t, 0x241); } else if (isRC300()) { From aeee318cca445461be9691fd13161a37429ad3a5 Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 7 Oct 2025 12:38:19 +0200 Subject: [PATCH 19/19] skip frequ-measurement in standalone build --- src/core/analogsensor.cpp | 6 ++++++ src/core/analogsensor.h | 2 ++ src/core/shuntingYard.cpp | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index 735681aad..2e3ff3dfe 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -23,6 +23,7 @@ namespace emsesp { uuid::log::Logger AnalogSensor::logger_{F_(analogsensor), uuid::log::Facility::DAEMON}; +#ifndef EMSESP_STANDALONE portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; unsigned long AnalogSensor::edge[] = {0, 0, 0}; unsigned long AnalogSensor::edgecnt[] = {0, 0, 0}; @@ -45,6 +46,7 @@ void IRAM_ATTR AnalogSensor::freqIrq2() { edge[2] = micros(); portEXIT_CRITICAL_ISR(&mux); } +#endif void AnalogSensor::start(const bool factory_settings) { // if (factory_settings && EMSESP::nvs_.getString("boot").equals("E32V2_2") && EMSESP::nvs_.getString("hwrevision").equals("3.0")) { @@ -228,6 +230,7 @@ void AnalogSensor::reload(bool get_nvs) { sensor.set_offset(0); sensor.set_value(0); publish_sensor(sensor); +#ifndef EMSESP_STANDALONE } else if (sensor.type() >= AnalogType::FREQ_0 && sensor.type() <= AnalogType::FREQ_2) { LOG_DEBUG("Frequency on GPIO %02d", sensor.gpio()); pinMode(sensor.gpio(), INPUT_PULLUP); @@ -238,6 +241,7 @@ void AnalogSensor::reload(bool get_nvs) { attachInterrupt(sensor.gpio(), index == 0 ? freqIrq0 : index == 1 ? freqIrq1 : freqIrq2, FALLING); lastedge[index] = edge[index] = micros(); edgecnt[index] = 0; +#endif } else if (sensor.type() == AnalogType::DIGITAL_IN) { LOG_DEBUG("Digital Read on GPIO %02d", sensor.gpio()); pinMode(sensor.gpio(), INPUT_PULLUP); @@ -369,6 +373,7 @@ void AnalogSensor::measure() { changed_ = true; publish_sensor(sensor); } +#ifndef EMSESP_STANDALONE } else if (sensor.type() >= AnalogType::FREQ_0 && sensor.type() <= AnalogType::FREQ_2) { auto index = sensor.type() - AnalogType::FREQ_0; auto oldval = sensor.value(); @@ -386,6 +391,7 @@ void AnalogSensor::measure() { changed_ = true; publish_sensor(sensor); } +#endif } } } diff --git a/src/core/analogsensor.h b/src/core/analogsensor.h index 18b400a1f..7125a2b3b 100644 --- a/src/core/analogsensor.h +++ b/src/core/analogsensor.h @@ -195,12 +195,14 @@ class AnalogSensor { uint32_t sensorfails_ = 0; uint32_t sensorreads_ = 0; +#ifndef EMSESP_STANDALONE static void IRAM_ATTR freqIrq0(); static void IRAM_ATTR freqIrq1(); static void IRAM_ATTR freqIrq2(); static unsigned long edge[3]; static unsigned long edgecnt[3]; unsigned long lastedge[3] = {0, 0, 0}; +#endif }; } // namespace emsesp diff --git a/src/core/shuntingYard.cpp b/src/core/shuntingYard.cpp index 4ee8c30bf..5cb262f50 100644 --- a/src/core/shuntingYard.cpp +++ b/src/core/shuntingYard.cpp @@ -518,7 +518,7 @@ std::string calculate(const std::string & expr) { #ifndef EMSESP_STANDALONE stack.push_back(to_string(rhd * esp_random() / UINT32_MAX)); #else - stack.push_back(to_string(rhd * random())); + stack.push_back(to_string(rhd * rand() / RAND_MAX)); #endif break; }