From 9a225569fd39d8b9eeb61a381934a4f3f03f98ff Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 15:06:32 +0200 Subject: [PATCH 01/19] formatting --- src/core/analogsensor.h | 8 +++--- src/core/emsdevicevalue.h | 56 ++++++++++++++++++------------------ src/core/network.cpp | 2 +- src/core/system.cpp | 12 ++++---- src/devices/thermostat.h | 2 +- src/web/WebStatusService.cpp | 4 +-- 6 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/core/analogsensor.h b/src/core/analogsensor.h index 6492e2c8a..592452f96 100644 --- a/src/core/analogsensor.h +++ b/src/core/analogsensor.h @@ -174,10 +174,10 @@ class AnalogSensor { return sensors_.size(); } - bool update(uint8_t gpio, const char * name, double offset, double factor, uint8_t uom, int8_t type, bool deleted, bool is_system); - bool get_value_info(JsonObject output, const char * cmd, const int8_t id = -1); - void store_counters(); - std::string get_metrics_prometheus(); + bool update(uint8_t gpio, const char * name, double offset, double factor, uint8_t uom, int8_t type, bool deleted, bool is_system); + bool get_value_info(JsonObject output, const char * cmd, const int8_t id = -1); + void store_counters(); + std::string get_metrics_prometheus(); static const std::vector & exclude_types() { return exclude_types_; } diff --git a/src/core/emsdevicevalue.h b/src/core/emsdevicevalue.h index b7b1a016c..0eeaf4f62 100644 --- a/src/core/emsdevicevalue.h +++ b/src/core/emsdevicevalue.h @@ -49,34 +49,34 @@ class DeviceValue { // also used with HA as uom // shows also the HA device class being used enum DeviceValueUOM : uint8_t { - NONE = 0, // 0 - DEGREES, // 1 - °C - temperature - DEGREES_R, // 2 - °C (relative temperature) - temperature - PERCENT, // 3 - % - power factor - LMIN, // 4 - l/min - volume flow rate - KWH, // 5 - kWh - energy - WH, // 6 - Wh - energy - HOURS, // 7 - h - duration - MINUTES, // 8 - m - duration - UA, // 9 - µA - current - BAR, // 10 - bar - pressure - KW, // 11 - kW - power - W, // 12 - W - power - KB, // 13 - kB - data size - SECONDS, // 14 - s - duration - DBM, // 15 - dBm - signal strength - FAHRENHEIT, // 16 - °F - temperature - MV, // 17 - mV - voltage - SQM, // 18 - m² - area - M3, // 19 - m³ - volume - L, // 20 - L - volume - KMIN, // 21 - K*min - K, // 22 - K - temperature - VOLTS, // 23 - V - voltage - MBAR, // 24 - mbar - atmospheric pressure - LH, // 25 - l/h - volume flow rate - CTKWH, // 26 - ct/kWh - monetary - HERTZ, // 27 - Hz - frequency + NONE = 0, // 0 + DEGREES, // 1 - °C - temperature + DEGREES_R, // 2 - °C (relative temperature) - temperature + PERCENT, // 3 - % - power factor + LMIN, // 4 - l/min - volume flow rate + KWH, // 5 - kWh - energy + WH, // 6 - Wh - energy + HOURS, // 7 - h - duration + MINUTES, // 8 - m - duration + UA, // 9 - µA - current + BAR, // 10 - bar - pressure + KW, // 11 - kW - power + W, // 12 - W - power + KB, // 13 - kB - data size + SECONDS, // 14 - s - duration + DBM, // 15 - dBm - signal strength + FAHRENHEIT, // 16 - °F - temperature + MV, // 17 - mV - voltage + SQM, // 18 - m² - area + M3, // 19 - m³ - volume + L, // 20 - L - volume + KMIN, // 21 - K*min + K, // 22 - K - temperature + VOLTS, // 23 - V - voltage + MBAR, // 24 - mbar - atmospheric pressure + LH, // 25 - l/h - volume flow rate + CTKWH, // 26 - ct/kWh - monetary + HERTZ, // 27 - Hz - frequency CONNECTIVITY, // 28 - used in HA - connectivity TIMESTAMP, // 29 - used in HA - timestamp }; diff --git a/src/core/network.cpp b/src/core/network.cpp index 826d96ac1..90ae94d01 100644 --- a/src/core/network.cpp +++ b/src/core/network.cpp @@ -82,7 +82,7 @@ void Network::begin() { WiFi.persistent(false); WiFi.setAutoReconnect(false); WiFi.mode(WIFI_STA); - WiFi.disconnect(true, true); // wipe old settings in NVS + WiFi.disconnect(true, true); // wipe old settings in NVS WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); WiFi.setHostname(hostname_.c_str()); // updates shared default_hostname buffer WiFi.enableSTA(true); // creates the STA netif diff --git a/src/core/system.cpp b/src/core/system.cpp index b49b8b8fd..c26628fdf 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1532,8 +1532,8 @@ bool System::check_upgrade() { return StateUpdateResult::UNCHANGED; }); // Scheduler name is now mandatory, update FS - uint8_t i = 0; - bool schedule_changed = false; + uint8_t i = 0; + bool schedule_changed = false; EMSESP::webSchedulerService.update([&](WebScheduler & scheduler) { for (ScheduleItem & scheduleItem : scheduler.scheduleItems) { if (scheduleItem.name[0] == '\0') { @@ -2970,7 +2970,7 @@ bool System::uploadFirmwareURL(const char * url) { String scheme = saved_url.substring(0, 8); scheme.toLowerCase(); - const bool is_https = scheme.startsWith("https://"); + const bool is_https = scheme.startsWith("https://"); const int scheme_len = is_https ? 8 : 7; // "https://" vs "http://" WiFiClient basic_client; @@ -2992,11 +2992,11 @@ bool System::uploadFirmwareURL(const char * url) { ssl_client.setBufferSizes(16384, 1024); ssl_client.setSessionTimeout(120); } - basic_client.setTimeout(15000); // socket-level read timeout - ssl_client.setTimeout(15000); // Stream::readBytes timeout used by Update + basic_client.setTimeout(15000); // socket-level read timeout + ssl_client.setTimeout(15000); // Stream::readBytes timeout used by Update ssl_client.setClient(&basic_client, is_https); // enableSSL = false for plain HTTP - const uint16_t port = is_https ? 443 : 80; + const uint16_t port = is_https ? 443 : 80; String url_remain = saved_url.substring(scheme_len); int redirect_count = 0; diff --git a/src/devices/thermostat.h b/src/devices/thermostat.h index 0ce01c51a..736af1eb1 100644 --- a/src/devices/thermostat.h +++ b/src/devices/thermostat.h @@ -304,7 +304,7 @@ class Thermostat : public EMSdevice { uint8_t instantstart; uint8_t coolstart; uint8_t coolondelay; - uint8_t cooloffdelay; + uint8_t cooloffdelay; // HybridHP uint8_t hybridStrategy_; // co2 = 1, cost = 2, temperature = 3, mix = 4 diff --git a/src/web/WebStatusService.cpp b/src/web/WebStatusService.cpp index 7966d04fc..81461379e 100644 --- a/src/web/WebStatusService.cpp +++ b/src/web/WebStatusService.cpp @@ -417,8 +417,8 @@ bool WebStatusService::refresh_versions_cache() { #else // detect scheme from EMSESP_VERSIONS_URL (case-insensitive). One code path for HTTP and HTTPS, // using ESP_SSLClient as a plain TCP passthrough when SSL is disabled. - String url = EMSESP_VERSIONS_URL; - String lower = url; + String url = EMSESP_VERSIONS_URL; + String lower = url; lower.toLowerCase(); const bool is_https = lower.startsWith("https://"); if (!is_https && !lower.startsWith("http://")) { From 41ff124d108afcf84d71f8d805fd78fd07d72ef5 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 15:06:43 +0200 Subject: [PATCH 02/19] package update --- interface/package.json | 20 +- interface/pnpm-lock.yaml | 662 +++++++++++++++++++-------------------- mock-api/package.json | 2 +- 3 files changed, 342 insertions(+), 342 deletions(-) diff --git a/interface/package.json b/interface/package.json index f4609e506..9f9a491a2 100644 --- a/interface/package.json +++ b/interface/package.json @@ -35,10 +35,10 @@ "jwt-decode": "^4.0.0", "mime-types": "^3.0.2", "preact": "^10.29.2", - "react": "^19.2.6", - "react-dom": "^19.2.6", + "react": "^19.2.7", + "react-dom": "^19.2.7", "react-icons": "^5.6.0", - "react-router": "^7.16.0", + "react-router": "^7.17.0", "react-toastify": "^11.1.0", "typesafe-i18n": "^5.27.1", "typescript": "^6.0.3" @@ -47,18 +47,18 @@ "@eslint/js": "^10.0.1", "@preact/preset-vite": "^2.10.5", "@trivago/prettier-plugin-sort-imports": "^6.0.2", - "@types/node": "^25.9.1", - "@types/react": "^19.2.15", + "@types/node": "^25.9.2", + "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", - "concurrently": "^10.0.0", - "eslint": "^10.4.0", + "concurrently": "^10.0.3", + "eslint": "^10.4.1", "eslint-config-prettier": "^10.1.8", "prettier": "^3.8.3", "rollup-plugin-visualizer": "^7.0.1", "terser": "^5.48.0", - "typescript-eslint": "^8.60.0", - "vite": "^8.0.14", + "typescript-eslint": "^8.60.1", + "vite": "^8.0.16", "vite-plugin-imagemin": "^0.6.1" }, - "packageManager": "pnpm@10.34.1+sha512.b58fbde6dca66a929538021581f648b4570b6ca19b18e7cbd7f2c07a7b24454155388dacdf08f2af3678e88a6d1fe04f9d609df24bf51735a060ea041b374ab7" + "packageManager": "pnpm@11.5.2+sha512.71c631e382066efc25625d5cf029075de07b61b37f6e27350fbd84b1bda5864c8c1967adc280776b45c30a715c0359a3be08fef42d5bb09e2b99029979692916" } diff --git a/interface/pnpm-lock.yaml b/interface/pnpm-lock.yaml index 80b5b8b96..f2d996746 100644 --- a/interface/pnpm-lock.yaml +++ b/interface/pnpm-lock.yaml @@ -13,19 +13,19 @@ importers: version: 2.3.1(alova@3.5.1) '@emotion/react': specifier: ^11.14.0 - version: 11.14.0(@types/react@19.2.15)(react@19.2.6) + version: 11.14.0(@types/react@19.2.17)(react@19.2.7) '@emotion/styled': specifier: ^11.14.1 - version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6) + version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7) '@mui/icons-material': specifier: ^9.0.1 - version: 9.0.1(@mui/material@9.0.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.15)(react@19.2.6) + version: 9.0.1(@mui/material@9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react@19.2.17)(react@19.2.7) '@mui/material': specifier: ^9.0.1 - version: 9.0.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@table-library/react-table-library': specifier: 4.1.15 - version: 4.1.15(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 4.1.15(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7) alova: specifier: ^3.5.1 version: 3.5.1 @@ -45,20 +45,20 @@ importers: specifier: ^10.29.2 version: 10.29.2 react: - specifier: ^19.2.6 - version: 19.2.6 + specifier: ^19.2.7 + version: 19.2.7 react-dom: - specifier: ^19.2.6 - version: 19.2.6(react@19.2.6) + specifier: ^19.2.7 + version: 19.2.7(react@19.2.7) react-icons: specifier: ^5.6.0 - version: 5.6.0(react@19.2.6) + version: 5.6.0(react@19.2.7) react-router: - specifier: ^7.16.0 - version: 7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + specifier: ^7.17.0 + version: 7.17.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) react-toastify: specifier: ^11.1.0 - version: 11.1.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 11.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7) typesafe-i18n: specifier: ^5.27.1 version: 5.27.1(typescript@6.0.3) @@ -68,49 +68,49 @@ importers: devDependencies: '@eslint/js': specifier: ^10.0.1 - version: 10.0.1(eslint@10.4.0) + version: 10.0.1(eslint@10.4.1) '@preact/preset-vite': specifier: ^2.10.5 - version: 2.10.5(@babel/core@7.29.7)(preact@10.29.2)(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0)) + version: 2.10.5(@babel/core@7.29.7)(preact@10.29.2)(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0)) '@trivago/prettier-plugin-sort-imports': specifier: ^6.0.2 version: 6.0.2(prettier@3.8.3) '@types/node': - specifier: ^25.9.1 - version: 25.9.1 + specifier: ^25.9.2 + version: 25.9.2 '@types/react': - specifier: ^19.2.15 - version: 19.2.15 + specifier: ^19.2.17 + version: 19.2.17 '@types/react-dom': specifier: ^19.2.3 - version: 19.2.3(@types/react@19.2.15) + version: 19.2.3(@types/react@19.2.17) concurrently: - specifier: ^10.0.0 - version: 10.0.0 + specifier: ^10.0.3 + version: 10.0.3 eslint: - specifier: ^10.4.0 - version: 10.4.0 + specifier: ^10.4.1 + version: 10.4.1 eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@10.4.0) + version: 10.1.8(eslint@10.4.1) prettier: specifier: ^3.8.3 version: 3.8.3 rollup-plugin-visualizer: specifier: ^7.0.1 - version: 7.0.1(rolldown@1.0.2) + version: 7.0.1(rolldown@1.0.3) terser: specifier: ^5.48.0 version: 5.48.0 typescript-eslint: - specifier: ^8.60.0 - version: 8.60.0(eslint@10.4.0)(typescript@6.0.3) + specifier: ^8.60.1 + version: 8.60.1(eslint@10.4.1)(typescript@6.0.3) vite: - specifier: ^8.0.14 - version: 8.0.14(@types/node@25.9.1)(terser@5.48.0) + specifier: ^8.0.16 + version: 8.0.16(@types/node@25.9.2)(terser@5.48.0) vite-plugin-imagemin: specifier: ^0.6.1 - version: 0.6.1(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0)) + version: 0.6.1(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0)) packages: @@ -323,8 +323,8 @@ packages: resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.7.1': - resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@humanfs/core@0.19.2': @@ -475,8 +475,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@oxc-project/types@0.132.0': - resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==} + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} @@ -504,97 +504,97 @@ packages: preact: ^10.4.0 || ^11.0.0-0 vite: '>=2.0.0' - '@rolldown/binding-android-arm64@1.0.2': - resolution: {integrity: sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==} + '@rolldown/binding-android-arm64@1.0.3': + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.2': - resolution: {integrity: sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==} + '@rolldown/binding-darwin-arm64@1.0.3': + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.2': - resolution: {integrity: sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==} + '@rolldown/binding-darwin-x64@1.0.3': + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.2': - resolution: {integrity: sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==} + '@rolldown/binding-freebsd-x64@1.0.3': + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.2': - resolution: {integrity: sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.2': - resolution: {integrity: sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==} + '@rolldown/binding-linux-arm64-gnu@1.0.3': + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.2': - resolution: {integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==} + '@rolldown/binding-linux-arm64-musl@1.0.3': + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.2': - resolution: {integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==} + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.2': - resolution: {integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==} + '@rolldown/binding-linux-s390x-gnu@1.0.3': + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.2': - resolution: {integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==} + '@rolldown/binding-linux-x64-gnu@1.0.3': + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.2': - resolution: {integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==} + '@rolldown/binding-linux-x64-musl@1.0.3': + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.2': - resolution: {integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==} + '@rolldown/binding-openharmony-arm64@1.0.3': + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.2': - resolution: {integrity: sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==} + '@rolldown/binding-wasm32-wasi@1.0.3': + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.2': - resolution: {integrity: sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==} + '@rolldown/binding-win32-arm64-msvc@1.0.3': + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.2': - resolution: {integrity: sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==} + '@rolldown/binding-win32-x64-msvc@1.0.3': + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -688,8 +688,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@25.9.1': - resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} + '@types/node@25.9.2': + resolution: {integrity: sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -707,8 +707,8 @@ packages: peerDependencies: '@types/react': '*' - '@types/react@19.2.15': - resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} + '@types/react@19.2.17': + resolution: {integrity: sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==} '@types/responselike@1.0.3': resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} @@ -716,63 +716,63 @@ packages: '@types/svgo@2.6.4': resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} - '@typescript-eslint/eslint-plugin@8.60.0': - resolution: {integrity: sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==} + '@typescript-eslint/eslint-plugin@8.60.1': + resolution: {integrity: sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.60.0 + '@typescript-eslint/parser': ^8.60.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.60.0': - resolution: {integrity: sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==} + '@typescript-eslint/parser@8.60.1': + resolution: {integrity: sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.60.0': - resolution: {integrity: sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==} + '@typescript-eslint/project-service@8.60.1': + resolution: {integrity: sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.60.0': - resolution: {integrity: sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==} + '@typescript-eslint/scope-manager@8.60.1': + resolution: {integrity: sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.60.0': - resolution: {integrity: sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==} + '@typescript-eslint/tsconfig-utils@8.60.1': + resolution: {integrity: sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.60.0': - resolution: {integrity: sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==} + '@typescript-eslint/type-utils@8.60.1': + resolution: {integrity: sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.60.0': - resolution: {integrity: sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==} + '@typescript-eslint/types@8.60.1': + resolution: {integrity: sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.60.0': - resolution: {integrity: sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==} + '@typescript-eslint/typescript-estree@8.60.1': + resolution: {integrity: sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.60.0': - resolution: {integrity: sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==} + '@typescript-eslint/utils@8.60.1': + resolution: {integrity: sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.60.0': - resolution: {integrity: sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==} + '@typescript-eslint/visitor-keys@8.60.1': + resolution: {integrity: sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} acorn-jsx@5.3.2: @@ -853,8 +853,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.32: - resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + baseline-browser-mapping@2.10.34: + resolution: {integrity: sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw==} engines: {node: '>=6.0.0'} hasBin: true @@ -952,8 +952,8 @@ packages: resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} engines: {node: '>=0.10.0'} - caniuse-lite@1.0.30001793: - resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + caniuse-lite@1.0.30001797: + resolution: {integrity: sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==} caw@2.0.1: resolution: {integrity: sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==} @@ -1003,8 +1003,8 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - concurrently@10.0.0: - resolution: {integrity: sha512-DRrk10z3sVPpguNe8od2cGNqZGqbT15rwAnxD4dG3b78mdNNb/gJyr8T834Oj518WcBmTktrt4FhdwZn09ZWSg==} + concurrently@10.0.3: + resolution: {integrity: sha512-hc3LH4UaKWd/bbyDK/IGVa4RB6PtQ3CUYwtrkzqHn+wIG3Hr5fhpRlk0L/gCa8ZE1L/Ufj50Zho69cI5w8SQBA==} engines: {node: '>=22'} hasBin: true @@ -1185,8 +1185,8 @@ packages: duplexer3@0.1.5: resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} - electron-to-chromium@1.5.364: - resolution: {integrity: sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==} + electron-to-chromium@1.5.368: + resolution: {integrity: sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -1371,8 +1371,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.4.0: - resolution: {integrity: sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==} + eslint@10.4.1: + resolution: {integrity: sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -2160,8 +2160,8 @@ packages: node-html-parser@6.1.13: resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==} - node-releases@2.0.46: - resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + node-releases@2.0.47: + resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} engines: {node: '>=18'} normalize-package-data@2.5.0: @@ -2422,10 +2422,10 @@ packages: rate-limiter-flexible@5.0.5: resolution: {integrity: sha512-+/dSQfo+3FYwYygUs/V2BBdwGa9nFtakDwKt4l0bnvNB53TNT++QSFewwHX9qXrZJuMe9j+TUaU21lm5ARgqdQ==} - react-dom@19.2.6: - resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + react-dom@19.2.7: + resolution: {integrity: sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==} peerDependencies: - react: ^19.2.6 + react: ^19.2.7 react-icons@5.6.0: resolution: {integrity: sha512-RH93p5ki6LfOiIt0UtDyNg/cee+HLVR6cHHtW3wALfo+eOHTp8RnU2kRkI6E+H19zMIs03DyxUG/GfZMOGvmiA==} @@ -2435,11 +2435,11 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - react-is@19.2.6: - resolution: {integrity: sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==} + react-is@19.2.7: + resolution: {integrity: sha512-kZFnouyVv7eP/Phmrlo9FK+zcAdriZJvzxXHF1Sl1P377WSGe2G/JxVolhTrB/jeV47lKImhNUsijjHAAbcl/A==} - react-router@7.16.0: - resolution: {integrity: sha512-wArC8lVyJb3+jM9OpDyW6hLCizACWkvQR/sSGqSs+o5uEXEtGlqdZ4v8hENR3Jad6i+LRkK93q/+bQAcvl6V1A==} + react-router@7.17.0: + resolution: {integrity: sha512-FDELK7rTMlCHO5+reyXsPlmfr7N1F91lPHsWYfMEGQm/KQ+F4JFM8jGoeQDmDvdTs93Fw9aSilH+uKRb4/jXvQ==} engines: {node: '>=20.0.0'} peerDependencies: react: '>=18' @@ -2473,8 +2473,8 @@ packages: react: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react@19.2.6: - resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} + react@19.2.7: + resolution: {integrity: sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==} engines: {node: '>=0.10.0'} read-pkg-up@1.0.1: @@ -2521,8 +2521,8 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rolldown@1.0.2: - resolution: {integrity: sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==} + rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -2582,8 +2582,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + semver@7.8.2: + resolution: {integrity: sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==} engines: {node: '>=10'} hasBin: true @@ -2773,8 +2773,8 @@ packages: resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} engines: {node: '>=0.10.0'} - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} to-buffer@1.2.2: @@ -2827,8 +2827,8 @@ packages: peerDependencies: typescript: '>=3.5.1' - typescript-eslint@8.60.0: - resolution: {integrity: sha512-9f65qWLZdAW9m1JaxBDUHcqRUfL8bkxxXL7XxEfI+F09q56PkBvIfCjLF3yInsDM/BBmwkqmCQdCZe/RYlIWEw==} + typescript-eslint@8.60.1: + resolution: {integrity: sha512-6m5hkkRAp8lKvhVpcprAIn5KkehQEh+47oHH2VGnExEh7dhNxXlg6GPAOIu6TxbVQxhebrJDvjl3020ooiWCMA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -2891,8 +2891,8 @@ packages: peerDependencies: vite: 5.x || 6.x || 7.x || 8.x - vite@8.0.14: - resolution: {integrity: sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==} + vite@8.0.16: + resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -2934,8 +2934,8 @@ packages: yaml: optional: true - which-typed-array@1.1.21: - resolution: {integrity: sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==} + which-typed-array@1.1.22: + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} engines: {node: '>= 0.4'} which@1.3.1: @@ -3186,19 +3186,19 @@ snapshots: '@emotion/memoize@0.9.0': {} - '@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6)': + '@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 '@emotion/babel-plugin': 11.13.5 '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.6) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.7) '@emotion/utils': 1.4.2 '@emotion/weak-memoize': 0.4.0 hoist-non-react-statics: 3.3.2 - react: 19.2.6 + react: 19.2.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 transitivePeerDependencies: - supports-color @@ -3212,26 +3212,26 @@ snapshots: '@emotion/sheet@1.4.0': {} - '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6)': + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 '@emotion/babel-plugin': 11.13.5 '@emotion/is-prop-valid': 1.4.0 - '@emotion/react': 11.14.0(@types/react@19.2.15)(react@19.2.6) + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) '@emotion/serialize': 1.3.3 - '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.6) + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.7) '@emotion/utils': 1.4.2 - react: 19.2.6 + react: 19.2.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 transitivePeerDependencies: - supports-color '@emotion/unitless@0.10.0': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.6)': + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.7)': dependencies: - react: 19.2.6 + react: 19.2.7 '@emotion/utils@1.4.2': {} @@ -3240,9 +3240,9 @@ snapshots: '@esbuild/linux-loong64@0.14.54': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.4.0)': + '@eslint-community/eslint-utils@4.9.1(eslint@10.4.1)': dependencies: - eslint: 10.4.0 + eslint: 10.4.1 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} @@ -3263,13 +3263,13 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/js@10.0.1(eslint@10.4.0)': + '@eslint/js@10.0.1(eslint@10.4.1)': optionalDependencies: - eslint: 10.4.0 + eslint: 10.4.1 '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.7.1': + '@eslint/plugin-kit@0.7.2': dependencies: '@eslint/core': 1.2.1 levn: 0.4.1 @@ -3316,45 +3316,45 @@ snapshots: '@mui/core-downloads-tracker@9.0.1': {} - '@mui/icons-material@9.0.1(@mui/material@9.0.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.15)(react@19.2.6)': + '@mui/icons-material@9.0.1(@mui/material@9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/react@19.2.17)(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 - '@mui/material': 9.0.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react: 19.2.6 + '@mui/material': 9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react: 19.2.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - '@mui/material@9.0.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@mui/material@9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 '@mui/core-downloads-tracker': 9.0.1 - '@mui/system': 9.0.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6) - '@mui/types': 9.0.0(@types/react@19.2.15) - '@mui/utils': 9.0.1(@types/react@19.2.15)(react@19.2.6) + '@mui/system': 9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7) + '@mui/types': 9.0.0(@types/react@19.2.17) + '@mui/utils': 9.0.1(@types/react@19.2.17)(react@19.2.7) '@popperjs/core': 2.11.8 - '@types/react-transition-group': 4.4.12(@types/react@19.2.15) + '@types/react-transition-group': 4.4.12(@types/react@19.2.17) clsx: 2.1.1 csstype: 3.2.3 prop-types: 15.8.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-is: 19.2.6 - react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-is: 19.2.7 + react-transition-group: 4.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7) optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.2.15)(react@19.2.6) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6) - '@types/react': 19.2.15 + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7) + '@types/react': 19.2.17 - '@mui/private-theming@9.0.1(@types/react@19.2.15)(react@19.2.6)': + '@mui/private-theming@9.0.1(@types/react@19.2.17)(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 - '@mui/utils': 9.0.1(@types/react@19.2.15)(react@19.2.6) + '@mui/utils': 9.0.1(@types/react@19.2.17)(react@19.2.7) prop-types: 15.8.1 - react: 19.2.6 + react: 19.2.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - '@mui/styled-engine@9.0.0(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(react@19.2.6)': + '@mui/styled-engine@9.0.0(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 '@emotion/cache': 11.14.0 @@ -3362,44 +3362,44 @@ snapshots: '@emotion/sheet': 1.4.0 csstype: 3.2.3 prop-types: 15.8.1 - react: 19.2.6 + react: 19.2.7 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.2.15)(react@19.2.6) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6) + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7) - '@mui/system@9.0.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6)': + '@mui/system@9.0.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 - '@mui/private-theming': 9.0.1(@types/react@19.2.15)(react@19.2.6) - '@mui/styled-engine': 9.0.0(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6))(react@19.2.6) - '@mui/types': 9.0.0(@types/react@19.2.15) - '@mui/utils': 9.0.1(@types/react@19.2.15)(react@19.2.6) + '@mui/private-theming': 9.0.1(@types/react@19.2.17)(react@19.2.7) + '@mui/styled-engine': 9.0.0(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7))(react@19.2.7) + '@mui/types': 9.0.0(@types/react@19.2.17) + '@mui/utils': 9.0.1(@types/react@19.2.17)(react@19.2.7) clsx: 2.1.1 csstype: 3.2.3 prop-types: 15.8.1 - react: 19.2.6 + react: 19.2.7 optionalDependencies: - '@emotion/react': 11.14.0(@types/react@19.2.15)(react@19.2.6) - '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(@types/react@19.2.15)(react@19.2.6) - '@types/react': 19.2.15 + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(@types/react@19.2.17)(react@19.2.7) + '@types/react': 19.2.17 - '@mui/types@9.0.0(@types/react@19.2.15)': + '@mui/types@9.0.0(@types/react@19.2.17)': dependencies: '@babel/runtime': 7.29.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - '@mui/utils@9.0.1(@types/react@19.2.15)(react@19.2.6)': + '@mui/utils@9.0.1(@types/react@19.2.17)(react@19.2.7)': dependencies: '@babel/runtime': 7.29.7 - '@mui/types': 9.0.0(@types/react@19.2.15) + '@mui/types': 9.0.0(@types/react@19.2.17) '@types/prop-types': 15.7.15 clsx: 2.1.1 prop-types: 15.8.1 - react: 19.2.6 - react-is: 19.2.6 + react: 19.2.7 + react-is: 19.2.7 optionalDependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: @@ -3420,23 +3420,23 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@oxc-project/types@0.132.0': {} + '@oxc-project/types@0.133.0': {} '@popperjs/core@2.11.8': {} - '@preact/preset-vite@2.10.5(@babel/core@7.29.7)(preact@10.29.2)(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0))': + '@preact/preset-vite@2.10.5(@babel/core@7.29.7)(preact@10.29.2)(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0))': dependencies: '@babel/core': 7.29.7 '@babel/plugin-transform-react-jsx': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-react-jsx-development': 7.29.7(@babel/core@7.29.7) - '@prefresh/vite': 2.4.12(preact@10.29.2)(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0)) + '@prefresh/vite': 2.4.12(preact@10.29.2)(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0)) '@rollup/pluginutils': 5.4.0 babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.29.7) debug: 4.4.3 magic-string: 0.30.21 picocolors: 1.1.1 - vite: 8.0.14(@types/node@25.9.1)(terser@5.48.0) - vite-prerender-plugin: 0.5.13(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0)) + vite: 8.0.16(@types/node@25.9.2)(terser@5.48.0) + vite-prerender-plugin: 0.5.13(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0)) zimmerframe: 1.1.4 transitivePeerDependencies: - preact @@ -3451,7 +3451,7 @@ snapshots: '@prefresh/utils@1.2.1': {} - '@prefresh/vite@2.4.12(preact@10.29.2)(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0))': + '@prefresh/vite@2.4.12(preact@10.29.2)(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0))': dependencies: '@babel/core': 7.29.7 '@prefresh/babel-plugin': 0.5.3 @@ -3459,57 +3459,57 @@ snapshots: '@prefresh/utils': 1.2.1 '@rollup/pluginutils': 4.2.1 preact: 10.29.2 - vite: 8.0.14(@types/node@25.9.1)(terser@5.48.0) + vite: 8.0.16(@types/node@25.9.2)(terser@5.48.0) transitivePeerDependencies: - supports-color - '@rolldown/binding-android-arm64@1.0.2': + '@rolldown/binding-android-arm64@1.0.3': optional: true - '@rolldown/binding-darwin-arm64@1.0.2': + '@rolldown/binding-darwin-arm64@1.0.3': optional: true - '@rolldown/binding-darwin-x64@1.0.2': + '@rolldown/binding-darwin-x64@1.0.3': optional: true - '@rolldown/binding-freebsd-x64@1.0.2': + '@rolldown/binding-freebsd-x64@1.0.3': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.2': + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.2': + '@rolldown/binding-linux-arm64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.2': + '@rolldown/binding-linux-arm64-musl@1.0.3': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.2': + '@rolldown/binding-linux-ppc64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.2': + '@rolldown/binding-linux-s390x-gnu@1.0.3': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.2': + '@rolldown/binding-linux-x64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-x64-musl@1.0.2': + '@rolldown/binding-linux-x64-musl@1.0.3': optional: true - '@rolldown/binding-openharmony-arm64@1.0.2': + '@rolldown/binding-openharmony-arm64@1.0.3': optional: true - '@rolldown/binding-wasm32-wasi@1.0.2': + '@rolldown/binding-wasm32-wasi@1.0.3': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.2': + '@rolldown/binding-win32-arm64-msvc@1.0.3': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.2': + '@rolldown/binding-win32-x64-msvc@1.0.3': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -3527,14 +3527,14 @@ snapshots: '@sindresorhus/is@0.7.0': {} - '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.2.15)(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@table-library/react-table-library@4.1.15(@emotion/react@11.14.0(@types/react@19.2.17)(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)': dependencies: - '@emotion/react': 11.14.0(@types/react@19.2.15)(react@19.2.6) + '@emotion/react': 11.14.0(@types/react@19.2.17)(react@19.2.7) clsx: 1.1.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) - react-virtualized-auto-sizer: 1.0.26(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - react-window: 1.8.11(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) + react-virtualized-auto-sizer: 1.0.26(react-dom@19.2.7(react@19.2.7))(react@19.2.7) + react-window: 1.8.11(react-dom@19.2.7(react@19.2.7))(react@19.2.7) '@trivago/prettier-plugin-sort-imports@6.0.2(prettier@3.8.3)': dependencies: @@ -3562,7 +3562,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 25.9.1 + '@types/node': 25.9.2 '@types/imagemin-gifsicle@7.0.4': dependencies: @@ -3591,19 +3591,19 @@ snapshots: '@types/imagemin@7.0.1': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.2 '@types/json-schema@7.0.15': {} '@types/keyv@3.1.4': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.2 '@types/minimatch@6.0.0': dependencies: minimatch: 10.2.5 - '@types/node@25.9.1': + '@types/node@25.9.2': dependencies: undici-types: 7.24.6 @@ -3611,35 +3611,35 @@ snapshots: '@types/prop-types@15.7.15': {} - '@types/react-dom@19.2.3(@types/react@19.2.15)': + '@types/react-dom@19.2.3(@types/react@19.2.17)': dependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - '@types/react-transition-group@4.4.12(@types/react@19.2.15)': + '@types/react-transition-group@4.4.12(@types/react@19.2.17)': dependencies: - '@types/react': 19.2.15 + '@types/react': 19.2.17 - '@types/react@19.2.15': + '@types/react@19.2.17': dependencies: csstype: 3.2.3 '@types/responselike@1.0.3': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.2 '@types/svgo@2.6.4': dependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.2 - '@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.4.0)(typescript@6.0.3))(eslint@10.4.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.60.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1)(typescript@6.0.3))(eslint@10.4.1)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.60.0(eslint@10.4.0)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/type-utils': 8.60.0(eslint@10.4.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.4.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 - eslint: 10.4.0 + '@typescript-eslint/parser': 8.60.1(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/type-utils': 8.60.1(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/utils': 8.60.1(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.60.1 + eslint: 10.4.1 ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -3647,79 +3647,79 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.60.0(eslint@10.4.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.60.1(eslint@10.4.1)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.60.1 debug: 4.4.3 - eslint: 10.4.0 + eslint: 10.4.1 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.60.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.60.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@6.0.3) + '@typescript-eslint/types': 8.60.1 debug: 4.4.3 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.60.0': + '@typescript-eslint/scope-manager@8.60.1': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/visitor-keys': 8.60.1 - '@typescript-eslint/tsconfig-utils@8.60.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.60.1(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.60.0(eslint@10.4.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.60.1(eslint@10.4.1)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.4.0)(typescript@6.0.3) + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.60.1(eslint@10.4.1)(typescript@6.0.3) debug: 4.4.3 - eslint: 10.4.0 + eslint: 10.4.1 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.60.0': {} + '@typescript-eslint/types@8.60.1': {} - '@typescript-eslint/typescript-estree@8.60.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.60.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.60.0(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/project-service': 8.60.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@6.0.3) + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/visitor-keys': 8.60.1 debug: 4.4.3 minimatch: 10.2.5 - semver: 7.8.1 - tinyglobby: 0.2.16 + semver: 7.8.2 + tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.60.0(eslint@10.4.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.60.1(eslint@10.4.1)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - eslint: 10.4.0 + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) + eslint: 10.4.1 typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.60.0': + '@typescript-eslint/visitor-keys@8.60.1': dependencies: - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.60.1 eslint-visitor-keys: 5.0.1 acorn-jsx@5.3.2(acorn@8.16.0): @@ -3784,7 +3784,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.10.32: {} + baseline-browser-mapping@2.10.34: {} bin-build@3.0.0: dependencies: @@ -3845,10 +3845,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.32 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.364 - node-releases: 2.0.46 + baseline-browser-mapping: 2.10.34 + caniuse-lite: 1.0.30001797 + electron-to-chromium: 1.5.368 + node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) buffer-alloc-unsafe@1.1.0: {} @@ -3909,7 +3909,7 @@ snapshots: camelcase@2.1.1: {} - caniuse-lite@1.0.30001793: {} + caniuse-lite@1.0.30001797: {} caw@2.0.1: dependencies: @@ -3959,7 +3959,7 @@ snapshots: concat-map@0.0.1: {} - concurrently@10.0.0: + concurrently@10.0.3: dependencies: chalk: 5.6.2 rxjs: 7.8.2 @@ -4202,7 +4202,7 @@ snapshots: duplexer3@0.1.5: {} - electron-to-chromium@1.5.364: {} + electron-to-chromium@1.5.368: {} emoji-regex@10.6.0: {} @@ -4316,9 +4316,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.4.0): + eslint-config-prettier@10.1.8(eslint@10.4.1): dependencies: - eslint: 10.4.0 + eslint: 10.4.1 eslint-scope@9.1.2: dependencies: @@ -4331,14 +4331,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.4.0: + eslint@10.4.1: dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.1 + '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -4874,7 +4874,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.21 + which-typed-array: 1.1.22 is-utf8@0.2.1: {} @@ -5132,7 +5132,7 @@ snapshots: css-select: 5.2.2 he: 1.2.0 - node-releases@2.0.46: {} + node-releases@2.0.47: {} normalize-package-data@2.5.0: dependencies: @@ -5365,55 +5365,55 @@ snapshots: rate-limiter-flexible@5.0.5: {} - react-dom@19.2.6(react@19.2.6): + react-dom@19.2.7(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 scheduler: 0.27.0 - react-icons@5.6.0(react@19.2.6): + react-icons@5.6.0(react@19.2.7): dependencies: - react: 19.2.6 + react: 19.2.7 react-is@16.13.1: {} - react-is@19.2.6: {} + react-is@19.2.7: {} - react-router@7.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-router@7.17.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: cookie: 1.1.1 - react: 19.2.6 + react: 19.2.7 set-cookie-parser: 2.7.2 optionalDependencies: - react-dom: 19.2.6(react@19.2.6) + react-dom: 19.2.7(react@19.2.7) - react-toastify@11.1.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-toastify@11.1.0(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: clsx: 2.1.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-transition-group@4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-transition-group@4.4.5(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: '@babel/runtime': 7.29.7 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-virtualized-auto-sizer@1.0.26(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-virtualized-auto-sizer@1.0.26(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react-window@1.8.11(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + react-window@1.8.11(react-dom@19.2.7(react@19.2.7))(react@19.2.7): dependencies: '@babel/runtime': 7.29.7 memoize-one: 5.2.1 - react: 19.2.6 - react-dom: 19.2.6(react@19.2.6) + react: 19.2.7 + react-dom: 19.2.7(react@19.2.7) - react@19.2.6: {} + react@19.2.7: {} read-pkg-up@1.0.1: dependencies: @@ -5466,35 +5466,35 @@ snapshots: dependencies: glob: 7.2.3 - rolldown@1.0.2: + rolldown@1.0.3: dependencies: - '@oxc-project/types': 0.132.0 + '@oxc-project/types': 0.133.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.2 - '@rolldown/binding-darwin-arm64': 1.0.2 - '@rolldown/binding-darwin-x64': 1.0.2 - '@rolldown/binding-freebsd-x64': 1.0.2 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.2 - '@rolldown/binding-linux-arm64-gnu': 1.0.2 - '@rolldown/binding-linux-arm64-musl': 1.0.2 - '@rolldown/binding-linux-ppc64-gnu': 1.0.2 - '@rolldown/binding-linux-s390x-gnu': 1.0.2 - '@rolldown/binding-linux-x64-gnu': 1.0.2 - '@rolldown/binding-linux-x64-musl': 1.0.2 - '@rolldown/binding-openharmony-arm64': 1.0.2 - '@rolldown/binding-wasm32-wasi': 1.0.2 - '@rolldown/binding-win32-arm64-msvc': 1.0.2 - '@rolldown/binding-win32-x64-msvc': 1.0.2 + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 - rollup-plugin-visualizer@7.0.1(rolldown@1.0.2): + rollup-plugin-visualizer@7.0.1(rolldown@1.0.3): dependencies: open: 11.0.0 picomatch: 4.0.4 source-map: 0.7.6 yargs: 18.0.0 optionalDependencies: - rolldown: 1.0.2 + rolldown: 1.0.3 run-applescript@7.1.0: {} @@ -5528,7 +5528,7 @@ snapshots: semver@6.3.1: {} - semver@7.8.1: {} + semver@7.8.2: {} set-cookie-parser@2.7.2: {} @@ -5704,7 +5704,7 @@ snapshots: timed-out@4.0.1: {} - tinyglobby@0.2.16: + tinyglobby@0.2.17: dependencies: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 @@ -5753,13 +5753,13 @@ snapshots: dependencies: typescript: 6.0.3 - typescript-eslint@8.60.0(eslint@10.4.0)(typescript@6.0.3): + typescript-eslint@8.60.1(eslint@10.4.1)(typescript@6.0.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.4.0)(typescript@6.0.3))(eslint@10.4.0)(typescript@6.0.3) - '@typescript-eslint/parser': 8.60.0(eslint@10.4.0)(typescript@6.0.3) - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.4.0)(typescript@6.0.3) - eslint: 10.4.0 + '@typescript-eslint/eslint-plugin': 8.60.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1)(typescript@6.0.3))(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/parser': 8.60.1(eslint@10.4.1)(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.60.1(eslint@10.4.1)(typescript@6.0.3) + eslint: 10.4.1 typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -5804,7 +5804,7 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-plugin-imagemin@0.6.1(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0)): + vite-plugin-imagemin@0.6.1(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0)): dependencies: '@types/imagemin': 7.0.1 '@types/imagemin-gifsicle': 7.0.4 @@ -5829,11 +5829,11 @@ snapshots: imagemin-webp: 6.1.0 jpegtran-bin: 6.0.1 pathe: 0.2.0 - vite: 8.0.14(@types/node@25.9.1)(terser@5.48.0) + vite: 8.0.16(@types/node@25.9.2)(terser@5.48.0) transitivePeerDependencies: - supports-color - vite-prerender-plugin@0.5.13(vite@8.0.14(@types/node@25.9.1)(terser@5.48.0)): + vite-prerender-plugin@0.5.13(vite@8.0.16(@types/node@25.9.2)(terser@5.48.0)): dependencies: kolorist: 1.8.0 magic-string: 0.30.21 @@ -5841,21 +5841,21 @@ snapshots: simple-code-frame: 1.3.0 source-map: 0.7.6 stack-trace: 1.0.0 - vite: 8.0.14(@types/node@25.9.1)(terser@5.48.0) + vite: 8.0.16(@types/node@25.9.2)(terser@5.48.0) - vite@8.0.14(@types/node@25.9.1)(terser@5.48.0): + vite@8.0.16(@types/node@25.9.2)(terser@5.48.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 postcss: 8.5.15 - rolldown: 1.0.2 - tinyglobby: 0.2.16 + rolldown: 1.0.3 + tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 25.9.1 + '@types/node': 25.9.2 fsevents: 2.3.3 terser: 5.48.0 - which-typed-array@1.1.21: + which-typed-array@1.1.22: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 diff --git a/mock-api/package.json b/mock-api/package.json index a854e8600..aa31cfaec 100644 --- a/mock-api/package.json +++ b/mock-api/package.json @@ -15,5 +15,5 @@ "itty-router": "^5.0.23", "prettier": "^3.8.3" }, - "packageManager": "pnpm@10.34.1+sha512.b58fbde6dca66a929538021581f648b4570b6ca19b18e7cbd7f2c07a7b24454155388dacdf08f2af3678e88a6d1fe04f9d609df24bf51735a060ea041b374ab7" + "packageManager": "pnpm@11.5.2+sha512.71c631e382066efc25625d5cf029075de07b61b37f6e27350fbd84b1bda5864c8c1967adc280776b45c30a715c0359a3be08fef42d5bb09e2b99029979692916" } From 1acc71a6b98c6928a2598250c44fbe57130639bf Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 15:06:50 +0200 Subject: [PATCH 03/19] 3.9.0-dev.11" --- src/emsesp_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/emsesp_version.h b/src/emsesp_version.h index 808c5e03b..f23c4d33f 100644 --- a/src/emsesp_version.h +++ b/src/emsesp_version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "3.9.0-dev.10" +#define EMSESP_APP_VERSION "3.9.0-dev.11" From 0b5d643863e96d5f5d8ab2e0988bbffec74ad45a Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 15:07:17 +0200 Subject: [PATCH 04/19] don't show Scheduler items of type immediate in Dashboard --- src/web/WebDataService.cpp | 27 ++++++++++++++------------- src/web/WebSchedulerService.cpp | 8 +++++--- src/web/WebSchedulerService.h | 4 ++-- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index beb487376..04a322e2b 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -488,24 +488,25 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { EMSESP::webSchedulerService.read([&](const WebScheduler & webScheduler) { for (const ScheduleItem & scheduleItem : webScheduler.scheduleItems) { - // only add if we have a name and it's not of type SCHEDULE_IMMEDIATE - we don't need a u (UOM) for this - if (scheduleItem.name[0] != '\0' && scheduleItem.flags != SCHEDULEFLAG_SCHEDULE_IMMEDIATE) { - JsonObject node = nodes.add(); - node["id"] = (EMSdevice::DeviceTypeUniqueID::SCHEDULER_UID * 100) + count++; + JsonObject node = nodes.add(); + node["id"] = (EMSdevice::DeviceTypeUniqueID::SCHEDULER_UID * 100) + count++; - JsonObject dv = node["dv"].to(); - dv["id"] = std::string("00") + scheduleItem.name; - dv["c"] = scheduleItem.name; - char s[12]; - dv["v"] = Helpers::render_boolean(s, scheduleItem.active, true); - JsonArray l = dv["l"].to(); - l.add(Helpers::render_boolean(s, false, true)); - l.add(Helpers::render_boolean(s, true, true)); - } + JsonObject dv = node["dv"].to(); + dv["id"] = std::string("00") + scheduleItem.name; + dv["c"] = scheduleItem.name; + char s[12]; + dv["v"] = Helpers::render_boolean(s, scheduleItem.active, true); + JsonArray l = dv["l"].to(); + l.add(Helpers::render_boolean(s, false, true)); + l.add(Helpers::render_boolean(s, true, true)); } }); } + Serial.println("All dashboard_data: "); + serializeJson(root, Serial); + Serial.println(); + #if defined(EMSESP_TEST) && defined(EMSESP_STANDALONE) Serial.println(); Serial.print("All dashboard_data: "); diff --git a/src/web/WebSchedulerService.cpp b/src/web/WebSchedulerService.cpp index 7705de4b0..81b7a4781 100644 --- a/src/web/WebSchedulerService.cpp +++ b/src/web/WebSchedulerService.cpp @@ -82,7 +82,7 @@ StateUpdateResult WebScheduler::update(JsonObject root, WebScheduler & webSchedu EMSESP::webSchedulerService.ha_reset(); // build up the list of schedule items - auto scheduleItems = root["schedule"].as(); + auto scheduleItems = root["schedule"].as(); for (const JsonObject schedule : scheduleItems) { // create each schedule item, overwriting any previous settings // ignore the id (as this is only used in the web for table rendering) @@ -333,10 +333,12 @@ void WebSchedulerService::publish(const bool force) { } // count number of entries, default: only named items -uint8_t WebSchedulerService::count_entities(bool cmd_only) { +// if exclude_immediate is true, include those that are of type SCHEDULEFLAG_SCHEDULE_IMMEDIATE +uint8_t WebSchedulerService::count_entities(bool exclude_immediate) { uint8_t count = 0; for (const ScheduleItem & scheduleItem : *scheduleItems_) { - if (scheduleItem.name[0] != '\0' || !cmd_only) { + // count all except SCHEDULE_IMMEDIATE if exclude_immediate is true, else count all + if (!exclude_immediate || scheduleItem.flags != SCHEDULEFLAG_SCHEDULE_IMMEDIATE) { count++; } } diff --git a/src/web/WebSchedulerService.h b/src/web/WebSchedulerService.h index af48d5a82..2fe3a3dc4 100644 --- a/src/web/WebSchedulerService.h +++ b/src/web/WebSchedulerService.h @@ -54,7 +54,7 @@ namespace emsesp { class ScheduleItem { public: boolean active; - uint8_t flags; // bit flags, see SCHEDULEFLAG_* defines + uint8_t flags; // bit flags, see SCHEDULEFLAG_* defines uint16_t elapsed_min; // total mins from 00:00 stringPSRAM time; // HH:MM stringPSRAM cmd; @@ -85,7 +85,7 @@ class WebSchedulerService : public StatefulService { void ha_reset() { ha_configdone_ = false; } - uint8_t count_entities(bool cmd_only = false); + uint8_t count_entities(bool exclude_immediate = false); bool onChange(const char * cmd); bool executeSchedule(const char * name); From b1bc8110cc855c0269c0c43a4dae0245d210e581 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 15:07:45 +0200 Subject: [PATCH 05/19] remove debug --- src/web/WebDataService.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 04a322e2b..608430cb5 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -503,10 +503,6 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { }); } - Serial.println("All dashboard_data: "); - serializeJson(root, Serial); - Serial.println(); - #if defined(EMSESP_TEST) && defined(EMSESP_STANDALONE) Serial.println(); Serial.print("All dashboard_data: "); From 791285e7f499d41f7ce0640a327f0f10db337f37 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 16:35:40 +0200 Subject: [PATCH 06/19] enable cancel mid-flight in an HTTPS firmware upload --- interface/src/app/status/SystemMonitor.tsx | 18 +++++++++++++++--- src/core/system.cpp | 20 ++++++++++++++++++++ src/core/system.h | 2 +- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/interface/src/app/status/SystemMonitor.tsx b/interface/src/app/status/SystemMonitor.tsx index b6fa12d1f..2a9e74343 100644 --- a/interface/src/app/status/SystemMonitor.tsx +++ b/interface/src/app/status/SystemMonitor.tsx @@ -145,9 +145,21 @@ const SystemMonitor = () => { {LL.PLEASE_WAIT()}… {isUploading && ( - - - + <> + + + + + + )} )} diff --git a/src/core/system.cpp b/src/core/system.cpp index c26628fdf..df63c2930 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -3149,6 +3149,18 @@ bool System::uploadFirmwareURL(const char * url) { int last_pct = -1; while (total_read < (size_t)firmware_size) { + // a cancel is signalled by the WebUI dropping the status below UPLOADING (back to NORMAL) + // via the systemStatus action, which runs on the AsyncTCP task while we're blocked here + if (EMSESP::system_.systemStatus() < SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING) { + LOG_WARNING("Firmware upload cancelled at %u of %d bytes", (unsigned)total_read, firmware_size); + Update.abort(); // release the OTA partition handle so a later attempt can start cleanly + ssl_client.stop(); // drop the connection + saved_url.clear(); // prevent it from downloading again + EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_NORMAL); + Shell::loop_all(); // flush log buffers so the cancel message shows in the console + return true; // not an error - don't trigger the failure/reset path in emsesp.cpp + } + // wait for some data or for the connection to drop uint32_t wait_start = millis(); while (!stream->available()) { @@ -3158,10 +3170,18 @@ bool System::uploadFirmwareURL(const char * url) { if (millis() - wait_start > READ_TIMEOUT_MS) { break; } + // also bail out promptly if a cancel arrives mid-stall + if (EMSESP::system_.systemStatus() < SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING) { + break; + } delay(1); } if (!stream->available()) { + // if the inner wait broke because of a cancel, loop back so the top-of-loop handler runs + if (EMSESP::system_.systemStatus() < SYSTEM_STATUS::SYSTEM_STATUS_UPLOADING) { + continue; + } LOG_ERROR("Firmware upload failed - read stalled at %u of %d bytes", (unsigned)total_read, firmware_size); EMSESP::system_.systemStatus(SYSTEM_STATUS::SYSTEM_STATUS_ERROR_UPLOAD); return false; diff --git a/src/core/system.h b/src/core/system.h index 1aa9351ab..6c6f62e2c 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -358,7 +358,7 @@ class System { static uint32_t heap_mem_; static uint32_t min_free_mem_; - uint8_t systemStatus_; // uses SYSTEM_STATUS enum + volatile uint8_t systemStatus_; // uses SYSTEM_STATUS enum - written from the AsyncTCP task (e.g. cancel) and read from the main loop during OTA void set_partition_install_date(); From 8f3adc800f32536c34544e4c6a2f264574f4d8c5 Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 16:39:17 +0200 Subject: [PATCH 07/19] use corepack v11 --- scripts/update_all.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/update_all.sh b/scripts/update_all.sh index 283e892c5..64277f760 100644 --- a/scripts/update_all.sh +++ b/scripts/update_all.sh @@ -5,7 +5,7 @@ cd interface rm -rf node_modules -corepack use pnpm@latest-10 +corepack use pnpm@latest pnpm update --latest pnpm install pnpm format @@ -13,7 +13,7 @@ pnpm lint cd ../mock-api rm -rf node_modules -corepack use pnpm@latest-10 +corepack use pnpm@latest pnpm update --latest pnpm install pnpm format From 2d0bb34d177d0720a10538c14a97dfbbbe57141c Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 16:39:58 +0200 Subject: [PATCH 08/19] update --- project-words.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/project-words.txt b/project-words.txt index aba4a3bb0..8d6209c83 100644 --- a/project-words.txt +++ b/project-words.txt @@ -1340,4 +1340,5 @@ sendmail serialises SPIRAM optimisations -IILE \ No newline at end of file +IILE +Sumr \ No newline at end of file From b85085790a19c213fbdd0ebea8e8f70f664dc40d Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 16:40:23 +0200 Subject: [PATCH 09/19] add volatile, as they are ISR-written outside the main loop --- src/core/analogsensor.cpp | 4 ++-- src/core/analogsensor.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index 6d4b3f59b..134c69977 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -26,8 +26,8 @@ std::vector AnalogSensor::exclude_types_; #ifndef EMSESP_STANDALONE portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED; -unsigned long AnalogSensor::edge[] = {0, 0, 0}; -unsigned long AnalogSensor::edgecnt[] = {0, 0, 0}; +volatile unsigned long AnalogSensor::edge[] = {0, 0, 0}; +volatile unsigned long AnalogSensor::edgecnt[] = {0, 0, 0}; void IRAM_ATTR AnalogSensor::freqIrq0() { portENTER_CRITICAL_ISR(&mux); diff --git a/src/core/analogsensor.h b/src/core/analogsensor.h index 592452f96..31a7af0ec 100644 --- a/src/core/analogsensor.h +++ b/src/core/analogsensor.h @@ -210,8 +210,8 @@ class AnalogSensor { 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]; + static volatile unsigned long edge[3]; // written from freqIrqN() ISRs, read from the main measure() loop (partly outside the critical section) + static volatile unsigned long edgecnt[3]; // written from freqIrqN() ISRs, read from the main measure() loop (partly outside the critical section) unsigned long lastedge[3] = {0, 0, 0}; #endif }; From a2afc4342e5492e3abd36a5633cc41fe7ecbe35a Mon Sep 17 00:00:00 2001 From: proddy Date: Sat, 6 Jun 2026 16:42:32 +0200 Subject: [PATCH 10/19] fix lint warning for C++20 volatile --- src/core/analogsensor.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/core/analogsensor.cpp b/src/core/analogsensor.cpp index 134c69977..170399e85 100644 --- a/src/core/analogsensor.cpp +++ b/src/core/analogsensor.cpp @@ -32,24 +32,24 @@ volatile unsigned long AnalogSensor::edgecnt[] = {0, 0, 0}; void IRAM_ATTR AnalogSensor::freqIrq0() { portENTER_CRITICAL_ISR(&mux); if (micros() - edge[0] > 10) { // limit to 100kHz - edgecnt[0]++; - edge[0] = micros(); + edgecnt[0] = edgecnt[0] + 1; + edge[0] = micros(); } portEXIT_CRITICAL_ISR(&mux); } void IRAM_ATTR AnalogSensor::freqIrq1() { portENTER_CRITICAL_ISR(&mux); if (micros() - edge[1] > 10) { // limit to 100kHz - edgecnt[1]++; - edge[1] = micros(); + edgecnt[1] = edgecnt[1] + 1; + edge[1] = micros(); } portEXIT_CRITICAL_ISR(&mux); } void IRAM_ATTR AnalogSensor::freqIrq2() { portENTER_CRITICAL_ISR(&mux); if (micros() - edge[2] > 10) { // limit to 100kHz - edgecnt[2]++; - edge[2] = micros(); + edgecnt[2] = edgecnt[2] + 1; + edge[2] = micros(); } portEXIT_CRITICAL_ISR(&mux); } @@ -272,8 +272,10 @@ void AnalogSensor::reload(bool get_nvs) { sensor.set_value(0); publish_sensor(sensor); attachInterrupt(sensor.gpio(), index == 0 ? freqIrq0 : index == 1 ? freqIrq1 : freqIrq2, FALLING); - lastedge[index] = edge[index] = micros(); - edgecnt[index] = 0; + unsigned long now = micros(); + edge[index] = now; + lastedge[index] = now; + edgecnt[index] = 0; } else if (sensor.type() >= AnalogType::CNT_0 && sensor.type() <= AnalogType::CNT_2) { auto index = sensor.type() - AnalogType::CNT_0; LOG_DEBUG("Counter %d on GPIO %02d", index, sensor.gpio()); From c55b8c5e2ee094e6de6d75573ee535d5f8391ec9 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 7 Jun 2026 09:55:48 +0200 Subject: [PATCH 11/19] fix showing immediate in dashboard --- src/web/WebDataService.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/web/WebDataService.cpp b/src/web/WebDataService.cpp index 608430cb5..93a8c834d 100644 --- a/src/web/WebDataService.cpp +++ b/src/web/WebDataService.cpp @@ -488,6 +488,9 @@ void WebDataService::dashboard_data(AsyncWebServerRequest * request) { EMSESP::webSchedulerService.read([&](const WebScheduler & webScheduler) { for (const ScheduleItem & scheduleItem : webScheduler.scheduleItems) { + if (scheduleItem.flags == SCHEDULEFLAG_SCHEDULE_IMMEDIATE) { + continue; + } JsonObject node = nodes.add(); node["id"] = (EMSdevice::DeviceTypeUniqueID::SCHEDULER_UID * 100) + count++; From cbfebabfa37f7957df741c6eb37074b78f332ca3 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 7 Jun 2026 09:56:07 +0200 Subject: [PATCH 12/19] Feature Request: Make the "EMS-ESP" title text in the web interface configurable. Fixes #3110 --- interface/pnpm-workspace.yaml | 11 ++++++++++ interface/src/app/main/types.ts | 1 + .../src/app/settings/ApplicationSettings.tsx | 14 ++++++++++++- .../src/components/layout/LayoutDrawer.tsx | 21 ++++++++++++++++++- interface/src/i18n/cz/index.ts | 3 ++- interface/src/i18n/de/index.ts | 3 ++- interface/src/i18n/en/index.ts | 3 ++- interface/src/i18n/fr/index.ts | 3 ++- interface/src/i18n/it/index.ts | 3 ++- interface/src/i18n/nl/index.ts | 3 ++- interface/src/i18n/no/index.ts | 3 ++- interface/src/i18n/pl/index.ts | 3 ++- interface/src/i18n/sk/index.ts | 3 ++- interface/src/i18n/sv/index.ts | 3 ++- interface/src/i18n/tr/index.ts | 3 ++- mock-api/restServer.ts | 1 + src/core/default_settings.h | 4 ++++ src/core/system.cpp | 14 +++---------- src/core/system.h | 5 +++++ src/web/WebSettingsService.cpp | 3 +++ src/web/WebSettingsService.h | 1 + 21 files changed, 84 insertions(+), 24 deletions(-) create mode 100644 interface/pnpm-workspace.yaml diff --git a/interface/pnpm-workspace.yaml b/interface/pnpm-workspace.yaml new file mode 100644 index 000000000..613c8cdaf --- /dev/null +++ b/interface/pnpm-workspace.yaml @@ -0,0 +1,11 @@ +allowBuilds: + cwebp-bin: false + esbuild: false + gifsicle: false + jpegtran-bin: false + mozjpeg: false + optipng-bin: false + pngquant-bin: false +minimumReleaseAgeExclude: + - '@types/node@25.9.2' + - '@types/react@19.2.17' diff --git a/interface/src/app/main/types.ts b/interface/src/app/main/types.ts index 80bc10d20..391c22a01 100644 --- a/interface/src/app/main/types.ts +++ b/interface/src/app/main/types.ts @@ -1,4 +1,5 @@ export interface Settings { + system_name: string; locale: string; tx_mode: number; ems_bus_id: number; diff --git a/interface/src/app/settings/ApplicationSettings.tsx b/interface/src/app/settings/ApplicationSettings.tsx index 60e240a80..17e55e7e3 100644 --- a/interface/src/app/settings/ApplicationSettings.tsx +++ b/interface/src/app/settings/ApplicationSettings.tsx @@ -189,7 +189,19 @@ const ApplicationSettings = () => { return ( <> - + + {LL.SYSTEM(0)}  + {LL.CUSTOMIZATIONS()} + + + {LL.SERVICES()} API diff --git a/interface/src/components/layout/LayoutDrawer.tsx b/interface/src/components/layout/LayoutDrawer.tsx index 89237615f..debe49bcb 100644 --- a/interface/src/components/layout/LayoutDrawer.tsx +++ b/interface/src/components/layout/LayoutDrawer.tsx @@ -2,6 +2,9 @@ import { memo } from 'react'; import { Box, Divider, Drawer, Toolbar, Typography, styled } from '@mui/material'; +import { readSettings } from 'api/app'; + +import { useRequest } from 'alova/client'; import { PROJECT_NAME } from 'env'; import { DRAWER_WIDTH } from './Layout'; @@ -24,12 +27,28 @@ interface LayoutDrawerProps { } const LayoutDrawerComponent = ({ mobileOpen, onClose }: LayoutDrawerProps) => { + const { data: settings } = useRequest(readSettings); + const system_name = settings?.system_name; + const drawer = ( <> - {PROJECT_NAME} + + {PROJECT_NAME} + {system_name && ( + + {system_name} + + )} + diff --git a/interface/src/i18n/cz/index.ts b/interface/src/i18n/cz/index.ts index 32e03654f..9aa52367a 100644 --- a/interface/src/i18n/cz/index.ts +++ b/interface/src/i18n/cz/index.ts @@ -363,7 +363,8 @@ const cz: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Tato aktualizace vyžaduje obnovení továrního nastavení. Ujistěte se, že nejprve stáhnete systémovou zálohu před pokračováním a poté nahrajte tento soubor po instalaci nové verze.', UPGRADE_IMPORTANT_MESSAGES_2: 'Aktualizujete se na novou hlavní verzi. Ujistěte se, že jste přečetli ChangeLog pro jakékoliv závažné změny.', WARNING_SYSTEM_BACKUP: 'Toto vytvoří zálohu vašich celých systémových konfigurací a nastavení. Všechna hesla budou v zálohovém souboru čitelná. Buďte opatrní při sdílení! Opravdu chcete pokračovat?', - TEST_EMAIL_SUCCESSFUL: 'Test email byl úspěšně odeslán' + TEST_EMAIL_SUCCESSFUL: 'Test email byl úspěšně odeslán', + SYSTEM_NAME: 'Název systému' }; export default cz; diff --git a/interface/src/i18n/de/index.ts b/interface/src/i18n/de/index.ts index b6a43b923..4aa9d5bb9 100644 --- a/interface/src/i18n/de/index.ts +++ b/interface/src/i18n/de/index.ts @@ -363,7 +363,8 @@ const de: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Für diese Aktualisierung ist ein Werksreset erforderlich. Stellen Sie sicher, dass Sie zuerst eine Systemsicherung herunterladen, bevor Sie fortfahren, und laden Sie diese Datei dann nach der Installation der neuen Version hoch.', UPGRADE_IMPORTANT_MESSAGES_2: 'Sie aktualisieren auf eine neue Hauptversion. Stellen Sie sicher, dass Sie den ChangeLog für alle wichtigen Änderungen gelesen haben.', WARNING_SYSTEM_BACKUP: 'Dies wird eine Sicherung Ihrer vollständigen Systemkonfiguration und Einstellungen erstellen. Alle Passwörter werden in dieser Sicherungsdatei lesbar sein. Seien Sie vorsichtig beim Teilen! Möchten Sie fortfahren?', - TEST_EMAIL_SUCCESSFUL: 'Test email erfolgreich gesendet' + TEST_EMAIL_SUCCESSFUL: 'Test email erfolgreich gesendet', + SYSTEM_NAME: 'Systemname' }; export default de; diff --git a/interface/src/i18n/en/index.ts b/interface/src/i18n/en/index.ts index e02415987..8c46008ff 100644 --- a/interface/src/i18n/en/index.ts +++ b/interface/src/i18n/en/index.ts @@ -363,7 +363,8 @@ const en: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'This upgrade requires a factory reset. Make sure you first download a System Backup before continuing, and then upload this file after the new version is installed.', UPGRADE_IMPORTANT_MESSAGES_2: 'You are upgrading to a new major version. Make sure you have read the ChangeLog for any breaking changes.', WARNING_SYSTEM_BACKUP: 'This will create a backup of your full system configuration and settings. All passwords will be readable in the backup file. Be careful with sharing! Do you want to continue?', - TEST_EMAIL_SUCCESSFUL: 'Test email sent successfully' + TEST_EMAIL_SUCCESSFUL: 'Test email sent successfully', + SYSTEM_NAME: 'System Name' }; export default en; diff --git a/interface/src/i18n/fr/index.ts b/interface/src/i18n/fr/index.ts index a4b1c031e..a28c5379f 100644 --- a/interface/src/i18n/fr/index.ts +++ b/interface/src/i18n/fr/index.ts @@ -363,7 +363,8 @@ const fr: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Cette mise à jour nécessite une réinitialisation de fabrique. Assurez-vous de télécharger une sauvegarde système avant de continuer, et de la charger après l\'installation de la nouvelle version.', UPGRADE_IMPORTANT_MESSAGES_2: 'Vous mettez à jour vers une nouvelle version majeure. Assurez-vous de lire le ChangeLog pour tout changement important.', WARNING_SYSTEM_BACKUP: 'Cela créera une sauvegarde de votre configuration et paramètres complets. Tous les mots de passe seront lisibles dans le fichier de sauvegarde. Soyez prudent avec le partage ! Voulez-vous continuer ?', - TEST_EMAIL_SUCCESSFUL: 'Test email envoyé avec succès' + TEST_EMAIL_SUCCESSFUL: 'Test email envoyé avec succès', + SYSTEM_NAME: 'Nom du système' }; export default fr; diff --git a/interface/src/i18n/it/index.ts b/interface/src/i18n/it/index.ts index 0c86e8729..dcd1d3942 100644 --- a/interface/src/i18n/it/index.ts +++ b/interface/src/i18n/it/index.ts @@ -363,7 +363,8 @@ const it: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Questa aggiornamento richiede un ripristino di fabbrica. Assicurati di prima scaricare un backup del sistema prima di continuare, e poi caricare questo file dopo l\'installazione della nuova versione.', UPGRADE_IMPORTANT_MESSAGES_2: 'Stai aggiornando a una nuova versione principale. Assicurati di aver letto il ChangeLog per qualsiasi cambiamento importante.', WARNING_SYSTEM_BACKUP: 'Questo creerà un backup delle tue configurazioni e impostazioni complete. Tutte le password saranno leggibili nel file di backup. Sei sicuro di voler continuare?', - TEST_EMAIL_SUCCESSFUL: 'Test email inviata con successo' + TEST_EMAIL_SUCCESSFUL: 'Test email inviata con successo', + SYSTEM_NAME: 'Nome del sistema' }; export default it; diff --git a/interface/src/i18n/nl/index.ts b/interface/src/i18n/nl/index.ts index bee059f8f..1d989d850 100644 --- a/interface/src/i18n/nl/index.ts +++ b/interface/src/i18n/nl/index.ts @@ -363,7 +363,8 @@ const nl: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Deze upgrade vereist een fabrieksinstelling. Zorg ervoor dat u eerst een Systeem Backup download voordat u doorgaat, en upload deze file na de installatie van de nieuwe versie.', UPGRADE_IMPORTANT_MESSAGES_2: 'U updatet naar een nieuwe grote versie. Zorg ervoor dat u de ChangeLog hebt gelezen voor alle brekende wijzigingen.', WARNING_SYSTEM_BACKUP: 'Dit zal een back-up van uw volledige systeemconfiguratie en instellingen maken. Alle wachtwoorden zijn leesbaar in het back-upbestand. Wees voorzichtig bij delen! Wilt u doorgaan?', - TEST_EMAIL_SUCCESSFUL: 'Test email verzonden succesvol' + TEST_EMAIL_SUCCESSFUL: 'Test email verzonden succesvol', + SYSTEM_NAME: 'Systeemnaam' }; export default nl; diff --git a/interface/src/i18n/no/index.ts b/interface/src/i18n/no/index.ts index 7817faeb7..2c3b1acc0 100644 --- a/interface/src/i18n/no/index.ts +++ b/interface/src/i18n/no/index.ts @@ -363,7 +363,8 @@ const no: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Denne oppdateringen krever en fabriksinstilling. Sørg for at du først lastet ned en System Backup før du fortsetter, og last denne filen etter at den nye versjonen er installert.', UPGRADE_IMPORTANT_MESSAGES_2: 'Du oppdaterer til en ny hovedversjon. Sørg for at du har lest ChangeLog for eventuelle bruddende endringer.', WARNING_SYSTEM_BACKUP: 'Dette vil lage en sikkerhetskopi av din fullstendige systemkonfigurasjon og innstillinger. Alle passord vil være lesbare i sikkerhetskopien. Vær forsiktig med deling! Vil du fortsette?', - TEST_EMAIL_SUCCESSFUL: 'Test email sendt suksessfullt' + TEST_EMAIL_SUCCESSFUL: 'Test email sendt suksessfullt', + SYSTEM_NAME: 'Systemnavn' }; export default no; diff --git a/interface/src/i18n/pl/index.ts b/interface/src/i18n/pl/index.ts index d0cea7a59..7f01b15be 100644 --- a/interface/src/i18n/pl/index.ts +++ b/interface/src/i18n/pl/index.ts @@ -363,7 +363,8 @@ const pl: BaseTranslation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Ta aktualizacja wymaga resetu fabrycznego. Upewnij się, że najpierw pobierzesz kopię zapasową systemu przed kontynuowaniem, a następnie przesuń tę plik po zainstalowaniu nowej wersji.', UPGRADE_IMPORTANT_MESSAGES_2: 'Aktualizujesz się do nowej głównej wersji. Upewnij się, że przeczytałeś ChangeLog dla wszelkich istotnych zmian.', WARNING_SYSTEM_BACKUP: 'To spowoduje utworzenie kopii zapasowej całej konfiguracji i ustawień systemu. Wszystkie hasła będą widoczne w pliku kopii zapasowej. Bądź ostrożny przy udostępnianiu! Chcesz kontynuować?', - TEST_EMAIL_SUCCESSFUL: 'Test email wysłany pomyślnie' + TEST_EMAIL_SUCCESSFUL: 'Test email wysłany pomyślnie', + SYSTEM_NAME: 'Nazwa systemu' }; export default pl; diff --git a/interface/src/i18n/sk/index.ts b/interface/src/i18n/sk/index.ts index d18c12a7a..bafe9916b 100644 --- a/interface/src/i18n/sk/index.ts +++ b/interface/src/i18n/sk/index.ts @@ -363,7 +363,8 @@ const sk: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Táto aktualizácia vyžaduje reštart základných nastavení. Uistite sa, že najprv stiahnete systémovú zálohu pred pokračovaním, a potom nahrajte tento súbor po instalácii novej verzie.', UPGRADE_IMPORTANT_MESSAGES_2: 'Aktualizujete sa na novú hlavnú verziu. Uistite sa, že ste prečítali ChangeLog pre akékoľvek dôležité zmeny.', WARNING_SYSTEM_BACKUP: 'Toto vytvorí zálohu všetkých vašich celých systémových konfigurácií a nastavení. Všetky hesla budú čitateľné v zálohovom súbore. Buďte opatrní pri zdieľaní! Chcete pokračovať?', - TEST_EMAIL_SUCCESSFUL: 'Test email bol úspešne odoslaný' + TEST_EMAIL_SUCCESSFUL: 'Test email bol úspešne odoslaný', + SYSTEM_NAME: 'Názov systému' }; export default sk; diff --git a/interface/src/i18n/sv/index.ts b/interface/src/i18n/sv/index.ts index fb3e644a6..d67ad48f1 100644 --- a/interface/src/i18n/sv/index.ts +++ b/interface/src/i18n/sv/index.ts @@ -363,7 +363,8 @@ const sv: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Denna uppdatering kräver en fabriksåterställning. Se till att du först laddar ned en System Backup innan du fortsätter, och ladda upp denna fil efter att den nya versionen är installerad.', UPGRADE_IMPORTANT_MESSAGES_2: 'Du uppdaterar till en ny huvudversion. Se till att du har läst ChangeLog för eventuella brkande ändringar.', WARNING_SYSTEM_BACKUP: 'Detta kommer att skapa en säkerhetskopia av din fullständiga systemkonfiguration och inställningar. Alla lösenord kommer att vara läsbara i säkerhetskopien. Var försiktig med att dela! Vill du fortsätta?', - TEST_EMAIL_SUCCESSFUL: 'Test email skickad lyckades' + TEST_EMAIL_SUCCESSFUL: 'Test email skickad lyckades', + SYSTEM_NAME: 'Systemnamn' }; export default sv; diff --git a/interface/src/i18n/tr/index.ts b/interface/src/i18n/tr/index.ts index 36b934b3c..4059a9d9e 100644 --- a/interface/src/i18n/tr/index.ts +++ b/interface/src/i18n/tr/index.ts @@ -363,7 +363,8 @@ const tr: Translation = { UPGRADE_IMPORTANT_MESSAGES_1: 'Bu güncelleme továrnı ayarlarını gerektirir. Yapılandırmanızı ve ayarlarınızı önce yedekleyin ve ardından yeni sürüm yüklendikten sonra yükleyin.', UPGRADE_IMPORTANT_MESSAGES_2: 'Yeni bir büyük sürüme yükselteceksiniz. Değişiklikleri ChangeLogı okuduğunuzdan emin olun.', WARNING_SYSTEM_BACKUP: 'Bu, sistem yapılandırmanızı ve ayarlarınızın bir yedeklemesi oluşturacaktır. Tüm şifreler yedekleme dosyasında okunabilir olacaktır. Paylaşırken dikkatli olun! Devam etmek istediğinize emin misiniz?', - TEST_EMAIL_SUCCESSFUL: 'Test email başarıyla gönderildi' + TEST_EMAIL_SUCCESSFUL: 'Test email başarıyla gönderildi', + SYSTEM_NAME: 'Sistem Adı' }; export default tr; diff --git a/mock-api/restServer.ts b/mock-api/restServer.ts index 18ace9b04..eda4d9c7e 100644 --- a/mock-api/restServer.ts +++ b/mock-api/restServer.ts @@ -15,6 +15,7 @@ const headers = { // EMS-ESP Application Settings let settings = { + system_name: '', locale: 'en', tx_mode: 1, ems_bus_id: 11, diff --git a/src/core/default_settings.h b/src/core/default_settings.h index 031056429..681622a68 100644 --- a/src/core/default_settings.h +++ b/src/core/default_settings.h @@ -21,6 +21,10 @@ // GENERAL SETTINGS +#ifndef EMSESP_DEFAULT_SYSTEM_NAME +#define EMSESP_DEFAULT_SYSTEM_NAME "" +#endif + #ifndef EMSESP_DEFAULT_LOCALE #define EMSESP_DEFAULT_LOCALE EMSESP_LOCALE_EN // English #endif diff --git a/src/core/system.cpp b/src/core/system.cpp index df63c2930..4af5a03f9 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -684,6 +684,7 @@ void System::store_settings(WebSettings & settings) { enum_format_ = settings.enum_format; readonly_mode_ = settings.readonly_mode; locale_ = settings.locale; + system_name_ = settings.system_name; developer_mode_ = settings.developer_mode; } @@ -836,8 +837,9 @@ void System::send_info_mqtt() { } _connection = connection; JsonDocument doc; - // doc["event"] = "connected"; + doc["version"] = EMSESP_APP_VERSION; + doc["system_name"] = system_name_.isEmpty() ? "EMS-ESP" : system_name_; // if NTP is enabled send the boot_time in local time in ISO 8601 format (eg: 2022-11-15 20:46:38) // https://github.com/emsesp/EMS-ESP32/issues/751 @@ -852,16 +854,6 @@ void System::send_info_mqtt() { if (EMSESP::network_.ethernet_connected()) { doc["network"] = "ethernet"; doc["hostname"] = ETH.getHostname(); - /* - doc["MAC"] = ETH.macAddress(); - doc["IPv4 address"] = uuid::printable_to_string(ETH.localIP()) + "/" + uuid::printable_to_string(ETH.subnetMask()); - doc["IPv4 gateway"] = uuid::printable_to_string(ETH.gatewayIP()); - doc["IPv4 nameserver"] = uuid::printable_to_string(ETH.dnsIP()); - if (ETH.localIPv6().toString() != "0000:0000:0000:0000:0000:0000:0000:0000" && ETH.localIPv6().toString() != "::") { - doc["IPv6 address"] = uuid::printable_to_string(ETH.localIPv6()); - } - */ - } else if (EMSESP::network_.wifi_connected()) { doc["network"] = "wifi"; doc["hostname"] = WiFi.getHostname(); diff --git a/src/core/system.h b/src/core/system.h index 6c6f62e2c..d09d4bfc6 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -265,6 +265,10 @@ class System { return std::string(locale_.c_str()); } + std::string system_name() { + return std::string(system_name_.c_str()); + } + void healthcheck(uint8_t healthcheck) { healthcheck_ = healthcheck; } @@ -410,6 +414,7 @@ class System { // EMS-ESP settings std::string hostname_; + String system_name_; String locale_; bool low_clock_; String board_profile_; diff --git a/src/web/WebSettingsService.cpp b/src/web/WebSettingsService.cpp index 38769e33d..db13df2d3 100644 --- a/src/web/WebSettingsService.cpp +++ b/src/web/WebSettingsService.cpp @@ -36,6 +36,7 @@ void WebSettings::read(WebSettings & settings, JsonObject root) { root["version"] = settings.version; root["board_profile"] = settings.board_profile; root["platform"] = EMSESP_PLATFORM; + root["system_name"] = settings.system_name; root["locale"] = settings.locale; root["tx_mode"] = settings.tx_mode; root["ems_bus_id"] = settings.ems_bus_id; @@ -284,6 +285,8 @@ StateUpdateResult WebSettings::update(JsonObject root, WebSettings & settings) { // // without checks or necessary restarts... // + settings.system_name = root["system_name"] | EMSESP_DEFAULT_SYSTEM_NAME; + settings.trace_raw = root["trace_raw"] | EMSESP_DEFAULT_TRACELOG_RAW; EMSESP::trace_raw(settings.trace_raw); diff --git a/src/web/WebSettingsService.h b/src/web/WebSettingsService.h index 0574437c1..29695a599 100644 --- a/src/web/WebSettingsService.h +++ b/src/web/WebSettingsService.h @@ -58,6 +58,7 @@ namespace emsesp { class WebSettings { public: String version = EMSESP_APP_VERSION; + String system_name; String locale; uint8_t tx_mode; uint8_t ems_bus_id; From cfcc84d0c488ce51a996474e0012a1ce67854310 Mon Sep 17 00:00:00 2001 From: proddy Date: Sun, 7 Jun 2026 12:37:34 +0200 Subject: [PATCH 13/19] call scheduler immediate from dashboard --- interface/src/app/main/Dashboard.tsx | 51 ++++--- interface/src/app/main/DevicesDialog.tsx | 153 ++++++++++++--------- interface/src/app/main/SchedulerDialog.tsx | 10 +- interface/src/i18n/cz/index.ts | 3 +- interface/src/i18n/de/index.ts | 3 +- interface/src/i18n/en/index.ts | 3 +- interface/src/i18n/fr/index.ts | 3 +- interface/src/i18n/it/index.ts | 3 +- interface/src/i18n/nl/index.ts | 3 +- interface/src/i18n/no/index.ts | 3 +- interface/src/i18n/pl/index.ts | 3 +- interface/src/i18n/sk/index.ts | 3 +- interface/src/i18n/sv/index.ts | 3 +- interface/src/i18n/tr/index.ts | 3 +- mock-api/restServer.ts | 35 +++-- src/web/WebDataService.cpp | 21 +-- src/web/WebSchedulerService.cpp | 14 +- src/web/WebSchedulerService.h | 2 +- 18 files changed, 195 insertions(+), 124 deletions(-) diff --git a/interface/src/app/main/Dashboard.tsx b/interface/src/app/main/Dashboard.tsx index 964f68e43..2ac3ee729 100644 --- a/interface/src/app/main/Dashboard.tsx +++ b/interface/src/app/main/Dashboard.tsx @@ -7,6 +7,7 @@ import ChevronRightIcon from '@mui/icons-material/ChevronRight'; import EditIcon from '@mui/icons-material/Edit'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import HelpOutlineIcon from '@mui/icons-material/HelpOutlined'; +import PlayArrowIcon from '@mui/icons-material/PlayArrow'; import UnfoldLessIcon from '@mui/icons-material/UnfoldLess'; import UnfoldMoreIcon from '@mui/icons-material/UnfoldMore'; import { @@ -75,24 +76,25 @@ const Dashboard = memo(() => { { immediate: false } - ); + ) + .onSuccess(() => { + toast.success(LL.WRITE_CMD_SENT()); + }) + .onError((error) => { + toast.error(String(error.error?.message || 'An error occurred')); + }); const deviceValueDialogSave = async (devicevalue: DeviceValue) => { if (!selectedDashboardItem) { return; } - const id = selectedDashboardItem.parentNode.id; // this is the parent ID - await sendDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v }) - .then(() => { - toast.success(LL.WRITE_CMD_SENT()); - }) - .catch((error: Error) => { - toast.error(error.message); - }) - .finally(() => { - setDeviceValueDialogOpen(false); - setSelectedDashboardItem(undefined); - }); + // skip if we're executing an immediate schedule + if (devicevalue.v !== undefined) { + const id = selectedDashboardItem.parentNode.id; // this is the parent ID + await sendDeviceValue({ id, c: devicevalue.c ?? '', v: devicevalue.v }); + } + setDeviceValueDialogOpen(false); + setSelectedDashboardItem(undefined); }; const dashboard_theme = useTheme({ @@ -210,7 +212,12 @@ const Dashboard = memo(() => { (parseInt(id.slice(0, 2), 16) & mask) === mask; const editDashboardValue = (di: DashboardItem) => { - if (me.admin && di.dv?.c) { + // don't execute on parent nodes + if (!me.admin || di.id <= 99) { + return; + } + + if (di.dv?.c) { setSelectedDashboardItem(di); setDeviceValueDialogOpen(true); } @@ -321,7 +328,19 @@ const Dashboard = memo(() => { {me.admin && di.dv?.c && - !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && ( + !hasMask(di.dv.id, DeviceEntityMask.DV_READONLY) && + (di.dv.v === '' || di.dv.v === undefined ? ( + editDashboardValue(di)} + > + + + ) : ( { sx={{ fontSize: 16 }} /> - )} + ))} ) : ( diff --git a/interface/src/app/main/DevicesDialog.tsx b/interface/src/app/main/DevicesDialog.tsx index 706c2d608..30fafa6c3 100644 --- a/interface/src/app/main/DevicesDialog.tsx +++ b/interface/src/app/main/DevicesDialog.tsx @@ -1,4 +1,5 @@ import { useEffect, useState } from 'react'; +import { toast } from 'react-toastify'; import CancelIcon from '@mui/icons-material/Cancel'; import WarningIcon from '@mui/icons-material/Warning'; @@ -18,7 +19,9 @@ import { Typography } from '@mui/material'; +import { callAction } from '@/api/app'; import { dialogStyle } from 'CustomTheme'; +import { useRequest } from 'alova/client'; import type Schema from 'async-validator'; import type { ValidateFieldsError } from 'async-validator'; import { ValidatedTextField } from 'components'; @@ -61,10 +64,25 @@ const DevicesDialog = ({ } }, [open, selectedItem]); - const save = async () => { + const { send: executeSchedule } = useRequest( + (id: string) => callAction({ action: 'executeSchedule', param: id }), + { immediate: false } + ) + .onSuccess(() => { + toast.success(LL.EXECUTE_SCHEDULE_SENT()); + }) + .onError((error) => { + toast.error(String(error.error?.message || 'An error occurred')); + }); + + const doAction = async () => { try { setFieldErrors(undefined); - await validate(validator, editItem); + if (editItem.v === undefined && editItem.c !== undefined) { + await executeSchedule(editItem.c); + } else { + await validate(validator, editItem); + } onSave(editItem); } catch (error) { setFieldErrors((error as ValidationError).fieldErrors); @@ -100,9 +118,14 @@ const DevicesDialog = ({ return undefined; }; - const isCommand = selectedItem.v === '' && selectedItem.c; + const isCommand = + (selectedItem.v === '' || selectedItem.v === undefined) && + Boolean(selectedItem.c); + const isSchedulerImmediate = selectedItem.v === undefined; const dialogTitle = isCommand - ? LL.RUN_COMMAND() + ? isSchedulerImmediate + ? LL.EXECUTE() + ' ' + LL.SCHEDULE(0) + : LL.RUN_COMMAND() : writeable ? LL.CHANGE_VALUE() : LL.VALUE(0); @@ -118,67 +141,69 @@ const DevicesDialog = ({ {editItem.id.slice(2)} - - - {editItem.l ? ( - - {editItem.l.map((val) => ( - - {val} - - ))} - - ) : editItem.s || editItem.u !== DeviceValueUOM.NONE ? ( - - {setUom(editItem.u)} - - ) - } - }} - /> - ) : ( - + {!isSchedulerImmediate && ( + + + {editItem.l ? ( + + {editItem.l.map((val) => ( + + {val} + + ))} + + ) : editItem.s || editItem.u !== DeviceValueUOM.NONE ? ( + + {setUom(editItem.u)} + + ) + } + }} + /> + ) : ( + + )} + + {writeable && helperText && ( + + {helperText} + )} - {writeable && helperText && ( - - {helperText} - - )} - + )} @@ -202,7 +227,7 @@ const DevicesDialog = ({