From 673b5831d1eefd55f060bd38c8b55cc22c234bbe Mon Sep 17 00:00:00 2001 From: HeavenVR Date: Wed, 9 Oct 2024 19:07:51 +0200 Subject: [PATCH 001/155] Isolate serial loop (#297) * Initial commit * Fix task creation check * Remove debug log * Format main.cpp --- include/serial/SerialInputHandler.h | 1 - src/main.cpp | 19 +++++--- src/serial/SerialInputHandler.cpp | 71 ++++++++++++++++------------- 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/include/serial/SerialInputHandler.h b/include/serial/SerialInputHandler.h index 4587e48a..d47c2d78 100644 --- a/include/serial/SerialInputHandler.h +++ b/include/serial/SerialInputHandler.h @@ -4,7 +4,6 @@ namespace OpenShock::SerialInputHandler { [[nodiscard]] bool Init(); - void Update(); bool SerialEchoEnabled(); void SetSerialEchoEnabled(bool enabled); diff --git a/src/main.cpp b/src/main.cpp index ec3f792d..1ba11079 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,7 +22,8 @@ const char* const TAG = "main"; #include // Internal setup function, returns true if setup succeeded, false otherwise. -bool trySetup() { +bool trySetup() +{ OpenShock::EventHandlers::Init(); if (!OpenShock::VisualStateManager::Init()) { @@ -57,7 +58,8 @@ bool trySetup() { } // OTA setup is the same as normal setup, but we invalidate the currently running app, and roll back if it fails. -void otaSetup() { +void otaSetup() +{ OS_LOGI(TAG, "Validating OTA app"); if (!trySetup()) { @@ -73,7 +75,8 @@ void otaSetup() { } // App setup is the same as normal setup, but we restart if it fails. -void appSetup() { +void appSetup() +{ if (!trySetup()) { OS_LOGI(TAG, "Restarting in 5 seconds..."); vTaskDelay(pdMS_TO_TICKS(5000)); @@ -82,7 +85,8 @@ void appSetup() { } // Arduino setup function -void setup() { +void setup() +{ ::Serial.begin(115'200); OpenShock::Config::Init(); @@ -94,9 +98,9 @@ void setup() { } } -void main_app(void* arg) { +void main_app(void* arg) +{ while (true) { - OpenShock::SerialInputHandler::Update(); OpenShock::CaptivePortal::Update(); OpenShock::GatewayConnectionManager::Update(); OpenShock::WiFiManager::Update(); @@ -105,7 +109,8 @@ void main_app(void* arg) { } } -void loop() { +void loop() +{ // Start the main task OpenShock::TaskUtils::TaskCreateExpensive(main_app, "main_app", 8192, nullptr, 1, nullptr); // PROFILED: 6KB stack usage diff --git a/src/serial/SerialInputHandler.cpp b/src/serial/SerialInputHandler.cpp index 66b3c2fe..5bd08dba 100644 --- a/src/serial/SerialInputHandler.cpp +++ b/src/serial/SerialInputHandler.cpp @@ -19,6 +19,7 @@ const char* const TAG = "SerialInputHandler"; #include "Time.h" #include "util/Base64Utils.h" #include "util/StringUtils.h" +#include "util/TaskUtils.h" #include "wifi/WiFiManager.h" #include @@ -537,6 +538,40 @@ void _processSerialLine(std::string_view line) SERPR_ERROR("Command \"%.*s\" not found", command.size(), command.data()); } +void _serialRxTask(void*) +{ + SerialBuffer buffer(32); + + while (true) { + switch (_tryReadSerialLine(buffer)) { + case SerialReadResult::LineEnd: + _processSerialLine(buffer); + + // Deallocate memory if the buffer is too large + if (buffer.capacity() > SERIAL_BUFFER_CLEAR_THRESHOLD) { + buffer.destroy(); + } else { + buffer.clear(); + } + + // Skip any remaining trailing whitespaces + _skipSerialWhitespaces(buffer); + break; + case SerialReadResult::AutoCompleteRequest: + ::Serial.printf(CLEAR_LINE "> %.*s [AutoComplete is not implemented]", buffer.size(), buffer.data()); + break; + case SerialReadResult::Data: + _echoHandleSerialInput(buffer, true); + break; + default: + _echoHandleSerialInput(buffer, false); + break; + } + + vTaskDelay(pdMS_TO_TICKS(20)); // 50 Hz update rate + } +} + bool SerialInputHandler::Init() { static bool s_initialized = false; @@ -562,39 +597,13 @@ bool SerialInputHandler::Init() return false; } - return true; -} - -void SerialInputHandler::Update() -{ - static SerialBuffer buffer(32); - - switch (_tryReadSerialLine(buffer)) { - case SerialReadResult::LineEnd: - _processSerialLine(buffer); - - // Deallocate memory if the buffer is too large - if (buffer.capacity() > SERIAL_BUFFER_CLEAR_THRESHOLD) { - buffer.destroy(); - } else { - buffer.clear(); - } - - // Skip any remaining trailing whitespaces - _skipSerialWhitespaces(buffer); - break; - case SerialReadResult::AutoCompleteRequest: - ::Serial.printf(CLEAR_LINE "> %.*s [AutoComplete is not implemented]", buffer.size(), buffer.data()); - break; - case SerialReadResult::Data: - _echoHandleSerialInput(buffer, true); - break; - default: - _echoHandleSerialInput(buffer, false); - break; + if (TaskUtils::TaskCreateExpensive(_serialRxTask, "SerialRX", 4096, nullptr, 1, nullptr) != pdPASS) { // TODO: Profile stack size + OS_LOGE(TAG, "Failed to create serial RX task"); + return false; } -} + return true; +} bool SerialInputHandler::SerialEchoEnabled() { return s_echoEnabled; From 143d68dd486c349268f09dd3faf1817d39b5fa5a Mon Sep 17 00:00:00 2001 From: HeavenVR Date: Wed, 9 Oct 2024 20:09:05 +0200 Subject: [PATCH 002/155] Isolate captiveportal loop (#298) * Initial commit * Reduce stack usage of SerialInputHandler * Format CaptivePortal.cpp --- include/CaptivePortal.h | 3 +- src/CaptivePortal.cpp | 116 ++++++++++++++++++++---------- src/main.cpp | 6 +- src/serial/SerialInputHandler.cpp | 2 +- 4 files changed, 86 insertions(+), 41 deletions(-) diff --git a/include/CaptivePortal.h b/include/CaptivePortal.h index c31a2f02..0270968a 100644 --- a/include/CaptivePortal.h +++ b/include/CaptivePortal.h @@ -4,13 +4,14 @@ #include namespace OpenShock::CaptivePortal { + [[nodiscard]] bool Init(); + void SetAlwaysEnabled(bool alwaysEnabled); bool IsAlwaysEnabled(); bool ForceClose(uint32_t timeoutMs); bool IsRunning(); - void Update(); bool SendMessageTXT(uint8_t socketId, std::string_view data); bool SendMessageBIN(uint8_t socketId, const uint8_t* data, std::size_t len); diff --git a/src/CaptivePortal.cpp b/src/CaptivePortal.cpp index e314c2b6..1378252e 100644 --- a/src/CaptivePortal.cpp +++ b/src/CaptivePortal.cpp @@ -15,6 +15,7 @@ const char* const TAG = "CaptivePortal"; #include #include +#include #include #include @@ -23,9 +24,11 @@ using namespace OpenShock; static bool s_alwaysEnabled = false; static bool s_forceClosed = false; +static esp_timer_handle_t s_captivePortalUpdateLoopTimer = nullptr; static std::unique_ptr s_instance = nullptr; -bool _startCaptive() { +bool _startCaptive() +{ if (s_instance != nullptr) { OS_LOGD(TAG, "Already started"); return true; @@ -75,7 +78,8 @@ bool _startCaptive() { return true; } -void _stopCaptive() { +void _stopCaptive() +{ if (s_instance == nullptr) { OS_LOGD(TAG, "Already stopped"); return; @@ -90,19 +94,78 @@ void _stopCaptive() { WiFi.softAPdisconnect(true); } +void _captivePortalUpdateLoop(void*) +{ + bool gatewayConnected = GatewayConnectionManager::IsConnected(); + bool commandHandlerOk = CommandHandler::Ok(); + bool shouldBeRunning = (s_alwaysEnabled || !gatewayConnected || !commandHandlerOk) && !s_forceClosed; + + if (s_instance == nullptr) { + if (shouldBeRunning) { + OS_LOGD(TAG, "Starting captive portal"); + OS_LOGD(TAG, " alwaysEnabled: %s", s_alwaysEnabled ? "true" : "false"); + OS_LOGD(TAG, " forceClosed: %s", s_forceClosed ? "true" : "false"); + OS_LOGD(TAG, " isConnected: %s", gatewayConnected ? "true" : "false"); + OS_LOGD(TAG, " commandHandlerOk: %s", commandHandlerOk ? "true" : "false"); + _startCaptive(); + } + return; + } + + if (!shouldBeRunning) { + OS_LOGD(TAG, "Stopping captive portal"); + OS_LOGD(TAG, " alwaysEnabled: %s", s_alwaysEnabled ? "true" : "false"); + OS_LOGD(TAG, " forceClosed: %s", s_forceClosed ? "true" : "false"); + OS_LOGD(TAG, " isConnected: %s", gatewayConnected ? "true" : "false"); + OS_LOGD(TAG, " commandHandlerOk: %s", commandHandlerOk ? "true" : "false"); + _stopCaptive(); + return; + } +} + using namespace OpenShock; -void CaptivePortal::SetAlwaysEnabled(bool alwaysEnabled) { +bool CaptivePortal::Init() +{ + esp_timer_create_args_t args = { + .callback = _captivePortalUpdateLoop, + .arg = nullptr, + .dispatch_method = ESP_TIMER_TASK, + .name = "captive_portal_update", + .skip_unhandled_events = true, + }; + + esp_err_t err; + + err = esp_timer_create(&args, &s_captivePortalUpdateLoopTimer); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to create captive portal update timer"); + return false; + } + + err = esp_timer_start_periodic(s_captivePortalUpdateLoopTimer, 500'000); // 500ms + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to start captive portal update timer"); + return false; + } + + return true; +} + +void CaptivePortal::SetAlwaysEnabled(bool alwaysEnabled) +{ s_alwaysEnabled = alwaysEnabled; Config::SetCaptivePortalConfig({ .alwaysEnabled = alwaysEnabled, }); } -bool CaptivePortal::IsAlwaysEnabled() { +bool CaptivePortal::IsAlwaysEnabled() +{ return s_alwaysEnabled; } -bool CaptivePortal::ForceClose(uint32_t timeoutMs) { +bool CaptivePortal::ForceClose(uint32_t timeoutMs) +{ s_forceClosed = true; if (s_instance == nullptr) return true; @@ -120,46 +183,21 @@ bool CaptivePortal::ForceClose(uint32_t timeoutMs) { return false; } -bool CaptivePortal::IsRunning() { +bool CaptivePortal::IsRunning() +{ return s_instance != nullptr; } -void CaptivePortal::Update() { - bool gatewayConnected = GatewayConnectionManager::IsConnected(); - bool commandHandlerOk = CommandHandler::Ok(); - bool shouldBeRunning = (s_alwaysEnabled || !gatewayConnected || !commandHandlerOk) && !s_forceClosed; - - if (s_instance == nullptr) { - if (shouldBeRunning) { - OS_LOGD(TAG, "Starting captive portal"); - OS_LOGD(TAG, " alwaysEnabled: %s", s_alwaysEnabled ? "true" : "false"); - OS_LOGD(TAG, " forceClosed: %s", s_forceClosed ? "true" : "false"); - OS_LOGD(TAG, " isConnected: %s", gatewayConnected ? "true" : "false"); - OS_LOGD(TAG, " commandHandlerOk: %s", commandHandlerOk ? "true" : "false"); - _startCaptive(); - } - return; - } - - if (!shouldBeRunning) { - OS_LOGD(TAG, "Stopping captive portal"); - OS_LOGD(TAG, " alwaysEnabled: %s", s_alwaysEnabled ? "true" : "false"); - OS_LOGD(TAG, " forceClosed: %s", s_forceClosed ? "true" : "false"); - OS_LOGD(TAG, " isConnected: %s", gatewayConnected ? "true" : "false"); - OS_LOGD(TAG, " commandHandlerOk: %s", commandHandlerOk ? "true" : "false"); - _stopCaptive(); - return; - } -} - -bool CaptivePortal::SendMessageTXT(uint8_t socketId, std::string_view data) { +bool CaptivePortal::SendMessageTXT(uint8_t socketId, std::string_view data) +{ if (s_instance == nullptr) return false; s_instance->sendMessageTXT(socketId, data); return true; } -bool CaptivePortal::SendMessageBIN(uint8_t socketId, const uint8_t* data, std::size_t len) { +bool CaptivePortal::SendMessageBIN(uint8_t socketId, const uint8_t* data, std::size_t len) +{ if (s_instance == nullptr) return false; s_instance->sendMessageBIN(socketId, data, len); @@ -167,14 +205,16 @@ bool CaptivePortal::SendMessageBIN(uint8_t socketId, const uint8_t* data, std::s return true; } -bool CaptivePortal::BroadcastMessageTXT(std::string_view data) { +bool CaptivePortal::BroadcastMessageTXT(std::string_view data) +{ if (s_instance == nullptr) return false; s_instance->broadcastMessageTXT(data); return true; } -bool CaptivePortal::BroadcastMessageBIN(const uint8_t* data, std::size_t len) { +bool CaptivePortal::BroadcastMessageBIN(const uint8_t* data, std::size_t len) +{ if (s_instance == nullptr) return false; s_instance->broadcastMessageBIN(data, len); diff --git a/src/main.cpp b/src/main.cpp index 1ba11079..4c38350f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -54,6 +54,11 @@ bool trySetup() return false; } + if (!OpenShock::CaptivePortal::Init()) { + OS_LOGE(TAG, "Unable to initialize CaptivePortal"); + return false; + } + return true; } @@ -101,7 +106,6 @@ void setup() void main_app(void* arg) { while (true) { - OpenShock::CaptivePortal::Update(); OpenShock::GatewayConnectionManager::Update(); OpenShock::WiFiManager::Update(); diff --git a/src/serial/SerialInputHandler.cpp b/src/serial/SerialInputHandler.cpp index 5bd08dba..bf65ce17 100644 --- a/src/serial/SerialInputHandler.cpp +++ b/src/serial/SerialInputHandler.cpp @@ -597,7 +597,7 @@ bool SerialInputHandler::Init() return false; } - if (TaskUtils::TaskCreateExpensive(_serialRxTask, "SerialRX", 4096, nullptr, 1, nullptr) != pdPASS) { // TODO: Profile stack size + if (TaskUtils::TaskCreateExpensive(_serialRxTask, "SerialRX", 3200, nullptr, 1, nullptr) != pdPASS) { // Profiled: 2.96KB stack usage OS_LOGE(TAG, "Failed to create serial RX task"); return false; } From 2089b48a4ca891ec3578e0277bba9b64a2dd6c69 Mon Sep 17 00:00:00 2001 From: HeavenVR Date: Wed, 9 Oct 2024 20:40:43 +0200 Subject: [PATCH 003/155] Isolate WiFiManager loop (#299) * Initial commit * Reduce stack usage * Format WiFiManager.cpp --- include/wifi/WiFiManager.h | 3 - src/main.cpp | 1 - src/wifi/WiFiManager.cpp | 199 +++++++++++++++++++++++-------------- 3 files changed, 125 insertions(+), 78 deletions(-) diff --git a/include/wifi/WiFiManager.h b/include/wifi/WiFiManager.h index 82157a49..ac13685f 100644 --- a/include/wifi/WiFiManager.h +++ b/include/wifi/WiFiManager.h @@ -64,9 +64,6 @@ namespace OpenShock::WiFiManager { /// @return True if the device is connected to a network bool GetIPv6Address(char* ipAddress); - /// @brief Runs the WiFiManager loop - void Update(); - /// @brief Gets a copy of the vector of discovered WiFi networks /// @return Vector of discovered WiFiNetworks std::vector GetDiscoveredWiFiNetworks(); diff --git a/src/main.cpp b/src/main.cpp index 4c38350f..a9ccc192 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -107,7 +107,6 @@ void main_app(void* arg) { while (true) { OpenShock::GatewayConnectionManager::Update(); - OpenShock::WiFiManager::Update(); vTaskDelay(5); // 5 ticks update interval } diff --git a/src/wifi/WiFiManager.cpp b/src/wifi/WiFiManager.cpp index 098df494..02302598 100644 --- a/src/wifi/WiFiManager.cpp +++ b/src/wifi/WiFiManager.cpp @@ -8,6 +8,7 @@ const char* const TAG = "WiFiManager"; #include "Logging.h" #include "serialization/WSLocal.h" #include "Time.h" +#include "util/TaskUtils.h" #include "VisualStateManager.h" #include "wifi/WiFiNetwork.h" #include "wifi/WiFiScanManager.h" @@ -28,13 +29,14 @@ enum class WiFiState : uint8_t { Connected = 1 << 1, }; -static WiFiState s_wifiState = WiFiState::Disconnected; +static WiFiState s_wifiState = WiFiState::Disconnected; static uint8_t s_connectedBSSID[6] = {0}; static uint8_t s_connectedCredentialsID = 0; static uint8_t s_preferredCredentialsID = 0; static std::vector s_wifiNetworks; -bool _isZeroBSSID(const uint8_t (&bssid)[6]) { +bool _isZeroBSSID(const uint8_t (&bssid)[6]) +{ for (std::size_t i = 0; i < sizeof(bssid); i++) { if (bssid[i] != 0) { return false; @@ -44,7 +46,8 @@ bool _isZeroBSSID(const uint8_t (&bssid)[6]) { return true; } -bool _attractivityComparer(const WiFiNetwork& a, const WiFiNetwork& b) { +bool _attractivityComparer(const WiFiNetwork& a, const WiFiNetwork& b) +{ if (a.credentialsID == 0) { return false; } @@ -55,7 +58,8 @@ bool _attractivityComparer(const WiFiNetwork& a, const WiFiNetwork& b) { return a.rssi > b.rssi; } -bool _isConnectRateLimited(const WiFiNetwork& net) { +bool _isConnectRateLimited(const WiFiNetwork& net) +{ if (net.lastConnectAttempt == 0) { return false; } @@ -69,26 +73,32 @@ bool _isConnectRateLimited(const WiFiNetwork& net) { return false; } -bool _isSaved(std::function predicate) { +bool _isSaved(std::function predicate) +{ return Config::AnyWiFiCredentials(predicate); } -std::vector::iterator _findNetwork(std::function predicate, bool sortByAttractivity = true) { +std::vector::iterator _findNetwork(std::function predicate, bool sortByAttractivity = true) +{ if (sortByAttractivity) { std::sort(s_wifiNetworks.begin(), s_wifiNetworks.end(), _attractivityComparer); } return std::find_if(s_wifiNetworks.begin(), s_wifiNetworks.end(), predicate); } -std::vector::iterator _findNetworkBySSID(const char* ssid, bool sortByAttractivity = true) { +std::vector::iterator _findNetworkBySSID(const char* ssid, bool sortByAttractivity = true) +{ return _findNetwork([ssid](const WiFiNetwork& net) { return strcmp(net.ssid, ssid) == 0; }, sortByAttractivity); } -std::vector::iterator _findNetworkByBSSID(const uint8_t (&bssid)[6]) { +std::vector::iterator _findNetworkByBSSID(const uint8_t (&bssid)[6]) +{ return _findNetwork([bssid](const WiFiNetwork& net) { return memcmp(net.bssid, bssid, sizeof(bssid)) == 0; }, false); } -std::vector::iterator _findNetworkByCredentialsID(uint8_t credentialsID, bool sortByAttractivity = true) { +std::vector::iterator _findNetworkByCredentialsID(uint8_t credentialsID, bool sortByAttractivity = true) +{ return _findNetwork([credentialsID](const WiFiNetwork& net) { return net.credentialsID == credentialsID; }, sortByAttractivity); } -bool _markNetworkAsAttempted(const uint8_t (&bssid)[6]) { +bool _markNetworkAsAttempted(const uint8_t (&bssid)[6]) +{ auto it = _findNetworkByBSSID(bssid); if (it == s_wifiNetworks.end()) { return false; @@ -100,7 +110,8 @@ bool _markNetworkAsAttempted(const uint8_t (&bssid)[6]) { return true; } -bool _getNextWiFiNetwork(OpenShock::Config::WiFiCredentials& creds) { +bool _getNextWiFiNetwork(OpenShock::Config::WiFiCredentials& creds) +{ return _findNetwork([&creds](const WiFiNetwork& net) { if (net.credentialsID == 0) { return false; @@ -118,7 +129,8 @@ bool _getNextWiFiNetwork(OpenShock::Config::WiFiCredentials& creds) { }) != s_wifiNetworks.end(); } -bool _connectImpl(const char* ssid, const char* password, const uint8_t (&bssid)[6]) { +bool _connectImpl(const char* ssid, const char* password, const uint8_t (&bssid)[6]) +{ OS_LOGV(TAG, "Connecting to network %s (" BSSID_FMT ")", ssid, BSSID_ARG(bssid)); _markNetworkAsAttempted(bssid); @@ -132,7 +144,8 @@ bool _connectImpl(const char* ssid, const char* password, const uint8_t (&bssid) return true; } -bool _connectHidden(const uint8_t (&bssid)[6], const std::string& password) { +bool _connectHidden(const uint8_t (&bssid)[6], const std::string& password) +{ (void)password; OS_LOGV(TAG, "Connecting to hidden network " BSSID_FMT, BSSID_ARG(bssid)); @@ -142,7 +155,8 @@ bool _connectHidden(const uint8_t (&bssid)[6], const std::string& password) { return false; } -bool _connect(const std::string& ssid, const std::string& password) { +bool _connect(const std::string& ssid, const std::string& password) +{ if (ssid.empty()) { OS_LOGW(TAG, "Cannot connect to network with empty SSID"); return false; @@ -156,7 +170,8 @@ bool _connect(const std::string& ssid, const std::string& password) { return _connectImpl(ssid.c_str(), password.c_str(), it->bssid); } -bool _connect(const uint8_t (&bssid)[6], const std::string& password) { +bool _connect(const uint8_t (&bssid)[6], const std::string& password) +{ if (_isZeroBSSID(bssid)) { OS_LOGW(TAG, "Cannot connect to network with zero BSSID"); return false; @@ -171,7 +186,8 @@ bool _connect(const uint8_t (&bssid)[6], const std::string& password) { return _connectImpl(it->ssid, password.c_str(), bssid); } -bool _authenticate(const WiFiNetwork& net, std::string_view password) { +bool _authenticate(const WiFiNetwork& net, std::string_view password) +{ uint8_t id = Config::AddWiFiCredentials(net.ssid, password); if (id == 0) { Serialization::Local::SerializeErrorMessage("too_many_credentials", CaptivePortal::BroadcastMessageBIN); @@ -183,7 +199,8 @@ bool _authenticate(const WiFiNetwork& net, std::string_view password) { return _connect(net.ssid, std::string(password)); } -void _evWiFiConnected(arduino_event_t* event) { +void _evWiFiConnected(arduino_event_t* event) +{ auto& info = event->event_info.wifi_sta_connected; s_wifiState = WiFiState::Connected; @@ -204,7 +221,8 @@ void _evWiFiConnected(arduino_event_t* event) { Serialization::Local::SerializeWiFiNetworkEvent(Serialization::Types::WifiNetworkEventType::Connected, *it, CaptivePortal::BroadcastMessageBIN); } -void _evWiFiGotIP(arduino_event_t* event) { +void _evWiFiGotIP(arduino_event_t* event) +{ const auto& info = event->event_info.got_ip; uint8_t ip[4]; @@ -212,14 +230,16 @@ void _evWiFiGotIP(arduino_event_t* event) { OS_LOGI(TAG, "Got IP address " IPV4ADDR_FMT " from network " BSSID_FMT, IPV4ADDR_ARG(ip), BSSID_ARG(s_connectedBSSID)); } -void _evWiFiGotIP6(arduino_event_t* event) { +void _evWiFiGotIP6(arduino_event_t* event) +{ auto& info = event->event_info.got_ip6; uint8_t* ip6 = reinterpret_cast(&info.ip6_info.ip.addr); OS_LOGI(TAG, "Got IPv6 address " IPV6ADDR_FMT " from network " BSSID_FMT, IPV6ADDR_ARG(ip6), BSSID_ARG(s_connectedBSSID)); } -void _evWiFiDisconnected(arduino_event_t* event) { +void _evWiFiDisconnected(arduino_event_t* event) +{ s_wifiState = WiFiState::Disconnected; auto& info = event->event_info.wifi_sta_disconnected; @@ -240,8 +260,11 @@ void _evWiFiDisconnected(arduino_event_t* event) { Serialization::Local::SerializeErrorMessage(reason, CaptivePortal::BroadcastMessageBIN); } } -void _evWiFiScanStarted() { } -void _evWiFiScanStatusChanged(OpenShock::WiFiScanStatus status) { +void _evWiFiScanStarted() +{ +} +void _evWiFiScanStatusChanged(OpenShock::WiFiScanStatus status) +{ // If the scan started, remove any networks that have not been seen in 3 scans if (status == OpenShock::WiFiScanStatus::Started) { for (auto it = s_wifiNetworks.begin(); it != s_wifiNetworks.end();) { @@ -264,7 +287,8 @@ void _evWiFiScanStatusChanged(OpenShock::WiFiScanStatus status) { // Send the scan status changed event Serialization::Local::SerializeWiFiScanStatusChangedEvent(status, CaptivePortal::BroadcastMessageBIN); } -void _evWiFiNetworksDiscovery(const std::vector& records) { +void _evWiFiNetworksDiscovery(const std::vector& records) +{ std::vector updatedNetworks; std::vector discoveredNetworks; @@ -306,7 +330,54 @@ void _evWiFiNetworksDiscovery(const std::vector& record esp_err_t set_esp_interface_dns(esp_interface_t interface, IPAddress main_dns, IPAddress backup_dns, IPAddress fallback_dns); -bool WiFiManager::Init() { +bool _tryConnect() +{ + Config::WiFiCredentials creds; + if (s_preferredCredentialsID != 0) { + bool foundCreds = Config::TryGetWiFiCredentialsByID(s_preferredCredentialsID, creds); + + s_preferredCredentialsID = 0; + + if (!foundCreds) { + OS_LOGE(TAG, "Failed to find credentials with ID %u", s_preferredCredentialsID); + return false; + } + + if (_connect(creds.ssid, creds.password)) { + return true; + } + + OS_LOGE(TAG, "Failed to connect to network %s", creds.ssid.c_str()); + } + + if (!_getNextWiFiNetwork(creds)) { + return false; + } + + return _connect(creds.ssid, creds.password); +} + +void _wifimanagerUpdateTask(void*) +{ + int64_t lastScanRequest = 0; + while (true) { + if (s_wifiState == WiFiState::Disconnected && !WiFiScanManager::IsScanning()) { + if (!_tryConnect()) { + int64_t now = OpenShock::millis(); + if (lastScanRequest == 0 || now - lastScanRequest > 30'000) { + lastScanRequest = now; + + OS_LOGV(TAG, "No networks to connect to, starting scan..."); + WiFiScanManager::StartScan(); + } + } + } + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} + +bool WiFiManager::Init() +{ WiFi.onEvent(_evWiFiConnected, ARDUINO_EVENT_WIFI_STA_CONNECTED); WiFi.onEvent(_evWiFiGotIP, ARDUINO_EVENT_WIFI_STA_GOT_IP); WiFi.onEvent(_evWiFiGotIP6, ARDUINO_EVENT_WIFI_STA_GOT_IP6); @@ -345,10 +416,16 @@ bool WiFiManager::Init() { return false; } + if (TaskUtils::TaskCreateUniversal(_wifimanagerUpdateTask, TAG, 2048, nullptr, 5, nullptr, 1) != pdPASS) { // Profiled: 1.716KB stack usage + OS_LOGE(TAG, "Failed to create WiFiManager update task"); + return false; + } + return true; } -bool WiFiManager::Save(const char* ssid, std::string_view password) { +bool WiFiManager::Save(const char* ssid, std::string_view password) +{ OS_LOGV(TAG, "Authenticating to network %s", ssid); auto it = _findNetworkBySSID(ssid); @@ -363,7 +440,8 @@ bool WiFiManager::Save(const char* ssid, std::string_view password) { return _authenticate(*it, password); } -bool WiFiManager::Forget(const char* ssid) { +bool WiFiManager::Forget(const char* ssid) +{ OS_LOGV(TAG, "Forgetting network %s", ssid); auto it = _findNetworkBySSID(ssid); @@ -389,7 +467,8 @@ bool WiFiManager::Forget(const char* ssid) { return true; } -bool WiFiManager::RefreshNetworkCredentials() { +bool WiFiManager::RefreshNetworkCredentials() +{ OS_LOGV(TAG, "Refreshing network credentials"); for (auto& net : s_wifiNetworks) { @@ -406,11 +485,13 @@ bool WiFiManager::RefreshNetworkCredentials() { return true; } -bool WiFiManager::IsSaved(const char* ssid) { +bool WiFiManager::IsSaved(const char* ssid) +{ return _isSaved([ssid](const Config::WiFiCredentials& creds) { return creds.ssid == ssid; }); } -bool WiFiManager::Connect(const char* ssid) { +bool WiFiManager::Connect(const char* ssid) +{ Config::WiFiCredentials creds; if (!Config::TryGetWiFiCredentialsBySSID(ssid, creds)) { OS_LOGE(TAG, "Failed to find credentials for network %s", ssid); @@ -431,7 +512,8 @@ bool WiFiManager::Connect(const char* ssid) { return false; } -bool WiFiManager::Connect(const uint8_t (&bssid)[6]) { +bool WiFiManager::Connect(const uint8_t (&bssid)[6]) +{ auto it = _findNetworkByBSSID(bssid); if (it == s_wifiNetworks.end()) { OS_LOGE(TAG, "Failed to find network " BSSID_FMT, BSSID_ARG(bssid)); @@ -458,14 +540,17 @@ bool WiFiManager::Connect(const uint8_t (&bssid)[6]) { return false; } -void WiFiManager::Disconnect() { +void WiFiManager::Disconnect() +{ WiFi.disconnect(false); } -bool WiFiManager::IsConnected() { +bool WiFiManager::IsConnected() +{ return s_wifiState == WiFiState::Connected; } -bool WiFiManager::GetConnectedNetwork(OpenShock::WiFiNetwork& network) { +bool WiFiManager::GetConnectedNetwork(OpenShock::WiFiNetwork& network) +{ if (s_connectedCredentialsID == 0) { if (IsConnected()) { // We connected without a scan, so populate the network with the current connection info manually @@ -489,7 +574,8 @@ bool WiFiManager::GetConnectedNetwork(OpenShock::WiFiNetwork& network) { return true; } -bool WiFiManager::GetIPAddress(char* ipAddress) { +bool WiFiManager::GetIPAddress(char* ipAddress) +{ if (!IsConnected()) { return false; } @@ -500,55 +586,20 @@ bool WiFiManager::GetIPAddress(char* ipAddress) { return true; } -bool WiFiManager::GetIPv6Address(char* ipAddress) { +bool WiFiManager::GetIPv6Address(char* ipAddress) +{ if (!IsConnected()) { return false; } - IPv6Address ip = WiFi.localIPv6(); + IPv6Address ip = WiFi.localIPv6(); const uint8_t* ipPtr = ip; // Using the implicit conversion operator of IPv6Address snprintf(ipAddress, IPV6ADDR_FMT_LEN + 1, IPV6ADDR_FMT, IPV6ADDR_ARG(ipPtr)); return true; } -static int64_t s_lastScanRequest = 0; -void WiFiManager::Update() { - if (s_wifiState != WiFiState::Disconnected || WiFiScanManager::IsScanning()) return; - - if (s_preferredCredentialsID != 0) { - Config::WiFiCredentials creds; - bool foundCreds = Config::TryGetWiFiCredentialsByID(s_preferredCredentialsID, creds); - - s_preferredCredentialsID = 0; - - if (!foundCreds) { - OS_LOGE(TAG, "Failed to find credentials with ID %u", s_preferredCredentialsID); - return; - } - - if (_connect(creds.ssid, creds.password)) { - return; - } - - OS_LOGE(TAG, "Failed to connect to network %s", creds.ssid.c_str()); - } - - Config::WiFiCredentials creds; - if (!_getNextWiFiNetwork(creds)) { - int64_t now = OpenShock::millis(); - if (s_lastScanRequest == 0 || now - s_lastScanRequest > 30'000) { - s_lastScanRequest = now; - - OS_LOGV(TAG, "No networks to connect to, starting scan..."); - WiFiScanManager::StartScan(); - } - return; - } - - _connect(creds.ssid, creds.password); -} - -std::vector WiFiManager::GetDiscoveredWiFiNetworks() { +std::vector WiFiManager::GetDiscoveredWiFiNetworks() +{ return s_wifiNetworks; } From 68a22e434394582a18a1f080e6ea84a235c97eae Mon Sep 17 00:00:00 2001 From: hhvrc Date: Thu, 10 Oct 2024 12:16:06 +0200 Subject: [PATCH 004/155] Clean up main.cpp a bit --- include/event_handlers/Init.h | 9 --------- src/main.cpp | 15 +++++++++------ 2 files changed, 9 insertions(+), 15 deletions(-) delete mode 100644 include/event_handlers/Init.h diff --git a/include/event_handlers/Init.h b/include/event_handlers/Init.h deleted file mode 100644 index 2f382854..00000000 --- a/include/event_handlers/Init.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "event_handlers/WebSocket.h" - -namespace OpenShock::EventHandlers { - void Init() { } - - void Deinit() { } -} // namespace OpenShock::EventHandlers diff --git a/src/main.cpp b/src/main.cpp index a9ccc192..42fa8cb7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,6 @@ const char* const TAG = "main"; #include "Common.h" #include "config/Config.h" #include "EStopManager.h" -#include "event_handlers/Init.h" #include "GatewayConnectionManager.h" #include "Logging.h" #include "OtaUpdateManager.h" @@ -24,14 +23,14 @@ const char* const TAG = "main"; // Internal setup function, returns true if setup succeeded, false otherwise. bool trySetup() { - OpenShock::EventHandlers::Init(); - if (!OpenShock::VisualStateManager::Init()) { - OS_PANIC(TAG, "Unable to initialize VisualStateManager"); + OS_LOGE(TAG, "Unable to initialize VisualStateManager"); + return false; } if (!OpenShock::EStopManager::Init()) { - OS_PANIC(TAG, "Unable to initialize EStopManager"); + OS_LOGE(TAG, "Unable to initialize EStopManager"); + return false; } if (!OpenShock::SerialInputHandler::Init()) { @@ -95,7 +94,11 @@ void setup() ::Serial.begin(115'200); OpenShock::Config::Init(); - OpenShock::OtaUpdateManager::Init(); + + if (!OpenShock::OtaUpdateManager::Init()) { + OS_PANIC(TAG, "Unable to initialize OTA Update Manager"); + } + if (OpenShock::OtaUpdateManager::IsValidatingApp()) { otaSetup(); } else { From ee22cf8d66d12659b122c1542ba29d3be71f4e6c Mon Sep 17 00:00:00 2001 From: hhvrc Date: Fri, 11 Oct 2024 15:20:24 +0200 Subject: [PATCH 005/155] Format SemVer --- include/SemVer.h | 50 ++++++++++++++++++++--------------- src/SemVer.cpp | 69 ++++++++++++++++++++++++++++++------------------ 2 files changed, 73 insertions(+), 46 deletions(-) diff --git a/include/SemVer.h b/include/SemVer.h index 24805232..91141387 100644 --- a/include/SemVer.h +++ b/include/SemVer.h @@ -12,21 +12,35 @@ namespace OpenShock { std::string prerelease; std::string build; - SemVer() : major(0), minor(0), patch(0), prerelease(), build() {} + SemVer() + : major(0) + , minor(0) + , patch(0) + , prerelease() + , build() + { + } SemVer(uint16_t major, uint16_t minor, uint16_t patch) - : major(major), minor(minor), patch(patch), prerelease(), build() - {} - SemVer(uint16_t major, uint16_t minor, uint16_t patch, std::string_view prerelease, std::string_view build) - : major(major), minor(minor), patch(patch), prerelease(std::string(prerelease)), build(std::string(build)) - {} - - bool operator==(const SemVer& other) const { - return major == other.major && minor == other.minor && patch == other.patch && prerelease == other.prerelease && build == other.build; + : major(major) + , minor(minor) + , patch(patch) + , prerelease() + , build() + { } - bool operator!=(const SemVer& other) const { - return !(*this == other); + SemVer(uint16_t major, uint16_t minor, uint16_t patch, std::string_view prerelease, std::string_view build) + : major(major) + , minor(minor) + , patch(patch) + , prerelease(std::string(prerelease)) + , build(std::string(build)) + { } - bool operator<(const SemVer& other) const { + + bool operator==(const SemVer& other) const { return major == other.major && minor == other.minor && patch == other.patch && prerelease == other.prerelease && build == other.build; } + bool operator!=(const SemVer& other) const { return !(*this == other); } + bool operator<(const SemVer& other) const + { if (major < other.major) { return true; } @@ -57,15 +71,9 @@ namespace OpenShock { return build < other.build; } - bool operator<=(const SemVer& other) const { - return *this < other || *this == other; - } - bool operator>(const SemVer& other) const { - return !(*this <= other); - } - bool operator>=(const SemVer& other) const { - return !(*this < other); - } + bool operator<=(const SemVer& other) const { return *this < other || *this == other; } + bool operator>(const SemVer& other) const { return !(*this <= other); } + bool operator>=(const SemVer& other) const { return !(*this < other); } bool isValid() const; diff --git a/src/SemVer.cpp b/src/SemVer.cpp index 4d9d544d..55aa8660 100644 --- a/src/SemVer.cpp +++ b/src/SemVer.cpp @@ -7,16 +7,20 @@ const char* const TAG = "SemVer"; using namespace OpenShock; -constexpr bool _semverIsLetter(char c) { +constexpr bool _semverIsLetter(char c) +{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } -constexpr bool _semverIsPositiveDigit(char c) { +constexpr bool _semverIsPositiveDigit(char c) +{ return c >= '1' && c <= '9'; } -constexpr bool _semverIsDigit(char c) { +constexpr bool _semverIsDigit(char c) +{ return c == '0' || _semverIsPositiveDigit(c); } -constexpr bool _semverIsDigits(std::string_view str) { +constexpr bool _semverIsDigits(std::string_view str) +{ if (str.empty()) { return false; } @@ -29,13 +33,16 @@ constexpr bool _semverIsDigits(std::string_view str) { return true; } -constexpr bool _semverIsNonDigit(char c) { +constexpr bool _semverIsNonDigit(char c) +{ return _semverIsLetter(c) || c == '-'; } -constexpr bool _semverIsIdentifierChararacter(char c) { +constexpr bool _semverIsIdentifierChararacter(char c) +{ return _semverIsDigit(c) || _semverIsNonDigit(c); } -constexpr bool _semverIsIdentifierChararacters(std::string_view str) { +constexpr bool _semverIsIdentifierChararacters(std::string_view str) +{ if (str.empty()) { return false; } @@ -48,7 +55,8 @@ constexpr bool _semverIsIdentifierChararacters(std::string_view str) { return true; } -constexpr bool _semverIsNumericIdentifier(std::string_view str) { +constexpr bool _semverIsNumericIdentifier(std::string_view str) +{ if (str.empty()) { return false; } @@ -59,7 +67,8 @@ constexpr bool _semverIsNumericIdentifier(std::string_view str) { return _semverIsPositiveDigit(str[0]) && _semverIsDigits(str.substr(1)); } -constexpr bool _semverIsAlphanumericIdentifier(std::string_view str) { +constexpr bool _semverIsAlphanumericIdentifier(std::string_view str) +{ if (str.empty()) { return false; } @@ -94,13 +103,16 @@ constexpr bool _semverIsAlphanumericIdentifier(std::string_view str) { return _semverIsIdentifierChararacters(before) && _semverIsIdentifierChararacters(after); } -constexpr bool _semverIsBuildIdentifier(std::string_view str) { +constexpr bool _semverIsBuildIdentifier(std::string_view str) +{ return _semverIsAlphanumericIdentifier(str) || _semverIsDigits(str); } -constexpr bool _semverIsPrereleaseIdentifier(std::string_view str) { +constexpr bool _semverIsPrereleaseIdentifier(std::string_view str) +{ return _semverIsAlphanumericIdentifier(str) || _semverIsNumericIdentifier(str); } -constexpr bool _semverIsDotSeperatedBuildIdentifiers(std::string_view str) { +constexpr bool _semverIsDotSeperatedBuildIdentifiers(std::string_view str) +{ if (str.empty()) { return false; } @@ -112,13 +124,14 @@ constexpr bool _semverIsDotSeperatedBuildIdentifiers(std::string_view str) { return false; } - str = str.substr(dotIdx + 1); + str = str.substr(dotIdx + 1); dotIdx = str.find('.'); } return _semverIsBuildIdentifier(str); } -constexpr bool _semverIsDotSeperatedPreleaseIdentifiers(std::string_view str) { +constexpr bool _semverIsDotSeperatedPreleaseIdentifiers(std::string_view str) +{ if (str.empty()) { return false; } @@ -130,18 +143,19 @@ constexpr bool _semverIsDotSeperatedPreleaseIdentifiers(std::string_view str) { return false; } - str = str.substr(dotIdx + 1); + str = str.substr(dotIdx + 1); dotIdx = str.find('.'); } return _semverIsPrereleaseIdentifier(str); } -const auto _semverIsPatch = _semverIsNumericIdentifier; -const auto _semverIsMinor = _semverIsNumericIdentifier; -const auto _semverIsMajor = _semverIsNumericIdentifier; +const auto _semverIsPatch = _semverIsNumericIdentifier; +const auto _semverIsMinor = _semverIsNumericIdentifier; +const auto _semverIsMajor = _semverIsNumericIdentifier; const auto _semverIsPrerelease = _semverIsDotSeperatedPreleaseIdentifiers; const auto _semverIsBuild = _semverIsDotSeperatedBuildIdentifiers; -bool _semverIsVersionCore(std::string_view str) { +bool _semverIsVersionCore(std::string_view str) +{ if (str.empty()) { return false; } @@ -153,7 +167,8 @@ bool _semverIsVersionCore(std::string_view str) { return _semverIsMajor(parts[0]) && _semverIsMinor(parts[1]) && _semverIsPatch(parts[2]); } -bool _semverIsSemver(std::string_view str) { +bool _semverIsSemver(std::string_view str) +{ if (str.empty()) { return false; } @@ -194,7 +209,8 @@ bool _semverIsSemver(std::string_view str) { return false; } -bool _tryParseU16(std::string_view str, uint16_t& out) { +bool _tryParseU16(std::string_view str, uint16_t& out) +{ if (str.empty()) { return false; } @@ -218,7 +234,8 @@ bool _tryParseU16(std::string_view str, uint16_t& out) { return true; } -bool SemVer::isValid() const { +bool SemVer::isValid() const +{ if (!this->prerelease.empty() && !_semverIsPrereleaseIdentifier(this->prerelease)) { return false; } @@ -230,7 +247,8 @@ bool SemVer::isValid() const { return true; } -std::string SemVer::toString() const { +std::string SemVer::toString() const +{ std::string str; str.reserve(32); @@ -253,7 +271,8 @@ std::string SemVer::toString() const { return str; } -bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver) { +bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver) +{ std::string_view parts[3]; if (!OpenShock::TryStringSplit(semverStr, '.', parts)) { OS_LOGE(TAG, "Failed to split version string: %.*s", semverStr.length(), semverStr.data()); @@ -265,7 +284,7 @@ bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver) { auto dashIdx = patchStr.find('-'); if (dashIdx != std::string_view::npos) { semver.prerelease = patchStr.substr(dashIdx + 1); - patchStr = patchStr.substr(0, dashIdx); + patchStr = patchStr.substr(0, dashIdx); } auto plusIdx = semver.prerelease.find('+'); From cbbdc0fb5d5c28e0ac9aba2abda5a1ab6dabe042 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Fri, 11 Oct 2024 15:32:07 +0200 Subject: [PATCH 006/155] SemVer: Implement string compare --- include/SemVer.h | 56 +++++++++++++--------------------------------- src/SemVer.cpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 40 deletions(-) diff --git a/include/SemVer.h b/include/SemVer.h index 91141387..18ae18e0 100644 --- a/include/SemVer.h +++ b/include/SemVer.h @@ -12,7 +12,7 @@ namespace OpenShock { std::string prerelease; std::string build; - SemVer() + inline SemVer() : major(0) , minor(0) , patch(0) @@ -20,7 +20,7 @@ namespace OpenShock { , build() { } - SemVer(uint16_t major, uint16_t minor, uint16_t patch) + inline SemVer(uint16_t major, uint16_t minor, uint16_t patch) : major(major) , minor(minor) , patch(patch) @@ -28,7 +28,7 @@ namespace OpenShock { , build() { } - SemVer(uint16_t major, uint16_t minor, uint16_t patch, std::string_view prerelease, std::string_view build) + inline SemVer(uint16_t major, uint16_t minor, uint16_t patch, std::string_view prerelease, std::string_view build) : major(major) , minor(minor) , patch(patch) @@ -37,43 +37,19 @@ namespace OpenShock { { } - bool operator==(const SemVer& other) const { return major == other.major && minor == other.minor && patch == other.patch && prerelease == other.prerelease && build == other.build; } - bool operator!=(const SemVer& other) const { return !(*this == other); } - bool operator<(const SemVer& other) const - { - if (major < other.major) { - return true; - } - if (major > other.major) { - return false; - } - - if (minor < other.minor) { - return true; - } - if (minor > other.minor) { - return false; - } - - if (patch < other.patch) { - return true; - } - if (patch > other.patch) { - return false; - } - - if (prerelease < other.prerelease) { - return true; - } - if (prerelease > other.prerelease) { - return false; - } - - return build < other.build; - } - bool operator<=(const SemVer& other) const { return *this < other || *this == other; } - bool operator>(const SemVer& other) const { return !(*this <= other); } - bool operator>=(const SemVer& other) const { return !(*this < other); } + bool operator==(const SemVer& other) const; + inline bool operator!=(const SemVer& other) const { return !(*this == other); } + bool operator<(const SemVer& other) const; + inline bool operator<=(const SemVer& other) const { return *this < other || *this == other; } + inline bool operator>(const SemVer& other) const { return !(*this <= other); } + inline bool operator>=(const SemVer& other) const { return !(*this < other); } + + bool operator==(const std::string_view& other) const; + inline bool operator!=(const std::string_view& other) const { return !(*this == other); } + bool operator<(const std::string_view& other) const; + inline bool operator<=(const std::string_view& other) const { return *this < other || *this == other; } + inline bool operator>(const std::string_view& other) const { return !(*this <= other); } + inline bool operator>=(const std::string_view& other) const { return !(*this < other); } bool isValid() const; diff --git a/src/SemVer.cpp b/src/SemVer.cpp index 55aa8660..9a25e51d 100644 --- a/src/SemVer.cpp +++ b/src/SemVer.cpp @@ -271,6 +271,64 @@ std::string SemVer::toString() const return str; } +bool SemVer::operator==(const SemVer& other) const +{ + return major == other.major && minor == other.minor && patch == other.patch && prerelease == other.prerelease && build == other.build; +} + +bool SemVer::operator<(const SemVer& other) const +{ + if (major < other.major) { + return true; + } + if (major > other.major) { + return false; + } + + if (minor < other.minor) { + return true; + } + if (minor > other.minor) { + return false; + } + + if (patch < other.patch) { + return true; + } + if (patch > other.patch) { + return false; + } + + if (prerelease < other.prerelease) { + return true; + } + if (prerelease > other.prerelease) { + return false; + } + + return build < other.build; +} + +bool SemVer::operator==(const std::string_view& other) const +{ + SemVer otherSemVer; + if (!OpenShock::TryParseSemVer(other, otherSemVer)) { + return false; + } + + return *this == otherSemVer; +} + +bool SemVer::operator<(const std::string_view& other) const +{ + SemVer otherSemVer; + if (!OpenShock::TryParseSemVer(other, otherSemVer)) { + return false; + } + + return *this < otherSemVer; +} + bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver) { std::string_view parts[3]; From 483f1cd10dd49b0a87b89e70a3942959b4f3c61d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Oct 2024 09:40:10 +0200 Subject: [PATCH 007/155] build(deps-dev): Bump the frontend group in /frontend with 5 updates (#302) Bumps the frontend group in /frontend with 5 updates: | Package | From | To | | --- | --- | --- | | [@playwright/test](https://github.com/microsoft/playwright) | `1.47.2` | `1.48.0` | | [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit) | `2.6.2` | `2.7.0` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.7.4` | `22.7.5` | | [svelte-check](https://github.com/sveltejs/language-tools) | `4.0.4` | `4.0.5` | | [typescript](https://github.com/microsoft/TypeScript) | `5.6.2` | `5.6.3` | Updates `@playwright/test` from 1.47.2 to 1.48.0 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.47.2...v1.48.0) Updates `@sveltejs/kit` from 2.6.2 to 2.7.0 - [Release notes](https://github.com/sveltejs/kit/releases) - [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md) - [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.7.0/packages/kit) Updates `@types/node` from 22.7.4 to 22.7.5 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `svelte-check` from 4.0.4 to 4.0.5 - [Release notes](https://github.com/sveltejs/language-tools/releases) - [Commits](https://github.com/sveltejs/language-tools/compare/svelte-check-4.0.4...svelte-check-4.0.5) Updates `typescript` from 5.6.2 to 5.6.3 - [Release notes](https://github.com/microsoft/TypeScript/releases) - [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release.yml) - [Commits](https://github.com/microsoft/TypeScript/compare/v5.6.2...v5.6.3) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: "@sveltejs/kit" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: svelte-check dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/package-lock.json | 64 +++++++++++++++++++------------------- frontend/package.json | 10 +++--- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 81582012..d04002fb 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,15 +11,15 @@ "@floating-ui/dom": "1.6.11" }, "devDependencies": { - "@playwright/test": "1.47.2", + "@playwright/test": "1.48.0", "@skeletonlabs/skeleton": "2.10.2", "@skeletonlabs/tw-plugin": "0.4.0", "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "2.6.2", + "@sveltejs/kit": "2.7.0", "@sveltejs/vite-plugin-svelte": "^3.1.2", "@tailwindcss/forms": "0.5.9", "@tailwindcss/typography": "0.5.15", - "@types/node": "22.7.4", + "@types/node": "22.7.5", "autoprefixer": "10.4.20", "eslint": "^9.12.0", "eslint-config-prettier": "9.1.0", @@ -29,10 +29,10 @@ "prettier": "3.3.3", "prettier-plugin-svelte": "3.2.7", "svelte": "4.2.19", - "svelte-check": "4.0.4", + "svelte-check": "4.0.5", "tailwindcss": "3.4.13", "tslib": "2.7.0", - "typescript": "5.6.2", + "typescript": "5.6.3", "vite": "^5.4.8", "vite-plugin-tailwind-purgecss": "^0.3.3", "vitest": "2.1.2" @@ -777,12 +777,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.47.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.47.2.tgz", - "integrity": "sha512-jTXRsoSPONAs8Za9QEQdyjFn+0ZQFjCiIztAIF6bi1HqhBzG9Ma7g1WotyiGqFSBRZjIEqMdT8RUlbk1QVhzCQ==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.0.tgz", + "integrity": "sha512-W5lhqPUVPqhtc/ySvZI5Q8X2ztBOUgZ8LbAFy0JQgrXZs2xaILrUcNO3rQjwbLPfGK13+rZsDa1FpG+tqYkT5w==", "dev": true, "dependencies": { - "playwright": "1.47.2" + "playwright": "1.48.0" }, "bin": { "playwright": "cli.js" @@ -1036,14 +1036,14 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.6.2.tgz", - "integrity": "sha512-ruogrSPXjckn5poUiZU8VYNCSPHq66SFR1AATvOikQxtP6LNI4niAZVX/AWZRe/EPDG3oY2DNJ9c5z7u0t2NAQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.0.tgz", + "integrity": "sha512-4XyY1SCB/Eyz8E9G7SEBKViysYwVtDftuA7kyQ5bmuFNPWC1KZC4988rMvaJxhH2BbCTsbLPjNOZwiEGXt8/2g==", "dev": true, "hasInstallScript": true, "dependencies": { "@types/cookie": "^0.6.0", - "cookie": "^0.7.0", + "cookie": "^0.6.0", "devalue": "^5.1.0", "esm-env": "^1.0.0", "import-meta-resolve": "^4.1.0", @@ -1152,9 +1152,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.7.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.4.tgz", - "integrity": "sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==", + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "dev": true, "dependencies": { "undici-types": "~6.19.2" @@ -1666,9 +1666,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "engines": { "node": ">= 0.6" @@ -3105,12 +3105,12 @@ } }, "node_modules/playwright": { - "version": "1.47.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.47.2.tgz", - "integrity": "sha512-nx1cLMmQWqmA3UsnjaaokyoUpdVaaDhJhMoxX2qj3McpjnsqFHs516QAKYhqHAgOP+oCFTEOCOAaD1RgD/RQfA==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.0.tgz", + "integrity": "sha512-qPqFaMEHuY/ug8o0uteYJSRfMGFikhUysk8ZvAtfKmUK3kc/6oNl/y3EczF8OFGYIi/Ex2HspMfzYArk6+XQSA==", "dev": true, "dependencies": { - "playwright-core": "1.47.2" + "playwright-core": "1.48.0" }, "bin": { "playwright": "cli.js" @@ -3123,9 +3123,9 @@ } }, "node_modules/playwright-core": { - "version": "1.47.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.47.2.tgz", - "integrity": "sha512-3JvMfF+9LJfe16l7AbSmU555PaTl2tPyQsVInqm3id16pdDfvZ8TTZ/pyzmkbDrZTQefyzU7AIHlZqQnxpqHVQ==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.0.tgz", + "integrity": "sha512-RBvzjM9rdpP7UUFrQzRwR8L/xR4HyC1QXMzGYTbf1vjw25/ya9NRAVnXi/0fvFopjebvyPzsmoK58xxeEOaVvA==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -3876,9 +3876,9 @@ } }, "node_modules/svelte-check": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.4.tgz", - "integrity": "sha512-AcHWIPuZb1mh/jKoIrww0ebBPpAvwWd1bfXCnwC2dx4OkydNMaiG//+Xnry91RJMHFH7CiE+6Y2p332DRIaOXQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.5.tgz", + "integrity": "sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", @@ -4218,9 +4218,9 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/frontend/package.json b/frontend/package.json index 892d5c1f..96cd3ded 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,15 +15,15 @@ "test:unit": "vitest" }, "devDependencies": { - "@playwright/test": "1.47.2", + "@playwright/test": "1.48.0", "@skeletonlabs/skeleton": "2.10.2", "@skeletonlabs/tw-plugin": "0.4.0", "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "2.6.2", + "@sveltejs/kit": "2.7.0", "@sveltejs/vite-plugin-svelte": "^3.1.2", "@tailwindcss/forms": "0.5.9", "@tailwindcss/typography": "0.5.15", - "@types/node": "22.7.4", + "@types/node": "22.7.5", "autoprefixer": "10.4.20", "eslint": "^9.12.0", "eslint-config-prettier": "9.1.0", @@ -33,10 +33,10 @@ "prettier": "3.3.3", "prettier-plugin-svelte": "3.2.7", "svelte": "4.2.19", - "svelte-check": "4.0.4", + "svelte-check": "4.0.5", "tailwindcss": "3.4.13", "tslib": "2.7.0", - "typescript": "5.6.2", + "typescript": "5.6.3", "vite": "^5.4.8", "vite-plugin-tailwind-purgecss": "^0.3.3", "vitest": "2.1.2" From 453d5846bdabbb682d15e6e7c5cab6f313ec134c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 09:30:06 +0200 Subject: [PATCH 008/155] build(deps-dev): Bump the frontend group in /frontend with 11 updates (#304) * build(deps-dev): Bump the frontend group in /frontend with 11 updates Bumps the frontend group in /frontend with 11 updates: | Package | From | To | | --- | --- | --- | | [@playwright/test](https://github.com/microsoft/playwright) | `1.48.0` | `1.48.1` | | [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit) | `2.7.0` | `2.7.2` | | [@sveltejs/vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte/tree/HEAD/packages/vite-plugin-svelte) | `3.1.2` | `4.0.0` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.7.5` | `22.7.7` | | [eslint](https://github.com/eslint/eslint) | `9.12.0` | `9.13.0` | | [eslint-plugin-svelte](https://github.com/sveltejs/eslint-plugin-svelte) | `2.44.1` | `2.46.0` | | [svelte](https://github.com/sveltejs/svelte/tree/HEAD/packages/svelte) | `4.2.19` | `5.0.3` | | [tailwindcss](https://github.com/tailwindlabs/tailwindcss) | `3.4.13` | `3.4.14` | | [tslib](https://github.com/Microsoft/tslib) | `2.7.0` | `2.8.0` | | [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `5.4.8` | `5.4.9` | | [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `2.1.2` | `2.1.3` | Updates `@playwright/test` from 1.48.0 to 1.48.1 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.48.0...v1.48.1) Updates `@sveltejs/kit` from 2.7.0 to 2.7.2 - [Release notes](https://github.com/sveltejs/kit/releases) - [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md) - [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.7.2/packages/kit) Updates `@sveltejs/vite-plugin-svelte` from 3.1.2 to 4.0.0 - [Release notes](https://github.com/sveltejs/vite-plugin-svelte/releases) - [Changelog](https://github.com/sveltejs/vite-plugin-svelte/blob/main/packages/vite-plugin-svelte/CHANGELOG.md) - [Commits](https://github.com/sveltejs/vite-plugin-svelte/commits/@sveltejs/vite-plugin-svelte@4.0.0/packages/vite-plugin-svelte) Updates `@types/node` from 22.7.5 to 22.7.7 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `eslint` from 9.12.0 to 9.13.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.12.0...v9.13.0) Updates `eslint-plugin-svelte` from 2.44.1 to 2.46.0 - [Release notes](https://github.com/sveltejs/eslint-plugin-svelte/releases) - [Commits](https://github.com/sveltejs/eslint-plugin-svelte/compare/eslint-plugin-svelte@2.44.1...eslint-plugin-svelte@2.46.0) Updates `svelte` from 4.2.19 to 5.0.3 - [Release notes](https://github.com/sveltejs/svelte/releases) - [Changelog](https://github.com/sveltejs/svelte/blob/main/packages/svelte/CHANGELOG.md) - [Commits](https://github.com/sveltejs/svelte/commits/svelte@5.0.3/packages/svelte) Updates `tailwindcss` from 3.4.13 to 3.4.14 - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/v3.4.14/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/compare/v3.4.13...v3.4.14) Updates `tslib` from 2.7.0 to 2.8.0 - [Release notes](https://github.com/Microsoft/tslib/releases) - [Commits](https://github.com/Microsoft/tslib/compare/v2.7.0...v2.8.0) Updates `vite` from 5.4.8 to 5.4.9 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.4.9/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.4.9/packages/vite) Updates `vitest` from 2.1.2 to 2.1.3 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.3/packages/vitest) --- updated-dependencies: - dependency-name: "@playwright/test" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@sveltejs/kit" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@sveltejs/vite-plugin-svelte" dependency-type: direct:development update-type: version-update:semver-major dependency-group: frontend - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: eslint-plugin-svelte dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: svelte dependency-type: direct:development update-type: version-update:semver-major dependency-group: frontend - dependency-name: tailwindcss dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: tslib dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: vitest dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend ... Signed-off-by: dependabot[bot] * Do not do Svelte 5 upgrade yet --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: hhvrc --- frontend/package-lock.json | 1883 ++++++++++++++++++++---------------- frontend/package.json | 20 +- 2 files changed, 1056 insertions(+), 847 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index d04002fb..e7c88625 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,43 +8,34 @@ "name": "frontend", "version": "0.0.1", "dependencies": { - "@floating-ui/dom": "1.6.11" + "vite": "^5.4.9" }, "devDependencies": { - "@playwright/test": "1.48.0", + "@floating-ui/dom": "1.6.11", + "@playwright/test": "1.48.1", "@skeletonlabs/skeleton": "2.10.2", "@skeletonlabs/tw-plugin": "0.4.0", "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "2.7.0", + "@sveltejs/kit": "2.7.2", "@sveltejs/vite-plugin-svelte": "^3.1.2", "@tailwindcss/forms": "0.5.9", "@tailwindcss/typography": "0.5.15", - "@types/node": "22.7.5", + "@types/node": "22.7.7", "autoprefixer": "10.4.20", - "eslint": "^9.12.0", + "eslint": "^9.13.0", "eslint-config-prettier": "9.1.0", - "eslint-plugin-svelte": "2.44.1", + "eslint-plugin-svelte": "2.46.0", "flatbuffers": "24.3.25", "postcss": "8.4.47", "prettier": "3.3.3", "prettier-plugin-svelte": "3.2.7", "svelte": "4.2.19", "svelte-check": "4.0.5", - "tailwindcss": "3.4.13", - "tslib": "2.7.0", + "tailwindcss": "3.4.14", + "tslib": "2.8.0", "typescript": "5.6.3", - "vite": "^5.4.8", "vite-plugin-tailwind-purgecss": "^0.3.3", - "vitest": "2.1.2" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "vitest": "2.1.3" } }, "node_modules/@alloc/quick-lru": { @@ -52,6 +43,7 @@ "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -64,6 +56,7 @@ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -79,7 +72,7 @@ "cpu": [ "ppc64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" @@ -95,7 +88,7 @@ "cpu": [ "arm" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -111,7 +104,7 @@ "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -127,7 +120,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -143,7 +136,7 @@ "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -159,7 +152,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -175,7 +168,7 @@ "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -191,7 +184,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -207,7 +200,7 @@ "cpu": [ "arm" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -223,7 +216,7 @@ "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -239,7 +232,7 @@ "cpu": [ "ia32" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -255,7 +248,7 @@ "cpu": [ "loong64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -271,7 +264,7 @@ "cpu": [ "mips64el" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -287,7 +280,7 @@ "cpu": [ "ppc64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -303,7 +296,7 @@ "cpu": [ "riscv64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -319,7 +312,7 @@ "cpu": [ "s390x" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -335,7 +328,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -351,7 +344,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -367,7 +360,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -383,7 +376,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -399,7 +392,7 @@ "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -415,7 +408,7 @@ "cpu": [ "ia32" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -431,7 +424,7 @@ "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -445,6 +438,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -455,11 +449,25 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -469,6 +477,7 @@ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.4", "debug": "^4.3.1", @@ -479,10 +488,11 @@ } }, "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", + "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -492,6 +502,7 @@ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -510,40 +521,12 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", - "dev": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/espree": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.0.1.tgz", - "integrity": "sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==", - "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@eslint/js": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", - "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", + "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } @@ -553,15 +536,17 @@ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", + "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", "dev": true, + "license": "Apache-2.0", "dependencies": { "levn": "^0.4.1" }, @@ -570,17 +555,21 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz", - "integrity": "sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==", + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "dev": true, + "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.4" + "@floating-ui/utils": "^0.2.8" } }, "node_modules/@floating-ui/dom": { "version": "1.6.11", "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", + "dev": true, + "license": "MIT", "dependencies": { "@floating-ui/core": "^1.6.0", "@floating-ui/utils": "^0.2.8" @@ -589,13 +578,16 @@ "node_modules/@floating-ui/utils": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", - "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "dev": true, + "license": "MIT" }, "node_modules/@humanfs/core": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18.0" } @@ -605,6 +597,7 @@ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.0", "@humanwhocodes/retry": "^0.3.0" @@ -618,6 +611,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -631,6 +625,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -644,6 +639,7 @@ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", @@ -656,38 +652,12 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -698,10 +668,11 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -711,6 +682,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -719,13 +691,15 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -736,6 +710,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -749,6 +724,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -758,6 +734,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -771,18 +748,20 @@ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", "dev": true, + "license": "MIT", "optional": true, "engines": { "node": ">=14" } }, "node_modules/@playwright/test": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.0.tgz", - "integrity": "sha512-W5lhqPUVPqhtc/ySvZI5Q8X2ztBOUgZ8LbAFy0JQgrXZs2xaILrUcNO3rQjwbLPfGK13+rZsDa1FpG+tqYkT5w==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.1.tgz", + "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "playwright": "1.48.0" + "playwright": "1.48.1" }, "bin": { "playwright": "cli.js" @@ -792,214 +771,215 @@ } }, "node_modules/@polka/url": { - "version": "1.0.0-next.24", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", - "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==", - "dev": true + "version": "1.0.0-next.28", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz", - "integrity": "sha512-Fxamp4aEZnfPOcGA8KSNEohV8hX7zVHOemC8jVBoBUHu5zpJK/Eu3uJwt6BMgy9fkvzxDaurgj96F/NiLukF2w==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", "cpu": [ "arm" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.22.4.tgz", - "integrity": "sha512-VXoK5UMrgECLYaMuGuVTOx5kcuap1Jm8g/M83RnCHBKOqvPPmROFJGQaZhGccnsFtfXQ3XYa4/jMCJvZnbJBdA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.22.4.tgz", - "integrity": "sha512-xMM9ORBqu81jyMKCDP+SZDhnX2QEVQzTcC6G18KlTQEzWK8r/oNZtKuZaCcHhnsa6fEeOBionoyl5JsAbE/36Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.22.4.tgz", - "integrity": "sha512-aJJyYKQwbHuhTUrjWjxEvGnNNBCnmpHDvrb8JFDbeSH3m2XdHcxDd3jthAzvmoI8w/kSjd2y0udT+4okADsZIw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.22.4.tgz", - "integrity": "sha512-j63YtCIRAzbO+gC2L9dWXRh5BFetsv0j0va0Wi9epXDgU/XUi5dJKo4USTttVyK7fGw2nPWK0PbAvyliz50SCQ==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", "cpu": [ "arm" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.22.4.tgz", - "integrity": "sha512-dJnWUgwWBX1YBRsuKKMOlXCzh2Wu1mlHzv20TpqEsfdZLb3WoJW2kIEsGwLkroYf24IrPAvOT/ZQ2OYMV6vlrg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", "cpu": [ "arm" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.22.4.tgz", - "integrity": "sha512-AdPRoNi3NKVLolCN/Sp4F4N1d98c4SBnHMKoLuiG6RXgoZ4sllseuGioszumnPGmPM2O7qaAX/IJdeDU8f26Aw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.22.4.tgz", - "integrity": "sha512-Gl0AxBtDg8uoAn5CCqQDMqAx22Wx22pjDOjBdmG0VIWX3qUBHzYmOKh8KXHL4UpogfJ14G4wk16EQogF+v8hmA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.22.4.tgz", - "integrity": "sha512-3aVCK9xfWW1oGQpTsYJJPF6bfpWfhbRnhdlyhak2ZiyFLDaayz0EP5j9V1RVLAAxlmWKTDfS9wyRyY3hvhPoOg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", "cpu": [ "ppc64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.22.4.tgz", - "integrity": "sha512-ePYIir6VYnhgv2C5Xe9u+ico4t8sZWXschR6fMgoPUK31yQu7hTEJb7bCqivHECwIClJfKgE7zYsh1qTP3WHUA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", "cpu": [ "riscv64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.22.4.tgz", - "integrity": "sha512-GqFJ9wLlbB9daxhVlrTe61vJtEY99/xB3C8e4ULVsVfflcpmR6c8UZXjtkMA6FhNONhj2eA5Tk9uAVw5orEs4Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", "cpu": [ "s390x" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.22.4.tgz", - "integrity": "sha512-87v0ol2sH9GE3cLQLNEy0K/R0pz1nvg76o8M5nhMR0+Q+BBGLnb35P0fVz4CQxHYXaAOhE8HhlkaZfsdUOlHwg==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.22.4.tgz", - "integrity": "sha512-UV6FZMUgePDZrFjrNGIWzDo/vABebuXBhJEqrHxrGiU6HikPy0Z3LfdtciIttEUQfuDdCn8fqh7wiFJjCNwO+g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.22.4.tgz", - "integrity": "sha512-BjI+NVVEGAXjGWYHz/vv0pBqfGoUH0IGZ0cICTn7kB9PyjrATSkX+8WkguNjWoj2qSr1im/+tTGRaY+4/PdcQw==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", "cpu": [ "arm64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.22.4.tgz", - "integrity": "sha512-SiWG/1TuUdPvYmzmYnmd3IEifzR61Tragkbx9D3+R8mzQqDBz8v+BvZNDlkiTtI9T15KYZhP0ehn3Dld4n9J5g==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", "cpu": [ "ia32" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.22.4.tgz", - "integrity": "sha512-j8pPKp53/lq9lMXN57S8cFz0MynJk8OWNuUnXct/9KCpKU7DgU3bYMJhwWmcqC0UU29p8Lr0/7KEVcaM6bf47Q==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", "cpu": [ "x64" ], - "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -1010,6 +990,7 @@ "resolved": "https://registry.npmjs.org/@skeletonlabs/skeleton/-/skeleton-2.10.2.tgz", "integrity": "sha512-TV2yWjvHpmtaF1F5luB8n7UbjKZcsrJMMiiJQHbZvqXjBWvudAcL8zywhE/NFKW5rYU//MtgOODdMZPZxvKu6w==", "dev": true, + "license": "MIT", "dependencies": { "esm-env": "1.0.0" }, @@ -1022,6 +1003,7 @@ "resolved": "https://registry.npmjs.org/@skeletonlabs/tw-plugin/-/tw-plugin-0.4.0.tgz", "integrity": "sha512-v6Y4deBq9ByRx3kTRGgekhhYkWEYgNNNu8UXOwJngCStB7w8SwmbNFSeHkluxMbgCgMnJyp220EMpw9nj/rEsQ==", "dev": true, + "license": "MIT", "peerDependencies": { "tailwindcss": ">=3.0.0" } @@ -1031,16 +1013,18 @@ "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.5.tgz", "integrity": "sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==", "dev": true, + "license": "MIT", "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/kit": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.0.tgz", - "integrity": "sha512-4XyY1SCB/Eyz8E9G7SEBKViysYwVtDftuA7kyQ5bmuFNPWC1KZC4988rMvaJxhH2BbCTsbLPjNOZwiEGXt8/2g==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.2.tgz", + "integrity": "sha512-bFwrl+0bNr0/DHQZM0INwwSPNYqDjfsKRhUoa6rj9d8tDZzszBrJ3La6/HVFxWGONEigtG+SzHXa1BEa1BLdwA==", "dev": true, "hasInstallScript": true, + "license": "MIT", "dependencies": { "@types/cookie": "^0.6.0", "cookie": "^0.6.0", @@ -1052,7 +1036,7 @@ "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", - "sirv": "^2.0.4", + "sirv": "^3.0.0", "tiny-glob": "^0.2.9" }, "bin": { @@ -1072,6 +1056,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.2.tgz", "integrity": "sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==", "dev": true, + "license": "MIT", "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", "debug": "^4.3.4", @@ -1094,6 +1079,7 @@ "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", "dev": true, + "license": "MIT", "dependencies": { "debug": "^4.3.4" }, @@ -1111,6 +1097,7 @@ "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", "integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", "dev": true, + "license": "MIT", "dependencies": { "mini-svg-data-uri": "^1.2.3" }, @@ -1123,6 +1110,7 @@ "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", "dev": true, + "license": "MIT", "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", @@ -1137,37 +1125,41 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "license": "MIT" }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", - "dev": true, + "version": "22.7.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz", + "integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==", + "devOptional": true, + "license": "MIT", "dependencies": { "undici-types": "~6.19.2" } }, "node_modules/@vitest/expect": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.2.tgz", - "integrity": "sha512-FEgtlN8mIUSEAAnlvn7mP8vzaWhEaAEvhSXCqrsijM7K6QqjB11qoRZYEd4AKSCDz8p0/+yH5LzhZ47qt+EyPg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.3.tgz", + "integrity": "sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.2", - "@vitest/utils": "2.1.2", + "@vitest/spy": "2.1.3", + "@vitest/utils": "2.1.3", "chai": "^5.1.1", "tinyrainbow": "^1.2.0" }, @@ -1176,12 +1168,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.2.tgz", - "integrity": "sha512-ExElkCGMS13JAJy+812fw1aCv2QO/LBK6CyO4WOPAzLTmve50gydOlWhgdBJPx2ztbADUq3JVI0C5U+bShaeEA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.3.tgz", + "integrity": "sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/spy": "^2.1.0-beta.1", + "@vitest/spy": "2.1.3", "estree-walker": "^3.0.3", "magic-string": "^0.30.11" }, @@ -1189,7 +1182,7 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/spy": "2.1.2", + "@vitest/spy": "2.1.3", "msw": "^2.3.5", "vite": "^5.0.0" }, @@ -1203,10 +1196,11 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.2.tgz", - "integrity": "sha512-FIoglbHrSUlOJPDGIrh2bjX1sNars5HbxlcsFKCtKzu4+5lpsRhOCVcuzp0fEhAGHkPZRIXVNzPcpSlkoZ3LuA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.3.tgz", + "integrity": "sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==", "dev": true, + "license": "MIT", "dependencies": { "tinyrainbow": "^1.2.0" }, @@ -1215,12 +1209,13 @@ } }, "node_modules/@vitest/runner": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.2.tgz", - "integrity": "sha512-UCsPtvluHO3u7jdoONGjOSil+uON5SSvU9buQh3lP7GgUXHp78guN1wRmZDX4wGK6J10f9NUtP6pO+SFquoMlw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.3.tgz", + "integrity": "sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.2", + "@vitest/utils": "2.1.3", "pathe": "^1.1.2" }, "funding": { @@ -1228,12 +1223,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.2.tgz", - "integrity": "sha512-xtAeNsZ++aRIYIUsek7VHzry/9AcxeULlegBvsdLncLmNCR6tR8SRjn8BbDP4naxtccvzTqZ+L1ltZlRCfBZFA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.3.tgz", + "integrity": "sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.2", + "@vitest/pretty-format": "2.1.3", "magic-string": "^0.30.11", "pathe": "^1.1.2" }, @@ -1242,10 +1238,11 @@ } }, "node_modules/@vitest/spy": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.2.tgz", - "integrity": "sha512-GSUi5zoy+abNRJwmFhBDC0yRuVUn8WMlQscvnbbXdKLXX9dE59YbfwXxuJ/mth6eeqIzofU8BB5XDo/Ns/qK2A==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.3.tgz", + "integrity": "sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==", "dev": true, + "license": "MIT", "dependencies": { "tinyspy": "^3.0.0" }, @@ -1254,12 +1251,13 @@ } }, "node_modules/@vitest/utils": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.2.tgz", - "integrity": "sha512-zMO2KdYy6mx56btx9JvAqAZ6EyS3g49krMPPrgOp1yxGZiA93HumGk+bZ5jIZtOg5/VBYl5eBmGRQHqq4FG6uQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.3.tgz", + "integrity": "sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==", "dev": true, + "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.2", + "@vitest/pretty-format": "2.1.3", "loupe": "^3.1.1", "tinyrainbow": "^1.2.0" }, @@ -1268,10 +1266,11 @@ } }, "node_modules/acorn": { - "version": "8.12.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", - "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1284,6 +1283,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1293,6 +1293,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1305,12 +1306,16 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/ansi-styles": { @@ -1318,6 +1323,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1332,13 +1338,15 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1347,25 +1355,41 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/arg": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", "dev": true, - "dependencies": { - "dequal": "^2.0.3" + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/assertion-error": { @@ -1373,6 +1397,7 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" } @@ -1396,6 +1421,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "browserslist": "^4.23.3", "caniuse-lite": "^1.0.30001646", @@ -1415,27 +1441,33 @@ } }, "node_modules/axobject-query": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", - "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", "dev": true, - "dependencies": { - "dequal": "^2.0.3" + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/brace-expansion": { @@ -1443,6 +1475,7 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1453,6 +1486,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -1461,9 +1495,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "dev": true, "funding": [ { @@ -1479,9 +1513,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.0" }, @@ -1497,6 +1532,7 @@ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1506,6 +1542,7 @@ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1515,14 +1552,15 @@ "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001649", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001649.tgz", - "integrity": "sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==", + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", + "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", "dev": true, "funding": [ { @@ -1537,13 +1575,15 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chai": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", "dev": true, + "license": "MIT", "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", @@ -1560,6 +1600,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -1576,47 +1617,25 @@ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 16" } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" + "node": ">= 14.16.0" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/code-red": { @@ -1624,6 +1643,7 @@ "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", "@types/estree": "^1.0.1", @@ -1637,6 +1657,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -1648,13 +1669,15 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/commander": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -1663,13 +1686,15 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1679,6 +1704,7 @@ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -1693,6 +1719,7 @@ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dev": true, + "license": "MIT", "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -1706,6 +1733,7 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -1718,6 +1746,7 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { "ms": "^2.1.3" }, @@ -1735,6 +1764,7 @@ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1743,43 +1773,39 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/devalue": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/domelementtype": { "version": "2.3.0", @@ -1791,13 +1817,15 @@ "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -1812,25 +1840,29 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.4.tgz", - "integrity": "sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==", - "dev": true + "version": "1.5.41", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.41.tgz", + "integrity": "sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==", + "dev": true, + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -1842,8 +1874,8 @@ "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -1877,10 +1909,11 @@ } }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -1890,6 +1923,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -1898,17 +1932,18 @@ } }, "node_modules/eslint": { - "version": "9.12.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", - "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", + "version": "9.13.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", + "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.11.0", "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", + "@eslint/core": "^0.7.0", "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.12.0", + "@eslint/js": "9.13.0", "@eslint/plugin-kit": "^0.2.0", "@humanfs/node": "^0.16.5", "@humanwhocodes/module-importer": "^1.0.1", @@ -1962,6 +1997,7 @@ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", "dev": true, + "license": "MIT", "dependencies": { "semver": "^7.5.4" }, @@ -1977,6 +2013,7 @@ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", "dev": true, + "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, @@ -1985,22 +2022,23 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "2.44.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.44.1.tgz", - "integrity": "sha512-w6wkoJPw1FJKFtM/2oln21rlu5+HTd2CSkkzhm32A+trNoW2EYQqTQAbDTU6k2GI/6Vh64rBHYQejqEgDld7fw==", + "version": "2.46.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.0.tgz", + "integrity": "sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@jridgewell/sourcemap-codec": "^1.4.15", "eslint-compat-utils": "^0.5.1", "esutils": "^2.0.3", - "known-css-properties": "^0.34.0", + "known-css-properties": "^0.35.0", "postcss": "^8.4.38", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^6.0.0", "postcss-selector-parser": "^6.1.0", "semver": "^7.6.2", - "svelte-eslint-parser": "^0.41.1" + "svelte-eslint-parser": "^0.43.0" }, "engines": { "node": "^14.17.0 || >=16.0.0" @@ -2010,7 +2048,7 @@ }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.191" + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { "svelte": { @@ -2019,10 +2057,11 @@ } }, "node_modules/eslint-plugin-svelte/node_modules/postcss-selector-parser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", - "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2032,44 +2071,11 @@ } }, "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true - }, - "node_modules/eslint/node_modules/eslint-scope": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2081,11 +2087,12 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { + "node_modules/eslint-visitor-keys": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2093,11 +2100,19 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/espree": { + "node_modules/esm-env": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", + "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/espree": { "version": "10.2.0", "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", @@ -2110,34 +2125,12 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/esm-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", - "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", - "dev": true - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -2150,6 +2143,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2162,6 +2156,7 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -2171,6 +2166,7 @@ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } @@ -2180,6 +2176,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -2188,13 +2185,15 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2211,6 +2210,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2222,28 +2222,47 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, + "node_modules/fdir": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, + "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" }, @@ -2256,6 +2275,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2268,6 +2288,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -2284,6 +2305,7 @@ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" @@ -2296,19 +2318,22 @@ "version": "24.3.25", "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.3.25.tgz", "integrity": "sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", "dev": true, + "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" @@ -2325,6 +2350,7 @@ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", "dev": true, + "license": "MIT", "engines": { "node": "*" }, @@ -2333,18 +2359,12 @@ "url": "https://github.com/sponsors/rawify" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -2358,17 +2378,30 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, - "engines": { - "node": "*" + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/glob-parent": { @@ -2376,6 +2409,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -2383,11 +2417,38 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -2399,28 +2460,32 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/globrex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -2429,10 +2494,11 @@ } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -2442,6 +2508,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -2458,6 +2525,7 @@ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "dev": true, + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2468,31 +2536,17 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -2501,12 +2555,16 @@ } }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", "dev": true, + "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2517,6 +2575,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2526,6 +2585,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2535,6 +2595,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -2547,6 +2608,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -2556,6 +2618,7 @@ "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "*" } @@ -2564,19 +2627,18 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" }, - "engines": { - "node": ">=14" - }, "funding": { "url": "https://github.com/sponsors/isaacs" }, @@ -2585,10 +2647,11 @@ } }, "node_modules/jiti": { - "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "version": "1.21.6", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", "dev": true, + "license": "MIT", "bin": { "jiti": "bin/jiti.js" } @@ -2598,6 +2661,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -2609,25 +2673,29 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } @@ -2637,21 +2705,24 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/known-css-properties": { - "version": "0.34.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.34.0.tgz", - "integrity": "sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==", - "dev": true + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", + "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", + "dev": true, + "license": "MIT" }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -2665,6 +2736,7 @@ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -2673,19 +2745,22 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/locate-character": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -2700,34 +2775,43 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/loupe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.1.tgz", - "integrity": "sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", + "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" }, "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", + "version": "0.30.12", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0" } @@ -2736,13 +2820,15 @@ "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "dev": true, + "license": "CC0-1.0" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -2752,6 +2838,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -2760,11 +2847,25 @@ "node": ">=8.6" } }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/mini-svg-data-uri": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", "dev": true, + "license": "MIT", "bin": { "mini-svg-data-uri": "cli.js" } @@ -2774,6 +2875,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -2782,10 +2884,11 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, + "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } @@ -2795,6 +2898,7 @@ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -2804,6 +2908,7 @@ "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -2812,13 +2917,15 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -2829,13 +2936,13 @@ "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -2847,19 +2954,22 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2869,6 +2979,7 @@ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2878,6 +2989,7 @@ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -2887,31 +2999,24 @@ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -2922,6 +3027,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -2937,6 +3043,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -2947,11 +3054,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -2960,24 +3075,26 @@ } }, "node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz", + "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==", "dev": true, + "license": "MIT", "dependencies": { - "entities": "^4.4.0" + "entities": "^4.5.0" }, "funding": { "url": "https://github.com/inikulin/parse5?sponsor=1" } }, "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "dev": true, + "license": "MIT", "dependencies": { - "domhandler": "^5.0.2", + "domhandler": "^5.0.3", "parse5": "^7.0.0" }, "funding": { @@ -2989,24 +3106,17 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3015,44 +3125,39 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/path-scurry": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", - "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=16 || 14 >=14.18" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true, - "engines": { - "node": "14 || >=16.14" - } - }, "node_modules/pathe": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/pathval": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", "dev": true, + "license": "MIT", "engines": { "node": ">= 14.16" } @@ -3062,6 +3167,7 @@ "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -3069,18 +3175,21 @@ } }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", + "optional": true, + "peer": true, "engines": { - "node": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" @@ -3091,6 +3200,7 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3100,17 +3210,19 @@ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/playwright": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.0.tgz", - "integrity": "sha512-qPqFaMEHuY/ug8o0uteYJSRfMGFikhUysk8ZvAtfKmUK3kc/6oNl/y3EczF8OFGYIi/Ex2HspMfzYArk6+XQSA==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.1.tgz", + "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.48.0" + "playwright-core": "1.48.1" }, "bin": { "playwright": "cli.js" @@ -3123,10 +3235,11 @@ } }, "node_modules/playwright-core": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.0.tgz", - "integrity": "sha512-RBvzjM9rdpP7UUFrQzRwR8L/xR4HyC1QXMzGYTbf1vjw25/ya9NRAVnXi/0fvFopjebvyPzsmoK58xxeEOaVvA==", + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz", + "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", "dev": true, + "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" }, @@ -3138,7 +3251,6 @@ "version": "8.4.47", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "dev": true, "funding": [ { "type": "opencollective", @@ -3153,6 +3265,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.1.0", @@ -3167,6 +3280,7 @@ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", "dev": true, + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", @@ -3184,6 +3298,7 @@ "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", "dev": true, + "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" }, @@ -3203,6 +3318,7 @@ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", "dev": true, + "license": "MIT", "dependencies": { "lilconfig": "^2.0.5", "yaml": "^1.10.2" @@ -3228,29 +3344,37 @@ } }, "node_modules/postcss-nested": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz", - "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "postcss-selector-parser": "^6.0.11" + "postcss-selector-parser": "^6.1.1" }, "engines": { "node": ">=12.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, "peerDependencies": { "postcss": "^8.2.14" } }, "node_modules/postcss-nested/node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3264,6 +3388,7 @@ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.0" }, @@ -3294,6 +3419,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "engines": { "node": ">=12.0" }, @@ -3306,6 +3432,7 @@ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3318,13 +3445,15 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -3334,6 +3463,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -3349,6 +3479,7 @@ "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.7.tgz", "integrity": "sha512-/Dswx/ea0lV34If1eDcG3nulQ63YNr5KPDfMsjbdtpSWOxKKJ7nAc2qlVuYwEvCr4raIuredNoR7K4JCkmTGaQ==", "dev": true, + "license": "MIT", "peerDependencies": { "prettier": "^3.0.0", "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" @@ -3359,6 +3490,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3368,6 +3500,7 @@ "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-6.0.0.tgz", "integrity": "sha512-s3EBxg5RSWmpqd0KGzNqPiaBbWDz1/As+2MzoYVGMqgDqRTLBhJW6sywfTBek7OwNfoS/6pS0xdtvChNhFj2cw==", "dev": true, + "license": "MIT", "dependencies": { "commander": "^12.0.0", "glob": "^10.3.10", @@ -3383,66 +3516,22 @@ "resolved": "https://registry.npmjs.org/purgecss-from-html/-/purgecss-from-html-6.0.0.tgz", "integrity": "sha512-GkgAUzgyC4kwcVY5+QOI2eqQghV1Lq7q2uIODAPIueiBn3mHpJOh9boSMjfUQg0/YU/ZEWq7SzjwetuqxTvD4g==", "dev": true, + "license": "ISC", "dependencies": { "parse5": "^7.1.2", "parse5-htmlparser2-tree-adapter": "^7.0.0" } }, - "node_modules/purgecss/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/purgecss/node_modules/commander": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", - "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" } }, - "node_modules/purgecss/node_modules/glob": { - "version": "10.3.12", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", - "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.10.2" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/purgecss/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3461,27 +3550,31 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", "dev": true, + "license": "MIT", "dependencies": { "pify": "^2.3.0" } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, + "license": "MIT", "engines": { - "node": ">=8.10.0" + "node": ">= 14.16.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/resolve": { @@ -3489,6 +3582,7 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dev": true, + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -3506,6 +3600,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -3515,18 +3610,19 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, "node_modules/rollup": { - "version": "4.22.4", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.22.4.tgz", - "integrity": "sha512-vD8HJ5raRcWOyymsR6Z3o6+RzfEPCnVLMFJ6vRslO1jt4LO6dUo5Qnpg7y4RkZFM2DMe3WUirkI5c16onjrc6A==", - "dev": true, + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.6" }, "bin": { "rollup": "dist/bin/rollup" @@ -3536,22 +3632,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.22.4", - "@rollup/rollup-android-arm64": "4.22.4", - "@rollup/rollup-darwin-arm64": "4.22.4", - "@rollup/rollup-darwin-x64": "4.22.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.22.4", - "@rollup/rollup-linux-arm-musleabihf": "4.22.4", - "@rollup/rollup-linux-arm64-gnu": "4.22.4", - "@rollup/rollup-linux-arm64-musl": "4.22.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.22.4", - "@rollup/rollup-linux-riscv64-gnu": "4.22.4", - "@rollup/rollup-linux-s390x-gnu": "4.22.4", - "@rollup/rollup-linux-x64-gnu": "4.22.4", - "@rollup/rollup-linux-x64-musl": "4.22.4", - "@rollup/rollup-win32-arm64-msvc": "4.22.4", - "@rollup/rollup-win32-ia32-msvc": "4.22.4", - "@rollup/rollup-win32-x64-msvc": "4.22.4", + "@rollup/rollup-android-arm-eabi": "4.24.0", + "@rollup/rollup-android-arm64": "4.24.0", + "@rollup/rollup-darwin-arm64": "4.24.0", + "@rollup/rollup-darwin-x64": "4.24.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", + "@rollup/rollup-linux-arm-musleabihf": "4.24.0", + "@rollup/rollup-linux-arm64-gnu": "4.24.0", + "@rollup/rollup-linux-arm64-musl": "4.24.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", + "@rollup/rollup-linux-riscv64-gnu": "4.24.0", + "@rollup/rollup-linux-s390x-gnu": "4.24.0", + "@rollup/rollup-linux-x64-gnu": "4.24.0", + "@rollup/rollup-linux-x64-musl": "4.24.0", + "@rollup/rollup-win32-arm64-msvc": "4.24.0", + "@rollup/rollup-win32-ia32-msvc": "4.24.0", + "@rollup/rollup-win32-x64-msvc": "4.24.0", "fsevents": "~2.3.2" } }, @@ -3574,6 +3670,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -3583,6 +3680,7 @@ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", "dev": true, + "license": "MIT", "dependencies": { "mri": "^1.1.0" }, @@ -3591,10 +3689,11 @@ } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3603,16 +3702,18 @@ } }, "node_modules/set-cookie-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.6.0.tgz", - "integrity": "sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==", - "dev": true + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", + "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==", + "dev": true, + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -3625,6 +3726,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3633,13 +3735,15 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, + "license": "ISC", "engines": { "node": ">=14" }, @@ -3648,24 +3752,25 @@ } }, "node_modules/sirv": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", "dev": true, + "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" }, "engines": { - "node": ">= 10" + "node": ">=18" } }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -3674,19 +3779,22 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/std-env": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -3705,6 +3813,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3714,29 +3823,42 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/string-width-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/string-width/node_modules/ansi-regex": { + "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/string-width/node_modules/strip-ansi": { + "node_modules/strip-ansi": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -3747,11 +3869,13 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/strip-ansi": { + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -3759,15 +3883,12 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, + "license": "MIT", "engines": { "node": ">=8" } @@ -3777,6 +3898,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3785,14 +3907,15 @@ } }, "node_modules/sucrase": { - "version": "3.34.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", - "integrity": "sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==", + "version": "3.35.0", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", + "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", - "glob": "7.1.6", + "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", @@ -3803,27 +3926,7 @@ "sucrase-node": "bin/sucrase-node" }, "engines": { - "node": ">=8" - } - }, - "node_modules/sucrase/node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=16 || 14 >=14.17" } }, "node_modules/supports-color": { @@ -3831,6 +3934,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3843,6 +3947,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3855,6 +3960,7 @@ "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", @@ -3880,6 +3986,7 @@ "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.5.tgz", "integrity": "sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", @@ -3898,87 +4005,80 @@ "typescript": ">=5.0.0" } }, - "node_modules/svelte-check/node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "node_modules/svelte-eslint-parser": { + "version": "0.43.0", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz", + "integrity": "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==", "dev": true, + "license": "MIT", "dependencies": { - "readdirp": "^4.0.1" + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "postcss": "^8.4.39", + "postcss-scss": "^4.0.9" }, "engines": { - "node": ">= 14.16.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/svelte-check/node_modules/fdir": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.3.0.tgz", - "integrity": "sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==", - "dev": true, + "url": "https://github.com/sponsors/ota-meshi" + }, "peerDependencies": { - "picomatch": "^3 || ^4" + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "peerDependenciesMeta": { - "picomatch": { + "svelte": { "optional": true } } }, - "node_modules/svelte-check/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "node_modules/svelte-eslint-parser/node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, - "optional": true, - "peer": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=12" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://opencollective.com/eslint" } }, - "node_modules/svelte-check/node_modules/readdirp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.1.tgz", - "integrity": "sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==", + "node_modules/svelte-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 14.16.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://opencollective.com/eslint" } }, - "node_modules/svelte-eslint-parser": { - "version": "0.41.1", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.41.1.tgz", - "integrity": "sha512-08ndI6zTghzI8SuJAFpvMbA/haPSGn3xz19pjre19yYMw8Nw/wQJ2PrZBI/L8ijGTgtkWCQQiLLy+Z1tfaCwNA==", + "node_modules/svelte-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "postcss": "^8.4.39", - "postcss-scss": "^4.0.9" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.191" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - } + "url": "https://opencollective.com/eslint" } }, "node_modules/svelte-hmr": { @@ -3986,6 +4086,7 @@ "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", "dev": true, + "license": "ISC", "engines": { "node": "^12.20 || ^14.13.1 || >= 16" }, @@ -3994,10 +4095,11 @@ } }, "node_modules/tailwindcss": { - "version": "3.4.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.13.tgz", - "integrity": "sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", "dev": true, + "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -4030,6 +4132,57 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tailwindcss/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tailwindcss/node_modules/postcss-load-config": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", @@ -4045,6 +4198,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" @@ -4066,19 +4220,24 @@ } }, "node_modules/tailwindcss/node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", "dev": true, + "license": "MIT", "engines": { "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/tailwindcss/node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "dev": true, + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -4087,11 +4246,28 @@ "node": ">=4" } }, + "node_modules/tailwindcss/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/tailwindcss/node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", + "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, "engines": { "node": ">= 14" } @@ -4100,13 +4276,15 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", "dev": true, + "license": "MIT", "dependencies": { "any-promise": "^1.0.0" } @@ -4116,6 +4294,7 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", "dev": true, + "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" }, @@ -4128,6 +4307,7 @@ "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", "dev": true, + "license": "MIT", "dependencies": { "globalyzer": "0.1.0", "globrex": "^0.1.2" @@ -4137,19 +4317,22 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tinyexec": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", - "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==", - "dev": true + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", + "dev": true, + "license": "MIT" }, "node_modules/tinypool": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.0.tgz", - "integrity": "sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", + "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", "dev": true, + "license": "MIT", "engines": { "node": "^18.0.0 || >=20.0.0" } @@ -4159,6 +4342,7 @@ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -4168,6 +4352,7 @@ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=14.0.0" } @@ -4177,6 +4362,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -4189,6 +4375,7 @@ "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4197,19 +4384,22 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true + "dev": true, + "license": "Apache-2.0" }, "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "dev": true + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", + "dev": true, + "license": "0BSD" }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -4222,6 +4412,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -4231,15 +4422,16 @@ } }, "node_modules/undici-types": { - "version": "6.19.6", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.6.tgz", - "integrity": "sha512-e/vggGopEfTKSvj4ihnOLTsqhrKRN3LeO6qSN/GxohhuRv8qH9bNQ4B8W7e/vFL+0XTnmHPB4/kegunZGA4Org==", - "dev": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "devOptional": true, + "license": "MIT" }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "dev": true, "funding": [ { @@ -4255,9 +4447,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -4271,6 +4464,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -4279,13 +4473,14 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", - "dev": true, + "version": "5.4.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", + "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", + "license": "MIT", "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", @@ -4341,10 +4536,11 @@ } }, "node_modules/vite-node": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.2.tgz", - "integrity": "sha512-HPcGNN5g/7I2OtPjLqgOtCRu/qhVvBxTUD3qzitmL0SrG1cWFzxzhMDWussxSbrRYWqnKf8P2jiNhPMSN+ymsQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.3.tgz", + "integrity": "sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==", "dev": true, + "license": "MIT", "dependencies": { "cac": "^6.7.14", "debug": "^4.3.6", @@ -4366,6 +4562,7 @@ "resolved": "https://registry.npmjs.org/vite-plugin-tailwind-purgecss/-/vite-plugin-tailwind-purgecss-0.3.3.tgz", "integrity": "sha512-fsTAzcSdFKrhLxX8zTq3zaTFjk+APmJWOAy+1ujsmxkh9y8hIvM81dWEgdXK1k7suQjns+b7JsoIUkHpxLf5UA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^5.3.0", "css-tree": "^2.3.1", @@ -4383,6 +4580,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -4394,8 +4592,8 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -4409,6 +4607,7 @@ "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", "dev": true, + "license": "MIT", "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" }, @@ -4419,18 +4618,19 @@ } }, "node_modules/vitest": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.2.tgz", - "integrity": "sha512-veNjLizOMkRrJ6xxb+pvxN6/QAWg95mzcRjtmkepXdN87FNfxAss9RKe2far/G9cQpipfgP2taqg0KiWsquj8A==", - "dev": true, - "dependencies": { - "@vitest/expect": "2.1.2", - "@vitest/mocker": "2.1.2", - "@vitest/pretty-format": "^2.1.2", - "@vitest/runner": "2.1.2", - "@vitest/snapshot": "2.1.2", - "@vitest/spy": "2.1.2", - "@vitest/utils": "2.1.2", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.3.tgz", + "integrity": "sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.3", + "@vitest/mocker": "2.1.3", + "@vitest/pretty-format": "^2.1.3", + "@vitest/runner": "2.1.3", + "@vitest/snapshot": "2.1.3", + "@vitest/spy": "2.1.3", + "@vitest/utils": "2.1.3", "chai": "^5.1.1", "debug": "^4.3.6", "magic-string": "^0.30.11", @@ -4441,7 +4641,7 @@ "tinypool": "^1.0.0", "tinyrainbow": "^1.2.0", "vite": "^5.0.0", - "vite-node": "2.1.2", + "vite-node": "2.1.3", "why-is-node-running": "^2.3.0" }, "bin": { @@ -4456,8 +4656,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.2", - "@vitest/ui": "2.1.2", + "@vitest/browser": "2.1.3", + "@vitest/ui": "2.1.3", "happy-dom": "*", "jsdom": "*" }, @@ -4487,6 +4687,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4502,6 +4703,7 @@ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, + "license": "MIT", "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" @@ -4513,11 +4715,22 @@ "node": ">=8" } }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/wrap-ansi": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -4536,6 +4749,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4548,17 +4762,29 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/wrap-ansi-cjs/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4568,16 +4794,17 @@ "node": ">=8" } }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">=8" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { @@ -4585,6 +4812,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -4592,32 +4820,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, "node_modules/yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true, + "license": "ISC", "engines": { "node": ">= 6" } @@ -4627,6 +4835,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/frontend/package.json b/frontend/package.json index 96cd3ded..1647f6e8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,34 +15,34 @@ "test:unit": "vitest" }, "devDependencies": { - "@playwright/test": "1.48.0", + "@floating-ui/dom": "1.6.11", + "@playwright/test": "1.48.1", "@skeletonlabs/skeleton": "2.10.2", "@skeletonlabs/tw-plugin": "0.4.0", "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "2.7.0", + "@sveltejs/kit": "2.7.2", "@sveltejs/vite-plugin-svelte": "^3.1.2", "@tailwindcss/forms": "0.5.9", "@tailwindcss/typography": "0.5.15", - "@types/node": "22.7.5", + "@types/node": "22.7.7", "autoprefixer": "10.4.20", - "eslint": "^9.12.0", + "eslint": "^9.13.0", "eslint-config-prettier": "9.1.0", - "eslint-plugin-svelte": "2.44.1", + "eslint-plugin-svelte": "2.46.0", "flatbuffers": "24.3.25", "postcss": "8.4.47", "prettier": "3.3.3", "prettier-plugin-svelte": "3.2.7", "svelte": "4.2.19", "svelte-check": "4.0.5", - "tailwindcss": "3.4.13", - "tslib": "2.7.0", + "tailwindcss": "3.4.14", + "tslib": "2.8.0", "typescript": "5.6.3", - "vite": "^5.4.8", "vite-plugin-tailwind-purgecss": "^0.3.3", - "vitest": "2.1.2" + "vitest": "2.1.3" }, "type": "module", "dependencies": { - "@floating-ui/dom": "1.6.11" + "vite": "^5.4.9" } } From 92b1914be5bcff84c4a637ce8733560aac668672 Mon Sep 17 00:00:00 2001 From: HeavenVR Date: Mon, 21 Oct 2024 11:59:47 +0200 Subject: [PATCH 009/155] Switch to pnpm (#305) * Switch to pnpm * maybe fix * maybe fix * Oops, no cjs * Fix tests --- .github/actions/build-frontend/action.yml | 34 +- .github/scripts/get-vars.js | 10 +- .github/scripts/package-lock.json | 253 -- .github/scripts/package.json | 12 +- .github/scripts/pnpm-lock.yaml | 230 + .github/workflows/ci-build.yml | 2 + .github/workflows/get-vars.yml | 20 +- frontend/.npmrc | 3 +- frontend/.nvmrc | 1 + frontend/.prettierignore | 10 + frontend/.prettierrc | 2 +- frontend/package-lock.json | 4847 --------------------- frontend/package.json | 15 +- frontend/playwright.config.ts | 12 +- frontend/pnpm-lock.yaml | 2978 +++++++++++++ frontend/tests/test.ts | 6 +- scripts/build_frontend.py | 4 +- 17 files changed, 3303 insertions(+), 5136 deletions(-) delete mode 100644 .github/scripts/package-lock.json create mode 100644 .github/scripts/pnpm-lock.yaml create mode 100644 frontend/.nvmrc delete mode 100644 frontend/package-lock.json create mode 100644 frontend/pnpm-lock.yaml diff --git a/.github/actions/build-frontend/action.yml b/.github/actions/build-frontend/action.yml index b7a9be66..3ae1bccb 100644 --- a/.github/actions/build-frontend/action.yml +++ b/.github/actions/build-frontend/action.yml @@ -1,6 +1,9 @@ name: build-frontend description: Builds the frontend and uploads it as an artifact inputs: + pnpm-version: + description: 'pnpm version to use' + required: true node-version: description: 'NodeJS runtime version to use' required: true @@ -18,21 +21,42 @@ runs: frontend path: ${{ github.repository }} + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: ${{ inputs.pnpm-version }} + run_install: false + - uses: actions/setup-node@v4 with: - node-version: ${{ inputs.node-version }} - cache: 'npm' - cache-dependency-path: ./frontend/package-lock.json + node-version-file: ./frontend/.nvmrc + cache: 'pnpm' + cache-dependency-path: ./frontend/pnpm-lock.yaml - name: Install dependencies working-directory: ./frontend shell: bash - run: npm ci + run: pnpm install --frozen-lockfile --strict-peer-dependencies + + - name: Check + working-directory: ./frontend + shell: bash + run: pnpm run check + + - name: Install playwright + working-directory: ./frontend + shell: bash + run: pnpx playwright install --with-deps + + - name: Test + working-directory: ./frontend + shell: bash + run: pnpm test - name: Build working-directory: ./frontend shell: bash - run: npm run build + run: pnpm run build - name: Upload artifacts uses: actions/upload-artifact@v4 diff --git a/.github/scripts/get-vars.js b/.github/scripts/get-vars.js index b02ad581..309ff3b5 100644 --- a/.github/scripts/get-vars.js +++ b/.github/scripts/get-vars.js @@ -1,8 +1,8 @@ -const fs = require('fs'); -const ini = require('ini'); -const semver = require('semver'); -const core = require('@actions/core'); -const child_process = require('child_process'); +import fs from 'fs'; +import ini from 'ini'; +import semver from 'semver'; +import core from '@actions/core'; +import child_process from 'child_process'; // Get branch name const gitRef = process.env.GITHUB_REF; diff --git a/.github/scripts/package-lock.json b/.github/scripts/package-lock.json deleted file mode 100644 index 8380d45f..00000000 --- a/.github/scripts/package-lock.json +++ /dev/null @@ -1,253 +0,0 @@ -{ - "name": "get-variables", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "get-variables", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@actions/core": "^1.10.1", - "@actions/github": "^6.0.0", - "ini": "^5.0.0", - "semver": "^7.6.0" - } - }, - "node_modules/@actions/core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.11.1.tgz", - "integrity": "sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==", - "dependencies": { - "@actions/exec": "^1.1.1", - "@actions/http-client": "^2.0.1" - } - }, - "node_modules/@actions/exec": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz", - "integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==", - "dependencies": { - "@actions/io": "^1.0.1" - } - }, - "node_modules/@actions/github": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@actions/github/-/github-6.0.0.tgz", - "integrity": "sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==", - "dependencies": { - "@actions/http-client": "^2.2.0", - "@octokit/core": "^5.0.1", - "@octokit/plugin-paginate-rest": "^9.0.0", - "@octokit/plugin-rest-endpoint-methods": "^10.0.0" - } - }, - "node_modules/@actions/http-client": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.2.0.tgz", - "integrity": "sha512-q+epW0trjVUUHboliPb4UF9g2msf+w61b32tAkFEwL/IwP0DQWgbCMM0Hbe3e3WXSKz5VcUXbzJQgy8Hkra/Lg==", - "dependencies": { - "tunnel": "^0.0.6", - "undici": "^5.25.4" - } - }, - "node_modules/@actions/io": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.3.tgz", - "integrity": "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==" - }, - "node_modules/@fastify/busboy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.0.tgz", - "integrity": "sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@octokit/auth-token": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/core": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.2.tgz", - "integrity": "sha512-cZUy1gUvd4vttMic7C0lwPed8IYXWYp8kHIMatyhY8t8n3Cpw2ILczkV5pGMPqef7v0bLo0pOHrEHarsau2Ydg==", - "dependencies": { - "@octokit/auth-token": "^4.0.0", - "@octokit/graphql": "^7.0.0", - "@octokit/request": "^8.0.2", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/endpoint": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz", - "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==", - "dependencies": { - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/graphql": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", - "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", - "dependencies": { - "@octokit/request": "^8.0.1", - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz", - "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz", - "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==", - "dependencies": { - "@octokit/types": "^12.4.0" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "@octokit/core": ">=5" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.2.0.tgz", - "integrity": "sha512-ePbgBMYtGoRNXDyKGvr9cyHjQ163PbwD0y1MkDJCpkO2YH4OeXX40c4wYHKikHGZcpGPbcRLuy0unPUuafco8Q==", - "dependencies": { - "@octokit/types": "^12.3.0" - }, - "engines": { - "node": ">= 18" - }, - "peerDependencies": { - "@octokit/core": ">=5" - } - }, - "node_modules/@octokit/request": { - "version": "8.1.6", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz", - "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==", - "dependencies": { - "@octokit/endpoint": "^9.0.0", - "@octokit/request-error": "^5.0.0", - "@octokit/types": "^12.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/request-error": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", - "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", - "dependencies": { - "@octokit/types": "^12.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/@octokit/types": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz", - "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==", - "dependencies": { - "@octokit/openapi-types": "^19.1.0" - } - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - }, - "node_modules/ini": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", - "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, - "node_modules/undici": { - "version": "5.28.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz", - "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - } - } -} diff --git a/.github/scripts/package.json b/.github/scripts/package.json index 094d60a9..e7ca838c 100644 --- a/.github/scripts/package.json +++ b/.github/scripts/package.json @@ -1,17 +1,23 @@ { "name": "get-variables", "version": "1.0.0", - "description": "", + "private": true, + "type": "module", "main": "src/index.ts", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "", - "license": "ISC", "dependencies": { "@actions/core": "^1.10.1", "@actions/github": "^6.0.0", "ini": "^5.0.0", "semver": "^7.6.0" + }, + "engines": { + "node": ">=20.18", + "pnpm": ">=9" + }, + "volta": { + "node": "20.18.0" } } diff --git a/.github/scripts/pnpm-lock.yaml b/.github/scripts/pnpm-lock.yaml new file mode 100644 index 00000000..77830559 --- /dev/null +++ b/.github/scripts/pnpm-lock.yaml @@ -0,0 +1,230 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@actions/core': + specifier: ^1.10.1 + version: 1.11.1 + '@actions/github': + specifier: ^6.0.0 + version: 6.0.0 + ini: + specifier: ^5.0.0 + version: 5.0.0 + semver: + specifier: ^7.6.0 + version: 7.6.3 + +packages: + + '@actions/core@1.11.1': + resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==} + + '@actions/exec@1.1.1': + resolution: {integrity: sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==} + + '@actions/github@6.0.0': + resolution: {integrity: sha512-alScpSVnYmjNEXboZjarjukQEzgCRmjMv6Xj47fsdnqGS73bjJNDpiiXmp8jr0UZLdUB6d9jW63IcmddUP+l0g==} + + '@actions/http-client@2.2.3': + resolution: {integrity: sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==} + + '@actions/io@1.1.3': + resolution: {integrity: sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==} + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@octokit/auth-token@4.0.0': + resolution: {integrity: sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==} + engines: {node: '>= 18'} + + '@octokit/core@5.2.0': + resolution: {integrity: sha512-1LFfa/qnMQvEOAdzlQymH0ulepxbxnCYAKJZfMci/5XJyIHWgEYnDmgnKakbTh7CH2tFQ5O60oYDvns4i9RAIg==} + engines: {node: '>= 18'} + + '@octokit/endpoint@9.0.5': + resolution: {integrity: sha512-ekqR4/+PCLkEBF6qgj8WqJfvDq65RH85OAgrtnVp1mSxaXF03u2xW/hUdweGS5654IlC0wkNYC18Z50tSYTAFw==} + engines: {node: '>= 18'} + + '@octokit/graphql@7.1.0': + resolution: {integrity: sha512-r+oZUH7aMFui1ypZnAvZmn0KSqAUgE1/tUXIWaqUCa1758ts/Jio84GZuzsvUkme98kv0WFY8//n0J1Z+vsIsQ==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@20.0.0': + resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} + + '@octokit/openapi-types@22.2.0': + resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==} + + '@octokit/plugin-paginate-rest@9.2.1': + resolution: {integrity: sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/plugin-rest-endpoint-methods@10.4.1': + resolution: {integrity: sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '5' + + '@octokit/request-error@5.1.0': + resolution: {integrity: sha512-GETXfE05J0+7H2STzekpKObFe765O5dlAKUTLNGeH+x47z7JjXHfsHKo5z21D/o/IOZTUEI6nyWyR+bZVP/n5Q==} + engines: {node: '>= 18'} + + '@octokit/request@8.4.0': + resolution: {integrity: sha512-9Bb014e+m2TgBeEJGEbdplMVWwPmL1FPtggHQRkV+WVsMggPtEkLKPlcVYm/o8xKLkpJ7B+6N8WfQMtDLX2Dpw==} + engines: {node: '>= 18'} + + '@octokit/types@12.6.0': + resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} + + '@octokit/types@13.6.1': + resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==} + + before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + + deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + + ini@5.0.0: + resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==} + engines: {node: ^18.17.0 || >=20.5.0} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + +snapshots: + + '@actions/core@1.11.1': + dependencies: + '@actions/exec': 1.1.1 + '@actions/http-client': 2.2.3 + + '@actions/exec@1.1.1': + dependencies: + '@actions/io': 1.1.3 + + '@actions/github@6.0.0': + dependencies: + '@actions/http-client': 2.2.3 + '@octokit/core': 5.2.0 + '@octokit/plugin-paginate-rest': 9.2.1(@octokit/core@5.2.0) + '@octokit/plugin-rest-endpoint-methods': 10.4.1(@octokit/core@5.2.0) + + '@actions/http-client@2.2.3': + dependencies: + tunnel: 0.0.6 + undici: 5.28.4 + + '@actions/io@1.1.3': {} + + '@fastify/busboy@2.1.1': {} + + '@octokit/auth-token@4.0.0': {} + + '@octokit/core@5.2.0': + dependencies: + '@octokit/auth-token': 4.0.0 + '@octokit/graphql': 7.1.0 + '@octokit/request': 8.4.0 + '@octokit/request-error': 5.1.0 + '@octokit/types': 13.6.1 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + + '@octokit/endpoint@9.0.5': + dependencies: + '@octokit/types': 13.6.1 + universal-user-agent: 6.0.1 + + '@octokit/graphql@7.1.0': + dependencies: + '@octokit/request': 8.4.0 + '@octokit/types': 13.6.1 + universal-user-agent: 6.0.1 + + '@octokit/openapi-types@20.0.0': {} + + '@octokit/openapi-types@22.2.0': {} + + '@octokit/plugin-paginate-rest@9.2.1(@octokit/core@5.2.0)': + dependencies: + '@octokit/core': 5.2.0 + '@octokit/types': 12.6.0 + + '@octokit/plugin-rest-endpoint-methods@10.4.1(@octokit/core@5.2.0)': + dependencies: + '@octokit/core': 5.2.0 + '@octokit/types': 12.6.0 + + '@octokit/request-error@5.1.0': + dependencies: + '@octokit/types': 13.6.1 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request@8.4.0': + dependencies: + '@octokit/endpoint': 9.0.5 + '@octokit/request-error': 5.1.0 + '@octokit/types': 13.6.1 + universal-user-agent: 6.0.1 + + '@octokit/types@12.6.0': + dependencies: + '@octokit/openapi-types': 20.0.0 + + '@octokit/types@13.6.1': + dependencies: + '@octokit/openapi-types': 22.2.0 + + before-after-hook@2.2.3: {} + + deprecation@2.3.1: {} + + ini@5.0.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + semver@7.6.3: {} + + tunnel@0.0.6: {} + + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + + universal-user-agent@6.0.1: {} + + wrappy@1.0.2: {} diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 06e5d12f..bed80c7f 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -18,6 +18,7 @@ on: name: ci-build env: + PNPM_VERSION: 9 NODE_VERSION: 20 PYTHON_VERSION: 3.12 @@ -37,6 +38,7 @@ jobs: - uses: ./.github/actions/build-frontend with: + pnpm-version: ${{ env.PNPM_VERSION }} node-version: ${{ env.NODE_VERSION }} build-staticfs: diff --git a/.github/workflows/get-vars.yml b/.github/workflows/get-vars.yml index 857b0452..f41bbb68 100644 --- a/.github/workflows/get-vars.yml +++ b/.github/workflows/get-vars.yml @@ -8,9 +8,13 @@ on: workflow_call: inputs: + pnpm-version: + type: string + default: '9' + description: 'The pnpm version to use' node-version: type: string - default: '18' + default: '20' description: 'The Node.js version to use' outputs: version: @@ -88,16 +92,22 @@ jobs: sparse-checkout: | .github + - uses: pnpm/action-setup@v4 + name: Install pnpm + with: + version: ${{ inputs.pnpm-version }} + run_install: false + - uses: actions/setup-node@v4 with: - node-version: ${{ inputs.node-version }} - cache: 'npm' - cache-dependency-path: ./.github/scripts/package-lock.json + node-version-file: ./.github/scripts/package.json + cache: 'pnpm' + cache-dependency-path: ./.github/scripts/pnpm-lock.yaml - name: Install dependencies working-directory: ./.github/scripts shell: bash - run: npm ci + run: pnpm install --frozen-lockfile --strict-peer-dependencies - name: Get variables id: get-vars diff --git a/frontend/.npmrc b/frontend/.npmrc index 0c05da45..4fd02195 100644 --- a/frontend/.npmrc +++ b/frontend/.npmrc @@ -1,2 +1 @@ -engine-strict=true -resolution-mode=highest +engine-strict=true \ No newline at end of file diff --git a/frontend/.nvmrc b/frontend/.nvmrc new file mode 100644 index 00000000..c1302226 --- /dev/null +++ b/frontend/.nvmrc @@ -0,0 +1 @@ +20.18.0 \ No newline at end of file diff --git a/frontend/.prettierignore b/frontend/.prettierignore index 93cb960b..38972655 100644 --- a/frontend/.prettierignore +++ b/frontend/.prettierignore @@ -1,3 +1,13 @@ +.DS_Store +node_modules /build /.svelte-kit /package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/frontend/.prettierrc b/frontend/.prettierrc index b4f0a3d9..96ea822f 100644 --- a/frontend/.prettierrc +++ b/frontend/.prettierrc @@ -4,7 +4,7 @@ "useTabs": false, "singleQuote": true, "trailingComma": "es5", - "printWidth": 256, + "printWidth": 100, "plugins": ["prettier-plugin-svelte"], "pluginSearchDirs": ["."], "overrides": [ diff --git a/frontend/package-lock.json b/frontend/package-lock.json deleted file mode 100644 index e7c88625..00000000 --- a/frontend/package-lock.json +++ /dev/null @@ -1,4847 +0,0 @@ -{ - "name": "frontend", - "version": "0.0.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "frontend", - "version": "0.0.1", - "dependencies": { - "vite": "^5.4.9" - }, - "devDependencies": { - "@floating-ui/dom": "1.6.11", - "@playwright/test": "1.48.1", - "@skeletonlabs/skeleton": "2.10.2", - "@skeletonlabs/tw-plugin": "0.4.0", - "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "2.7.2", - "@sveltejs/vite-plugin-svelte": "^3.1.2", - "@tailwindcss/forms": "0.5.9", - "@tailwindcss/typography": "0.5.15", - "@types/node": "22.7.7", - "autoprefixer": "10.4.20", - "eslint": "^9.13.0", - "eslint-config-prettier": "9.1.0", - "eslint-plugin-svelte": "2.46.0", - "flatbuffers": "24.3.25", - "postcss": "8.4.47", - "prettier": "3.3.3", - "prettier-plugin-svelte": "3.2.7", - "svelte": "4.2.19", - "svelte-check": "4.0.5", - "tailwindcss": "3.4.14", - "tslib": "2.8.0", - "typescript": "5.6.3", - "vite-plugin-tailwind-purgecss": "^0.3.3", - "vitest": "2.1.3" - } - }, - "node_modules/@alloc/quick-lru": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", - "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.7.0.tgz", - "integrity": "sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/js": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.13.0.tgz", - "integrity": "sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz", - "integrity": "sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz", - "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/utils": "^0.2.8" - } - }, - "node_modules/@floating-ui/dom": { - "version": "1.6.11", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.11.tgz", - "integrity": "sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.6.0", - "@floating-ui/utils": "^0.2.8" - } - }, - "node_modules/@floating-ui/utils": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", - "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", - "dev": true, - "license": "MIT" - }, - "node_modules/@humanfs/core": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", - "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.5", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", - "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.0", - "@humanwhocodes/retry": "^0.3.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@playwright/test": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.1.tgz", - "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright": "1.48.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.28", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.28.tgz", - "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@skeletonlabs/skeleton": { - "version": "2.10.2", - "resolved": "https://registry.npmjs.org/@skeletonlabs/skeleton/-/skeleton-2.10.2.tgz", - "integrity": "sha512-TV2yWjvHpmtaF1F5luB8n7UbjKZcsrJMMiiJQHbZvqXjBWvudAcL8zywhE/NFKW5rYU//MtgOODdMZPZxvKu6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "esm-env": "1.0.0" - }, - "peerDependencies": { - "svelte": "^3.56.0 || ^4.0.0" - } - }, - "node_modules/@skeletonlabs/tw-plugin": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@skeletonlabs/tw-plugin/-/tw-plugin-0.4.0.tgz", - "integrity": "sha512-v6Y4deBq9ByRx3kTRGgekhhYkWEYgNNNu8UXOwJngCStB7w8SwmbNFSeHkluxMbgCgMnJyp220EMpw9nj/rEsQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "tailwindcss": ">=3.0.0" - } - }, - "node_modules/@sveltejs/adapter-static": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.5.tgz", - "integrity": "sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@sveltejs/kit": "^2.0.0" - } - }, - "node_modules/@sveltejs/kit": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.7.2.tgz", - "integrity": "sha512-bFwrl+0bNr0/DHQZM0INwwSPNYqDjfsKRhUoa6rj9d8tDZzszBrJ3La6/HVFxWGONEigtG+SzHXa1BEa1BLdwA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@types/cookie": "^0.6.0", - "cookie": "^0.6.0", - "devalue": "^5.1.0", - "esm-env": "^1.0.0", - "import-meta-resolve": "^4.1.0", - "kleur": "^4.1.5", - "magic-string": "^0.30.5", - "mrmime": "^2.0.0", - "sade": "^1.8.1", - "set-cookie-parser": "^2.6.0", - "sirv": "^3.0.0", - "tiny-glob": "^0.2.9" - }, - "bin": { - "svelte-kit": "svelte-kit.js" - }, - "engines": { - "node": ">=18.13" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.3" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.2.tgz", - "integrity": "sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", - "debug": "^4.3.4", - "deepmerge": "^4.3.1", - "kleur": "^4.1.5", - "magic-string": "^0.30.10", - "svelte-hmr": "^0.16.0", - "vitefu": "^0.2.5" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@sveltejs/vite-plugin-svelte-inspector": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", - "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.0.0 || >=20" - }, - "peerDependencies": { - "@sveltejs/vite-plugin-svelte": "^3.0.0", - "svelte": "^4.0.0 || ^5.0.0-next.0", - "vite": "^5.0.0" - } - }, - "node_modules/@tailwindcss/forms": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.9.tgz", - "integrity": "sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mini-svg-data-uri": "^1.2.3" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20" - } - }, - "node_modules/@tailwindcss/typography": { - "version": "0.5.15", - "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.15.tgz", - "integrity": "sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.castarray": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.merge": "^4.6.2", - "postcss-selector-parser": "6.0.10" - }, - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20" - } - }, - "node_modules/@types/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.7.tgz", - "integrity": "sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@vitest/expect": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.3.tgz", - "integrity": "sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "2.1.3", - "@vitest/utils": "2.1.3", - "chai": "^5.1.1", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/mocker": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.3.tgz", - "integrity": "sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "2.1.3", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.11" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@vitest/spy": "2.1.3", - "msw": "^2.3.5", - "vite": "^5.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/@vitest/pretty-format": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.3.tgz", - "integrity": "sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.3.tgz", - "integrity": "sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "2.1.3", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.3.tgz", - "integrity": "sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.1.3", - "magic-string": "^0.30.11", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.3.tgz", - "integrity": "sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^3.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.3.tgz", - "integrity": "sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.1.3", - "loupe": "^3.1.1", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/acorn": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", - "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", - "dev": true, - "license": "MIT" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/anymatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/autoprefixer": { - "version": "10.4.20", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", - "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "browserslist": "^4.23.3", - "caniuse-lite": "^1.0.30001646", - "fraction.js": "^4.3.7", - "normalize-range": "^0.1.2", - "picocolors": "^1.0.1", - "postcss-value-parser": "^4.2.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/axobject-query": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", - "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001669", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz", - "integrity": "sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chai": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.1.1.tgz", - "integrity": "sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, - "node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", - "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", - "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/devalue": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.1.1.tgz", - "integrity": "sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==", - "dev": true, - "license": "MIT" - }, - "node_modules/didyoumean": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", - "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true, - "license": "MIT" - }, - "node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "^2.3.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.41", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.41.tgz", - "integrity": "sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.13.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.13.0.tgz", - "integrity": "sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.7.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.13.0", - "@eslint/plugin-kit": "^0.2.0", - "@humanfs/node": "^0.16.5", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.1", - "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.1.0", - "eslint-visitor-keys": "^4.1.0", - "espree": "^10.2.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-compat-utils": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", - "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.4" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-plugin-svelte": { - "version": "2.46.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.46.0.tgz", - "integrity": "sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@jridgewell/sourcemap-codec": "^1.4.15", - "eslint-compat-utils": "^0.5.1", - "esutils": "^2.0.3", - "known-css-properties": "^0.35.0", - "postcss": "^8.4.38", - "postcss-load-config": "^3.1.4", - "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.1.0", - "semver": "^7.6.2", - "svelte-eslint-parser": "^0.43.0" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-svelte/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-scope": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", - "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", - "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esm-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esm-env/-/esm-env-1.0.0.tgz", - "integrity": "sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/espree": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", - "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fdir": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", - "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatbuffers": { - "version": "24.3.25", - "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-24.3.25.tgz", - "integrity": "sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fraction.js": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - }, - "funding": { - "type": "patreon", - "url": "https://github.com/sponsors/rawify" - } - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalyzer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", - "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/globrex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", - "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-meta-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", - "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-reference": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", - "dev": true, - "license": "MIT", - "bin": { - "jiti": "bin/jiti.js" - } - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/known-css-properties": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz", - "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==", - "dev": true, - "license": "MIT" - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lilconfig": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-character": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", - "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==", - "dev": true, - "license": "MIT" - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.castarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz", - "integrity": "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/loupe": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.2.tgz", - "integrity": "sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/magic-string": { - "version": "0.30.12", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.12.tgz", - "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/mini-svg-data-uri": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz", - "integrity": "sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==", - "dev": true, - "license": "MIT", - "bin": { - "mini-svg-data-uri": "cli.js" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/mrmime": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", - "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, - "license": "BlueOak-1.0.0" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse5": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.0.tgz", - "integrity": "sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^4.5.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "domhandler": "^5.0.3", - "parse5": "^7.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz", - "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "optional": true, - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/playwright": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.1.tgz", - "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "playwright-core": "1.48.1" - }, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/playwright-core": { - "version": "1.48.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz", - "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "playwright-core": "cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-import": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", - "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", - "dev": true, - "license": "MIT", - "dependencies": { - "postcss-value-parser": "^4.0.0", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "postcss": "^8.0.0" - } - }, - "node_modules/postcss-js": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz", - "integrity": "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase-css": "^2.0.1" - }, - "engines": { - "node": "^12 || ^14 || >= 16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.4.21" - } - }, - "node_modules/postcss-load-config": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", - "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lilconfig": "^2.0.5", - "yaml": "^1.10.2" - }, - "engines": { - "node": ">= 10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/postcss-nested": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", - "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "postcss-selector-parser": "^6.1.1" - }, - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.2.14" - } - }, - "node_modules/postcss-nested/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, - "node_modules/postcss-scss": { - "version": "4.0.9", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz", - "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss-scss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "engines": { - "node": ">=12.0" - }, - "peerDependencies": { - "postcss": "^8.4.29" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-plugin-svelte": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/prettier-plugin-svelte/-/prettier-plugin-svelte-3.2.7.tgz", - "integrity": "sha512-/Dswx/ea0lV34If1eDcG3nulQ63YNr5KPDfMsjbdtpSWOxKKJ7nAc2qlVuYwEvCr4raIuredNoR7K4JCkmTGaQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "prettier": "^3.0.0", - "svelte": "^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/purgecss": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-6.0.0.tgz", - "integrity": "sha512-s3EBxg5RSWmpqd0KGzNqPiaBbWDz1/As+2MzoYVGMqgDqRTLBhJW6sywfTBek7OwNfoS/6pS0xdtvChNhFj2cw==", - "dev": true, - "license": "MIT", - "dependencies": { - "commander": "^12.0.0", - "glob": "^10.3.10", - "postcss": "^8.4.4", - "postcss-selector-parser": "^6.0.7" - }, - "bin": { - "purgecss": "bin/purgecss.js" - } - }, - "node_modules/purgecss-from-html": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/purgecss-from-html/-/purgecss-from-html-6.0.0.tgz", - "integrity": "sha512-GkgAUzgyC4kwcVY5+QOI2eqQghV1Lq7q2uIODAPIueiBn3mHpJOh9boSMjfUQg0/YU/ZEWq7SzjwetuqxTvD4g==", - "dev": true, - "license": "ISC", - "dependencies": { - "parse5": "^7.1.2", - "parse5-htmlparser2-tree-adapter": "^7.0.0" - } - }, - "node_modules/purgecss/node_modules/commander": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", - "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^2.3.0" - } - }, - "node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "mri": "^1.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.0.tgz", - "integrity": "sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sirv": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-3.0.0.tgz", - "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@polka/url": "^1.0.0-next.24", - "mrmime": "^2.0.0", - "totalist": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sucrase": { - "version": "3.35.0", - "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", - "integrity": "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.2", - "commander": "^4.0.0", - "glob": "^10.3.10", - "lines-and-columns": "^1.1.6", - "mz": "^2.7.0", - "pirates": "^4.0.1", - "ts-interface-checker": "^0.1.9" - }, - "bin": { - "sucrase": "bin/sucrase", - "sucrase-node": "bin/sucrase-node" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svelte": { - "version": "4.2.19", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.19.tgz", - "integrity": "sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "@types/estree": "^1.0.1", - "acorn": "^8.9.0", - "aria-query": "^5.3.0", - "axobject-query": "^4.0.0", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", - "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/svelte-check": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-4.0.5.tgz", - "integrity": "sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "chokidar": "^4.0.1", - "fdir": "^6.2.0", - "picocolors": "^1.0.0", - "sade": "^1.7.4" - }, - "bin": { - "svelte-check": "bin/svelte-check" - }, - "engines": { - "node": ">= 18.0.0" - }, - "peerDependencies": { - "svelte": "^4.0.0 || ^5.0.0-next.0", - "typescript": ">=5.0.0" - } - }, - "node_modules/svelte-eslint-parser": { - "version": "0.43.0", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.43.0.tgz", - "integrity": "sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "postcss": "^8.4.39", - "postcss-scss": "^4.0.9" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - } - } - }, - "node_modules/svelte-eslint-parser/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/svelte-eslint-parser/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/svelte-eslint-parser/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/svelte-hmr": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", - "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^12.20 || ^14.13.1 || >= 16" - }, - "peerDependencies": { - "svelte": "^3.19.0 || ^4.0.0" - } - }, - "node_modules/tailwindcss": { - "version": "3.4.14", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", - "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@alloc/quick-lru": "^5.2.0", - "arg": "^5.0.2", - "chokidar": "^3.5.3", - "didyoumean": "^1.2.2", - "dlv": "^1.1.3", - "fast-glob": "^3.3.0", - "glob-parent": "^6.0.2", - "is-glob": "^4.0.3", - "jiti": "^1.21.0", - "lilconfig": "^2.1.0", - "micromatch": "^4.0.5", - "normalize-path": "^3.0.0", - "object-hash": "^3.0.0", - "picocolors": "^1.0.0", - "postcss": "^8.4.23", - "postcss-import": "^15.1.0", - "postcss-js": "^4.0.1", - "postcss-load-config": "^4.0.1", - "postcss-nested": "^6.0.1", - "postcss-selector-parser": "^6.0.11", - "resolve": "^1.22.2", - "sucrase": "^3.32.0" - }, - "bin": { - "tailwind": "lib/cli.js", - "tailwindcss": "lib/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tailwindcss/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/tailwindcss/node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/tailwindcss/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/tailwindcss/node_modules/postcss-load-config": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz", - "integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "lilconfig": "^3.0.0", - "yaml": "^2.3.4" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "postcss": ">=8.0.9", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "postcss": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/tailwindcss/node_modules/postcss-load-config/node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, - "node_modules/tailwindcss/node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tailwindcss/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/tailwindcss/node_modules/yaml": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", - "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", - "dev": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tiny-glob": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", - "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "globalyzer": "0.1.0", - "globrex": "^0.1.2" - } - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz", - "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinypool": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", - "integrity": "sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/totalist": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ts-interface-checker": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", - "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/tslib": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", - "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==", - "dev": true, - "license": "0BSD" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/vite": { - "version": "5.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.9.tgz", - "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.3.tgz", - "integrity": "sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.6", - "pathe": "^1.1.2", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vite-plugin-tailwind-purgecss": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/vite-plugin-tailwind-purgecss/-/vite-plugin-tailwind-purgecss-0.3.3.tgz", - "integrity": "sha512-fsTAzcSdFKrhLxX8zTq3zaTFjk+APmJWOAy+1ujsmxkh9y8hIvM81dWEgdXK1k7suQjns+b7JsoIUkHpxLf5UA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^5.3.0", - "css-tree": "^2.3.1", - "fast-glob": "^3.3.2", - "purgecss": "^6.0.0", - "purgecss-from-html": "^6.0.0" - }, - "peerDependencies": { - "tailwindcss": "^3.3.0", - "vite": "^4.1.1 || ^5.0.0" - } - }, - "node_modules/vite-plugin-tailwind-purgecss/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/vite/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/vitefu": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", - "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } - } - }, - "node_modules/vitest": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.3.tgz", - "integrity": "sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "2.1.3", - "@vitest/mocker": "2.1.3", - "@vitest/pretty-format": "^2.1.3", - "@vitest/runner": "2.1.3", - "@vitest/snapshot": "2.1.3", - "@vitest/spy": "2.1.3", - "@vitest/utils": "2.1.3", - "chai": "^5.1.1", - "debug": "^4.3.6", - "magic-string": "^0.30.11", - "pathe": "^1.1.2", - "std-env": "^3.7.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.0", - "tinypool": "^1.0.0", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.1.3", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.3", - "@vitest/ui": "2.1.3", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/frontend/package.json b/frontend/package.json index 1647f6e8..45ccccdf 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -2,15 +2,16 @@ "name": "frontend", "version": "0.0.1", "private": true, + "type": "module", "scripts": { "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "test": "npm run test:integration && npm run test:unit", + "test": "pnpm run test:integration && pnpm run test:unit", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", - "lint": "prettier --plugin-search-dir . --check . && eslint .", - "format": "prettier --plugin-search-dir . --write .", + "lint": "prettier --check . && eslint .", + "format": "prettier --write .", "test:integration": "playwright test", "test:unit": "vitest" }, @@ -41,8 +42,14 @@ "vite-plugin-tailwind-purgecss": "^0.3.3", "vitest": "2.1.3" }, - "type": "module", "dependencies": { "vite": "^5.4.9" + }, + "engines": { + "node": ">=20.18", + "pnpm": ">=9" + }, + "volta": { + "node": "20.18.0" } } diff --git a/frontend/playwright.config.ts b/frontend/playwright.config.ts index 1c5d7a1f..7917352f 100644 --- a/frontend/playwright.config.ts +++ b/frontend/playwright.config.ts @@ -1,12 +1,12 @@ import type { PlaywrightTestConfig } from '@playwright/test'; const config: PlaywrightTestConfig = { - webServer: { - command: 'npm run build && npm run preview', - port: 4173 - }, - testDir: 'tests', - testMatch: /(.+\.)?(test|spec)\.[jt]s/ + webServer: { + command: 'pnpm run build && pnpm run preview', + port: 4173, + }, + testDir: 'tests', + testMatch: /(.+\.)?(test|spec)\.[jt]s/, }; export default config; diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml new file mode 100644 index 00000000..294ad71b --- /dev/null +++ b/frontend/pnpm-lock.yaml @@ -0,0 +1,2978 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + vite: + specifier: ^5.4.9 + version: 5.4.9(@types/node@22.7.7) + devDependencies: + '@floating-ui/dom': + specifier: 1.6.11 + version: 1.6.11 + '@playwright/test': + specifier: 1.48.1 + version: 1.48.1 + '@skeletonlabs/skeleton': + specifier: 2.10.2 + version: 2.10.2(svelte@4.2.19) + '@skeletonlabs/tw-plugin': + specifier: 0.4.0 + version: 0.4.0(tailwindcss@3.4.14) + '@sveltejs/adapter-static': + specifier: ^3.0.5 + version: 3.0.5(@sveltejs/kit@2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))) + '@sveltejs/kit': + specifier: 2.7.2 + version: 2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + '@sveltejs/vite-plugin-svelte': + specifier: ^3.1.2 + version: 3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + '@tailwindcss/forms': + specifier: 0.5.9 + version: 0.5.9(tailwindcss@3.4.14) + '@tailwindcss/typography': + specifier: 0.5.15 + version: 0.5.15(tailwindcss@3.4.14) + '@types/node': + specifier: 22.7.7 + version: 22.7.7 + autoprefixer: + specifier: 10.4.20 + version: 10.4.20(postcss@8.4.47) + eslint: + specifier: ^9.13.0 + version: 9.13.0(jiti@1.21.6) + eslint-config-prettier: + specifier: 9.1.0 + version: 9.1.0(eslint@9.13.0(jiti@1.21.6)) + eslint-plugin-svelte: + specifier: 2.46.0 + version: 2.46.0(eslint@9.13.0(jiti@1.21.6))(svelte@4.2.19) + flatbuffers: + specifier: 24.3.25 + version: 24.3.25 + postcss: + specifier: 8.4.47 + version: 8.4.47 + prettier: + specifier: 3.3.3 + version: 3.3.3 + prettier-plugin-svelte: + specifier: 3.2.7 + version: 3.2.7(prettier@3.3.3)(svelte@4.2.19) + svelte: + specifier: 4.2.19 + version: 4.2.19 + svelte-check: + specifier: 4.0.5 + version: 4.0.5(svelte@4.2.19)(typescript@5.6.3) + tailwindcss: + specifier: 3.4.14 + version: 3.4.14 + tslib: + specifier: 2.8.0 + version: 2.8.0 + typescript: + specifier: 5.6.3 + version: 5.6.3 + vite-plugin-tailwind-purgecss: + specifier: ^0.3.3 + version: 0.3.3(tailwindcss@3.4.14)(vite@5.4.9(@types/node@22.7.7)) + vitest: + specifier: 2.1.3 + version: 2.1.3(@types/node@22.7.7) + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.7.0': + resolution: {integrity: sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.13.0': + resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.1': + resolution: {integrity: sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@floating-ui/core@1.6.8': + resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} + + '@floating-ui/dom@1.6.11': + resolution: {integrity: sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==} + + '@floating-ui/utils@0.2.8': + resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} + + '@humanfs/core@0.19.0': + resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.5': + resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@playwright/test@1.48.1': + resolution: {integrity: sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==} + engines: {node: '>=18'} + hasBin: true + + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + + '@rollup/rollup-android-arm-eabi@4.24.0': + resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.24.0': + resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.24.0': + resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.24.0': + resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.24.0': + resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.24.0': + resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.24.0': + resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.24.0': + resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.24.0': + resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.24.0': + resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.24.0': + resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.24.0': + resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.24.0': + resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.24.0': + resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} + cpu: [x64] + os: [win32] + + '@skeletonlabs/skeleton@2.10.2': + resolution: {integrity: sha512-TV2yWjvHpmtaF1F5luB8n7UbjKZcsrJMMiiJQHbZvqXjBWvudAcL8zywhE/NFKW5rYU//MtgOODdMZPZxvKu6w==} + peerDependencies: + svelte: ^3.56.0 || ^4.0.0 + + '@skeletonlabs/tw-plugin@0.4.0': + resolution: {integrity: sha512-v6Y4deBq9ByRx3kTRGgekhhYkWEYgNNNu8UXOwJngCStB7w8SwmbNFSeHkluxMbgCgMnJyp220EMpw9nj/rEsQ==} + peerDependencies: + tailwindcss: '>=3.0.0' + + '@sveltejs/adapter-static@3.0.5': + resolution: {integrity: sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==} + peerDependencies: + '@sveltejs/kit': ^2.0.0 + + '@sveltejs/kit@2.7.2': + resolution: {integrity: sha512-bFwrl+0bNr0/DHQZM0INwwSPNYqDjfsKRhUoa6rj9d8tDZzszBrJ3La6/HVFxWGONEigtG+SzHXa1BEa1BLdwA==} + engines: {node: '>=18.13'} + hasBin: true + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.3 + + '@sveltejs/vite-plugin-svelte-inspector@2.1.0': + resolution: {integrity: sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==} + engines: {node: ^18.0.0 || >=20} + peerDependencies: + '@sveltejs/vite-plugin-svelte': ^3.0.0 + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 + + '@sveltejs/vite-plugin-svelte@3.1.2': + resolution: {integrity: sha512-Txsm1tJvtiYeLUVRNqxZGKR/mI+CzuIQuc2gn+YCs9rMTowpNZ2Nqt53JdL8KF9bLhAf2ruR/dr9eZCwdTriRA==} + engines: {node: ^18.0.0 || >=20} + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + vite: ^5.0.0 + + '@tailwindcss/forms@0.5.9': + resolution: {integrity: sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==} + peerDependencies: + tailwindcss: '>=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20' + + '@tailwindcss/typography@0.5.15': + resolution: {integrity: sha512-AqhlCXl+8grUz8uqExv5OTtgpjuVIwFTSXTrh8y9/pw6q2ek7fJ+Y8ZEVw7EB2DCcuCOtEjf9w3+J3rzts01uA==} + peerDependencies: + tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20' + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@22.7.7': + resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} + + '@vitest/expect@2.1.3': + resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} + + '@vitest/mocker@2.1.3': + resolution: {integrity: sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==} + peerDependencies: + '@vitest/spy': 2.1.3 + msw: ^2.3.5 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.3': + resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} + + '@vitest/runner@2.1.3': + resolution: {integrity: sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==} + + '@vitest/snapshot@2.1.3': + resolution: {integrity: sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==} + + '@vitest/spy@2.1.3': + resolution: {integrity: sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==} + + '@vitest/utils@2.1.3': + resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.0: + resolution: {integrity: sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} + + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + + code-red@1.0.4: + resolution: {integrity: sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + devalue@5.1.1: + resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + electron-to-chromium@1.5.41: + resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-svelte@2.46.0: + resolution: {integrity: sha512-1A7iEMkzmCZ9/Iz+EAfOGYL8IoIG6zeKEq1SmpxGeM5SXmoQq+ZNnCpXFVJpsxPWYx8jIVGMerQMzX20cqUl0g==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0-0 || ^9.0.0-0 + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + svelte: + optional: true + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-scope@8.1.0: + resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.1.0: + resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.13.0: + resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + esm-env@1.0.0: + resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} + + espree@10.2.0: + resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatbuffers@24.3.25: + resolution: {integrity: sha512-3HDgPbgiwWMI9zVB7VYBHaMrbOO7Gm0v+yD2FV/sCKj+9NDeVL7BOBYUuhWAQGKWOzBo8S9WdMvV0eixO233XQ==} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalyzer@0.1.0: + resolution: {integrity: sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==} + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-meta-resolve@4.1.0: + resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-reference@3.0.2: + resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + known-css-properties@0.35.0: + resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + locate-character@3.0.0: + resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.castarray@4.4.0: + resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loupe@3.1.2: + resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mini-svg-data-uri@1.4.4: + resolution: {integrity: sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==} + hasBin: true + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5@7.2.0: + resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + periscopic@3.1.0: + resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + playwright-core@1.48.1: + resolution: {integrity: sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==} + engines: {node: '>=18'} + hasBin: true + + playwright@1.48.1: + resolution: {integrity: sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==} + engines: {node: '>=18'} + hasBin: true + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.0.1: + resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-load-config@4.0.2: + resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-safe-parser@6.0.0: + resolution: {integrity: sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.3.3 + + postcss-scss@4.0.9: + resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.4.29 + + postcss-selector-parser@6.0.10: + resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} + engines: {node: '>=4'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.47: + resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-plugin-svelte@3.2.7: + resolution: {integrity: sha512-/Dswx/ea0lV34If1eDcG3nulQ63YNr5KPDfMsjbdtpSWOxKKJ7nAc2qlVuYwEvCr4raIuredNoR7K4JCkmTGaQ==} + peerDependencies: + prettier: ^3.0.0 + svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0 + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + purgecss-from-html@6.0.0: + resolution: {integrity: sha512-GkgAUzgyC4kwcVY5+QOI2eqQghV1Lq7q2uIODAPIueiBn3mHpJOh9boSMjfUQg0/YU/ZEWq7SzjwetuqxTvD4g==} + + purgecss@6.0.0: + resolution: {integrity: sha512-s3EBxg5RSWmpqd0KGzNqPiaBbWDz1/As+2MzoYVGMqgDqRTLBhJW6sywfTBek7OwNfoS/6pS0xdtvChNhFj2cw==} + hasBin: true + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.24.0: + resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + set-cookie-parser@2.7.0: + resolution: {integrity: sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sirv@3.0.0: + resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} + engines: {node: '>=18'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svelte-check@4.0.5: + resolution: {integrity: sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==} + engines: {node: '>= 18.0.0'} + hasBin: true + peerDependencies: + svelte: ^4.0.0 || ^5.0.0-next.0 + typescript: '>=5.0.0' + + svelte-eslint-parser@0.43.0: + resolution: {integrity: sha512-GpU52uPKKcVnh8tKN5P4UZpJ/fUDndmq7wfsvoVXsyP+aY0anol7Yqo01fyrlaWGMFfm4av5DyrjlaXdLRJvGA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + svelte: + optional: true + + svelte-hmr@0.16.0: + resolution: {integrity: sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==} + engines: {node: ^12.20 || ^14.13.1 || >= 16} + peerDependencies: + svelte: ^3.19.0 || ^4.0.0 + + svelte@4.2.19: + resolution: {integrity: sha512-IY1rnGr6izd10B0A8LqsBfmlT5OILVuZ7XsI0vdGPEvuonFV7NYEUK4dAkm9Zg2q0Um92kYjTpS1CAP3Nh/KWw==} + engines: {node: '>=16'} + + tailwindcss@3.4.14: + resolution: {integrity: sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==} + engines: {node: '>=14.0.0'} + hasBin: true + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tiny-glob@0.2.9: + resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite-node@2.1.3: + resolution: {integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-plugin-tailwind-purgecss@0.3.3: + resolution: {integrity: sha512-fsTAzcSdFKrhLxX8zTq3zaTFjk+APmJWOAy+1ujsmxkh9y8hIvM81dWEgdXK1k7suQjns+b7JsoIUkHpxLf5UA==} + peerDependencies: + tailwindcss: ^3.3.0 + vite: ^4.1.1 || ^5.0.0 + + vite@5.4.9: + resolution: {integrity: sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitefu@0.2.5: + resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + vite: + optional: true + + vitest@2.1.3: + resolution: {integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.3 + '@vitest/ui': 2.1.3 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + + yaml@2.6.0: + resolution: {integrity: sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==} + engines: {node: '>= 14'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@9.13.0(jiti@1.21.6))': + dependencies: + eslint: 9.13.0(jiti@1.21.6) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.1': {} + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.7.0': {} + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 10.2.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.13.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.1': + dependencies: + levn: 0.4.1 + + '@floating-ui/core@1.6.8': + dependencies: + '@floating-ui/utils': 0.2.8 + + '@floating-ui/dom@1.6.11': + dependencies: + '@floating-ui/core': 1.6.8 + '@floating-ui/utils': 0.2.8 + + '@floating-ui/utils@0.2.8': {} + + '@humanfs/core@0.19.0': {} + + '@humanfs/node@0.16.5': + dependencies: + '@humanfs/core': 0.19.0 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@playwright/test@1.48.1': + dependencies: + playwright: 1.48.1 + + '@polka/url@1.0.0-next.28': {} + + '@rollup/rollup-android-arm-eabi@4.24.0': + optional: true + + '@rollup/rollup-android-arm64@4.24.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.24.0': + optional: true + + '@rollup/rollup-darwin-x64@4.24.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.24.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.24.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.24.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.24.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.24.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.24.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.24.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.24.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.24.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.24.0': + optional: true + + '@skeletonlabs/skeleton@2.10.2(svelte@4.2.19)': + dependencies: + esm-env: 1.0.0 + svelte: 4.2.19 + + '@skeletonlabs/tw-plugin@0.4.0(tailwindcss@3.4.14)': + dependencies: + tailwindcss: 3.4.14 + + '@sveltejs/adapter-static@3.0.5(@sveltejs/kit@2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))': + dependencies: + '@sveltejs/kit': 2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + + '@sveltejs/kit@2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))': + dependencies: + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + '@types/cookie': 0.6.0 + cookie: 0.6.0 + devalue: 5.1.1 + esm-env: 1.0.0 + import-meta-resolve: 4.1.0 + kleur: 4.1.5 + magic-string: 0.30.12 + mrmime: 2.0.0 + sade: 1.8.1 + set-cookie-parser: 2.7.0 + sirv: 3.0.0 + svelte: 4.2.19 + tiny-glob: 0.2.9 + vite: 5.4.9(@types/node@22.7.7) + + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))': + dependencies: + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + debug: 4.3.7 + svelte: 4.2.19 + vite: 5.4.9(@types/node@22.7.7) + transitivePeerDependencies: + - supports-color + + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))': + dependencies: + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + debug: 4.3.7 + deepmerge: 4.3.1 + kleur: 4.1.5 + magic-string: 0.30.12 + svelte: 4.2.19 + svelte-hmr: 0.16.0(svelte@4.2.19) + vite: 5.4.9(@types/node@22.7.7) + vitefu: 0.2.5(vite@5.4.9(@types/node@22.7.7)) + transitivePeerDependencies: + - supports-color + + '@tailwindcss/forms@0.5.9(tailwindcss@3.4.14)': + dependencies: + mini-svg-data-uri: 1.4.4 + tailwindcss: 3.4.14 + + '@tailwindcss/typography@0.5.15(tailwindcss@3.4.14)': + dependencies: + lodash.castarray: 4.4.0 + lodash.isplainobject: 4.0.6 + lodash.merge: 4.6.2 + postcss-selector-parser: 6.0.10 + tailwindcss: 3.4.14 + + '@types/cookie@0.6.0': {} + + '@types/estree@1.0.6': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@22.7.7': + dependencies: + undici-types: 6.19.8 + + '@vitest/expect@2.1.3': + dependencies: + '@vitest/spy': 2.1.3 + '@vitest/utils': 2.1.3 + chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.7))': + dependencies: + '@vitest/spy': 2.1.3 + estree-walker: 3.0.3 + magic-string: 0.30.12 + optionalDependencies: + vite: 5.4.9(@types/node@22.7.7) + + '@vitest/pretty-format@2.1.3': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.3': + dependencies: + '@vitest/utils': 2.1.3 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.3': + dependencies: + '@vitest/pretty-format': 2.1.3 + magic-string: 0.30.12 + pathe: 1.1.2 + + '@vitest/spy@2.1.3': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.3': + dependencies: + '@vitest/pretty-format': 2.1.3 + loupe: 3.1.2 + tinyrainbow: 1.2.0 + + acorn-jsx@5.3.2(acorn@8.13.0): + dependencies: + acorn: 8.13.0 + + acorn@8.13.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + assertion-error@2.0.1: {} + + autoprefixer@10.4.20(postcss@8.4.47): + dependencies: + browserslist: 4.24.0 + caniuse-lite: 1.0.30001669 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.0: + dependencies: + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.41 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.0) + + cac@6.7.14: {} + + callsites@3.1.0: {} + + camelcase-css@2.0.1: {} + + caniuse-lite@1.0.30001669: {} + + chai@5.1.1: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.2 + pathval: 2.0.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + check-error@2.1.1: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + + code-red@1.0.4: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + '@types/estree': 1.0.6 + acorn: 8.13.0 + estree-walker: 3.0.3 + periscopic: 3.1.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@12.1.0: {} + + commander@4.1.1: {} + + concat-map@0.0.1: {} + + cookie@0.6.0: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + cssesc@3.0.0: {} + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + devalue@5.1.1: {} + + didyoumean@1.2.2: {} + + dlv@1.1.3: {} + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + eastasianwidth@0.2.0: {} + + electron-to-chromium@1.5.41: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + entities@4.5.0: {} + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-compat-utils@0.5.1(eslint@9.13.0(jiti@1.21.6)): + dependencies: + eslint: 9.13.0(jiti@1.21.6) + semver: 7.6.3 + + eslint-config-prettier@9.1.0(eslint@9.13.0(jiti@1.21.6)): + dependencies: + eslint: 9.13.0(jiti@1.21.6) + + eslint-plugin-svelte@2.46.0(eslint@9.13.0(jiti@1.21.6))(svelte@4.2.19): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + '@jridgewell/sourcemap-codec': 1.5.0 + eslint: 9.13.0(jiti@1.21.6) + eslint-compat-utils: 0.5.1(eslint@9.13.0(jiti@1.21.6)) + esutils: 2.0.3 + known-css-properties: 0.35.0 + postcss: 8.4.47 + postcss-load-config: 3.1.4(postcss@8.4.47) + postcss-safe-parser: 6.0.0(postcss@8.4.47) + postcss-selector-parser: 6.1.2 + semver: 7.6.3 + svelte-eslint-parser: 0.43.0(svelte@4.2.19) + optionalDependencies: + svelte: 4.2.19 + transitivePeerDependencies: + - ts-node + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-scope@8.1.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.1.0: {} + + eslint@9.13.0(jiti@1.21.6): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + '@eslint-community/regexpp': 4.11.1 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.7.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.13.0 + '@eslint/plugin-kit': 0.2.1 + '@humanfs/node': 0.16.5 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.7 + escape-string-regexp: 4.0.0 + eslint-scope: 8.1.0 + eslint-visitor-keys: 4.1.0 + espree: 10.2.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + text-table: 0.2.0 + optionalDependencies: + jiti: 1.21.6 + transitivePeerDependencies: + - supports-color + + esm-env@1.0.0: {} + + espree@10.2.0: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 4.1.0 + + espree@9.6.1: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 3.4.3 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fdir@6.4.2: {} + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatbuffers@24.3.25: {} + + flatted@3.3.1: {} + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + fraction.js@4.3.7: {} + + fsevents@2.3.2: + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globals@14.0.0: {} + + globalyzer@0.1.0: {} + + globrex@0.1.2: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-meta-resolve@4.1.0: {} + + imurmurhash@0.1.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-reference@3.0.2: + dependencies: + '@types/estree': 1.0.6 + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.6: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@4.1.5: {} + + known-css-properties@0.35.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@2.1.0: {} + + lilconfig@3.1.2: {} + + lines-and-columns@1.2.4: {} + + locate-character@3.0.0: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.castarray@4.4.0: {} + + lodash.isplainobject@4.0.6: {} + + lodash.merge@4.6.2: {} + + loupe@3.1.2: {} + + lru-cache@10.4.3: {} + + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + mdn-data@2.0.30: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mini-svg-data-uri@1.4.4: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mri@1.2.0: {} + + mrmime@2.0.0: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.7: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.18: {} + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.2.0 + + parse5@7.2.0: + dependencies: + entities: 4.5.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pathe@1.1.2: {} + + pathval@2.0.0: {} + + periscopic@3.1.0: + dependencies: + '@types/estree': 1.0.6 + estree-walker: 3.0.3 + is-reference: 3.0.2 + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pify@2.3.0: {} + + pirates@4.0.6: {} + + playwright-core@1.48.1: {} + + playwright@1.48.1: + dependencies: + playwright-core: 1.48.1 + optionalDependencies: + fsevents: 2.3.2 + + postcss-import@15.1.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.8 + + postcss-js@4.0.1(postcss@8.4.47): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.4.47 + + postcss-load-config@3.1.4(postcss@8.4.47): + dependencies: + lilconfig: 2.1.0 + yaml: 1.10.2 + optionalDependencies: + postcss: 8.4.47 + + postcss-load-config@4.0.2(postcss@8.4.47): + dependencies: + lilconfig: 3.1.2 + yaml: 2.6.0 + optionalDependencies: + postcss: 8.4.47 + + postcss-nested@6.2.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + + postcss-safe-parser@6.0.0(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + postcss-scss@4.0.9(postcss@8.4.47): + dependencies: + postcss: 8.4.47 + + postcss-selector-parser@6.0.10: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.47: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-plugin-svelte@3.2.7(prettier@3.3.3)(svelte@4.2.19): + dependencies: + prettier: 3.3.3 + svelte: 4.2.19 + + prettier@3.3.3: {} + + punycode@2.3.1: {} + + purgecss-from-html@6.0.0: + dependencies: + parse5: 7.2.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + + purgecss@6.0.0: + dependencies: + commander: 12.1.0 + glob: 10.4.5 + postcss: 8.4.47 + postcss-selector-parser: 6.1.2 + + queue-microtask@1.2.3: {} + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.0.2: {} + + resolve-from@4.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rollup@4.24.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.24.0 + '@rollup/rollup-android-arm64': 4.24.0 + '@rollup/rollup-darwin-arm64': 4.24.0 + '@rollup/rollup-darwin-x64': 4.24.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 + '@rollup/rollup-linux-arm-musleabihf': 4.24.0 + '@rollup/rollup-linux-arm64-gnu': 4.24.0 + '@rollup/rollup-linux-arm64-musl': 4.24.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 + '@rollup/rollup-linux-riscv64-gnu': 4.24.0 + '@rollup/rollup-linux-s390x-gnu': 4.24.0 + '@rollup/rollup-linux-x64-gnu': 4.24.0 + '@rollup/rollup-linux-x64-musl': 4.24.0 + '@rollup/rollup-win32-arm64-msvc': 4.24.0 + '@rollup/rollup-win32-ia32-msvc': 4.24.0 + '@rollup/rollup-win32-x64-msvc': 4.24.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + semver@7.6.3: {} + + set-cookie-parser@2.7.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + sirv@3.0.0: + dependencies: + '@polka/url': 1.0.0-next.28 + mrmime: 2.0.0 + totalist: 3.0.1 + + source-map-js@1.2.1: {} + + stackback@0.0.2: {} + + std-env@3.7.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-json-comments@3.1.1: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svelte-check@4.0.5(svelte@4.2.19)(typescript@5.6.3): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + chokidar: 4.0.1 + fdir: 6.4.2 + picocolors: 1.1.1 + sade: 1.8.1 + svelte: 4.2.19 + typescript: 5.6.3 + transitivePeerDependencies: + - picomatch + + svelte-eslint-parser@0.43.0(svelte@4.2.19): + dependencies: + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + postcss: 8.4.47 + postcss-scss: 4.0.9(postcss@8.4.47) + optionalDependencies: + svelte: 4.2.19 + + svelte-hmr@0.16.0(svelte@4.2.19): + dependencies: + svelte: 4.2.19 + + svelte@4.2.19: + dependencies: + '@ampproject/remapping': 2.3.0 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + '@types/estree': 1.0.6 + acorn: 8.13.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + code-red: 1.0.4 + css-tree: 2.3.1 + estree-walker: 3.0.3 + is-reference: 3.0.2 + locate-character: 3.0.0 + magic-string: 0.30.12 + periscopic: 3.1.0 + + tailwindcss@3.4.14: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47) + postcss-nested: 6.2.0(postcss@8.4.47) + postcss-selector-parser: 6.1.2 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tiny-glob@0.2.9: + dependencies: + globalyzer: 0.1.0 + globrex: 0.1.2 + + tinybench@2.9.0: {} + + tinyexec@0.3.1: {} + + tinypool@1.0.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + ts-interface-checker@0.1.13: {} + + tslib@2.8.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript@5.6.3: {} + + undici-types@6.19.8: {} + + update-browserslist-db@1.1.1(browserslist@4.24.0): + dependencies: + browserslist: 4.24.0 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vite-node@2.1.3(@types/node@22.7.7): + dependencies: + cac: 6.7.14 + debug: 4.3.7 + pathe: 1.1.2 + vite: 5.4.9(@types/node@22.7.7) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-tailwind-purgecss@0.3.3(tailwindcss@3.4.14)(vite@5.4.9(@types/node@22.7.7)): + dependencies: + chalk: 5.3.0 + css-tree: 2.3.1 + fast-glob: 3.3.2 + purgecss: 6.0.0 + purgecss-from-html: 6.0.0 + tailwindcss: 3.4.14 + vite: 5.4.9(@types/node@22.7.7) + + vite@5.4.9(@types/node@22.7.7): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.47 + rollup: 4.24.0 + optionalDependencies: + '@types/node': 22.7.7 + fsevents: 2.3.3 + + vitefu@0.2.5(vite@5.4.9(@types/node@22.7.7)): + optionalDependencies: + vite: 5.4.9(@types/node@22.7.7) + + vitest@2.1.3(@types/node@22.7.7): + dependencies: + '@vitest/expect': 2.1.3 + '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.7)) + '@vitest/pretty-format': 2.1.3 + '@vitest/runner': 2.1.3 + '@vitest/snapshot': 2.1.3 + '@vitest/spy': 2.1.3 + '@vitest/utils': 2.1.3 + chai: 5.1.1 + debug: 4.3.7 + magic-string: 0.30.12 + pathe: 1.1.2 + std-env: 3.7.0 + tinybench: 2.9.0 + tinyexec: 0.3.1 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.4.9(@types/node@22.7.7) + vite-node: 2.1.3(@types/node@22.7.7) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.7.7 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + yaml@1.10.2: {} + + yaml@2.6.0: {} + + yocto-queue@0.1.0: {} diff --git a/frontend/tests/test.ts b/frontend/tests/test.ts index 5816be41..3f61a7d0 100644 --- a/frontend/tests/test.ts +++ b/frontend/tests/test.ts @@ -1,6 +1,6 @@ import { expect, test } from '@playwright/test'; -test('index page has expected h1', async ({ page }) => { - await page.goto('/'); - await expect(page.getByRole('heading', { name: 'Welcome to SvelteKit' })).toBeVisible(); +test('index page has expected h3', async ({ page }) => { + await page.goto('/'); + await expect(page.getByRole('heading', { name: 'Configure WiFi' })).toBeVisible(); }); diff --git a/scripts/build_frontend.py b/scripts/build_frontend.py index 4bd82331..6bb5e446 100644 --- a/scripts/build_frontend.py +++ b/scripts/build_frontend.py @@ -172,8 +172,8 @@ def build_frontend(source, target, env): # This could also lead to some annoying behaviour where the frontend is not updated when the firmware is built. if not sysenv.get_bool('CI', False): print('Building frontend...') - os.system('npm i') - os.system('npm run build') + os.system('pnpm i') + os.system('pnpm run build') print('Frontend build complete.') # Change working directory back to root. From f85a99169b396a45d0eae0f50d7fcba0cca859a6 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Wed, 23 Oct 2024 10:55:45 +0200 Subject: [PATCH 010/155] Proxy PinPatternManager::RunPattern --- include/PinPatternManager.h | 5 +++-- src/PinPatternManager.cpp | 15 ++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/include/PinPatternManager.h b/include/PinPatternManager.h index d0a91c01..75fbd221 100644 --- a/include/PinPatternManager.h +++ b/include/PinPatternManager.h @@ -28,14 +28,15 @@ namespace OpenShock { void SetPattern(const State* pattern, std::size_t patternLength); template - inline void SetPattern(const State (&pattern)[N]) { + inline void SetPattern(const State (&pattern)[N]) + { SetPattern(pattern, N); } void ClearPattern(); private: void ClearPatternInternal(); - static void RunPattern(void* arg); + void RunPattern(); gpio_num_t m_gpioPin; std::vector m_pattern; diff --git a/src/PinPatternManager.cpp b/src/PinPatternManager.cpp index c6d8dd90..b56d928b 100644 --- a/src/PinPatternManager.cpp +++ b/src/PinPatternManager.cpp @@ -6,6 +6,8 @@ const char* const TAG = "PinPatternManager"; #include "Chipset.h" #include "Logging.h" +#include "util/FnProxy.h" +#include "util/TaskUtils.h" using namespace OpenShock; @@ -62,7 +64,7 @@ void PinPatternManager::SetPattern(const State* pattern, std::size_t patternLeng snprintf(name, sizeof(name), "PinPatternManager-%hhi", m_gpioPin); // Start the task - BaseType_t result = xTaskCreate(RunPattern, name, 1024, this, 1, &m_taskHandle); // PROFILED: 0.5KB stack usage + BaseType_t result = TaskUtils::TaskCreateUniversal(&Util::FnProxy<&PinPatternManager::RunPattern>, name, 1024, this, 1, &m_taskHandle, 1); // PROFILED: 0.5KB stack usage if (result != pdPASS) { OS_LOGE(TAG, "[pin-%hhi] Failed to create task: %d", m_gpioPin, result); @@ -92,16 +94,11 @@ void PinPatternManager::ClearPatternInternal() m_pattern.clear(); } -void PinPatternManager::RunPattern(void* arg) +void PinPatternManager::RunPattern() { - PinPatternManager* thisPtr = reinterpret_cast(arg); - - gpio_num_t pin = thisPtr->m_gpioPin; - std::vector& pattern = thisPtr->m_pattern; - while (true) { - for (const auto& state : pattern) { - gpio_set_level(pin, state.level); + for (const auto& state : m_pattern) { + gpio_set_level(m_gpioPin, state.level); vTaskDelay(pdMS_TO_TICKS(state.duration)); } } From 652de8ea72a083c7d3080dbd6634d1d22f491244 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Thu, 24 Oct 2024 00:53:23 +0200 Subject: [PATCH 011/155] Squashed commit of the following: commit e10f5effaaca6634da36790430ebf29e70612b07 Author: hhvrc Date: Wed Oct 23 10:42:44 2024 +0200 Start using SimpleMutex --- include/PinPatternManager.h | 4 +- include/RGBPatternManager.h | 7 +- src/CommandHandler.cpp | 37 +++++----- src/EStopManager.cpp | 6 +- src/OtaUpdateManager.cpp | 84 ++++++++++++++--------- src/PinPatternManager.cpp | 16 ++--- src/RGBPatternManager.cpp | 16 +++-- src/http/HTTPRequestManager.cpp | 116 ++++++++++++++++++++------------ src/wifi/WiFiScanManager.cpp | 106 +++++++++++++++-------------- 9 files changed, 224 insertions(+), 168 deletions(-) diff --git a/include/PinPatternManager.h b/include/PinPatternManager.h index 75fbd221..29dad47f 100644 --- a/include/PinPatternManager.h +++ b/include/PinPatternManager.h @@ -1,10 +1,10 @@ #pragma once #include "Common.h" +#include "SimpleMutex.h" #include -#include #include #include @@ -41,6 +41,6 @@ namespace OpenShock { gpio_num_t m_gpioPin; std::vector m_pattern; TaskHandle_t m_taskHandle; - SemaphoreHandle_t m_taskMutex; + SimpleMutex m_taskMutex; }; } // namespace OpenShock diff --git a/include/RGBPatternManager.h b/include/RGBPatternManager.h index 6f8cc822..e98e1760 100644 --- a/include/RGBPatternManager.h +++ b/include/RGBPatternManager.h @@ -1,10 +1,10 @@ #pragma once #include "Common.h" +#include "SimpleMutex.h" #include -#include #include #include @@ -32,7 +32,8 @@ namespace OpenShock { void SetPattern(const RGBState* pattern, std::size_t patternLength); template - inline void SetPattern(const RGBState (&pattern)[N]) { + inline void SetPattern(const RGBState (&pattern)[N]) + { SetPattern(pattern, N); } void SetBrightness(uint8_t brightness); @@ -47,6 +48,6 @@ namespace OpenShock { std::vector m_pattern; rmt_obj_t* m_rmtHandle; TaskHandle_t m_taskHandle; - SemaphoreHandle_t m_taskMutex; + SimpleMutex m_taskMutex; }; } // namespace OpenShock diff --git a/src/CommandHandler.cpp b/src/CommandHandler.cpp index 9b798d6f..cb261ea0 100644 --- a/src/CommandHandler.cpp +++ b/src/CommandHandler.cpp @@ -11,11 +11,11 @@ const char* const TAG = "CommandHandler"; #include "Logging.h" #include "radio/RFTransmitter.h" #include "ReadWriteMutex.h" +#include "SimpleMutex.h" #include "Time.h" #include "util/TaskUtils.h" #include -#include #include #include @@ -23,8 +23,6 @@ const char* const TAG = "CommandHandler"; const int64_t KEEP_ALIVE_INTERVAL = 60'000; const uint16_t KEEP_ALIVE_DURATION = 300; -using namespace OpenShock; - uint32_t calculateEepyTime(int64_t timeToKeepAlive) { int64_t now = OpenShock::millis(); @@ -33,19 +31,21 @@ uint32_t calculateEepyTime(int64_t timeToKeepAlive) struct KnownShocker { bool killTask; - ShockerModelType model; + OpenShock::ShockerModelType model; uint16_t shockerId; int64_t lastActivityTimestamp; }; -static ReadWriteMutex s_rfTransmitterMutex = {}; -static std::unique_ptr s_rfTransmitter = nullptr; +static OpenShock::ReadWriteMutex s_rfTransmitterMutex = {}; +static std::unique_ptr s_rfTransmitter = nullptr; -static SemaphoreHandle_t s_estopManagerMutex = nullptr; +static OpenShock::SimpleMutex s_estopManagerMutex = {}; -static ReadWriteMutex s_keepAliveMutex = {}; -static QueueHandle_t s_keepAliveQueue = nullptr; -static TaskHandle_t s_keepAliveTaskHandle = nullptr; +static OpenShock::ReadWriteMutex s_keepAliveMutex = {}; +static QueueHandle_t s_keepAliveQueue = nullptr; +static TaskHandle_t s_keepAliveTaskHandle = nullptr; + +using namespace OpenShock; void _keepAliveTask(void* arg) { @@ -111,7 +111,7 @@ bool _internalSetKeepAliveEnabled(bool enabled) return true; } - ScopedWriteLock keepAliveLock(&s_keepAliveMutex); + ScopedWriteLock lock__(&s_keepAliveMutex); if (enabled) { OS_LOGV(TAG, "Enabling keep-alive task"); @@ -160,8 +160,6 @@ bool CommandHandler::Init() } initialized = true; - s_estopManagerMutex = xSemaphoreCreateMutex(); - Config::RFConfig rfConfig; if (!Config::GetRFConfig(rfConfig)) { OS_LOGE(TAG, "Failed to get RF config"); @@ -218,7 +216,7 @@ SetGPIOResultCode CommandHandler::SetRfTxPin(gpio_num_t txPin) return SetGPIOResultCode::InvalidPin; } - ScopedWriteLock rftxLock(&s_rfTransmitterMutex); + ScopedWriteLock lock__(&s_rfTransmitterMutex); if (s_rfTransmitter != nullptr) { OS_LOGV(TAG, "Destroying existing RF transmitter"); @@ -245,23 +243,20 @@ SetGPIOResultCode CommandHandler::SetRfTxPin(gpio_num_t txPin) SetGPIOResultCode CommandHandler::SetEStopPin(gpio_num_t estopPin) { if (OpenShock::IsValidInputPin(static_cast(estopPin))) { - xSemaphoreTake(s_estopManagerMutex, portMAX_DELAY); + ScopedLock lock__(&s_estopManagerMutex); if (!EStopManager::SetEStopPin(estopPin)) { OS_LOGE(TAG, "Failed to set EStop pin"); - xSemaphoreGive(s_estopManagerMutex); return SetGPIOResultCode::InternalError; } if (!Config::SetEStopGpioPin(estopPin)) { OS_LOGE(TAG, "Failed to set EStop pin in config"); - xSemaphoreGive(s_estopManagerMutex); return SetGPIOResultCode::InternalError; } - xSemaphoreGive(s_estopManagerMutex); return SetGPIOResultCode::Success; } else { return SetGPIOResultCode::InvalidPin; @@ -318,7 +313,7 @@ gpio_num_t CommandHandler::GetRfTxPin() bool CommandHandler::HandleCommand(ShockerModelType model, uint16_t shockerId, ShockerCommandType type, uint8_t intensity, uint16_t durationMs) { - ScopedReadLock rftxLock(&s_rfTransmitterMutex); + ScopedReadLock lock__rf(&s_rfTransmitterMutex); if (s_rfTransmitter == nullptr) { OS_LOGW(TAG, "RF Transmitter is not initialized, ignoring command"); @@ -340,8 +335,8 @@ bool CommandHandler::HandleCommand(ShockerModelType model, uint16_t shockerId, S bool ok = s_rfTransmitter->SendCommand(model, shockerId, type, intensity, durationMs); - rftxLock.unlock(); - ScopedReadLock keepAliveLock(&s_keepAliveMutex); + lock__rf.unlock(); + ScopedReadLock lock__ka(&s_keepAliveMutex); if (ok && s_keepAliveQueue != nullptr) { KnownShocker cmd {.model = model, .shockerId = shockerId, .lastActivityTimestamp = OpenShock::millis() + durationMs}; diff --git a/src/EStopManager.cpp b/src/EStopManager.cpp index 1558d854..3fb6e534 100644 --- a/src/EStopManager.cpp +++ b/src/EStopManager.cpp @@ -213,7 +213,7 @@ bool EStopManager::Init() return false; } - OpenShock::ScopedLock lock(&s_estopMutex); + OpenShock::ScopedLock lock__(&s_estopMutex); if (!_setEStopPinImpl(cfg.gpioPin)) { OS_LOGE(TAG, "Failed to set EStop pin"); @@ -230,7 +230,7 @@ bool EStopManager::Init() bool EStopManager::SetEStopEnabled(bool enabled) { - OpenShock::ScopedLock lock(&s_estopMutex); + OpenShock::ScopedLock lock__(&s_estopMutex); if (s_estopPin == GPIO_NUM_NC) { gpio_num_t pin; @@ -251,7 +251,7 @@ bool EStopManager::SetEStopEnabled(bool enabled) bool EStopManager::SetEStopPin(gpio_num_t pin) { - OpenShock::ScopedLock lock(&s_estopMutex); + OpenShock::ScopedLock lock__(&s_estopMutex); return _setEStopPinImpl(pin); } diff --git a/src/OtaUpdateManager.cpp b/src/OtaUpdateManager.cpp index 907bda9a..33247351 100644 --- a/src/OtaUpdateManager.cpp +++ b/src/OtaUpdateManager.cpp @@ -11,6 +11,7 @@ const char* const TAG = "OtaUpdateManager"; #include "Logging.h" #include "SemVer.h" #include "serialization/WSGateway.h" +#include "SimpleMutex.h" #include "Time.h" #include "util/HexUtils.h" #include "util/PartitionUtils.h" @@ -49,12 +50,11 @@ using namespace std::string_view_literals; /// /// @see .platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-misc.c /// @return true -bool verifyRollbackLater() { +bool verifyRollbackLater() +{ return true; } -using namespace OpenShock; - enum OtaTaskEventFlag : uint32_t { OTA_TASK_EVENT_UPDATE_REQUESTED = 1 << 0, OTA_TASK_EVENT_WIFI_DISCONNECTED = 1 << 1, // If both connected and disconnected are set, disconnected takes priority. @@ -65,46 +65,53 @@ static esp_ota_img_states_t _otaImageState; static OpenShock::FirmwareBootType _bootType; static TaskHandle_t _taskHandle; static OpenShock::SemVer _requestedVersion; -static SemaphoreHandle_t _requestedVersionMutex = xSemaphoreCreateMutex(); +static OpenShock::SimpleMutex _requestedVersionMutex = {}; + +using namespace OpenShock; -bool _tryQueueUpdateRequest(const OpenShock::SemVer& version) { - if (xSemaphoreTake(_requestedVersionMutex, pdMS_TO_TICKS(1000)) != pdTRUE) { +bool _tryQueueUpdateRequest(const OpenShock::SemVer& version) +{ + if (!_requestedVersionMutex.lock(pdMS_TO_TICKS(1000))) { OS_LOGE(TAG, "Failed to take requested version mutex"); return false; } _requestedVersion = version; - xSemaphoreGive(_requestedVersionMutex); + _requestedVersionMutex.unlock(); xTaskNotify(_taskHandle, OTA_TASK_EVENT_UPDATE_REQUESTED, eSetBits); return true; } -bool _tryGetRequestedVersion(OpenShock::SemVer& version) { - if (xSemaphoreTake(_requestedVersionMutex, pdMS_TO_TICKS(1000)) != pdTRUE) { +bool _tryGetRequestedVersion(OpenShock::SemVer& version) +{ + if (!_requestedVersionMutex.lock(pdMS_TO_TICKS(1000))) { OS_LOGE(TAG, "Failed to take requested version mutex"); return false; } version = _requestedVersion; - xSemaphoreGive(_requestedVersionMutex); + _requestedVersionMutex.unlock(); return true; } -void _otaEvGotIPHandler(arduino_event_t* event) { +void _otaEvGotIPHandler(arduino_event_t* event) +{ (void)event; xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_CONNECTED, eSetBits); } -void _otaEvWiFiDisconnectedHandler(arduino_event_t* event) { +void _otaEvWiFiDisconnectedHandler(arduino_event_t* event) +{ (void)event; xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_DISCONNECTED, eSetBits); } -bool _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask task, float progress) { +bool _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask task, float progress) +{ int32_t updateId; if (!Config::GetOtaUpdateId(updateId)) { OS_LOGE(TAG, "Failed to get OTA update ID"); @@ -118,7 +125,8 @@ bool _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask task, f return true; } -bool _sendFailureMessage(std::string_view message, bool fatal = false) { +bool _sendFailureMessage(std::string_view message, bool fatal = false) +{ int32_t updateId; if (!Config::GetOtaUpdateId(updateId)) { OS_LOGE(TAG, "Failed to get OTA update ID"); @@ -133,7 +141,8 @@ bool _sendFailureMessage(std::string_view message, bool fatal = false) { return true; } -bool _flashAppPartition(const esp_partition_t* partition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) { +bool _flashAppPartition(const esp_partition_t* partition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) +{ OS_LOGD(TAG, "Flashing app partition"); if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::FlashingApplication, 0.0f)) { @@ -168,7 +177,8 @@ bool _flashAppPartition(const esp_partition_t* partition, std::string_view remot return true; } -bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) { +bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) +{ if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::PreparingForInstall, 0.0f)) { return false; } @@ -218,13 +228,14 @@ bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view return true; } -void _otaUpdateTask(void* arg) { +void _otaUpdateTask(void* arg) +{ (void)arg; OS_LOGD(TAG, "OTA update task started"); - bool connected = false; - bool updateRequested = false; + bool connected = false; + bool updateRequested = false; int64_t lastUpdateCheck = 0; // Update task loop. @@ -264,7 +275,7 @@ void _otaUpdateTask(void* arg) { continue; } - bool firstCheck = lastUpdateCheck == 0; + bool firstCheck = lastUpdateCheck == 0; int64_t diff = now - lastUpdateCheck; int64_t diffMins = diff / 60'000LL; @@ -395,7 +406,8 @@ void _otaUpdateTask(void* arg) { esp_restart(); } -bool _tryGetStringList(std::string_view url, std::vector& list) { +bool _tryGetStringList(std::string_view url, std::vector& list) +{ auto response = OpenShock::HTTP::GetString( url, { @@ -428,7 +440,8 @@ bool _tryGetStringList(std::string_view url, std::vector& list) { return true; } -bool OtaUpdateManager::Init() { +bool OtaUpdateManager::Init() +{ OS_LOGN(TAG, "Fetching current partition"); // Fetch current partition info. @@ -484,7 +497,8 @@ bool OtaUpdateManager::Init() { return true; } -bool OtaUpdateManager::TryGetFirmwareVersion(OtaUpdateChannel channel, OpenShock::SemVer& version) { +bool OtaUpdateManager::TryGetFirmwareVersion(OtaUpdateChannel channel, OpenShock::SemVer& version) +{ std::string_view channelIndexUrl; switch (channel) { case OtaUpdateChannel::Stable: @@ -523,7 +537,8 @@ bool OtaUpdateManager::TryGetFirmwareVersion(OtaUpdateChannel channel, OpenShock return true; } -bool OtaUpdateManager::TryGetFirmwareBoards(const OpenShock::SemVer& version, std::vector& boards) { +bool OtaUpdateManager::TryGetFirmwareBoards(const OpenShock::SemVer& version, std::vector& boards) +{ std::string channelIndexUrl; if (!FormatToString(channelIndexUrl, OPENSHOCK_FW_CDN_BOARDS_INDEX_URL_FORMAT, version.toString().c_str())) { // TODO: This is abusing the SemVer::toString() method causing alot of string copies, fix this OS_LOGE(TAG, "Failed to format URL"); @@ -540,7 +555,8 @@ bool OtaUpdateManager::TryGetFirmwareBoards(const OpenShock::SemVer& version, st return true; } -bool _tryParseIntoHash(std::string_view hash, uint8_t (&hashBytes)[32]) { +bool _tryParseIntoHash(std::string_view hash, uint8_t (&hashBytes)[32]) +{ if (!HexUtils::TryParseHex(hash.data(), hash.size(), hashBytes, 32)) { OS_LOGE(TAG, "Failed to parse hash: %.*s", hash.size(), hash.data()); return false; @@ -549,7 +565,8 @@ bool _tryParseIntoHash(std::string_view hash, uint8_t (&hashBytes)[32]) { return true; } -bool OtaUpdateManager::TryGetFirmwareRelease(const OpenShock::SemVer& version, FirmwareRelease& release) { +bool OtaUpdateManager::TryGetFirmwareRelease(const OpenShock::SemVer& version, FirmwareRelease& release) +{ auto versionStr = version.toString(); // TODO: This is abusing the SemVer::toString() method causing alot of string copies, fix this if (!FormatToString(release.appBinaryUrl, OPENSHOCK_FW_CDN_APP_URL_FORMAT, versionStr.c_str())) { @@ -633,21 +650,25 @@ bool OtaUpdateManager::TryGetFirmwareRelease(const OpenShock::SemVer& version, F return true; } -bool OtaUpdateManager::TryStartFirmwareInstallation(const OpenShock::SemVer& version) { +bool OtaUpdateManager::TryStartFirmwareInstallation(const OpenShock::SemVer& version) +{ OS_LOGD(TAG, "Requesting firmware version %s", version.toString().c_str()); // TODO: This is abusing the SemVer::toString() method causing alot of string copies, fix this return _tryQueueUpdateRequest(version); } -FirmwareBootType OtaUpdateManager::GetFirmwareBootType() { +FirmwareBootType OtaUpdateManager::GetFirmwareBootType() +{ return _bootType; } -bool OtaUpdateManager::IsValidatingApp() { +bool OtaUpdateManager::IsValidatingApp() +{ return _otaImageState == ESP_OTA_IMG_PENDING_VERIFY; } -void OtaUpdateManager::InvalidateAndRollback() { +void OtaUpdateManager::InvalidateAndRollback() +{ // Set OTA boot type in config. if (!Config::SetOtaUpdateStep(OpenShock::OtaUpdateStep::RollingBack)) { OS_PANIC(TAG, "Failed to set OTA firmware boot type in critical section"); // TODO: THIS IS A CRITICAL SECTION, WHAT DO WE DO? @@ -674,7 +695,8 @@ void OtaUpdateManager::InvalidateAndRollback() { esp_restart(); } -void OtaUpdateManager::ValidateApp() { +void OtaUpdateManager::ValidateApp() +{ if (esp_ota_mark_app_valid_cancel_rollback() != ESP_OK) { OS_PANIC(TAG, "Unable to mark app as valid, WTF?"); // TODO: Wtf do we do here? } diff --git a/src/PinPatternManager.cpp b/src/PinPatternManager.cpp index b56d928b..573e0a14 100644 --- a/src/PinPatternManager.cpp +++ b/src/PinPatternManager.cpp @@ -15,7 +15,7 @@ PinPatternManager::PinPatternManager(gpio_num_t gpioPin) : m_gpioPin(GPIO_NUM_NC) , m_pattern() , m_taskHandle(nullptr) - , m_taskMutex(xSemaphoreCreateMutex()) + , m_taskMutex() { if (gpioPin == GPIO_NUM_NC) { OS_LOGE(TAG, "Pin is not set"); @@ -45,8 +45,6 @@ PinPatternManager::~PinPatternManager() { ClearPattern(); - vSemaphoreDelete(m_taskMutex); - if (m_gpioPin != GPIO_NUM_NC) { gpio_reset_pin(m_gpioPin); } @@ -54,6 +52,8 @@ PinPatternManager::~PinPatternManager() void PinPatternManager::SetPattern(const State* pattern, std::size_t patternLength) { + m_taskMutex.lock(portMAX_DELAY); + ClearPatternInternal(); // Set new values @@ -72,20 +72,20 @@ void PinPatternManager::SetPattern(const State* pattern, std::size_t patternLeng m_pattern.clear(); } - // Give the semaphore back - xSemaphoreGive(m_taskMutex); + m_taskMutex.unlock(); } void PinPatternManager::ClearPattern() { + m_taskMutex.lock(portMAX_DELAY); + ClearPatternInternal(); - xSemaphoreGive(m_taskMutex); + + m_taskMutex.unlock(); } void PinPatternManager::ClearPatternInternal() { - xSemaphoreTake(m_taskMutex, portMAX_DELAY); - if (m_taskHandle != nullptr) { vTaskDelete(m_taskHandle); m_taskHandle = nullptr; diff --git a/src/RGBPatternManager.cpp b/src/RGBPatternManager.cpp index 7fdae6b3..ee509538 100644 --- a/src/RGBPatternManager.cpp +++ b/src/RGBPatternManager.cpp @@ -22,7 +22,7 @@ RGBPatternManager::RGBPatternManager(gpio_num_t gpioPin) , m_pattern() , m_rmtHandle(nullptr) , m_taskHandle(nullptr) - , m_taskMutex(xSemaphoreCreateMutex()) + , m_taskMutex() { if (gpioPin == GPIO_NUM_NC) { OS_LOGE(TAG, "Pin is not set"); @@ -52,11 +52,13 @@ RGBPatternManager::~RGBPatternManager() { ClearPattern(); - vSemaphoreDelete(m_taskMutex); + rmtDeinit(m_rmtHandle); } void RGBPatternManager::SetPattern(const RGBState* pattern, std::size_t patternLength) { + m_taskMutex.lock(portMAX_DELAY); + ClearPatternInternal(); // Set new values @@ -72,20 +74,20 @@ void RGBPatternManager::SetPattern(const RGBState* pattern, std::size_t patternL m_pattern.clear(); } - // Give the semaphore back - xSemaphoreGive(m_taskMutex); + m_taskMutex.unlock(); } void RGBPatternManager::ClearPattern() { + m_taskMutex.lock(portMAX_DELAY); + ClearPatternInternal(); - xSemaphoreGive(m_taskMutex); + + m_taskMutex.unlock(); } void RGBPatternManager::ClearPatternInternal() { - xSemaphoreTake(m_taskMutex, portMAX_DELAY); - if (m_taskHandle != nullptr) { vTaskDelete(m_taskHandle); m_taskHandle = nullptr; diff --git a/src/http/HTTPRequestManager.cpp b/src/http/HTTPRequestManager.cpp index 751a36fc..9ed9d704 100644 --- a/src/http/HTTPRequestManager.cpp +++ b/src/http/HTTPRequestManager.cpp @@ -4,6 +4,7 @@ const char* const TAG = "HTTPRequestManager"; #include "Common.h" #include "Logging.h" +#include "SimpleMutex.h" #include "Time.h" #include "util/StringUtils.h" @@ -22,31 +23,40 @@ const std::size_t HTTP_BUFFER_SIZE = 4096LLU; const int HTTP_DOWNLOAD_SIZE_LIMIT = 200 * 1024 * 1024; // 200 MB struct RateLimit { - RateLimit() : m_mutex(xSemaphoreCreateMutex()), m_blockUntilMs(0), m_limits(), m_requests() { } + RateLimit() + : m_mutex() + , m_blockUntilMs(0) + , m_limits() + , m_requests() + { + } - void addLimit(uint32_t durationMs, uint16_t count) { - xSemaphoreTake(m_mutex, portMAX_DELAY); + void addLimit(uint32_t durationMs, uint16_t count) + { + m_mutex.lock(portMAX_DELAY); // Insert sorted m_limits.insert(std::upper_bound(m_limits.begin(), m_limits.end(), durationMs, [](int64_t durationMs, const Limit& limit) { return durationMs > limit.durationMs; }), {durationMs, count}); - xSemaphoreGive(m_mutex); + m_mutex.unlock(); } - void clearLimits() { - xSemaphoreTake(m_mutex, portMAX_DELAY); + + void clearLimits() + { + m_mutex.lock(portMAX_DELAY); m_limits.clear(); - xSemaphoreGive(m_mutex); + m_mutex.unlock(); } - bool tryRequest() { + bool tryRequest() + { int64_t now = OpenShock::millis(); - xSemaphoreTake(m_mutex, portMAX_DELAY); + OpenShock::ScopedLock lock__(&m_mutex); if (m_blockUntilMs > now) { - xSemaphoreGive(m_mutex); return false; } @@ -59,34 +69,37 @@ struct RateLimit { auto it = std::find_if(m_limits.begin(), m_limits.end(), [this](const RateLimit::Limit& limit) { return m_requests.size() >= limit.count; }); if (it != m_limits.end()) { m_blockUntilMs = now + it->durationMs; - xSemaphoreGive(m_mutex); return false; } // Add the request m_requests.push_back(now); - xSemaphoreGive(m_mutex); - return true; } - void clearRequests() { - xSemaphoreTake(m_mutex, portMAX_DELAY); + void clearRequests() + { + m_mutex.lock(portMAX_DELAY); + m_requests.clear(); - xSemaphoreGive(m_mutex); + + m_mutex.unlock(); } - void blockUntil(int64_t blockUntilMs) { - xSemaphoreTake(m_mutex, portMAX_DELAY); + void blockUntil(int64_t blockUntilMs) + { + m_mutex.lock(portMAX_DELAY); + m_blockUntilMs = blockUntilMs; - xSemaphoreGive(m_mutex); + + m_mutex.unlock(); } - uint32_t requestsSince(int64_t sinceMs) { - xSemaphoreTake(m_mutex, portMAX_DELAY); - uint32_t result = std::count_if(m_requests.begin(), m_requests.end(), [sinceMs](int64_t requestMs) { return requestMs >= sinceMs; }); - xSemaphoreGive(m_mutex); - return result; + uint32_t requestsSince(int64_t sinceMs) + { + OpenShock::ScopedLock lock__(&m_mutex); + + return std::count_if(m_requests.begin(), m_requests.end(), [sinceMs](int64_t requestMs) { return requestMs >= sinceMs; }); } private: @@ -95,18 +108,19 @@ struct RateLimit { uint16_t count; }; - SemaphoreHandle_t m_mutex; + OpenShock::SimpleMutex m_mutex; int64_t m_blockUntilMs; std::vector m_limits; std::vector m_requests; }; -SemaphoreHandle_t s_rateLimitsMutex = xSemaphoreCreateMutex(); -std::unordered_map> s_rateLimits; +static OpenShock::SimpleMutex s_rateLimitsMutex = {}; +static std::unordered_map> s_rateLimits = {}; using namespace OpenShock; -std::string_view _getDomain(std::string_view url) { +std::string_view _getDomain(std::string_view url) +{ if (url.empty()) { return {}; } @@ -142,7 +156,8 @@ std::string_view _getDomain(std::string_view url) { return url; } -std::shared_ptr _rateLimitFactory(std::string_view domain) { +std::shared_ptr _rateLimitFactory(std::string_view domain) +{ auto rateLimit = std::make_shared(); // Add default limits @@ -158,13 +173,14 @@ std::shared_ptr _rateLimitFactory(std::string_view domain) { return rateLimit; } -std::shared_ptr _getRateLimiter(std::string_view url) { +std::shared_ptr _getRateLimiter(std::string_view url) +{ auto domain = std::string(_getDomain(url)); if (domain.empty()) { return nullptr; } - xSemaphoreTake(s_rateLimitsMutex, portMAX_DELAY); + s_rateLimitsMutex.lock(portMAX_DELAY); auto it = s_rateLimits.find(domain); if (it == s_rateLimits.end()) { @@ -172,12 +188,13 @@ std::shared_ptr _getRateLimiter(std::string_view url) { it = s_rateLimits.find(domain); } - xSemaphoreGive(s_rateLimitsMutex); + s_rateLimitsMutex.unlock(); return it->second; } -void _setupClient(HTTPClient& client) { +void _setupClient(HTTPClient& client) +{ client.setUserAgent(OpenShock::Constants::FW_USERAGENT); } @@ -186,10 +203,12 @@ struct StreamReaderResult { std::size_t nWritten; }; -constexpr bool _isCRLF(const uint8_t* buffer) { +constexpr bool _isCRLF(const uint8_t* buffer) +{ return buffer[0] == '\r' && buffer[1] == '\n'; } -constexpr bool _tryFindCRLF(std::size_t& pos, const uint8_t* buffer, std::size_t len) { +constexpr bool _tryFindCRLF(std::size_t& pos, const uint8_t* buffer, std::size_t len) +{ const uint8_t* cur = buffer; const uint8_t* end = buffer + len - 1; @@ -204,7 +223,8 @@ constexpr bool _tryFindCRLF(std::size_t& pos, const uint8_t* buffer, std::size_t return false; } -constexpr bool _tryParseHexSizeT(std::size_t& result, std::string_view str) { +constexpr bool _tryParseHexSizeT(std::size_t& result, std::string_view str) +{ if (str.empty() || str.size() > sizeof(std::size_t) * 2) { return false; } @@ -232,7 +252,8 @@ enum ParserState : uint8_t { Invalid, }; -ParserState _parseChunkHeader(const uint8_t* buffer, std::size_t bufferLen, std::size_t& headerLen, std::size_t& payloadLen) { +ParserState _parseChunkHeader(const uint8_t* buffer, std::size_t bufferLen, std::size_t& headerLen, std::size_t& payloadLen) +{ if (bufferLen < 5) { // Bare minimum: "0\r\n\r\n" return ParserState::NeedMoreData; } @@ -282,7 +303,8 @@ ParserState _parseChunkHeader(const uint8_t* buffer, std::size_t bufferLen, std: return ParserState::Ok; } -ParserState _parseChunk(const uint8_t* buffer, std::size_t bufferLen, std::size_t& payloadPos, std::size_t& payloadLen) { +ParserState _parseChunk(const uint8_t* buffer, std::size_t bufferLen, std::size_t& payloadPos, std::size_t& payloadLen) +{ if (payloadPos == 0) { ParserState state = _parseChunkHeader(buffer, bufferLen, payloadPos, payloadLen); if (state != ParserState::Ok) { @@ -304,7 +326,8 @@ ParserState _parseChunk(const uint8_t* buffer, std::size_t bufferLen, std::size_ return ParserState::Ok; } -void _alignChunk(uint8_t* buffer, std::size_t& bufferCursor, std::size_t payloadPos, std::size_t payloadLen) { +void _alignChunk(uint8_t* buffer, std::size_t& bufferCursor, std::size_t payloadPos, std::size_t payloadLen) +{ std::size_t totalLen = payloadPos + payloadLen + 2; // +2 for CRLF std::size_t remaining = bufferCursor - totalLen; if (remaining > 0) { @@ -315,7 +338,8 @@ void _alignChunk(uint8_t* buffer, std::size_t& bufferCursor, std::size_t payload } } -StreamReaderResult _readStreamDataChunked(HTTPClient& client, WiFiClient* stream, HTTP::DownloadCallback downloadCallback, int64_t begin, uint32_t timeoutMs) { +StreamReaderResult _readStreamDataChunked(HTTPClient& client, WiFiClient* stream, HTTP::DownloadCallback downloadCallback, int64_t begin, uint32_t timeoutMs) +{ std::size_t totalWritten = 0; HTTP::RequestResult result = HTTP::RequestResult::Success; @@ -395,7 +419,8 @@ StreamReaderResult _readStreamDataChunked(HTTPClient& client, WiFiClient* stream return {result, totalWritten}; } -StreamReaderResult _readStreamData(HTTPClient& client, WiFiClient* stream, std::size_t contentLength, HTTP::DownloadCallback downloadCallback, int64_t begin, uint32_t timeoutMs) { +StreamReaderResult _readStreamData(HTTPClient& client, WiFiClient* stream, std::size_t contentLength, HTTP::DownloadCallback downloadCallback, int64_t begin, uint32_t timeoutMs) +{ std::size_t nWritten = 0; HTTP::RequestResult result = HTTP::RequestResult::Success; @@ -448,7 +473,8 @@ HTTP::Response _doGetStream( HTTP::GotContentLengthCallback contentLengthCallback, HTTP::DownloadCallback downloadCallback, uint32_t timeoutMs -) { +) +{ int64_t begin = OpenShock::millis(); if (!client.begin(OpenShock::StringToArduinoString(url))) { OS_LOGE(TAG, "Failed to begin HTTP request"); @@ -535,7 +561,8 @@ HTTP::Response _doGetStream( } HTTP::Response - HTTP::Download(std::string_view url, const std::map& headers, HTTP::GotContentLengthCallback contentLengthCallback, HTTP::DownloadCallback downloadCallback, const std::vector& acceptedCodes, uint32_t timeoutMs) { + HTTP::Download(std::string_view url, const std::map& headers, HTTP::GotContentLengthCallback contentLengthCallback, HTTP::DownloadCallback downloadCallback, const std::vector& acceptedCodes, uint32_t timeoutMs) +{ std::shared_ptr rateLimiter = _getRateLimiter(url); if (rateLimiter == nullptr) { return {RequestResult::InvalidURL, 0, 0}; @@ -551,7 +578,8 @@ HTTP::Response return _doGetStream(client, url, headers, acceptedCodes, rateLimiter, contentLengthCallback, downloadCallback, timeoutMs); } -HTTP::Response HTTP::GetString(std::string_view url, const std::map& headers, const std::vector& acceptedCodes, uint32_t timeoutMs) { +HTTP::Response HTTP::GetString(std::string_view url, const std::map& headers, const std::vector& acceptedCodes, uint32_t timeoutMs) +{ std::string result; auto allocator = [&result](std::size_t contentLength) { diff --git a/src/wifi/WiFiScanManager.cpp b/src/wifi/WiFiScanManager.cpp index 23074e06..ed2ea260 100644 --- a/src/wifi/WiFiScanManager.cpp +++ b/src/wifi/WiFiScanManager.cpp @@ -5,6 +5,7 @@ const char* const TAG = "WiFiScanManager"; #include "Logging.h" +#include "SimpleMutex.h" #include "util/TaskUtils.h" #include @@ -22,40 +23,40 @@ enum WiFiScanTaskNotificationFlags { CLEAR_FLAGS = CHANNEL_DONE | ERROR }; -using namespace OpenShock; - -static bool s_initialized = false; -static TaskHandle_t s_scanTaskHandle = nullptr; -static SemaphoreHandle_t s_scanTaskMutex = xSemaphoreCreateMutex(); -static uint8_t s_currentChannel = 0; -static std::map s_statusChangedHandlers; -static std::map s_networksDiscoveredHandlers; +static bool s_initialized = false; +static TaskHandle_t s_scanTaskHandle = nullptr; +static OpenShock::SimpleMutex s_scanTaskMutex = {}; +static uint8_t s_currentChannel = 0; +static std::map s_statusChangedHandlers; +static std::map s_networksDiscoveredHandlers; -bool _notifyTask(WiFiScanTaskNotificationFlags flags) { - xSemaphoreTake(s_scanTaskMutex, portMAX_DELAY); +using namespace OpenShock; - bool success = false; +bool _notifyTask(WiFiScanTaskNotificationFlags flags) +{ + ScopedLock lock__(&s_scanTaskMutex); - if (s_scanTaskHandle != nullptr) { - success = xTaskNotify(s_scanTaskHandle, flags, eSetBits) == pdPASS; + if (s_scanTaskHandle == nullptr) { + return false; } - xSemaphoreGive(s_scanTaskMutex); - - return success; + return xTaskNotify(s_scanTaskHandle, flags, eSetBits) == pdPASS; } -void _notifyStatusChangedHandlers(OpenShock::WiFiScanStatus status) { +void _notifyStatusChangedHandlers(OpenShock::WiFiScanStatus status) +{ for (auto& it : s_statusChangedHandlers) { it.second(status); } } -bool _isScanError(int16_t retval) { +bool _isScanError(int16_t retval) +{ return retval < 0 && retval != WIFI_SCAN_RUNNING; } -void _handleScanError(int16_t retval) { +void _handleScanError(int16_t retval) +{ if (retval >= 0) return; _notifyTask(WiFiScanTaskNotificationFlags::ERROR); @@ -73,7 +74,8 @@ void _handleScanError(int16_t retval) { OS_LOGE(TAG, "Scan returned an unknown error"); } -int16_t _scanChannel(uint8_t channel) { +int16_t _scanChannel(uint8_t channel) +{ int16_t retval = WiFi.scanNetworks(true, true, false, OPENSHOCK_WIFI_SCAN_MAX_MS_PER_CHANNEL, channel); if (!_isScanError(retval)) { return retval; @@ -84,7 +86,8 @@ int16_t _scanChannel(uint8_t channel) { return retval; } -WiFiScanStatus _scanningTaskImpl() { +WiFiScanStatus _scanningTaskImpl() +{ // Start the scan on the highest channel and work our way down uint8_t channel = OPENSHOCK_WIFI_SCAN_MAX_CHANNEL; @@ -138,25 +141,29 @@ WiFiScanStatus _scanningTaskImpl() { return WiFiScanStatus::Completed; } -void _scanningTask(void* arg) { +void _scanningTask(void* arg) +{ (void)arg; - + // Start the scan WiFiScanStatus status = _scanningTaskImpl(); // Notify the status changed handlers of the scan result _notifyStatusChangedHandlers(status); + s_scanTaskMutex.lock(portMAX_DELAY); + // Clear the task handle - xSemaphoreTake(s_scanTaskMutex, portMAX_DELAY); s_scanTaskHandle = nullptr; - xSemaphoreGive(s_scanTaskMutex); + + s_scanTaskMutex.unlock(); // Kill this task vTaskDelete(nullptr); } -void _evScanCompleted(arduino_event_id_t event, arduino_event_info_t info) { +void _evScanCompleted(arduino_event_id_t event, arduino_event_info_t info) +{ (void)event; (void)info; @@ -192,14 +199,16 @@ void _evScanCompleted(arduino_event_id_t event, arduino_event_info_t info) { // Notify the scan task that we're done _notifyTask(WiFiScanTaskNotificationFlags::CHANNEL_DONE); } -void _evSTAStopped(arduino_event_id_t event, arduino_event_info_t info) { +void _evSTAStopped(arduino_event_id_t event, arduino_event_info_t info) +{ (void)event; (void)info; _notifyTask(WiFiScanTaskNotificationFlags::WIFI_DISABLED); } -bool WiFiScanManager::Init() { +bool WiFiScanManager::Init() +{ if (s_initialized) { OS_LOGW(TAG, "WiFiScanManager is already initialized"); return true; @@ -213,40 +222,36 @@ bool WiFiScanManager::Init() { return true; } -bool WiFiScanManager::IsScanning() { +bool WiFiScanManager::IsScanning() +{ return s_scanTaskHandle != nullptr; } -bool WiFiScanManager::StartScan() { - xSemaphoreTake(s_scanTaskMutex, portMAX_DELAY); +bool WiFiScanManager::StartScan() +{ + ScopedLock lock__(&s_scanTaskMutex); // Check if a scan is already in progress if (s_scanTaskHandle != nullptr && eTaskGetState(s_scanTaskHandle) != eDeleted) { OS_LOGW(TAG, "Cannot start scan: scan task is already running"); - - xSemaphoreGive(s_scanTaskMutex); return false; } // Start the scan task if (TaskUtils::TaskCreateExpensive(_scanningTask, "WiFiScanManager", 4096, nullptr, 1, &s_scanTaskHandle) != pdPASS) { // PROFILED: 1.8KB stack usage OS_LOGE(TAG, "Failed to create scan task"); - - xSemaphoreGive(s_scanTaskMutex); return false; } - xSemaphoreGive(s_scanTaskMutex); return true; } -bool WiFiScanManager::AbortScan() { - xSemaphoreTake(s_scanTaskMutex, portMAX_DELAY); +bool WiFiScanManager::AbortScan() +{ + ScopedLock lock__(&s_scanTaskMutex); // Check if a scan is in progress if (s_scanTaskHandle == nullptr || eTaskGetState(s_scanTaskHandle) == eDeleted) { OS_LOGW(TAG, "Cannot abort scan: no scan is in progress"); - - xSemaphoreGive(s_scanTaskMutex); return false; } @@ -259,17 +264,18 @@ bool WiFiScanManager::AbortScan() { it.second(WiFiScanStatus::Aborted); } - xSemaphoreGive(s_scanTaskMutex); return true; } -uint64_t WiFiScanManager::RegisterStatusChangedHandler(const WiFiScanManager::StatusChangedHandler& handler) { - static uint64_t nextHandle = 0; - uint64_t handle = nextHandle++; +uint64_t WiFiScanManager::RegisterStatusChangedHandler(const WiFiScanManager::StatusChangedHandler& handler) +{ + static uint64_t nextHandle = 0; + uint64_t handle = nextHandle++; s_statusChangedHandlers[handle] = handler; return handle; } -void WiFiScanManager::UnregisterStatusChangedHandler(uint64_t handle) { +void WiFiScanManager::UnregisterStatusChangedHandler(uint64_t handle) +{ auto it = s_statusChangedHandlers.find(handle); if (it != s_statusChangedHandlers.end()) { @@ -277,13 +283,15 @@ void WiFiScanManager::UnregisterStatusChangedHandler(uint64_t handle) { } } -uint64_t WiFiScanManager::RegisterNetworksDiscoveredHandler(const WiFiScanManager::NetworksDiscoveredHandler& handler) { - static uint64_t nextHandle = 0; - uint64_t handle = nextHandle++; +uint64_t WiFiScanManager::RegisterNetworksDiscoveredHandler(const WiFiScanManager::NetworksDiscoveredHandler& handler) +{ + static uint64_t nextHandle = 0; + uint64_t handle = nextHandle++; s_networksDiscoveredHandlers[handle] = handler; return handle; } -void WiFiScanManager::UnregisterNetworksDiscoveredHandler(uint64_t handle) { +void WiFiScanManager::UnregisterNetworksDiscoveredHandler(uint64_t handle) +{ auto it = s_networksDiscoveredHandlers.find(handle); if (it != s_networksDiscoveredHandlers.end()) { From 8d6f80581aae1c382a9529cbd88b64b5316545b5 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Thu, 24 Oct 2024 01:06:42 +0200 Subject: [PATCH 012/155] Add integer to string methods --- include/Convert.h | 12 ++++ include/util/DigitCounter.h | 42 +++++++++++++ src/Convert.cpp | 117 ++++++++++++++++++++++++++++++------ src/SemVer.cpp | 53 +++++++--------- src/util/DigitCounter.cpp | 13 ++++ 5 files changed, 186 insertions(+), 51 deletions(-) create mode 100644 include/util/DigitCounter.h create mode 100644 src/util/DigitCounter.cpp diff --git a/include/Convert.h b/include/Convert.h index 9b56207c..d39074ca 100644 --- a/include/Convert.h +++ b/include/Convert.h @@ -3,9 +3,21 @@ #include #include +#include #include namespace OpenShock::Convert { + void FromInt8(int8_t val, std::string& str); + void FromUint8(uint8_t val, std::string& str); + void FromInt16(int16_t val, std::string& str); + void FromUint16(uint16_t val, std::string& str); + void FromInt32(int32_t val, std::string& str); + void FromUint32(uint32_t val, std::string& str); + void FromInt64(int64_t val, std::string& str); + void FromUint64(uint64_t val, std::string& str); + void FromBool(bool val, std::string& str); + void FromGpioNum(gpio_num_t val, std::string& str); + bool ToInt8(std::string_view str, int8_t& val); bool ToUint8(std::string_view str, uint8_t& val); bool ToInt16(std::string_view str, int16_t& val); diff --git a/include/util/DigitCounter.h b/include/util/DigitCounter.h new file mode 100644 index 00000000..d4cd7ceb --- /dev/null +++ b/include/util/DigitCounter.h @@ -0,0 +1,42 @@ +#pragma once + +#include +#include +#include + +namespace OpenShock::Util { + template + constexpr std::size_t Digits10CountMax() + { + static_assert(std::is_integral::value); + uint64_t num = std::numeric_limits::max(); + + std::size_t digits = std::is_signed::value ? 2 : 1; + while (num >= 10) { + num /= 10; + digits++; + } + + return digits; + } + + template + constexpr std::size_t Digits10Count(T val) + { + static_assert(std::is_integral::value); + + std::size_t digits = 1; + + if (std::is_signed::value && val < 0) { + digits++; + val = -val; + } + + while (val >= 10) { + val /= 10; + digits++; + } + + return digits; + } +} // namespace OpenShock::Util diff --git a/src/Convert.cpp b/src/Convert.cpp index c21b5ff6..afb1a2e8 100644 --- a/src/Convert.cpp +++ b/src/Convert.cpp @@ -1,5 +1,7 @@ #include "Convert.h" +#include "util/DigitCounter.h" + #include #include #include @@ -8,19 +10,52 @@ using namespace std::string_view_literals; +// Base converter template -constexpr unsigned int NumDigits() +void fromNonZeroT(T val, std::string& str) { static_assert(std::is_integral::value); - uint64_t num = std::numeric_limits::max(); + const std::size_t MaxDigits = OpenShock::Util::Digits10CountMax(); + + char buf[MaxDigits + 1]; // +1 for null terminator + + char* ptr = buf + MaxDigits; + + // Null terminator + *ptr-- = '\0'; + + // Handle negative numbers + bool negative = val < 0; + if (negative) { + val = -val; + } + + // Convert to string + while (val > 0) { + *ptr-- = '0' + (val % 10); + val /= 10; + } - unsigned int digits = std::is_signed::value ? 2 : 1; - while (num >= 10) { - num /= 10; - digits++; + if (negative) { + *ptr-- = '-'; } - return digits; + // Append to string with length + str.append(ptr + 1, buf + MaxDigits + 1); +} + +// Base converter +template +void fromT(T val, std::string& str) +{ + static_assert(std::is_integral::value); + + if (val == 0) { + str.push_back('0'); + return; + } + + fromNonZeroT(val, str); } // Base converter @@ -65,7 +100,7 @@ constexpr bool spanToUT(std::string_view str, T& val) { static_assert(std::is_unsigned::value); - if (str.empty() || str.length() > NumDigits()) { + if (str.empty() || str.length() > OpenShock::Util::Digits10CountMax()) { return false; } @@ -78,7 +113,7 @@ constexpr bool spanToST(std::string_view str, T& val) { static_assert(std::is_signed::value); - if (str.empty() || str.length() > NumDigits()) { + if (str.empty() || str.length() > OpenShock::Util::Digits10CountMax()) { return false; } @@ -107,6 +142,60 @@ constexpr bool spanToST(std::string_view str, T& val) using namespace OpenShock; // Specific converters +void Convert::FromInt8(int8_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromUint8(uint8_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromInt16(int16_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromUint16(uint16_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromInt32(int32_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromUint32(uint32_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromInt64(int64_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromUint64(uint64_t val, std::string& str) +{ + fromT(val, str); +} + +void Convert::FromBool(bool val, std::string& str) +{ + if (val) { + str += "true"; + } else { + str += "false"; + } +} + +void Convert::FromGpioNum(gpio_num_t val, std::string& str) +{ + fromT(static_cast(val), str); +} + bool Convert::ToInt8(std::string_view str, int8_t& val) { return spanToST(str, val); @@ -174,16 +263,6 @@ bool Convert::ToGpioNum(std::string_view str, gpio_num_t& val) return true; } -static_assert(NumDigits() == 3, "NumDigits test for uint8_t failed"); -static_assert(NumDigits() == 5, "NumDigits test for uint16_t failed"); -static_assert(NumDigits() == 10, "NumDigits test for uint32_t failed"); -static_assert(NumDigits() == 20, "NumDigits test for uint64_t failed"); - -static_assert(NumDigits() == 4, "NumDigits test for int8_t failed"); -static_assert(NumDigits() == 6, "NumDigits test for int16_t failed"); -static_assert(NumDigits() == 11, "NumDigits test for int32_t failed"); -static_assert(NumDigits() == 20, "NumDigits test for int64_t failed"); - constexpr bool test_spanToUT8() { uint8_t u8 = 0; diff --git a/src/SemVer.cpp b/src/SemVer.cpp index 9a25e51d..5cac5c61 100644 --- a/src/SemVer.cpp +++ b/src/SemVer.cpp @@ -2,11 +2,16 @@ const char* const TAG = "SemVer"; +#include "Convert.h" #include "Logging.h" +#include "util/DigitCounter.h" #include "util/StringUtils.h" using namespace OpenShock; +// https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions +#pragma region Validation Functions + constexpr bool _semverIsLetter(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); @@ -208,31 +213,7 @@ bool _semverIsSemver(std::string_view str) return false; } - -bool _tryParseU16(std::string_view str, uint16_t& out) -{ - if (str.empty()) { - return false; - } - - uint32_t u32 = 0; - for (auto c : str) { - if (c < '0' || c > '9') { - return false; - } - - u32 *= 10; - u32 += c - '0'; - - if (u32 > std::numeric_limits::max()) { - return false; - } - } - - out = static_cast(u32); - - return true; -} +#pragma endregion bool SemVer::isValid() const { @@ -249,14 +230,22 @@ bool SemVer::isValid() const std::string SemVer::toString() const { + std::size_t length = 2 + Util::Digits10Count(major) + Util::Digits10Count(minor) + Util::Digits10Count(patch); + if (!prerelease.empty()) { + length += 1 + prerelease.length(); + } + if (!build.empty()) { + length += 1 + build.length(); + } + std::string str; - str.reserve(32); + str.reserve(length); - str += std::to_string(major); + Convert::FromUint16(major, str); str += '.'; - str += std::to_string(minor); + Convert::FromUint16(minor, str); str += '.'; - str += std::to_string(patch); + Convert::FromUint16(patch, str); if (!prerelease.empty()) { str += '-'; @@ -351,17 +340,17 @@ bool OpenShock::TryParseSemVer(std::string_view semverStr, SemVer& semver) semver.prerelease = semver.prerelease.substr(0, plusIdx); } - if (!_tryParseU16(majorStr, semver.major)) { + if (!Convert::ToUint16(majorStr, semver.major)) { OS_LOGE(TAG, "Invalid major version: %.*s", majorStr.length(), majorStr.data()); return false; } - if (!_tryParseU16(minorStr, semver.minor)) { + if (!Convert::ToUint16(minorStr, semver.minor)) { OS_LOGE(TAG, "Invalid minor version: %.*s", minorStr.length(), minorStr.data()); return false; } - if (!_tryParseU16(patchStr, semver.patch)) { + if (!Convert::ToUint16(patchStr, semver.patch)) { OS_LOGE(TAG, "Invalid patch version: %.*s", patchStr.length(), patchStr.data()); return false; } diff --git a/src/util/DigitCounter.cpp b/src/util/DigitCounter.cpp new file mode 100644 index 00000000..5dda109b --- /dev/null +++ b/src/util/DigitCounter.cpp @@ -0,0 +1,13 @@ +#include "util/DigitCounter.h" + +using namespace OpenShock; + +static_assert(Util::Digits10CountMax() == 3, "NumDigits test for uint8_t failed"); +static_assert(Util::Digits10CountMax() == 5, "NumDigits test for uint16_t failed"); +static_assert(Util::Digits10CountMax() == 10, "NumDigits test for uint32_t failed"); +static_assert(Util::Digits10CountMax() == 20, "NumDigits test for uint64_t failed"); + +static_assert(Util::Digits10CountMax() == 4, "NumDigits test for int8_t failed"); +static_assert(Util::Digits10CountMax() == 6, "NumDigits test for int16_t failed"); +static_assert(Util::Digits10CountMax() == 11, "NumDigits test for int32_t failed"); +static_assert(Util::Digits10CountMax() == 20, "NumDigits test for int64_t failed"); From e83e52dbfeab49532042164921296216f3e0e9c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:08:43 +0100 Subject: [PATCH 013/155] build(deps): Bump the frontend group across 1 directory with 6 updates (#309) Bumps the frontend group with 6 updates in the /frontend directory: | Package | From | To | | --- | --- | --- | | [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `5.4.9` | `5.4.10` | | [@playwright/test](https://github.com/microsoft/playwright) | `1.48.1` | `1.48.2` | | [@skeletonlabs/skeleton](https://github.com/skeletonlabs/skeleton) | `2.10.2` | `2.10.3` | | [@sveltejs/adapter-static](https://github.com/sveltejs/kit/tree/HEAD/packages/adapter-static) | `3.0.5` | `3.0.6` | | [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit) | `2.7.2` | `2.7.3` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.7.7` | `22.8.1` | Updates `vite` from 5.4.9 to 5.4.10 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/v5.4.10/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.4.10/packages/vite) Updates `@playwright/test` from 1.48.1 to 1.48.2 - [Release notes](https://github.com/microsoft/playwright/releases) - [Commits](https://github.com/microsoft/playwright/compare/v1.48.1...v1.48.2) Updates `@skeletonlabs/skeleton` from 2.10.2 to 2.10.3 - [Release notes](https://github.com/skeletonlabs/skeleton/releases) - [Commits](https://github.com/skeletonlabs/skeleton/compare/@skeletonlabs/skeleton@2.10.2...@skeletonlabs/skeleton@2.10.3) Updates `@sveltejs/adapter-static` from 3.0.5 to 3.0.6 - [Release notes](https://github.com/sveltejs/kit/releases) - [Changelog](https://github.com/sveltejs/kit/blob/main/packages/adapter-static/CHANGELOG.md) - [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/adapter-static@3.0.6/packages/adapter-static) Updates `@sveltejs/kit` from 2.7.2 to 2.7.3 - [Release notes](https://github.com/sveltejs/kit/releases) - [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md) - [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.7.3/packages/kit) Updates `@types/node` from 22.7.7 to 22.8.1 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: vite dependency-type: direct:production update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@playwright/test" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@skeletonlabs/skeleton" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@sveltejs/adapter-static" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@sveltejs/kit" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/package.json | 12 +- frontend/pnpm-lock.yaml | 294 +++++++++++++++++++++------------------- 2 files changed, 162 insertions(+), 144 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 45ccccdf..b4869cc5 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,15 +17,15 @@ }, "devDependencies": { "@floating-ui/dom": "1.6.11", - "@playwright/test": "1.48.1", - "@skeletonlabs/skeleton": "2.10.2", + "@playwright/test": "1.48.2", + "@skeletonlabs/skeleton": "2.10.3", "@skeletonlabs/tw-plugin": "0.4.0", - "@sveltejs/adapter-static": "^3.0.5", - "@sveltejs/kit": "2.7.2", + "@sveltejs/adapter-static": "^3.0.6", + "@sveltejs/kit": "2.7.3", "@sveltejs/vite-plugin-svelte": "^3.1.2", "@tailwindcss/forms": "0.5.9", "@tailwindcss/typography": "0.5.15", - "@types/node": "22.7.7", + "@types/node": "22.8.1", "autoprefixer": "10.4.20", "eslint": "^9.13.0", "eslint-config-prettier": "9.1.0", @@ -43,7 +43,7 @@ "vitest": "2.1.3" }, "dependencies": { - "vite": "^5.4.9" + "vite": "^5.4.10" }, "engines": { "node": ">=20.18", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 294ad71b..71cdce4c 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -9,30 +9,30 @@ importers: .: dependencies: vite: - specifier: ^5.4.9 - version: 5.4.9(@types/node@22.7.7) + specifier: ^5.4.10 + version: 5.4.10(@types/node@22.8.1) devDependencies: '@floating-ui/dom': specifier: 1.6.11 version: 1.6.11 '@playwright/test': - specifier: 1.48.1 - version: 1.48.1 + specifier: 1.48.2 + version: 1.48.2 '@skeletonlabs/skeleton': - specifier: 2.10.2 - version: 2.10.2(svelte@4.2.19) + specifier: 2.10.3 + version: 2.10.3(svelte@4.2.19) '@skeletonlabs/tw-plugin': specifier: 0.4.0 version: 0.4.0(tailwindcss@3.4.14) '@sveltejs/adapter-static': - specifier: ^3.0.5 - version: 3.0.5(@sveltejs/kit@2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))) + specifier: ^3.0.6 + version: 3.0.6(@sveltejs/kit@2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))) '@sveltejs/kit': - specifier: 2.7.2 - version: 2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + specifier: 2.7.3 + version: 2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + version: 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) '@tailwindcss/forms': specifier: 0.5.9 version: 0.5.9(tailwindcss@3.4.14) @@ -40,8 +40,8 @@ importers: specifier: 0.5.15 version: 0.5.15(tailwindcss@3.4.14) '@types/node': - specifier: 22.7.7 - version: 22.7.7 + specifier: 22.8.1 + version: 22.8.1 autoprefixer: specifier: 10.4.20 version: 10.4.20(postcss@8.4.47) @@ -83,10 +83,10 @@ importers: version: 5.6.3 vite-plugin-tailwind-purgecss: specifier: ^0.3.3 - version: 0.3.3(tailwindcss@3.4.14)(vite@5.4.9(@types/node@22.7.7)) + version: 0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.1)) vitest: specifier: 2.1.3 - version: 2.1.3(@types/node@22.7.7) + version: 2.1.3(@types/node@22.8.1) packages: @@ -333,111 +333,121 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@playwright/test@1.48.1': - resolution: {integrity: sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==} + '@playwright/test@1.48.2': + resolution: {integrity: sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==} engines: {node: '>=18'} hasBin: true '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} - '@rollup/rollup-android-arm-eabi@4.24.0': - resolution: {integrity: sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==} + '@rollup/rollup-android-arm-eabi@4.24.2': + resolution: {integrity: sha512-ufoveNTKDg9t/b7nqI3lwbCG/9IJMhADBNjjz/Jn6LxIZxD7T5L8l2uO/wD99945F1Oo8FvgbbZJRguyk/BdzA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.24.0': - resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} + '@rollup/rollup-android-arm64@4.24.2': + resolution: {integrity: sha512-iZoYCiJz3Uek4NI0J06/ZxUgwAfNzqltK0MptPDO4OR0a88R4h0DSELMsflS6ibMCJ4PnLvq8f7O1d7WexUvIA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.24.0': - resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} + '@rollup/rollup-darwin-arm64@4.24.2': + resolution: {integrity: sha512-/UhrIxobHYCBfhi5paTkUDQ0w+jckjRZDZ1kcBL132WeHZQ6+S5v9jQPVGLVrLbNUebdIRpIt00lQ+4Z7ys4Rg==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.24.0': - resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} + '@rollup/rollup-darwin-x64@4.24.2': + resolution: {integrity: sha512-1F/jrfhxJtWILusgx63WeTvGTwE4vmsT9+e/z7cZLKU8sBMddwqw3UV5ERfOV+H1FuRK3YREZ46J4Gy0aP3qDA==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': - resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} + '@rollup/rollup-freebsd-arm64@4.24.2': + resolution: {integrity: sha512-1YWOpFcGuC6iGAS4EI+o3BV2/6S0H+m9kFOIlyFtp4xIX5rjSnL3AwbTBxROX0c8yWtiWM7ZI6mEPTI7VkSpZw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.24.2': + resolution: {integrity: sha512-3qAqTewYrCdnOD9Gl9yvPoAoFAVmPJsBvleabvx4bnu1Kt6DrB2OALeRVag7BdWGWLhP1yooeMLEi6r2nYSOjg==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.24.2': + resolution: {integrity: sha512-ArdGtPHjLqWkqQuoVQ6a5UC5ebdX8INPuJuJNWRe0RGa/YNhVvxeWmCTFQ7LdmNCSUzVZzxAvUznKaYx645Rig==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.24.0': - resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} + '@rollup/rollup-linux-arm-musleabihf@4.24.2': + resolution: {integrity: sha512-B6UHHeNnnih8xH6wRKB0mOcJGvjZTww1FV59HqJoTJ5da9LCG6R4SEBt6uPqzlawv1LoEXSS0d4fBlHNWl6iYw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.24.0': - resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} + '@rollup/rollup-linux-arm64-gnu@4.24.2': + resolution: {integrity: sha512-kr3gqzczJjSAncwOS6i7fpb4dlqcvLidqrX5hpGBIM1wtt0QEVtf4wFaAwVv8QygFU8iWUMYEoJZWuWxyua4GQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.24.0': - resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} + '@rollup/rollup-linux-arm64-musl@4.24.2': + resolution: {integrity: sha512-TDdHLKCWgPuq9vQcmyLrhg/bgbOvIQ8rtWQK7MRxJ9nvaxKx38NvY7/Lo6cYuEnNHqf6rMqnivOIPIQt6H2AoA==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': - resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} + '@rollup/rollup-linux-powerpc64le-gnu@4.24.2': + resolution: {integrity: sha512-xv9vS648T3X4AxFFZGWeB5Dou8ilsv4VVqJ0+loOIgDO20zIhYfDLkk5xoQiej2RiSQkld9ijF/fhLeonrz2mw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.24.0': - resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} + '@rollup/rollup-linux-riscv64-gnu@4.24.2': + resolution: {integrity: sha512-tbtXwnofRoTt223WUZYiUnbxhGAOVul/3StZ947U4A5NNjnQJV5irKMm76G0LGItWs6y+SCjUn/Q0WaMLkEskg==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.24.0': - resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} + '@rollup/rollup-linux-s390x-gnu@4.24.2': + resolution: {integrity: sha512-gc97UebApwdsSNT3q79glOSPdfwgwj5ELuiyuiMY3pEWMxeVqLGKfpDFoum4ujivzxn6veUPzkGuSYoh5deQ2Q==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.24.0': - resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} + '@rollup/rollup-linux-x64-gnu@4.24.2': + resolution: {integrity: sha512-jOG/0nXb3z+EM6SioY8RofqqmZ+9NKYvJ6QQaa9Mvd3RQxlH68/jcB/lpyVt4lCiqr04IyaC34NzhUqcXbB5FQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.24.0': - resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} + '@rollup/rollup-linux-x64-musl@4.24.2': + resolution: {integrity: sha512-XAo7cJec80NWx9LlZFEJQxqKOMz/lX3geWs2iNT5CHIERLFfd90f3RYLLjiCBm1IMaQ4VOX/lTC9lWfzzQm14Q==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.24.0': - resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} + '@rollup/rollup-win32-arm64-msvc@4.24.2': + resolution: {integrity: sha512-A+JAs4+EhsTjnPQvo9XY/DC0ztaws3vfqzrMNMKlwQXuniBKOIIvAAI8M0fBYiTCxQnElYu7mLk7JrhlQ+HeOw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.24.0': - resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} + '@rollup/rollup-win32-ia32-msvc@4.24.2': + resolution: {integrity: sha512-ZhcrakbqA1SCiJRMKSU64AZcYzlZ/9M5LaYil9QWxx9vLnkQ9Vnkve17Qn4SjlipqIIBFKjBES6Zxhnvh0EAEw==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.24.0': - resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} + '@rollup/rollup-win32-x64-msvc@4.24.2': + resolution: {integrity: sha512-2mLH46K1u3r6uwc95hU+OR9q/ggYMpnS7pSp83Ece1HUQgF9Nh/QwTK5rcgbFnV9j+08yBrU5sA/P0RK2MSBNA==} cpu: [x64] os: [win32] - '@skeletonlabs/skeleton@2.10.2': - resolution: {integrity: sha512-TV2yWjvHpmtaF1F5luB8n7UbjKZcsrJMMiiJQHbZvqXjBWvudAcL8zywhE/NFKW5rYU//MtgOODdMZPZxvKu6w==} + '@skeletonlabs/skeleton@2.10.3': + resolution: {integrity: sha512-O1RecF68zEVvZl3GgRS4emqWMUIQLHvTOFoqGOw/2OXCPE06IxUQrHQf2hnxCPxtGZNXY2YX8UNV38l+eH8GNQ==} peerDependencies: - svelte: ^3.56.0 || ^4.0.0 + svelte: ^3.56.0 || ^4.0.0 || ^5.0.0 '@skeletonlabs/tw-plugin@0.4.0': resolution: {integrity: sha512-v6Y4deBq9ByRx3kTRGgekhhYkWEYgNNNu8UXOwJngCStB7w8SwmbNFSeHkluxMbgCgMnJyp220EMpw9nj/rEsQ==} peerDependencies: tailwindcss: '>=3.0.0' - '@sveltejs/adapter-static@3.0.5': - resolution: {integrity: sha512-kFJR7RxeB6FBvrKZWAEzIALatgy11ISaaZbcPup8JdWUdrmmfUHHTJ738YHJTEfnCiiXi6aX8Q6ePY7tnSMD6Q==} + '@sveltejs/adapter-static@3.0.6': + resolution: {integrity: sha512-MGJcesnJWj7FxDcB/GbrdYD3q24Uk0PIL4QIX149ku+hlJuj//nxUbb0HxUTpjkecWfHjVveSUnUaQWnPRXlpg==} peerDependencies: '@sveltejs/kit': ^2.0.0 - '@sveltejs/kit@2.7.2': - resolution: {integrity: sha512-bFwrl+0bNr0/DHQZM0INwwSPNYqDjfsKRhUoa6rj9d8tDZzszBrJ3La6/HVFxWGONEigtG+SzHXa1BEa1BLdwA==} + '@sveltejs/kit@2.7.3': + resolution: {integrity: sha512-Vx7nq5MJ86I8qXYsVidC5PX6xm+uxt8DydvOdmJoyOK7LvGP18OFEG359yY+aa51t6pENvqZAMqAREQQx1OI2Q==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -479,8 +489,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@22.7.7': - resolution: {integrity: sha512-SRxCrrg9CL/y54aiMCG3edPKdprgMVGDXjA3gB8UmmBW5TcXzRUYAh8EWzTnSJFAd1rgImPELza+A3bJ+qxz8Q==} + '@types/node@22.8.1': + resolution: {integrity: sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg==} '@vitest/expect@2.1.3': resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} @@ -1158,13 +1168,13 @@ packages: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} - playwright-core@1.48.1: - resolution: {integrity: sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==} + playwright-core@1.48.2: + resolution: {integrity: sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==} engines: {node: '>=18'} hasBin: true - playwright@1.48.1: - resolution: {integrity: sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==} + playwright@1.48.2: + resolution: {integrity: sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==} engines: {node: '>=18'} hasBin: true @@ -1289,8 +1299,8 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rollup@4.24.0: - resolution: {integrity: sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==} + rollup@4.24.2: + resolution: {integrity: sha512-do/DFGq5g6rdDhdpPq5qb2ecoczeK6y+2UAjdJ5trjQJj5f1AiVdLRWRc9A9/fFukfvJRgM0UXzxBIYMovm5ww==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -1306,8 +1316,8 @@ packages: engines: {node: '>=10'} hasBin: true - set-cookie-parser@2.7.0: - resolution: {integrity: sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==} + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -1483,8 +1493,8 @@ packages: tailwindcss: ^3.3.0 vite: ^4.1.1 || ^5.0.0 - vite@5.4.9: - resolution: {integrity: sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==} + vite@5.4.10: + resolution: {integrity: sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -1762,61 +1772,67 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@playwright/test@1.48.1': + '@playwright/test@1.48.2': dependencies: - playwright: 1.48.1 + playwright: 1.48.2 '@polka/url@1.0.0-next.28': {} - '@rollup/rollup-android-arm-eabi@4.24.0': + '@rollup/rollup-android-arm-eabi@4.24.2': + optional: true + + '@rollup/rollup-android-arm64@4.24.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.24.2': optional: true - '@rollup/rollup-android-arm64@4.24.0': + '@rollup/rollup-darwin-x64@4.24.2': optional: true - '@rollup/rollup-darwin-arm64@4.24.0': + '@rollup/rollup-freebsd-arm64@4.24.2': optional: true - '@rollup/rollup-darwin-x64@4.24.0': + '@rollup/rollup-freebsd-x64@4.24.2': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.24.0': + '@rollup/rollup-linux-arm-gnueabihf@4.24.2': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.24.0': + '@rollup/rollup-linux-arm-musleabihf@4.24.2': optional: true - '@rollup/rollup-linux-arm64-gnu@4.24.0': + '@rollup/rollup-linux-arm64-gnu@4.24.2': optional: true - '@rollup/rollup-linux-arm64-musl@4.24.0': + '@rollup/rollup-linux-arm64-musl@4.24.2': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.24.2': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.24.0': + '@rollup/rollup-linux-riscv64-gnu@4.24.2': optional: true - '@rollup/rollup-linux-s390x-gnu@4.24.0': + '@rollup/rollup-linux-s390x-gnu@4.24.2': optional: true - '@rollup/rollup-linux-x64-gnu@4.24.0': + '@rollup/rollup-linux-x64-gnu@4.24.2': optional: true - '@rollup/rollup-linux-x64-musl@4.24.0': + '@rollup/rollup-linux-x64-musl@4.24.2': optional: true - '@rollup/rollup-win32-arm64-msvc@4.24.0': + '@rollup/rollup-win32-arm64-msvc@4.24.2': optional: true - '@rollup/rollup-win32-ia32-msvc@4.24.0': + '@rollup/rollup-win32-ia32-msvc@4.24.2': optional: true - '@rollup/rollup-win32-x64-msvc@4.24.0': + '@rollup/rollup-win32-x64-msvc@4.24.2': optional: true - '@skeletonlabs/skeleton@2.10.2(svelte@4.2.19)': + '@skeletonlabs/skeleton@2.10.3(svelte@4.2.19)': dependencies: esm-env: 1.0.0 svelte: 4.2.19 @@ -1825,13 +1841,13 @@ snapshots: dependencies: tailwindcss: 3.4.14 - '@sveltejs/adapter-static@3.0.5(@sveltejs/kit@2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))': + '@sveltejs/adapter-static@3.0.6(@sveltejs/kit@2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))': dependencies: - '@sveltejs/kit': 2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + '@sveltejs/kit': 2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) - '@sveltejs/kit@2.7.2(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))': + '@sveltejs/kit@2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.1.1 @@ -1841,32 +1857,32 @@ snapshots: magic-string: 0.30.12 mrmime: 2.0.0 sade: 1.8.1 - set-cookie-parser: 2.7.0 + set-cookie-parser: 2.7.1 sirv: 3.0.0 svelte: 4.2.19 tiny-glob: 0.2.9 - vite: 5.4.9(@types/node@22.7.7) + vite: 5.4.10(@types/node@22.8.1) - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) debug: 4.3.7 svelte: 4.2.19 - vite: 5.4.9(@types/node@22.7.7) + vite: 5.4.10(@types/node@22.8.1) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)))(svelte@4.2.19)(vite@5.4.9(@types/node@22.7.7)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) debug: 4.3.7 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.12 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.4.9(@types/node@22.7.7) - vitefu: 0.2.5(vite@5.4.9(@types/node@22.7.7)) + vite: 5.4.10(@types/node@22.8.1) + vitefu: 0.2.5(vite@5.4.10(@types/node@22.8.1)) transitivePeerDependencies: - supports-color @@ -1889,7 +1905,7 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@22.7.7': + '@types/node@22.8.1': dependencies: undici-types: 6.19.8 @@ -1900,13 +1916,13 @@ snapshots: chai: 5.1.1 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.7))': + '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@22.8.1))': dependencies: '@vitest/spy': 2.1.3 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - vite: 5.4.9(@types/node@22.7.7) + vite: 5.4.10(@types/node@22.8.1) '@vitest/pretty-format@2.1.3': dependencies: @@ -2545,11 +2561,11 @@ snapshots: pirates@4.0.6: {} - playwright-core@1.48.1: {} + playwright-core@1.48.2: {} - playwright@1.48.1: + playwright@1.48.2: dependencies: - playwright-core: 1.48.1 + playwright-core: 1.48.2 optionalDependencies: fsevents: 2.3.2 @@ -2655,26 +2671,28 @@ snapshots: reusify@1.0.4: {} - rollup@4.24.0: + rollup@4.24.2: dependencies: '@types/estree': 1.0.6 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.24.0 - '@rollup/rollup-android-arm64': 4.24.0 - '@rollup/rollup-darwin-arm64': 4.24.0 - '@rollup/rollup-darwin-x64': 4.24.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.24.0 - '@rollup/rollup-linux-arm-musleabihf': 4.24.0 - '@rollup/rollup-linux-arm64-gnu': 4.24.0 - '@rollup/rollup-linux-arm64-musl': 4.24.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.24.0 - '@rollup/rollup-linux-riscv64-gnu': 4.24.0 - '@rollup/rollup-linux-s390x-gnu': 4.24.0 - '@rollup/rollup-linux-x64-gnu': 4.24.0 - '@rollup/rollup-linux-x64-musl': 4.24.0 - '@rollup/rollup-win32-arm64-msvc': 4.24.0 - '@rollup/rollup-win32-ia32-msvc': 4.24.0 - '@rollup/rollup-win32-x64-msvc': 4.24.0 + '@rollup/rollup-android-arm-eabi': 4.24.2 + '@rollup/rollup-android-arm64': 4.24.2 + '@rollup/rollup-darwin-arm64': 4.24.2 + '@rollup/rollup-darwin-x64': 4.24.2 + '@rollup/rollup-freebsd-arm64': 4.24.2 + '@rollup/rollup-freebsd-x64': 4.24.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.24.2 + '@rollup/rollup-linux-arm-musleabihf': 4.24.2 + '@rollup/rollup-linux-arm64-gnu': 4.24.2 + '@rollup/rollup-linux-arm64-musl': 4.24.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.24.2 + '@rollup/rollup-linux-riscv64-gnu': 4.24.2 + '@rollup/rollup-linux-s390x-gnu': 4.24.2 + '@rollup/rollup-linux-x64-gnu': 4.24.2 + '@rollup/rollup-linux-x64-musl': 4.24.2 + '@rollup/rollup-win32-arm64-msvc': 4.24.2 + '@rollup/rollup-win32-ia32-msvc': 4.24.2 + '@rollup/rollup-win32-x64-msvc': 4.24.2 fsevents: 2.3.3 run-parallel@1.2.0: @@ -2687,7 +2705,7 @@ snapshots: semver@7.6.3: {} - set-cookie-parser@2.7.0: {} + set-cookie-parser@2.7.1: {} shebang-command@2.0.0: dependencies: @@ -2874,12 +2892,12 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@2.1.3(@types/node@22.7.7): + vite-node@2.1.3(@types/node@22.8.1): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.4.9(@types/node@22.7.7) + vite: 5.4.10(@types/node@22.8.1) transitivePeerDependencies: - '@types/node' - less @@ -2891,7 +2909,7 @@ snapshots: - supports-color - terser - vite-plugin-tailwind-purgecss@0.3.3(tailwindcss@3.4.14)(vite@5.4.9(@types/node@22.7.7)): + vite-plugin-tailwind-purgecss@0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.1)): dependencies: chalk: 5.3.0 css-tree: 2.3.1 @@ -2899,25 +2917,25 @@ snapshots: purgecss: 6.0.0 purgecss-from-html: 6.0.0 tailwindcss: 3.4.14 - vite: 5.4.9(@types/node@22.7.7) + vite: 5.4.10(@types/node@22.8.1) - vite@5.4.9(@types/node@22.7.7): + vite@5.4.10(@types/node@22.8.1): dependencies: esbuild: 0.21.5 postcss: 8.4.47 - rollup: 4.24.0 + rollup: 4.24.2 optionalDependencies: - '@types/node': 22.7.7 + '@types/node': 22.8.1 fsevents: 2.3.3 - vitefu@0.2.5(vite@5.4.9(@types/node@22.7.7)): + vitefu@0.2.5(vite@5.4.10(@types/node@22.8.1)): optionalDependencies: - vite: 5.4.9(@types/node@22.7.7) + vite: 5.4.10(@types/node@22.8.1) - vitest@2.1.3(@types/node@22.7.7): + vitest@2.1.3(@types/node@22.8.1): dependencies: '@vitest/expect': 2.1.3 - '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.9(@types/node@22.7.7)) + '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@22.8.1)) '@vitest/pretty-format': 2.1.3 '@vitest/runner': 2.1.3 '@vitest/snapshot': 2.1.3 @@ -2932,11 +2950,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.9(@types/node@22.7.7) - vite-node: 2.1.3(@types/node@22.7.7) + vite: 5.4.10(@types/node@22.8.1) + vite-node: 2.1.3(@types/node@22.8.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.7.7 + '@types/node': 22.8.1 transitivePeerDependencies: - less - lightningcss From 4f2899c757947b63cb0a195a13910a801529381e Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 1 Nov 2024 22:42:55 +0100 Subject: [PATCH 014/155] Switch to using bunny cdn --- .github/actions/cdn-bump-version/action.yml | 2 +- .github/actions/cdn-prepare/action.yml | 30 ++++++++++--------- .../actions/cdn-upload-firmware/action.yml | 5 +--- .../cdn-upload-version-info/action.yml | 5 +--- .github/workflows/ci-build.yml | 24 +++++++-------- 5 files changed, 31 insertions(+), 35 deletions(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index 6f76f067..acb03760 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -19,4 +19,4 @@ runs: run: | mkdir -p upload echo "${{ inputs.version }}" >> upload/version-${{ inputs.release-channel }}.txt - rclone copy upload cdn:${{ inputs.cf-bucket }}/ + rclone copy upload cdn:/ diff --git a/.github/actions/cdn-prepare/action.yml b/.github/actions/cdn-prepare/action.yml index 3f70b0c1..a08696cb 100644 --- a/.github/actions/cdn-prepare/action.yml +++ b/.github/actions/cdn-prepare/action.yml @@ -1,14 +1,17 @@ -name: cdn-prepare -description: Prepares the CDN for firmware uploads +name: bunny-prepare +description: Bunny rclone setup inputs: - cf-account-id: - description: Cloudflare Account ID + bunny-stor-hostname: + description: Bunny SFTP Hostname required: true - cf-access-key-id: - description: Cloudflare Access Key ID + bunny-stor-port: + description: Bunny SFTP Port required: true - cf-secret-access-key: - description: Cloudflare Secret Access Key + bunny-stor-username: + description: Bunny SFTP Username + required: true + bunny-stor-password: + description: Bunny SFTP Password required: true runs: @@ -24,10 +27,9 @@ runs: mkdir -p ~/.config/rclone/ conf=~/.config/rclone/rclone.conf echo "[cdn]" >> $conf - echo "type = s3" >> $conf - echo "provider = Cloudflare" >> $conf - echo "access_key_id = ${{ inputs.cf-access-key-id }}" >> $conf - echo "secret_access_key = ${{ inputs.cf-secret-access-key }}" >> $conf - echo "endpoint = https://${{ inputs.cf-account-id }}.r2.cloudflarestorage.com" >> $conf - echo "acl = public-read" >> $conf + echo "type = sftp" >> $conf + echo "host = ${{ inputs.bunny-stor-hostname }}" >> $conf + echo "user = ${{ inputs.bunny-stor-username }}" >> $conf + echo "port = ${{ bunny-stor-port }}" >> $conf + echo "password = ${{ bunny-stor-password }}" >> $conf diff --git a/.github/actions/cdn-upload-firmware/action.yml b/.github/actions/cdn-upload-firmware/action.yml index eb591ee4..05b3157a 100644 --- a/.github/actions/cdn-upload-firmware/action.yml +++ b/.github/actions/cdn-upload-firmware/action.yml @@ -1,9 +1,6 @@ name: cdn-upload-firmware description: Uploads firmware partitions and merged binaries to CDN along with SHA256 checksums inputs: - cf-bucket: - description: Name of the S3 bucket - required: true fw-version: description: Firmware version required: true @@ -49,4 +46,4 @@ runs: mkdir -p upload mv *.bin upload/ mv hashes.*.txt upload/ - rclone copy upload 'cdn:${{ inputs.cf-bucket }}/${{ inputs.fw-version }}/${{ inputs.board }}/' + rclone copy upload 'cdn:${{ inputs.fw-version }}/${{ inputs.board }}/' diff --git a/.github/actions/cdn-upload-version-info/action.yml b/.github/actions/cdn-upload-version-info/action.yml index 9c8aa569..0a2d3683 100644 --- a/.github/actions/cdn-upload-version-info/action.yml +++ b/.github/actions/cdn-upload-version-info/action.yml @@ -1,9 +1,6 @@ name: cdn-upload-version-info description: Uploads version specific info to CDN inputs: - cf-bucket: - description: Name of the S3 bucket - required: true fw-version: description: Firmware version required: true @@ -27,4 +24,4 @@ runs: run: | mkdir -p upload mv boards.txt upload/ - rclone copy upload 'cdn:${{ inputs.cf-bucket }}/${{ inputs.fw-version }}/${{ inputs.board }}/' + rclone copy upload 'cdn:${{ inputs.fw-version }}/${{ inputs.board }}/' diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index bed80c7f..f81491a3 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -114,14 +114,14 @@ jobs: # Set up rclone for CDN uploads. - uses: ./.github/actions/cdn-prepare with: - cf-account-id: ${{ vars.S3_ACCOUNT_ID }} - cf-access-key-id: ${{ vars.S3_ACCESS_KEY_ID }} - cf-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }} + bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} + bunny-stor-port: ${{ vars.BUNNY_STOR_PORT }} + bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} + bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} # Upload firmware to CDN. - uses: ./.github/actions/cdn-upload-firmware with: - cf-bucket: ${{ vars.S3_BUCKET }} fw-version: ${{ needs.getvars.outputs.version }} board: ${{ matrix.board }} @@ -140,14 +140,14 @@ jobs: # Set up rclone for CDN uploads. - uses: ./.github/actions/cdn-prepare with: - cf-account-id: ${{ vars.S3_ACCOUNT_ID }} - cf-access-key-id: ${{ vars.S3_ACCESS_KEY_ID }} - cf-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }} + bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} + bunny-stor-port: ${{ vars.BUNNY_STOR_PORT }} + bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} + bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} # Upload firmware to CDN. - uses: ./.github/actions/cdn-upload-version-info with: - cf-bucket: ${{ vars.S3_BUCKET }} fw-version: ${{ needs.getvars.outputs.version }} release-channel: ${{ needs.getvars.outputs.release-channel }} boards: ${{ needs.getvars.outputs.board-list }} @@ -166,14 +166,14 @@ jobs: # Set up rclone for CDN uploads. - uses: ./.github/actions/cdn-prepare with: - cf-account-id: ${{ vars.S3_ACCOUNT_ID }} - cf-access-key-id: ${{ vars.S3_ACCESS_KEY_ID }} - cf-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }} + bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} + bunny-stor-port: ${{ vars.BUNNY_STOR_PORT }} + bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} + bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} # Upload firmware to CDN. - uses: ./.github/actions/cdn-bump-version with: - cf-bucket: ${{ vars.S3_BUCKET }} version: ${{ needs.getvars.outputs.version }} release-channel: ${{ needs.getvars.outputs.release-channel }} From aa4a2040776adb367d936ab2c035e9802a413c5f Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 1 Nov 2024 22:50:02 +0100 Subject: [PATCH 015/155] fix variable usage --- .github/actions/cdn-prepare/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/cdn-prepare/action.yml b/.github/actions/cdn-prepare/action.yml index a08696cb..99ec8b45 100644 --- a/.github/actions/cdn-prepare/action.yml +++ b/.github/actions/cdn-prepare/action.yml @@ -30,6 +30,6 @@ runs: echo "type = sftp" >> $conf echo "host = ${{ inputs.bunny-stor-hostname }}" >> $conf echo "user = ${{ inputs.bunny-stor-username }}" >> $conf - echo "port = ${{ bunny-stor-port }}" >> $conf - echo "password = ${{ bunny-stor-password }}" >> $conf + echo "port = ${{ inputs.bunny-stor-port }}" >> $conf + echo "password = ${{ inputs.bunny-stor-password }}" >> $conf From 1243bfa0537b2f8b883bd350341cbad87e4cc312 Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 1 Nov 2024 23:22:39 +0100 Subject: [PATCH 016/155] fix password name --- .github/actions/cdn-prepare/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cdn-prepare/action.yml b/.github/actions/cdn-prepare/action.yml index 99ec8b45..c92b83fc 100644 --- a/.github/actions/cdn-prepare/action.yml +++ b/.github/actions/cdn-prepare/action.yml @@ -31,5 +31,5 @@ runs: echo "host = ${{ inputs.bunny-stor-hostname }}" >> $conf echo "user = ${{ inputs.bunny-stor-username }}" >> $conf echo "port = ${{ inputs.bunny-stor-port }}" >> $conf - echo "password = ${{ inputs.bunny-stor-password }}" >> $conf + echo "pass = ${{ inputs.bunny-stor-password }}" >> $conf From c0589dfbce05ee974c98df9403fb31e4f28dfc98 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 00:00:02 +0100 Subject: [PATCH 017/155] Use scp... --- .github/actions/cdn-bump-version/action.yml | 11 ++++++- .github/actions/cdn-prepare/action.yml | 30 +++++-------------- .../actions/cdn-upload-firmware/action.yml | 11 ++++++- .../cdn-upload-version-info/action.yml | 11 ++++++- .github/workflows/ci-build.yml | 24 +++++++-------- 5 files changed, 49 insertions(+), 38 deletions(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index acb03760..a4198e39 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -1,6 +1,15 @@ name: cdn-bump-version description: Uploads version file to CDN inputs: + bunny-stor-host: + description: Bunny SFTP Hostname + required: true + bunny-stor-username: + description: Bunny SFTP Username + required: true + bunny-stor-password: + description: Bunny SFTP Password + required: true cf-bucket: description: Name of the S3 bucket required: true @@ -19,4 +28,4 @@ runs: run: | mkdir -p upload echo "${{ inputs.version }}" >> upload/version-${{ inputs.release-channel }}.txt - rclone copy upload cdn:/ + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-host }}:/ diff --git a/.github/actions/cdn-prepare/action.yml b/.github/actions/cdn-prepare/action.yml index c92b83fc..6396f8a3 100644 --- a/.github/actions/cdn-prepare/action.yml +++ b/.github/actions/cdn-prepare/action.yml @@ -1,35 +1,19 @@ -name: bunny-prepare -description: Bunny rclone setup +name: cdn-prepare +description: Bunny sshpass and knowhosts setup inputs: - bunny-stor-hostname: + bunny-ssh-knownhosts: description: Bunny SFTP Hostname required: true - bunny-stor-port: - description: Bunny SFTP Port - required: true - bunny-stor-username: - description: Bunny SFTP Username - required: true - bunny-stor-password: - description: Bunny SFTP Password - required: true runs: using: composite steps: - - name: Install rclone + - name: Install sshpass shell: bash - run: sudo apt-get install -y rclone + run: sudo apt-get install -y sshpass - - name: Configure rclone + - name: Configure known hosts shell: bash run: | - mkdir -p ~/.config/rclone/ - conf=~/.config/rclone/rclone.conf - echo "[cdn]" >> $conf - echo "type = sftp" >> $conf - echo "host = ${{ inputs.bunny-stor-hostname }}" >> $conf - echo "user = ${{ inputs.bunny-stor-username }}" >> $conf - echo "port = ${{ inputs.bunny-stor-port }}" >> $conf - echo "pass = ${{ inputs.bunny-stor-password }}" >> $conf + echo "${{ inputs.bunny-ssh-knownhosts }}" >> ~/.ssh/known_hosts diff --git a/.github/actions/cdn-upload-firmware/action.yml b/.github/actions/cdn-upload-firmware/action.yml index 05b3157a..c51c55ff 100644 --- a/.github/actions/cdn-upload-firmware/action.yml +++ b/.github/actions/cdn-upload-firmware/action.yml @@ -1,6 +1,15 @@ name: cdn-upload-firmware description: Uploads firmware partitions and merged binaries to CDN along with SHA256 checksums inputs: + bunny-stor-host: + description: Bunny SFTP Hostname + required: true + bunny-stor-username: + description: Bunny SFTP Username + required: true + bunny-stor-password: + description: Bunny SFTP Password + required: true fw-version: description: Firmware version required: true @@ -46,4 +55,4 @@ runs: mkdir -p upload mv *.bin upload/ mv hashes.*.txt upload/ - rclone copy upload 'cdn:${{ inputs.fw-version }}/${{ inputs.board }}/' + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-host }}:/${{ inputs.fw-version }}/${{ inputs.board }} \ No newline at end of file diff --git a/.github/actions/cdn-upload-version-info/action.yml b/.github/actions/cdn-upload-version-info/action.yml index 0a2d3683..74104825 100644 --- a/.github/actions/cdn-upload-version-info/action.yml +++ b/.github/actions/cdn-upload-version-info/action.yml @@ -1,6 +1,15 @@ name: cdn-upload-version-info description: Uploads version specific info to CDN inputs: + bunny-stor-host: + description: Bunny SFTP Hostname + required: true + bunny-stor-username: + description: Bunny SFTP Username + required: true + bunny-stor-password: + description: Bunny SFTP Password + required: true fw-version: description: Firmware version required: true @@ -24,4 +33,4 @@ runs: run: | mkdir -p upload mv boards.txt upload/ - rclone copy upload 'cdn:${{ inputs.fw-version }}/${{ inputs.board }}/' + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-host }}:/${{ inputs.fw-version }}/${{ inputs.board }} diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index f81491a3..830345df 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -114,14 +114,14 @@ jobs: # Set up rclone for CDN uploads. - uses: ./.github/actions/cdn-prepare with: - bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} - bunny-stor-port: ${{ vars.BUNNY_STOR_PORT }} - bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} - bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} + bunny-ssh-knownhosts: ${{ vars.BUNNY_SSH_KNOWNHOSTS }} # Upload firmware to CDN. - uses: ./.github/actions/cdn-upload-firmware with: + bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} + bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} + bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} fw-version: ${{ needs.getvars.outputs.version }} board: ${{ matrix.board }} @@ -140,14 +140,14 @@ jobs: # Set up rclone for CDN uploads. - uses: ./.github/actions/cdn-prepare with: - bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} - bunny-stor-port: ${{ vars.BUNNY_STOR_PORT }} - bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} - bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} + bunny-ssh-knownhosts: ${{ vars.BUNNY_SSH_KNOWNHOSTS }} # Upload firmware to CDN. - uses: ./.github/actions/cdn-upload-version-info with: + bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} + bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} + bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} fw-version: ${{ needs.getvars.outputs.version }} release-channel: ${{ needs.getvars.outputs.release-channel }} boards: ${{ needs.getvars.outputs.board-list }} @@ -166,14 +166,14 @@ jobs: # Set up rclone for CDN uploads. - uses: ./.github/actions/cdn-prepare with: - bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} - bunny-stor-port: ${{ vars.BUNNY_STOR_PORT }} - bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} - bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} + bunny-ssh-knownhosts: ${{ vars.BUNNY_SSH_KNOWNHOSTS }} # Upload firmware to CDN. - uses: ./.github/actions/cdn-bump-version with: + bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} + bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} + bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} version: ${{ needs.getvars.outputs.version }} release-channel: ${{ needs.getvars.outputs.release-channel }} From d325ec28eb048b391005d0e2fd56c680f9a389d5 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 00:09:32 +0100 Subject: [PATCH 018/155] Add .ssh folder lol.. --- .github/actions/cdn-prepare/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/cdn-prepare/action.yml b/.github/actions/cdn-prepare/action.yml index 6396f8a3..c00e3b67 100644 --- a/.github/actions/cdn-prepare/action.yml +++ b/.github/actions/cdn-prepare/action.yml @@ -15,5 +15,6 @@ runs: - name: Configure known hosts shell: bash run: | + mkdir -p ~/.ssh echo "${{ inputs.bunny-ssh-knownhosts }}" >> ~/.ssh/known_hosts From a5f7dcbf7fdb9ab3d1bb6c5488c7c216db441e54 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 00:14:21 +0100 Subject: [PATCH 019/155] fix naming --- .github/actions/cdn-bump-version/action.yml | 2 +- .github/actions/cdn-upload-firmware/action.yml | 2 +- .github/actions/cdn-upload-version-info/action.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index a4198e39..120cc1a8 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -1,7 +1,7 @@ name: cdn-bump-version description: Uploads version file to CDN inputs: - bunny-stor-host: + bunny-stor-hostname: description: Bunny SFTP Hostname required: true bunny-stor-username: diff --git a/.github/actions/cdn-upload-firmware/action.yml b/.github/actions/cdn-upload-firmware/action.yml index c51c55ff..c2f9d22f 100644 --- a/.github/actions/cdn-upload-firmware/action.yml +++ b/.github/actions/cdn-upload-firmware/action.yml @@ -1,7 +1,7 @@ name: cdn-upload-firmware description: Uploads firmware partitions and merged binaries to CDN along with SHA256 checksums inputs: - bunny-stor-host: + bunny-stor-hostname: description: Bunny SFTP Hostname required: true bunny-stor-username: diff --git a/.github/actions/cdn-upload-version-info/action.yml b/.github/actions/cdn-upload-version-info/action.yml index 74104825..19855704 100644 --- a/.github/actions/cdn-upload-version-info/action.yml +++ b/.github/actions/cdn-upload-version-info/action.yml @@ -1,7 +1,7 @@ name: cdn-upload-version-info description: Uploads version specific info to CDN inputs: - bunny-stor-host: + bunny-stor-hostname: description: Bunny SFTP Hostname required: true bunny-stor-username: From de0a7ef0c4b7b68dd502ef3d84ec26df664a89b8 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 00:19:44 +0100 Subject: [PATCH 020/155] Fix more namings --- .github/actions/cdn-bump-version/action.yml | 2 +- .github/actions/cdn-upload-firmware/action.yml | 2 +- .github/actions/cdn-upload-version-info/action.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index 120cc1a8..a46ced17 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -28,4 +28,4 @@ runs: run: | mkdir -p upload echo "${{ inputs.version }}" >> upload/version-${{ inputs.release-channel }}.txt - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-host }}:/ + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/ diff --git a/.github/actions/cdn-upload-firmware/action.yml b/.github/actions/cdn-upload-firmware/action.yml index c2f9d22f..3d5d4d11 100644 --- a/.github/actions/cdn-upload-firmware/action.yml +++ b/.github/actions/cdn-upload-firmware/action.yml @@ -55,4 +55,4 @@ runs: mkdir -p upload mv *.bin upload/ mv hashes.*.txt upload/ - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-host }}:/${{ inputs.fw-version }}/${{ inputs.board }} \ No newline at end of file + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} \ No newline at end of file diff --git a/.github/actions/cdn-upload-version-info/action.yml b/.github/actions/cdn-upload-version-info/action.yml index 19855704..1832710a 100644 --- a/.github/actions/cdn-upload-version-info/action.yml +++ b/.github/actions/cdn-upload-version-info/action.yml @@ -33,4 +33,4 @@ runs: run: | mkdir -p upload mv boards.txt upload/ - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-host }}:/${{ inputs.fw-version }}/${{ inputs.board }} + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} From 94581284069cf2f09362d148e4c41a2cf5938eed Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 00:31:53 +0100 Subject: [PATCH 021/155] Fix upload paths --- .github/actions/cdn-bump-version/action.yml | 2 +- .github/actions/cdn-upload-firmware/action.yml | 2 +- .github/actions/cdn-upload-version-info/action.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index a46ced17..797402e0 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -28,4 +28,4 @@ runs: run: | mkdir -p upload echo "${{ inputs.version }}" >> upload/version-${{ inputs.release-channel }}.txt - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/ + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/* ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/ diff --git a/.github/actions/cdn-upload-firmware/action.yml b/.github/actions/cdn-upload-firmware/action.yml index 3d5d4d11..22afafdf 100644 --- a/.github/actions/cdn-upload-firmware/action.yml +++ b/.github/actions/cdn-upload-firmware/action.yml @@ -55,4 +55,4 @@ runs: mkdir -p upload mv *.bin upload/ mv hashes.*.txt upload/ - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} \ No newline at end of file + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/* ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} \ No newline at end of file diff --git a/.github/actions/cdn-upload-version-info/action.yml b/.github/actions/cdn-upload-version-info/action.yml index 1832710a..9ff59f54 100644 --- a/.github/actions/cdn-upload-version-info/action.yml +++ b/.github/actions/cdn-upload-version-info/action.yml @@ -33,4 +33,4 @@ runs: run: | mkdir -p upload mv boards.txt upload/ - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/* ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} From a937dad0c79c09a0a2695da1a121aab18a034297 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 00:36:51 +0100 Subject: [PATCH 022/155] Dont do that for firmware.. i guess --- .github/actions/cdn-upload-firmware/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cdn-upload-firmware/action.yml b/.github/actions/cdn-upload-firmware/action.yml index 22afafdf..3d5d4d11 100644 --- a/.github/actions/cdn-upload-firmware/action.yml +++ b/.github/actions/cdn-upload-firmware/action.yml @@ -55,4 +55,4 @@ runs: mkdir -p upload mv *.bin upload/ mv hashes.*.txt upload/ - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/* ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} \ No newline at end of file + sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/ ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/${{ inputs.fw-version }}/${{ inputs.board }} \ No newline at end of file From 8946e60fa21b6d6d4bfe17b9fd1111575ca3e7a0 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 01:00:55 +0100 Subject: [PATCH 023/155] debug bump --- .github/actions/cdn-bump-version/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index 797402e0..ba408323 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -28,4 +28,4 @@ runs: run: | mkdir -p upload echo "${{ inputs.version }}" >> upload/version-${{ inputs.release-channel }}.txt - sshpass -p "${{ inputs.bunny-stor-password }}" scp -r upload/* ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/ + sshpass -p "${{ inputs.bunny-stor-password }}" scp -v -r upload/* ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/ From e6fe5dfda1146d1298a87e5f114b465de464b692 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 02:37:36 +0100 Subject: [PATCH 024/155] Purge cache --- .github/actions/cdn-bump-version/action.yml | 14 ++++++++++++-- .github/workflows/ci-build.yml | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index ba408323..eb8eeef0 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -10,8 +10,11 @@ inputs: bunny-stor-password: description: Bunny SFTP Password required: true - cf-bucket: - description: Name of the S3 bucket + bunny-api-key: + description: Bunny API key + required: true + bunny-cdn-url: + description: Bunny pull zone base url e.g. https://firmware.openshock.org (no trailing slash) required: true version: description: 'Version of the release' @@ -29,3 +32,10 @@ runs: mkdir -p upload echo "${{ inputs.version }}" >> upload/version-${{ inputs.release-channel }}.txt sshpass -p "${{ inputs.bunny-stor-password }}" scp -v -r upload/* ${{ inputs.bunny-stor-username }}@${{ inputs.bunny-stor-hostname }}:/ + + - name: Purge CDN cache + shell: bash + run: | + curl -X POST "https://api.bunny.net/purge?url=${{inputs.bunny-cdn-url}}/version-${{ inputs.release-channel }}.txt" \ + -H "Content-Type: application/json" \ + -H "AccessKey: ${{ input.bunny-api-key }}" \' \ No newline at end of file diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 830345df..ef3cf6bc 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -174,6 +174,8 @@ jobs: bunny-stor-hostname: ${{ vars.BUNNY_STOR_HOSTNAME }} bunny-stor-username: ${{ secrets.BUNNY_STOR_USERNAME }} bunny-stor-password: ${{ secrets.BUNNY_STOR_PASSWORD }} + bunny-api-key: ${{ secrets.BUNNY_APIKEY }} + bunny-cdn-url: ${{ vars.BUNNY_CDN_URL }} version: ${{ needs.getvars.outputs.version }} release-channel: ${{ needs.getvars.outputs.release-channel }} From 4c7d0c22d6c5036d3d5c9e304f3d036b7c1048eb Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 02:52:06 +0100 Subject: [PATCH 025/155] fix syntax --- .github/actions/cdn-bump-version/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index eb8eeef0..771bc3ff 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -38,4 +38,4 @@ runs: run: | curl -X POST "https://api.bunny.net/purge?url=${{inputs.bunny-cdn-url}}/version-${{ inputs.release-channel }}.txt" \ -H "Content-Type: application/json" \ - -H "AccessKey: ${{ input.bunny-api-key }}" \' \ No newline at end of file + -H "AccessKey: ${{ input.bunny-api-key }}" \ No newline at end of file From b7b6e8e3f90e9ff7c2655028c08e79176df1c61b Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 03:21:42 +0100 Subject: [PATCH 026/155] fix syntax --- .github/actions/cdn-bump-version/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index 771bc3ff..bec24eea 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -36,6 +36,6 @@ runs: - name: Purge CDN cache shell: bash run: | - curl -X POST "https://api.bunny.net/purge?url=${{inputs.bunny-cdn-url}}/version-${{ inputs.release-channel }}.txt" \ + curl -X POST "https://api.bunny.net/purge?url=${{ inputs.bunny-cdn-url }}/version-${{ inputs.release-channel }}.txt" \ -H "Content-Type: application/json" \ -H "AccessKey: ${{ input.bunny-api-key }}" \ No newline at end of file From fffeddd393bcac8c7a6e96635231ed50a7127d05 Mon Sep 17 00:00:00 2001 From: Luca Date: Sat, 2 Nov 2024 03:28:25 +0100 Subject: [PATCH 027/155] fix syntax --- .github/actions/cdn-bump-version/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/cdn-bump-version/action.yml b/.github/actions/cdn-bump-version/action.yml index bec24eea..b63659e6 100644 --- a/.github/actions/cdn-bump-version/action.yml +++ b/.github/actions/cdn-bump-version/action.yml @@ -38,4 +38,4 @@ runs: run: | curl -X POST "https://api.bunny.net/purge?url=${{ inputs.bunny-cdn-url }}/version-${{ inputs.release-channel }}.txt" \ -H "Content-Type: application/json" \ - -H "AccessKey: ${{ input.bunny-api-key }}" \ No newline at end of file + -H "AccessKey: ${{ inputs.bunny-api-key }}" \ No newline at end of file From 6fe50ac0cb2f420eac17e16b0abfb793127d200f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 09:03:35 +0100 Subject: [PATCH 028/155] build(deps-dev): Bump the frontend group in /frontend with 6 updates (#310) Bumps the frontend group in /frontend with 6 updates: | Package | From | To | | --- | --- | --- | | [@floating-ui/dom](https://github.com/floating-ui/floating-ui/tree/HEAD/packages/dom) | `1.6.11` | `1.6.12` | | [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit) | `2.7.3` | `2.7.4` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `22.8.1` | `22.8.7` | | [eslint](https://github.com/eslint/eslint) | `9.13.0` | `9.14.0` | | [tslib](https://github.com/Microsoft/tslib) | `2.8.0` | `2.8.1` | | [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest) | `2.1.3` | `2.1.4` | Updates `@floating-ui/dom` from 1.6.11 to 1.6.12 - [Release notes](https://github.com/floating-ui/floating-ui/releases) - [Changelog](https://github.com/floating-ui/floating-ui/blob/master/packages/dom/CHANGELOG.md) - [Commits](https://github.com/floating-ui/floating-ui/commits/@floating-ui/dom@1.6.12/packages/dom) Updates `@sveltejs/kit` from 2.7.3 to 2.7.4 - [Release notes](https://github.com/sveltejs/kit/releases) - [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md) - [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.7.4/packages/kit) Updates `@types/node` from 22.8.1 to 22.8.7 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `eslint` from 9.13.0 to 9.14.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v9.13.0...v9.14.0) Updates `tslib` from 2.8.0 to 2.8.1 - [Release notes](https://github.com/Microsoft/tslib/releases) - [Commits](https://github.com/Microsoft/tslib/compare/v2.8.0...v2.8.1) Updates `vitest` from 2.1.3 to 2.1.4 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Commits](https://github.com/vitest-dev/vitest/commits/v2.1.4/packages/vitest) --- updated-dependencies: - dependency-name: "@floating-ui/dom" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@sveltejs/kit" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: tslib dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: vitest dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/package.json | 12 +- frontend/pnpm-lock.yaml | 353 ++++++++++++++++++++++------------------ 2 files changed, 200 insertions(+), 165 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index b4869cc5..7cd130e1 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,18 +16,18 @@ "test:unit": "vitest" }, "devDependencies": { - "@floating-ui/dom": "1.6.11", + "@floating-ui/dom": "1.6.12", "@playwright/test": "1.48.2", "@skeletonlabs/skeleton": "2.10.3", "@skeletonlabs/tw-plugin": "0.4.0", "@sveltejs/adapter-static": "^3.0.6", - "@sveltejs/kit": "2.7.3", + "@sveltejs/kit": "2.7.4", "@sveltejs/vite-plugin-svelte": "^3.1.2", "@tailwindcss/forms": "0.5.9", "@tailwindcss/typography": "0.5.15", - "@types/node": "22.8.1", + "@types/node": "22.8.7", "autoprefixer": "10.4.20", - "eslint": "^9.13.0", + "eslint": "^9.14.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-svelte": "2.46.0", "flatbuffers": "24.3.25", @@ -37,10 +37,10 @@ "svelte": "4.2.19", "svelte-check": "4.0.5", "tailwindcss": "3.4.14", - "tslib": "2.8.0", + "tslib": "2.8.1", "typescript": "5.6.3", "vite-plugin-tailwind-purgecss": "^0.3.3", - "vitest": "2.1.3" + "vitest": "2.1.4" }, "dependencies": { "vite": "^5.4.10" diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 71cdce4c..fc76f54a 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -10,11 +10,11 @@ importers: dependencies: vite: specifier: ^5.4.10 - version: 5.4.10(@types/node@22.8.1) + version: 5.4.10(@types/node@22.8.7) devDependencies: '@floating-ui/dom': - specifier: 1.6.11 - version: 1.6.11 + specifier: 1.6.12 + version: 1.6.12 '@playwright/test': specifier: 1.48.2 version: 1.48.2 @@ -26,13 +26,13 @@ importers: version: 0.4.0(tailwindcss@3.4.14) '@sveltejs/adapter-static': specifier: ^3.0.6 - version: 3.0.6(@sveltejs/kit@2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))) + version: 3.0.6(@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))) '@sveltejs/kit': - specifier: 2.7.3 - version: 2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) + specifier: 2.7.4 + version: 2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) + version: 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) '@tailwindcss/forms': specifier: 0.5.9 version: 0.5.9(tailwindcss@3.4.14) @@ -40,20 +40,20 @@ importers: specifier: 0.5.15 version: 0.5.15(tailwindcss@3.4.14) '@types/node': - specifier: 22.8.1 - version: 22.8.1 + specifier: 22.8.7 + version: 22.8.7 autoprefixer: specifier: 10.4.20 version: 10.4.20(postcss@8.4.47) eslint: - specifier: ^9.13.0 - version: 9.13.0(jiti@1.21.6) + specifier: ^9.14.0 + version: 9.14.0(jiti@1.21.6) eslint-config-prettier: specifier: 9.1.0 - version: 9.1.0(eslint@9.13.0(jiti@1.21.6)) + version: 9.1.0(eslint@9.14.0(jiti@1.21.6)) eslint-plugin-svelte: specifier: 2.46.0 - version: 2.46.0(eslint@9.13.0(jiti@1.21.6))(svelte@4.2.19) + version: 2.46.0(eslint@9.14.0(jiti@1.21.6))(svelte@4.2.19) flatbuffers: specifier: 24.3.25 version: 24.3.25 @@ -76,17 +76,17 @@ importers: specifier: 3.4.14 version: 3.4.14 tslib: - specifier: 2.8.0 - version: 2.8.0 + specifier: 2.8.1 + version: 2.8.1 typescript: specifier: 5.6.3 version: 5.6.3 vite-plugin-tailwind-purgecss: specifier: ^0.3.3 - version: 0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.1)) + version: 0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.7)) vitest: - specifier: 2.1.3 - version: 2.1.3(@types/node@22.8.1) + specifier: 2.1.4 + version: 2.1.4(@types/node@22.8.7) packages: @@ -242,8 +242,14 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.11.1': - resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.18.0': @@ -258,33 +264,33 @@ packages: resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.13.0': - resolution: {integrity: sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA==} + '@eslint/js@9.14.0': + resolution: {integrity: sha512-pFoEtFWCPyDOl+C6Ift+wC7Ro89otjigCf5vcuWqWgqNSQbRrpjSvdeE6ofLz4dHmyxD5f7gIdGT4+p36L6Twg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.4': resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.1': - resolution: {integrity: sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw==} + '@eslint/plugin-kit@0.2.2': + resolution: {integrity: sha512-CXtq5nR4Su+2I47WPOlWud98Y5Lv8Kyxp2ukhgFx/eW6Blm18VXJO5WuQylPugRo8nbluoi6GvvxBLqHcvqUUw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@floating-ui/core@1.6.8': resolution: {integrity: sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==} - '@floating-ui/dom@1.6.11': - resolution: {integrity: sha512-qkMCxSR24v2vGkhYDo/UzxfJN3D4syqSjyuTFz6C7XcpU1pASPRieNI0Kj5VP3/503mOfYiGY891ugBX1GlABQ==} + '@floating-ui/dom@1.6.12': + resolution: {integrity: sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==} '@floating-ui/utils@0.2.8': resolution: {integrity: sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==} - '@humanfs/core@0.19.0': - resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.5': - resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': @@ -295,6 +301,10 @@ packages: resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} + '@humanwhocodes/retry@0.4.0': + resolution: {integrity: sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==} + engines: {node: '>=18.18'} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -446,8 +456,8 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 - '@sveltejs/kit@2.7.3': - resolution: {integrity: sha512-Vx7nq5MJ86I8qXYsVidC5PX6xm+uxt8DydvOdmJoyOK7LvGP18OFEG359yY+aa51t6pENvqZAMqAREQQx1OI2Q==} + '@sveltejs/kit@2.7.4': + resolution: {integrity: sha512-3DOPQYck3CpAmPgGq/HuhJMCCz8GF0ukbompPJQ2zShoSzrEKW9iG/l0nZmaxMvuOO3NNLmZj8F3W9uzqmkNdw==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -489,17 +499,16 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@22.8.1': - resolution: {integrity: sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg==} + '@types/node@22.8.7': + resolution: {integrity: sha512-LidcG+2UeYIWcMuMUpBKOnryBWG/rnmOHQR5apjn8myTQcx3rinFRn7DcIFhMnS0PPFSC6OafdIKEad0lj6U0Q==} - '@vitest/expect@2.1.3': - resolution: {integrity: sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ==} + '@vitest/expect@2.1.4': + resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} - '@vitest/mocker@2.1.3': - resolution: {integrity: sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ==} + '@vitest/mocker@2.1.4': + resolution: {integrity: sha512-Ky/O1Lc0QBbutJdW0rqLeFNbuLEyS+mIPiNdlVlp2/yhJ0SbyYqObS5IHdhferJud8MbbwMnexg4jordE5cCoQ==} peerDependencies: - '@vitest/spy': 2.1.3 - msw: ^2.3.5 + msw: ^2.4.9 vite: ^5.0.0 peerDependenciesMeta: msw: @@ -507,20 +516,20 @@ packages: vite: optional: true - '@vitest/pretty-format@2.1.3': - resolution: {integrity: sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ==} + '@vitest/pretty-format@2.1.4': + resolution: {integrity: sha512-L95zIAkEuTDbUX1IsjRl+vyBSLh3PwLLgKpghl37aCK9Jvw0iP+wKwIFhfjdUtA2myLgjrG6VU6JCFLv8q/3Ww==} - '@vitest/runner@2.1.3': - resolution: {integrity: sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ==} + '@vitest/runner@2.1.4': + resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} - '@vitest/snapshot@2.1.3': - resolution: {integrity: sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg==} + '@vitest/snapshot@2.1.4': + resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} - '@vitest/spy@2.1.3': - resolution: {integrity: sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ==} + '@vitest/spy@2.1.4': + resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} - '@vitest/utils@2.1.3': - resolution: {integrity: sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA==} + '@vitest/utils@2.1.4': + resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -532,6 +541,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -620,8 +634,8 @@ packages: caniuse-lite@1.0.30001669: resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} - chai@5.1.1: - resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + chai@5.1.2: + resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} chalk@4.1.2: @@ -773,20 +787,20 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-scope@8.1.0: - resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.1.0: - resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.13.0: - resolution: {integrity: sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA==} + eslint@9.14.0: + resolution: {integrity: sha512-c2FHsVBr87lnUtjP4Yhvk4yEhKrQavGafRA/Se1ouse8PfbfC/Qh9Mxa00yWsZRlqeUB9raXip0aiiUZkgnr9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -798,8 +812,11 @@ packages: esm-env@1.0.0: resolution: {integrity: sha512-Cf6VksWPsTuW01vU9Mk/3vRue91Zevka5SjyNf3nEpokFRuqt/KjUQoGAwq9qMmhpLTHmXzSIrFRw8zxWzmFBA==} - espree@10.2.0: - resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} + esm-env@1.1.4: + resolution: {integrity: sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg==} + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@9.6.1: @@ -825,6 +842,10 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + expect-type@1.1.0: + resolution: {integrity: sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA==} + engines: {node: '>=12.0.0'} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1455,8 +1476,8 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - tslib@2.8.0: - resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -1482,8 +1503,8 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - vite-node@2.1.3: - resolution: {integrity: sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA==} + vite-node@2.1.4: + resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -1532,15 +1553,15 @@ packages: vite: optional: true - vitest@2.1.3: - resolution: {integrity: sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA==} + vitest@2.1.4: + resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.3 - '@vitest/ui': 2.1.3 + '@vitest/browser': 2.1.4 + '@vitest/ui': 2.1.4 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -1670,12 +1691,17 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.13.0(jiti@1.21.6))': + '@eslint-community/eslint-utils@4.4.0(eslint@9.14.0(jiti@1.21.6))': dependencies: - eslint: 9.13.0(jiti@1.21.6) + eslint: 9.14.0(jiti@1.21.6) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.11.1': {} + '@eslint-community/eslint-utils@4.4.1(eslint@9.14.0(jiti@1.21.6))': + dependencies: + eslint: 9.14.0(jiti@1.21.6) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} '@eslint/config-array@0.18.0': dependencies: @@ -1691,7 +1717,7 @@ snapshots: dependencies: ajv: 6.12.6 debug: 4.3.7 - espree: 10.2.0 + espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.0 @@ -1701,11 +1727,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.13.0': {} + '@eslint/js@9.14.0': {} '@eslint/object-schema@2.1.4': {} - '@eslint/plugin-kit@0.2.1': + '@eslint/plugin-kit@0.2.2': dependencies: levn: 0.4.1 @@ -1713,24 +1739,26 @@ snapshots: dependencies: '@floating-ui/utils': 0.2.8 - '@floating-ui/dom@1.6.11': + '@floating-ui/dom@1.6.12': dependencies: '@floating-ui/core': 1.6.8 '@floating-ui/utils': 0.2.8 '@floating-ui/utils@0.2.8': {} - '@humanfs/core@0.19.0': {} + '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.5': + '@humanfs/node@0.16.6': dependencies: - '@humanfs/core': 0.19.0 + '@humanfs/core': 0.19.1 '@humanwhocodes/retry': 0.3.1 '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/retry@0.3.1': {} + '@humanwhocodes/retry@0.4.0': {} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -1841,17 +1869,17 @@ snapshots: dependencies: tailwindcss: 3.4.14 - '@sveltejs/adapter-static@3.0.6(@sveltejs/kit@2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))': + '@sveltejs/adapter-static@3.0.6(@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))': dependencies: - '@sveltejs/kit': 2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) + '@sveltejs/kit': 2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) - '@sveltejs/kit@2.7.3(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))': + '@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.1.1 - esm-env: 1.0.0 + esm-env: 1.1.4 import-meta-resolve: 4.1.0 kleur: 4.1.5 magic-string: 0.30.12 @@ -1861,28 +1889,28 @@ snapshots: sirv: 3.0.0 svelte: 4.2.19 tiny-glob: 0.2.9 - vite: 5.4.10(@types/node@22.8.1) + vite: 5.4.10(@types/node@22.8.7) - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) debug: 4.3.7 svelte: 4.2.19 - vite: 5.4.10(@types/node@22.8.1) + vite: 5.4.10(@types/node@22.8.7) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.1)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) debug: 4.3.7 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.12 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.4.10(@types/node@22.8.1) - vitefu: 0.2.5(vite@5.4.10(@types/node@22.8.1)) + vite: 5.4.10(@types/node@22.8.7) + vitefu: 0.2.5(vite@5.4.10(@types/node@22.8.7)) transitivePeerDependencies: - supports-color @@ -1905,56 +1933,58 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@22.8.1': + '@types/node@22.8.7': dependencies: undici-types: 6.19.8 - '@vitest/expect@2.1.3': + '@vitest/expect@2.1.4': dependencies: - '@vitest/spy': 2.1.3 - '@vitest/utils': 2.1.3 - chai: 5.1.1 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@22.8.1))': + '@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.8.7))': dependencies: - '@vitest/spy': 2.1.3 + '@vitest/spy': 2.1.4 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - vite: 5.4.10(@types/node@22.8.1) + vite: 5.4.10(@types/node@22.8.7) - '@vitest/pretty-format@2.1.3': + '@vitest/pretty-format@2.1.4': dependencies: tinyrainbow: 1.2.0 - '@vitest/runner@2.1.3': + '@vitest/runner@2.1.4': dependencies: - '@vitest/utils': 2.1.3 + '@vitest/utils': 2.1.4 pathe: 1.1.2 - '@vitest/snapshot@2.1.3': + '@vitest/snapshot@2.1.4': dependencies: - '@vitest/pretty-format': 2.1.3 + '@vitest/pretty-format': 2.1.4 magic-string: 0.30.12 pathe: 1.1.2 - '@vitest/spy@2.1.3': + '@vitest/spy@2.1.4': dependencies: tinyspy: 3.0.2 - '@vitest/utils@2.1.3': + '@vitest/utils@2.1.4': dependencies: - '@vitest/pretty-format': 2.1.3 + '@vitest/pretty-format': 2.1.4 loupe: 3.1.2 tinyrainbow: 1.2.0 - acorn-jsx@5.3.2(acorn@8.13.0): + acorn-jsx@5.3.2(acorn@8.14.0): dependencies: - acorn: 8.13.0 + acorn: 8.14.0 acorn@8.13.0: {} + acorn@8.14.0: {} + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -2031,7 +2061,7 @@ snapshots: caniuse-lite@1.0.30001669: {} - chai@5.1.1: + chai@5.1.2: dependencies: assertion-error: 2.0.1 check-error: 2.1.1 @@ -2161,21 +2191,21 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.13.0(jiti@1.21.6)): + eslint-compat-utils@0.5.1(eslint@9.14.0(jiti@1.21.6)): dependencies: - eslint: 9.13.0(jiti@1.21.6) + eslint: 9.14.0(jiti@1.21.6) semver: 7.6.3 - eslint-config-prettier@9.1.0(eslint@9.13.0(jiti@1.21.6)): + eslint-config-prettier@9.1.0(eslint@9.14.0(jiti@1.21.6)): dependencies: - eslint: 9.13.0(jiti@1.21.6) + eslint: 9.14.0(jiti@1.21.6) - eslint-plugin-svelte@2.46.0(eslint@9.13.0(jiti@1.21.6))(svelte@4.2.19): + eslint-plugin-svelte@2.46.0(eslint@9.14.0(jiti@1.21.6))(svelte@4.2.19): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.14.0(jiti@1.21.6)) '@jridgewell/sourcemap-codec': 1.5.0 - eslint: 9.13.0(jiti@1.21.6) - eslint-compat-utils: 0.5.1(eslint@9.13.0(jiti@1.21.6)) + eslint: 9.14.0(jiti@1.21.6) + eslint-compat-utils: 0.5.1(eslint@9.14.0(jiti@1.21.6)) esutils: 2.0.3 known-css-properties: 0.35.0 postcss: 8.4.47 @@ -2194,27 +2224,27 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-scope@8.1.0: + eslint-scope@8.2.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.1.0: {} + eslint-visitor-keys@4.2.0: {} - eslint@9.13.0(jiti@1.21.6): + eslint@9.14.0(jiti@1.21.6): dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.13.0(jiti@1.21.6)) - '@eslint-community/regexpp': 4.11.1 + '@eslint-community/eslint-utils': 4.4.1(eslint@9.14.0(jiti@1.21.6)) + '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.18.0 '@eslint/core': 0.7.0 '@eslint/eslintrc': 3.1.0 - '@eslint/js': 9.13.0 - '@eslint/plugin-kit': 0.2.1 - '@humanfs/node': 0.16.5 + '@eslint/js': 9.14.0 + '@eslint/plugin-kit': 0.2.2 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.0 '@types/estree': 1.0.6 '@types/json-schema': 7.0.15 ajv: 6.12.6 @@ -2222,9 +2252,9 @@ snapshots: cross-spawn: 7.0.3 debug: 4.3.7 escape-string-regexp: 4.0.0 - eslint-scope: 8.1.0 - eslint-visitor-keys: 4.1.0 - espree: 10.2.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -2247,16 +2277,18 @@ snapshots: esm-env@1.0.0: {} - espree@10.2.0: + esm-env@1.1.4: {} + + espree@10.3.0: dependencies: - acorn: 8.13.0 - acorn-jsx: 5.3.2(acorn@8.13.0) - eslint-visitor-keys: 4.1.0 + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 espree@9.6.1: dependencies: - acorn: 8.13.0 - acorn-jsx: 5.3.2(acorn@8.13.0) + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) eslint-visitor-keys: 3.4.3 esquery@1.6.0: @@ -2275,6 +2307,8 @@ snapshots: esutils@2.0.3: {} + expect-type@1.1.0: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.2: @@ -2870,7 +2904,7 @@ snapshots: ts-interface-checker@0.1.13: {} - tslib@2.8.0: {} + tslib@2.8.1: {} type-check@0.4.0: dependencies: @@ -2892,12 +2926,12 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@2.1.3(@types/node@22.8.1): + vite-node@2.1.4(@types/node@22.8.7): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.4.10(@types/node@22.8.1) + vite: 5.4.10(@types/node@22.8.7) transitivePeerDependencies: - '@types/node' - less @@ -2909,7 +2943,7 @@ snapshots: - supports-color - terser - vite-plugin-tailwind-purgecss@0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.1)): + vite-plugin-tailwind-purgecss@0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.7)): dependencies: chalk: 5.3.0 css-tree: 2.3.1 @@ -2917,32 +2951,33 @@ snapshots: purgecss: 6.0.0 purgecss-from-html: 6.0.0 tailwindcss: 3.4.14 - vite: 5.4.10(@types/node@22.8.1) + vite: 5.4.10(@types/node@22.8.7) - vite@5.4.10(@types/node@22.8.1): + vite@5.4.10(@types/node@22.8.7): dependencies: esbuild: 0.21.5 postcss: 8.4.47 rollup: 4.24.2 optionalDependencies: - '@types/node': 22.8.1 + '@types/node': 22.8.7 fsevents: 2.3.3 - vitefu@0.2.5(vite@5.4.10(@types/node@22.8.1)): + vitefu@0.2.5(vite@5.4.10(@types/node@22.8.7)): optionalDependencies: - vite: 5.4.10(@types/node@22.8.1) - - vitest@2.1.3(@types/node@22.8.1): - dependencies: - '@vitest/expect': 2.1.3 - '@vitest/mocker': 2.1.3(@vitest/spy@2.1.3)(vite@5.4.10(@types/node@22.8.1)) - '@vitest/pretty-format': 2.1.3 - '@vitest/runner': 2.1.3 - '@vitest/snapshot': 2.1.3 - '@vitest/spy': 2.1.3 - '@vitest/utils': 2.1.3 - chai: 5.1.1 + vite: 5.4.10(@types/node@22.8.7) + + vitest@2.1.4(@types/node@22.8.7): + dependencies: + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.8.7)) + '@vitest/pretty-format': 2.1.4 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 debug: 4.3.7 + expect-type: 1.1.0 magic-string: 0.30.12 pathe: 1.1.2 std-env: 3.7.0 @@ -2950,11 +2985,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@22.8.1) - vite-node: 2.1.3(@types/node@22.8.1) + vite: 5.4.10(@types/node@22.8.7) + vite-node: 2.1.4(@types/node@22.8.7) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.8.1 + '@types/node': 22.8.7 transitivePeerDependencies: - less - lightningcss From d2c3b8c53781bc8ab399ac6cb7445a7430bc856a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:16:36 +0100 Subject: [PATCH 029/155] build(deps-dev): Bump the frontend group in /frontend with 4 updates (#311) Bumps the frontend group in /frontend with 4 updates: [@sveltejs/kit](https://github.com/sveltejs/kit/tree/HEAD/packages/kit), [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node), [postcss](https://github.com/postcss/postcss) and [svelte-check](https://github.com/sveltejs/language-tools). Updates `@sveltejs/kit` from 2.7.4 to 2.8.0 - [Release notes](https://github.com/sveltejs/kit/releases) - [Changelog](https://github.com/sveltejs/kit/blob/main/packages/kit/CHANGELOG.md) - [Commits](https://github.com/sveltejs/kit/commits/@sveltejs/kit@2.8.0/packages/kit) Updates `@types/node` from 22.8.7 to 22.9.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `postcss` from 8.4.47 to 8.4.48 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.47...8.4.48) Updates `svelte-check` from 4.0.5 to 4.0.6 - [Release notes](https://github.com/sveltejs/language-tools/releases) - [Commits](https://github.com/sveltejs/language-tools/compare/svelte-check-4.0.5...svelte-check-4.0.6) --- updated-dependencies: - dependency-name: "@sveltejs/kit" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: frontend - dependency-name: postcss dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend - dependency-name: svelte-check dependency-type: direct:development update-type: version-update:semver-patch dependency-group: frontend ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- frontend/package.json | 8 +- frontend/pnpm-lock.yaml | 160 ++++++++++++++++++++-------------------- 2 files changed, 84 insertions(+), 84 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 7cd130e1..086dd11b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,21 +21,21 @@ "@skeletonlabs/skeleton": "2.10.3", "@skeletonlabs/tw-plugin": "0.4.0", "@sveltejs/adapter-static": "^3.0.6", - "@sveltejs/kit": "2.7.4", + "@sveltejs/kit": "2.8.0", "@sveltejs/vite-plugin-svelte": "^3.1.2", "@tailwindcss/forms": "0.5.9", "@tailwindcss/typography": "0.5.15", - "@types/node": "22.8.7", + "@types/node": "22.9.0", "autoprefixer": "10.4.20", "eslint": "^9.14.0", "eslint-config-prettier": "9.1.0", "eslint-plugin-svelte": "2.46.0", "flatbuffers": "24.3.25", - "postcss": "8.4.47", + "postcss": "8.4.48", "prettier": "3.3.3", "prettier-plugin-svelte": "3.2.7", "svelte": "4.2.19", - "svelte-check": "4.0.5", + "svelte-check": "4.0.6", "tailwindcss": "3.4.14", "tslib": "2.8.1", "typescript": "5.6.3", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index fc76f54a..01c513dc 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -10,7 +10,7 @@ importers: dependencies: vite: specifier: ^5.4.10 - version: 5.4.10(@types/node@22.8.7) + version: 5.4.10(@types/node@22.9.0) devDependencies: '@floating-ui/dom': specifier: 1.6.12 @@ -26,13 +26,13 @@ importers: version: 0.4.0(tailwindcss@3.4.14) '@sveltejs/adapter-static': specifier: ^3.0.6 - version: 3.0.6(@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))) + version: 3.0.6(@sveltejs/kit@2.8.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0))) '@sveltejs/kit': - specifier: 2.7.4 - version: 2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) + specifier: 2.8.0 + version: 2.8.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)) '@sveltejs/vite-plugin-svelte': specifier: ^3.1.2 - version: 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) + version: 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)) '@tailwindcss/forms': specifier: 0.5.9 version: 0.5.9(tailwindcss@3.4.14) @@ -40,11 +40,11 @@ importers: specifier: 0.5.15 version: 0.5.15(tailwindcss@3.4.14) '@types/node': - specifier: 22.8.7 - version: 22.8.7 + specifier: 22.9.0 + version: 22.9.0 autoprefixer: specifier: 10.4.20 - version: 10.4.20(postcss@8.4.47) + version: 10.4.20(postcss@8.4.48) eslint: specifier: ^9.14.0 version: 9.14.0(jiti@1.21.6) @@ -58,8 +58,8 @@ importers: specifier: 24.3.25 version: 24.3.25 postcss: - specifier: 8.4.47 - version: 8.4.47 + specifier: 8.4.48 + version: 8.4.48 prettier: specifier: 3.3.3 version: 3.3.3 @@ -70,8 +70,8 @@ importers: specifier: 4.2.19 version: 4.2.19 svelte-check: - specifier: 4.0.5 - version: 4.0.5(svelte@4.2.19)(typescript@5.6.3) + specifier: 4.0.6 + version: 4.0.6(svelte@4.2.19)(typescript@5.6.3) tailwindcss: specifier: 3.4.14 version: 3.4.14 @@ -83,10 +83,10 @@ importers: version: 5.6.3 vite-plugin-tailwind-purgecss: specifier: ^0.3.3 - version: 0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.7)) + version: 0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.9.0)) vitest: specifier: 2.1.4 - version: 2.1.4(@types/node@22.8.7) + version: 2.1.4(@types/node@22.9.0) packages: @@ -456,8 +456,8 @@ packages: peerDependencies: '@sveltejs/kit': ^2.0.0 - '@sveltejs/kit@2.7.4': - resolution: {integrity: sha512-3DOPQYck3CpAmPgGq/HuhJMCCz8GF0ukbompPJQ2zShoSzrEKW9iG/l0nZmaxMvuOO3NNLmZj8F3W9uzqmkNdw==} + '@sveltejs/kit@2.8.0': + resolution: {integrity: sha512-HCiWupCuKJQ3aPaC4Xc6lpPdjOOnoGzEiYjOqMqppdtfGtY2ABrx932Vw66ZwS2RGXc0BmZvFvNq5SzqlmDVLg==} engines: {node: '>=18.13'} hasBin: true peerDependencies: @@ -499,8 +499,8 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/node@22.8.7': - resolution: {integrity: sha512-LidcG+2UeYIWcMuMUpBKOnryBWG/rnmOHQR5apjn8myTQcx3rinFRn7DcIFhMnS0PPFSC6OafdIKEad0lj6U0Q==} + '@types/node@22.9.0': + resolution: {integrity: sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==} '@vitest/expect@2.1.4': resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} @@ -1264,8 +1264,8 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.4.47: - resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} + postcss@8.4.48: + resolution: {integrity: sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -1402,8 +1402,8 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - svelte-check@4.0.5: - resolution: {integrity: sha512-icBTBZ3ibBaywbXUat3cK6hB5Du+Kq9Z8CRuyLmm64XIe2/r+lQcbuBx/IQgsbrC+kT2jQ0weVpZSSRIPwB6jQ==} + svelte-check@4.0.6: + resolution: {integrity: sha512-2XwmQNJaKbenJbvu5at+DuRpvF4v73Zu7f0/WkMl1O7WDm/IfF+E13t8D0nnRiRcMsNYm9ufHyLwfeMEnebpdg==} engines: {node: '>= 18.0.0'} hasBin: true peerDependencies: @@ -1869,13 +1869,13 @@ snapshots: dependencies: tailwindcss: 3.4.14 - '@sveltejs/adapter-static@3.0.6(@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))': + '@sveltejs/adapter-static@3.0.6(@sveltejs/kit@2.8.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))': dependencies: - '@sveltejs/kit': 2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) + '@sveltejs/kit': 2.8.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)) - '@sveltejs/kit@2.7.4(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))': + '@sveltejs/kit@2.8.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)) '@types/cookie': 0.6.0 cookie: 0.6.0 devalue: 5.1.1 @@ -1889,28 +1889,28 @@ snapshots: sirv: 3.0.0 svelte: 4.2.19 tiny-glob: 0.2.9 - vite: 5.4.10(@types/node@22.8.7) + vite: 5.4.10(@types/node@22.9.0) - '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))': + '@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) + '@sveltejs/vite-plugin-svelte': 3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)) debug: 4.3.7 svelte: 4.2.19 - vite: 5.4.10(@types/node@22.8.7) + vite: 5.4.10(@types/node@22.9.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7))': + '@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.8.7)) + '@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.1.2(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)))(svelte@4.2.19)(vite@5.4.10(@types/node@22.9.0)) debug: 4.3.7 deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.12 svelte: 4.2.19 svelte-hmr: 0.16.0(svelte@4.2.19) - vite: 5.4.10(@types/node@22.8.7) - vitefu: 0.2.5(vite@5.4.10(@types/node@22.8.7)) + vite: 5.4.10(@types/node@22.9.0) + vitefu: 0.2.5(vite@5.4.10(@types/node@22.9.0)) transitivePeerDependencies: - supports-color @@ -1933,7 +1933,7 @@ snapshots: '@types/json-schema@7.0.15': {} - '@types/node@22.8.7': + '@types/node@22.9.0': dependencies: undici-types: 6.19.8 @@ -1944,13 +1944,13 @@ snapshots: chai: 5.1.2 tinyrainbow: 1.2.0 - '@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.8.7))': + '@vitest/mocker@2.1.4(vite@5.4.10(@types/node@22.9.0))': dependencies: '@vitest/spy': 2.1.4 estree-walker: 3.0.3 magic-string: 0.30.12 optionalDependencies: - vite: 5.4.10(@types/node@22.8.7) + vite: 5.4.10(@types/node@22.9.0) '@vitest/pretty-format@2.1.4': dependencies: @@ -2017,14 +2017,14 @@ snapshots: assertion-error@2.0.1: {} - autoprefixer@10.4.20(postcss@8.4.47): + autoprefixer@10.4.20(postcss@8.4.48): dependencies: browserslist: 4.24.0 caniuse-lite: 1.0.30001669 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.4.47 + postcss: 8.4.48 postcss-value-parser: 4.2.0 axobject-query@4.1.0: {} @@ -2208,9 +2208,9 @@ snapshots: eslint-compat-utils: 0.5.1(eslint@9.14.0(jiti@1.21.6)) esutils: 2.0.3 known-css-properties: 0.35.0 - postcss: 8.4.47 - postcss-load-config: 3.1.4(postcss@8.4.47) - postcss-safe-parser: 6.0.0(postcss@8.4.47) + postcss: 8.4.48 + postcss-load-config: 3.1.4(postcss@8.4.48) + postcss-safe-parser: 6.0.0(postcss@8.4.48) postcss-selector-parser: 6.1.2 semver: 7.6.3 svelte-eslint-parser: 0.43.0(svelte@4.2.19) @@ -2603,44 +2603,44 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - postcss-import@15.1.0(postcss@8.4.47): + postcss-import@15.1.0(postcss@8.4.48): dependencies: - postcss: 8.4.47 + postcss: 8.4.48 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - postcss-js@4.0.1(postcss@8.4.47): + postcss-js@4.0.1(postcss@8.4.48): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.47 + postcss: 8.4.48 - postcss-load-config@3.1.4(postcss@8.4.47): + postcss-load-config@3.1.4(postcss@8.4.48): dependencies: lilconfig: 2.1.0 yaml: 1.10.2 optionalDependencies: - postcss: 8.4.47 + postcss: 8.4.48 - postcss-load-config@4.0.2(postcss@8.4.47): + postcss-load-config@4.0.2(postcss@8.4.48): dependencies: lilconfig: 3.1.2 yaml: 2.6.0 optionalDependencies: - postcss: 8.4.47 + postcss: 8.4.48 - postcss-nested@6.2.0(postcss@8.4.47): + postcss-nested@6.2.0(postcss@8.4.48): dependencies: - postcss: 8.4.47 + postcss: 8.4.48 postcss-selector-parser: 6.1.2 - postcss-safe-parser@6.0.0(postcss@8.4.47): + postcss-safe-parser@6.0.0(postcss@8.4.48): dependencies: - postcss: 8.4.47 + postcss: 8.4.48 - postcss-scss@4.0.9(postcss@8.4.47): + postcss-scss@4.0.9(postcss@8.4.48): dependencies: - postcss: 8.4.47 + postcss: 8.4.48 postcss-selector-parser@6.0.10: dependencies: @@ -2654,7 +2654,7 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.4.47: + postcss@8.4.48: dependencies: nanoid: 3.3.7 picocolors: 1.1.1 @@ -2680,7 +2680,7 @@ snapshots: dependencies: commander: 12.1.0 glob: 10.4.5 - postcss: 8.4.47 + postcss: 8.4.48 postcss-selector-parser: 6.1.2 queue-microtask@1.2.3: {} @@ -2801,7 +2801,7 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.0.5(svelte@4.2.19)(typescript@5.6.3): + svelte-check@4.0.6(svelte@4.2.19)(typescript@5.6.3): dependencies: '@jridgewell/trace-mapping': 0.3.25 chokidar: 4.0.1 @@ -2818,8 +2818,8 @@ snapshots: eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - postcss: 8.4.47 - postcss-scss: 4.0.9(postcss@8.4.47) + postcss: 8.4.48 + postcss-scss: 4.0.9(postcss@8.4.48) optionalDependencies: svelte: 4.2.19 @@ -2860,11 +2860,11 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.4.47 - postcss-import: 15.1.0(postcss@8.4.47) - postcss-js: 4.0.1(postcss@8.4.47) - postcss-load-config: 4.0.2(postcss@8.4.47) - postcss-nested: 6.2.0(postcss@8.4.47) + postcss: 8.4.48 + postcss-import: 15.1.0(postcss@8.4.48) + postcss-js: 4.0.1(postcss@8.4.48) + postcss-load-config: 4.0.2(postcss@8.4.48) + postcss-nested: 6.2.0(postcss@8.4.48) postcss-selector-parser: 6.1.2 resolve: 1.22.8 sucrase: 3.35.0 @@ -2926,12 +2926,12 @@ snapshots: util-deprecate@1.0.2: {} - vite-node@2.1.4(@types/node@22.8.7): + vite-node@2.1.4(@types/node@22.9.0): dependencies: cac: 6.7.14 debug: 4.3.7 pathe: 1.1.2 - vite: 5.4.10(@types/node@22.8.7) + vite: 5.4.10(@types/node@22.9.0) transitivePeerDependencies: - '@types/node' - less @@ -2943,7 +2943,7 @@ snapshots: - supports-color - terser - vite-plugin-tailwind-purgecss@0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.8.7)): + vite-plugin-tailwind-purgecss@0.3.3(tailwindcss@3.4.14)(vite@5.4.10(@types/node@22.9.0)): dependencies: chalk: 5.3.0 css-tree: 2.3.1 @@ -2951,25 +2951,25 @@ snapshots: purgecss: 6.0.0 purgecss-from-html: 6.0.0 tailwindcss: 3.4.14 - vite: 5.4.10(@types/node@22.8.7) + vite: 5.4.10(@types/node@22.9.0) - vite@5.4.10(@types/node@22.8.7): + vite@5.4.10(@types/node@22.9.0): dependencies: esbuild: 0.21.5 - postcss: 8.4.47 + postcss: 8.4.48 rollup: 4.24.2 optionalDependencies: - '@types/node': 22.8.7 + '@types/node': 22.9.0 fsevents: 2.3.3 - vitefu@0.2.5(vite@5.4.10(@types/node@22.8.7)): + vitefu@0.2.5(vite@5.4.10(@types/node@22.9.0)): optionalDependencies: - vite: 5.4.10(@types/node@22.8.7) + vite: 5.4.10(@types/node@22.9.0) - vitest@2.1.4(@types/node@22.8.7): + vitest@2.1.4(@types/node@22.9.0): dependencies: '@vitest/expect': 2.1.4 - '@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.8.7)) + '@vitest/mocker': 2.1.4(vite@5.4.10(@types/node@22.9.0)) '@vitest/pretty-format': 2.1.4 '@vitest/runner': 2.1.4 '@vitest/snapshot': 2.1.4 @@ -2985,11 +2985,11 @@ snapshots: tinyexec: 0.3.1 tinypool: 1.0.1 tinyrainbow: 1.2.0 - vite: 5.4.10(@types/node@22.8.7) - vite-node: 2.1.4(@types/node@22.8.7) + vite: 5.4.10(@types/node@22.9.0) + vite-node: 2.1.4(@types/node@22.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.8.7 + '@types/node': 22.9.0 transitivePeerDependencies: - less - lightningcss From 535d89294b40e3d261fe949fe996afe920a7c12e Mon Sep 17 00:00:00 2001 From: hhvrc Date: Mon, 11 Nov 2024 14:05:03 +0100 Subject: [PATCH 030/155] Fix possible memory leak --- src/wifi/WiFiScanManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/wifi/WiFiScanManager.cpp b/src/wifi/WiFiScanManager.cpp index ed2ea260..9e0e43ec 100644 --- a/src/wifi/WiFiScanManager.cpp +++ b/src/wifi/WiFiScanManager.cpp @@ -237,6 +237,11 @@ bool WiFiScanManager::StartScan() return false; } + // Free the TCB + if (s_scanTaskHandle != nullptr) { + vTaskDelete(s_scanTaskHandle); + } + // Start the scan task if (TaskUtils::TaskCreateExpensive(_scanningTask, "WiFiScanManager", 4096, nullptr, 1, &s_scanTaskHandle) != pdPASS) { // PROFILED: 1.8KB stack usage OS_LOGE(TAG, "Failed to create scan task"); From c208800bfbf30d911feabc96409ca9dcee104012 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Mon, 11 Nov 2024 14:05:23 +0100 Subject: [PATCH 031/155] Make IsScanning method more robust --- src/wifi/WiFiScanManager.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wifi/WiFiScanManager.cpp b/src/wifi/WiFiScanManager.cpp index 9e0e43ec..3e24aeee 100644 --- a/src/wifi/WiFiScanManager.cpp +++ b/src/wifi/WiFiScanManager.cpp @@ -224,7 +224,15 @@ bool WiFiScanManager::Init() bool WiFiScanManager::IsScanning() { - return s_scanTaskHandle != nullptr; + // Quick check + if (s_scanTaskHandle == nullptr) { + return false; + } + + // It wasnt null, lock and perform proper check + ScopedLock lock__(&s_scanTaskMutex); + + return s_scanTaskHandle != nullptr && eTaskGetState(s_scanTaskHandle) != eDeleted; } bool WiFiScanManager::StartScan() From 6f6adc99dddcb8cc2bcfd098d3ae3f27afa75776 Mon Sep 17 00:00:00 2001 From: HeavenVR Date: Mon, 11 Nov 2024 14:14:17 +0100 Subject: [PATCH 032/155] Use event loops to decouple code (#300) * Initial commit * Working for GatewayConnection events * Add EStop to events * Ditch Arduino WiFi event system * Ditch Arduino WiFi event system in OtaUpdateManager * Clean up main.cpp more * Initialize events before otaupdatemanager to fix crashloop * Run CPP-Linter * Isolate EStopManager * Fix up includes * Move event_handlers to message_handlers --- include/CommandHandler.h | 1 - include/EStopManager.h | 2 + include/EStopState.h | 12 + include/GatewayClient.h | 15 +- include/GatewayClientState.h | 12 + include/VisualStateManager.h | 2 - include/events/Events.h | 22 ++ .../WebSocket.h | 2 +- .../impl/WSGateway.h | 0 .../impl/WSLocal.h | 0 src/CaptivePortalInstance.cpp | 31 +- src/CommandHandler.cpp | 40 +-- src/EStopManager.cpp | 43 +-- src/GatewayClient.cpp | 76 ++--- src/GatewayConnectionManager.cpp | 43 ++- src/OtaUpdateManager.cpp | 48 ++- src/VisualStateManager.cpp | 279 ++++++++++-------- src/events/Events.cpp | 22 ++ src/main.cpp | 5 + .../websocket/Gateway.cpp | 7 +- .../websocket/Local.cpp | 7 +- .../websocket/gateway/CaptivePortalConfig.cpp | 5 +- .../websocket/gateway/OtaInstall.cpp | 5 +- .../websocket/gateway/ShockerCommandList.cpp | 11 +- .../websocket/gateway/_InvalidMessage.cpp | 5 +- .../websocket/local/AccountLinkCommand.cpp | 8 +- .../websocket/local/AccountUnlinkCommand.cpp | 5 +- .../websocket/local/SetEStopPinCommand.cpp | 2 +- .../websocket/local/SetRfTxPinCommand.cpp | 2 +- .../local/WiFiNetworkConnectCommand.cpp | 7 +- .../local/WiFiNetworkDisconnectCommand.cpp | 7 +- .../local/WiFiNetworkForgetCommand.cpp | 7 +- .../local/WiFiNetworkSaveCommand.cpp | 7 +- .../websocket/local/WiFiScanCommand.cpp | 7 +- .../websocket/local/_InvalidMessage.cpp | 7 +- 35 files changed, 453 insertions(+), 301 deletions(-) create mode 100644 include/EStopState.h create mode 100644 include/GatewayClientState.h create mode 100644 include/events/Events.h rename include/{event_handlers => message_handlers}/WebSocket.h (78%) rename include/{event_handlers => message_handlers}/impl/WSGateway.h (100%) rename include/{event_handlers => message_handlers}/impl/WSLocal.h (100%) create mode 100644 src/events/Events.cpp rename src/{event_handlers => message_handlers}/websocket/Gateway.cpp (90%) rename src/{event_handlers => message_handlers}/websocket/Local.cpp (92%) rename src/{event_handlers => message_handlers}/websocket/gateway/CaptivePortalConfig.cpp (86%) rename src/{event_handlers => message_handlers}/websocket/gateway/OtaInstall.cpp (93%) rename src/{event_handlers => message_handlers}/websocket/gateway/ShockerCommandList.cpp (82%) rename src/{event_handlers => message_handlers}/websocket/gateway/_InvalidMessage.cpp (79%) rename src/{event_handlers => message_handlers}/websocket/local/AccountLinkCommand.cpp (90%) rename src/{event_handlers => message_handlers}/websocket/local/AccountUnlinkCommand.cpp (81%) rename src/{event_handlers => message_handlers}/websocket/local/SetEStopPinCommand.cpp (97%) rename src/{event_handlers => message_handlers}/websocket/local/SetRfTxPinCommand.cpp (97%) rename src/{event_handlers => message_handlers}/websocket/local/WiFiNetworkConnectCommand.cpp (94%) rename src/{event_handlers => message_handlers}/websocket/local/WiFiNetworkDisconnectCommand.cpp (91%) rename src/{event_handlers => message_handlers}/websocket/local/WiFiNetworkForgetCommand.cpp (88%) rename src/{event_handlers => message_handlers}/websocket/local/WiFiNetworkSaveCommand.cpp (91%) rename src/{event_handlers => message_handlers}/websocket/local/WiFiScanCommand.cpp (83%) rename src/{event_handlers => message_handlers}/websocket/local/_InvalidMessage.cpp (78%) diff --git a/include/CommandHandler.h b/include/CommandHandler.h index 17be512d..2fe01e04 100644 --- a/include/CommandHandler.h +++ b/include/CommandHandler.h @@ -21,7 +21,6 @@ namespace OpenShock::CommandHandler { gpio_num_t GetEstopPin(); bool SetKeepAliveEnabled(bool enabled); - bool SetKeepAlivePaused(bool paused); bool HandleCommand(ShockerModelType shockerModel, uint16_t shockerId, ShockerCommandType type, uint8_t intensity, uint16_t durationMs); } // namespace OpenShock::CommandHandler diff --git a/include/EStopManager.h b/include/EStopManager.h index db01eeda..80a183ed 100644 --- a/include/EStopManager.h +++ b/include/EStopManager.h @@ -1,5 +1,7 @@ #pragma once +#include "EStopState.h" + #include #include diff --git a/include/EStopState.h b/include/EStopState.h new file mode 100644 index 00000000..c104e5f0 --- /dev/null +++ b/include/EStopState.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace OpenShock { + enum class EStopState : uint8_t { + Idle, + Active, + ActiveClearing, + AwaitingRelease + }; +} // namespace OpenShock diff --git a/include/GatewayClient.h b/include/GatewayClient.h index 99012e3e..a81a88af 100644 --- a/include/GatewayClient.h +++ b/include/GatewayClient.h @@ -1,5 +1,7 @@ #pragma once +#include "GatewayClientState.h" + #include #include @@ -13,14 +15,7 @@ namespace OpenShock { GatewayClient(const std::string& authToken); ~GatewayClient(); - enum class State : uint8_t { - Disconnected, - Disconnecting, - Connecting, - Connected, - }; - - constexpr State state() const { return m_state; } + constexpr GatewayClientState state() const { return m_state; } void connect(const char* lcgFqdn); void disconnect(); @@ -31,13 +26,13 @@ namespace OpenShock { bool loop(); private: - void _setState(State state); + void _setState(GatewayClientState state); void _sendKeepAlive(); void _sendBootStatus(); void _handleEvent(WStype_t type, uint8_t* payload, std::size_t length); WebSocketsClient m_webSocket; int64_t m_lastKeepAlive; - State m_state; + GatewayClientState m_state; }; } // namespace OpenShock diff --git a/include/GatewayClientState.h b/include/GatewayClientState.h new file mode 100644 index 00000000..33cbfe7e --- /dev/null +++ b/include/GatewayClientState.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace OpenShock { + enum class GatewayClientState : uint8_t { + Disconnected, + Disconnecting, + Connecting, + Connected, + }; +} // namespace OpenShock diff --git a/include/VisualStateManager.h b/include/VisualStateManager.h index 2831f960..19b92a03 100644 --- a/include/VisualStateManager.h +++ b/include/VisualStateManager.h @@ -8,6 +8,4 @@ namespace OpenShock::VisualStateManager { void SetCriticalError(); void SetScanningStarted(); - void SetEmergencyStopStatus(bool isActive, bool isAwaitingRelease); - void SetWebSocketConnected(bool isConnected); } // namespace OpenShock::VisualStateManager diff --git a/include/events/Events.h b/include/events/Events.h new file mode 100644 index 00000000..a47706a3 --- /dev/null +++ b/include/events/Events.h @@ -0,0 +1,22 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +ESP_EVENT_DECLARE_BASE(OPENSHOCK_EVENTS); + +enum { + OPENSHOCK_EVENT_ESTOP_STATE_CHANGED, // Event for when the EStop activation state changes + OPENSHOCK_EVENT_GATEWAY_CLIENT_STATE_CHANGED, // Event for when the gateway connection state changes +}; + +#ifdef __cplusplus +} +#endif + +namespace OpenShock::Events { + bool Init(); +} diff --git a/include/event_handlers/WebSocket.h b/include/message_handlers/WebSocket.h similarity index 78% rename from include/event_handlers/WebSocket.h rename to include/message_handlers/WebSocket.h index 626b6216..98c8dc0e 100644 --- a/include/event_handlers/WebSocket.h +++ b/include/message_handlers/WebSocket.h @@ -2,7 +2,7 @@ #include -namespace OpenShock::EventHandlers::WebSocket { +namespace OpenShock::MessageHandlers::WebSocket { void HandleGatewayBinary(const uint8_t* data, std::size_t len); void HandleLocalBinary(uint8_t socketId, const uint8_t* data, std::size_t len); } diff --git a/include/event_handlers/impl/WSGateway.h b/include/message_handlers/impl/WSGateway.h similarity index 100% rename from include/event_handlers/impl/WSGateway.h rename to include/message_handlers/impl/WSGateway.h diff --git a/include/event_handlers/impl/WSLocal.h b/include/message_handlers/impl/WSLocal.h similarity index 100% rename from include/event_handlers/impl/WSLocal.h rename to include/message_handlers/impl/WSLocal.h diff --git a/src/CaptivePortalInstance.cpp b/src/CaptivePortalInstance.cpp index 876729b5..62970fe1 100644 --- a/src/CaptivePortalInstance.cpp +++ b/src/CaptivePortalInstance.cpp @@ -5,9 +5,9 @@ const char* const TAG = "CaptivePortalInstance"; #include "CommandHandler.h" -#include "event_handlers/WebSocket.h" #include "GatewayConnectionManager.h" #include "Logging.h" +#include "message_handlers/WebSocket.h" #include "serialization/WSLocal.h" #include "util/FnProxy.h" #include "util/HexUtils.h" @@ -29,7 +29,8 @@ const uint32_t WEBSOCKET_UPDATE_INTERVAL = 10; // 10ms / 100Hz using namespace OpenShock; -const esp_partition_t* _getStaticPartition() { +const esp_partition_t* _getStaticPartition() +{ const esp_partition_t* partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "static0"); if (partition != nullptr) { return partition; @@ -43,7 +44,8 @@ const esp_partition_t* _getStaticPartition() { return nullptr; } -const char* _getPartitionHash() { +const char* _getPartitionHash() +{ const esp_partition_t* partition = _getStaticPartition(); if (partition == nullptr) { return nullptr; @@ -63,7 +65,8 @@ CaptivePortalInstance::CaptivePortalInstance() , m_socketDeFragger(std::bind(&CaptivePortalInstance::handleWebSocketEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)) , m_fileSystem() , m_dnsServer() - , m_taskHandle(nullptr) { + , m_taskHandle(nullptr) +{ m_socketServer.onEvent(std::bind(&WebSocketDeFragger::handler, &m_socketDeFragger, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); m_socketServer.begin(); m_socketServer.enableHeartbeat(WEBSOCKET_PING_INTERVAL, WEBSOCKET_PING_TIMEOUT, WEBSOCKET_PING_RETRIES); @@ -130,7 +133,8 @@ discord.gg/OpenShock } } -CaptivePortalInstance::~CaptivePortalInstance() { +CaptivePortalInstance::~CaptivePortalInstance() +{ if (m_taskHandle != nullptr) { vTaskDelete(m_taskHandle); m_taskHandle = nullptr; @@ -141,7 +145,8 @@ CaptivePortalInstance::~CaptivePortalInstance() { m_dnsServer.stop(); } -void CaptivePortalInstance::task() { +void CaptivePortalInstance::task() +{ while (true) { m_socketServer.loop(); // instance->m_dnsServer.processNextRequest(); @@ -149,7 +154,8 @@ void CaptivePortalInstance::task() { } } -void CaptivePortalInstance::handleWebSocketClientConnected(uint8_t socketId) { +void CaptivePortalInstance::handleWebSocketClientConnected(uint8_t socketId) +{ OS_LOGD(TAG, "WebSocket client #%u connected from %s", socketId, m_socketServer.remoteIP(socketId).toString().c_str()); WiFiNetwork connectedNetwork; @@ -166,15 +172,18 @@ void CaptivePortalInstance::handleWebSocketClientConnected(uint8_t socketId) { Serialization::Local::SerializeWiFiNetworksEvent(Serialization::Types::WifiNetworkEventType::Discovered, networks, std::bind(&CaptivePortalInstance::sendMessageBIN, this, socketId, std::placeholders::_1, std::placeholders::_2)); } -void CaptivePortalInstance::handleWebSocketClientDisconnected(uint8_t socketId) { +void CaptivePortalInstance::handleWebSocketClientDisconnected(uint8_t socketId) +{ OS_LOGD(TAG, "WebSocket client #%u disconnected", socketId); } -void CaptivePortalInstance::handleWebSocketClientError(uint8_t socketId, uint16_t code, const char* message) { +void CaptivePortalInstance::handleWebSocketClientError(uint8_t socketId, uint16_t code, const char* message) +{ OS_LOGE(TAG, "WebSocket client #%u error %u: %s", socketId, code, message); } -void CaptivePortalInstance::handleWebSocketEvent(uint8_t socketId, WebSocketMessageType type, const uint8_t* payload, std::size_t length) { +void CaptivePortalInstance::handleWebSocketEvent(uint8_t socketId, WebSocketMessageType type, const uint8_t* payload, std::size_t length) +{ switch (type) { case WebSocketMessageType::Connected: handleWebSocketClientConnected(socketId); @@ -186,7 +195,7 @@ void CaptivePortalInstance::handleWebSocketEvent(uint8_t socketId, WebSocketMess OS_LOGE(TAG, "Message type is not supported"); break; case WebSocketMessageType::Binary: - EventHandlers::WebSocket::HandleLocalBinary(socketId, payload, length); + MessageHandlers::WebSocket::HandleLocalBinary(socketId, payload, length); break; case WebSocketMessageType::Error: handleWebSocketClientError(socketId, length, reinterpret_cast(payload)); diff --git a/src/CommandHandler.cpp b/src/CommandHandler.cpp index cb261ea0..d32ae0f7 100644 --- a/src/CommandHandler.cpp +++ b/src/CommandHandler.cpp @@ -8,6 +8,8 @@ const char* const TAG = "CommandHandler"; #include "Common.h" #include "config/Config.h" #include "EStopManager.h" +#include "EStopState.h" +#include "events/Events.h" #include "Logging.h" #include "radio/RFTransmitter.h" #include "ReadWriteMutex.h" @@ -151,8 +153,21 @@ bool _internalSetKeepAliveEnabled(bool enabled) return true; } +void _handleOpenShockEStopStateChangeEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + (void)event_handler_arg; + (void)event_base; + (void)event_id; + + EStopState state = *reinterpret_cast(event_data); + + _internalSetKeepAliveEnabled(state == EStopState::Idle); +} + bool CommandHandler::Init() { + esp_err_t err; + static bool initialized = false; if (initialized) { OS_LOGW(TAG, "RF Transmitter and EStopManager are already initialized?"); @@ -200,6 +215,12 @@ bool CommandHandler::Init() return false; } + err = esp_event_handler_register(OPENSHOCK_EVENTS, OPENSHOCK_EVENT_ESTOP_STATE_CHANGED, _handleOpenShockEStopStateChangeEvent, nullptr); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to register event handler for OPENSHOCK_EVENTS: %s", esp_err_to_name(err)); + return false; + } + // TODO: Implement EStopManager pin change logic return true; @@ -277,25 +298,6 @@ bool CommandHandler::SetKeepAliveEnabled(bool enabled) return true; } -bool CommandHandler::SetKeepAlivePaused(bool paused) -{ - bool keepAliveEnabled = false; - if (!Config::GetRFConfigKeepAliveEnabled(keepAliveEnabled)) { - OS_LOGE(TAG, "Failed to get keep-alive enabled from config"); - return false; - } - - if (keepAliveEnabled == false && paused == false) { - OS_LOGW(TAG, "Keep-alive is disabled in config, ignoring unpause command"); - return false; - } - if (!_internalSetKeepAliveEnabled(!paused)) { - return false; - } - - return true; -} - gpio_num_t CommandHandler::GetRfTxPin() { if (s_rfTransmitter != nullptr) { diff --git a/src/EStopManager.cpp b/src/EStopManager.cpp index 3fb6e534..910cd99a 100644 --- a/src/EStopManager.cpp +++ b/src/EStopManager.cpp @@ -5,18 +5,20 @@ const char* const TAG = "EStopManager"; #include "Chipset.h" -#include "CommandHandler.h" #include "config/Config.h" +#include "events/Events.h" #include "Logging.h" #include "SimpleMutex.h" #include "Time.h" #include "util/TaskUtils.h" -#include "VisualStateManager.h" #include #include +#include #include +#include + using namespace OpenShock; const uint32_t k_estopHoldToClearTime = 5000; @@ -28,26 +30,16 @@ static OpenShock::SimpleMutex s_estopMutex = {}; static gpio_num_t s_estopPin = GPIO_NUM_NC; static TaskHandle_t s_estopTask; +EStopState s_estopState = EStopState::Idle; static bool s_estopActive = false; static int64_t s_estopActivatedAt = 0; void _estopUpdateExternals(bool isActive, bool isAwaitingRelease) { - // Set visual state - OpenShock::VisualStateManager::SetEmergencyStopStatus(isActive, isAwaitingRelease); - - // Set KeepAlive state - OpenShock::CommandHandler::SetKeepAlivePaused(isActive); + // Post an event + ESP_ERROR_CHECK(esp_event_post(OPENSHOCK_EVENTS, OPENSHOCK_EVENT_ESTOP_STATE_CHANGED, &s_estopState, sizeof(s_estopState), portMAX_DELAY)); } -enum class EStopState { - Idle, - ActiveAwaitingRelease, - Active, - Deactivating, - DeactivatingAwaitingRelease, -}; - // Samples the estop at a fixed rate and sends messages to the estop event handler task void _estopCheckerTask(void* pvParameters) { @@ -72,8 +64,8 @@ void _estopCheckerTask(void* pvParameters) bool btnState = (history & k_estopCheckMask) != k_estopCheckMask; if (btnState == lastBtnState) { // If the state hasn't changed, handle timing transitions - if (state == EStopState::Deactivating && now > deactivatesAt) { - state = EStopState::DeactivatingAwaitingRelease; + if (state == EStopState::ActiveClearing && now > deactivatesAt) { + state = EStopState::AwaitingRelease; _estopUpdateExternals(s_estopActive, true); } continue; @@ -83,30 +75,25 @@ void _estopCheckerTask(void* pvParameters) switch (state) { case EStopState::Idle: if (btnState) { - state = EStopState::ActiveAwaitingRelease; + state = EStopState::Active; s_estopActive = true; s_estopActivatedAt = now; } break; - case EStopState::ActiveAwaitingRelease: - if (!btnState) { - state = EStopState::Active; - } - break; case EStopState::Active: if (btnState) { - state = EStopState::Deactivating; + state = EStopState::ActiveClearing; deactivatesAt = now + k_estopHoldToClearTime; } break; - case EStopState::Deactivating: + case EStopState::ActiveClearing: if (!btnState) { state = EStopState::Active; } else if (now > deactivatesAt) { - state = EStopState::DeactivatingAwaitingRelease; + state = EStopState::AwaitingRelease; } break; - case EStopState::DeactivatingAwaitingRelease: + case EStopState::AwaitingRelease: if (!btnState) { state = EStopState::Idle; s_estopActive = false; @@ -116,7 +103,7 @@ void _estopCheckerTask(void* pvParameters) continue; } - _estopUpdateExternals(s_estopActive, state == EStopState::DeactivatingAwaitingRelease); + _estopUpdateExternals(s_estopActive, state == EStopState::AwaitingRelease); } } diff --git a/src/GatewayClient.cpp b/src/GatewayClient.cpp index 3bd2d0b0..ca445c35 100644 --- a/src/GatewayClient.cpp +++ b/src/GatewayClient.cpp @@ -4,8 +4,9 @@ const char* const TAG = "GatewayClient"; #include "Common.h" #include "config/Config.h" -#include "event_handlers/WebSocket.h" +#include "events/Events.h" #include "Logging.h" +#include "message_handlers/WebSocket.h" #include "OtaUpdateManager.h" #include "serialization/WSGateway.h" #include "Time.h" @@ -16,7 +17,11 @@ using namespace OpenShock; static bool s_bootStatusSent = false; -GatewayClient::GatewayClient(const std::string& authToken) : m_webSocket(), m_lastKeepAlive(0), m_state(State::Disconnected) { +GatewayClient::GatewayClient(const std::string& authToken) + : m_webSocket() + , m_lastKeepAlive(0) + , m_state(GatewayClientState::Disconnected) +{ OS_LOGD(TAG, "Creating GatewayClient"); std::string headers = "Firmware-Version: " OPENSHOCK_FW_VERSION "\r\n" @@ -27,17 +32,21 @@ GatewayClient::GatewayClient(const std::string& authToken) : m_webSocket(), m_la m_webSocket.setExtraHeaders(headers.c_str()); m_webSocket.onEvent(std::bind(&GatewayClient::_handleEvent, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } -GatewayClient::~GatewayClient() { +GatewayClient::~GatewayClient() +{ + _setState(GatewayClientState::Disconnected); + OS_LOGD(TAG, "Destroying GatewayClient"); m_webSocket.disconnect(); } -void GatewayClient::connect(const char* lcgFqdn) { - if (m_state != State::Disconnected) { +void GatewayClient::connect(const char* lcgFqdn) +{ + if (m_state != GatewayClientState::Disconnected) { return; } - _setState(State::Connecting); + _setState(GatewayClientState::Connecting); // // ###### ######## ###### ## ## ######## #### ######## ## ## ######## #### ###### ## ## @@ -56,39 +65,43 @@ void GatewayClient::connect(const char* lcgFqdn) { OS_LOGW(TAG, "WEBSOCKET CONNECTION BY RFC DEFINITION IS INSECURE, remote endpoint can not be verified due to lack of CA verification support, theoretically this is a security risk and allows for MITM attacks, but the realistic risk is low"); } -void GatewayClient::disconnect() { - if (m_state != State::Connected) { +void GatewayClient::disconnect() +{ + if (m_state != GatewayClientState::Connected) { return; } - _setState(State::Disconnecting); + _setState(GatewayClientState::Disconnecting); m_webSocket.disconnect(); } -bool GatewayClient::sendMessageTXT(std::string_view data) { - if (m_state != State::Connected) { +bool GatewayClient::sendMessageTXT(std::string_view data) +{ + if (m_state != GatewayClientState::Connected) { return false; } return m_webSocket.sendTXT(data.data(), data.length()); } -bool GatewayClient::sendMessageBIN(const uint8_t* data, std::size_t length) { - if (m_state != State::Connected) { +bool GatewayClient::sendMessageBIN(const uint8_t* data, std::size_t length) +{ + if (m_state != GatewayClientState::Connected) { return false; } return m_webSocket.sendBIN(data, length); } -bool GatewayClient::loop() { - if (m_state == State::Disconnected) { +bool GatewayClient::loop() +{ + if (m_state == GatewayClientState::Disconnected) { return false; } m_webSocket.loop(); // We are still in the process of connecting or disconnecting - if (m_state != State::Connected) { + if (m_state != GatewayClientState::Connected) { // return true to indicate that we are still busy return true; } @@ -105,33 +118,25 @@ bool GatewayClient::loop() { return true; } -void GatewayClient::_setState(State state) { +void GatewayClient::_setState(GatewayClientState state) +{ if (m_state == state) { return; } m_state = state; - switch (m_state) { - case State::Disconnected: - OS_LOGI(TAG, "Disconnected from API"); - OpenShock::VisualStateManager::SetWebSocketConnected(false); - break; - case State::Connected: - OS_LOGI(TAG, "Connected to API"); - OpenShock::VisualStateManager::SetWebSocketConnected(true); - break; - default: - break; - } + ESP_ERROR_CHECK(esp_event_post(OPENSHOCK_EVENTS, OPENSHOCK_EVENT_GATEWAY_CLIENT_STATE_CHANGED, &m_state, sizeof(m_state), portMAX_DELAY)); } -void GatewayClient::_sendKeepAlive() { +void GatewayClient::_sendKeepAlive() +{ OS_LOGV(TAG, "Sending Gateway keep-alive message"); Serialization::Gateway::SerializeKeepAliveMessage([this](const uint8_t* data, std::size_t len) { return m_webSocket.sendBIN(data, len); }); } -void GatewayClient::_sendBootStatus() { +void GatewayClient::_sendBootStatus() +{ if (s_bootStatusSent) return; OS_LOGV(TAG, "Sending Gateway boot status message"); @@ -163,15 +168,16 @@ void GatewayClient::_sendBootStatus() { } } -void GatewayClient::_handleEvent(WStype_t type, uint8_t* payload, std::size_t length) { +void GatewayClient::_handleEvent(WStype_t type, uint8_t* payload, std::size_t length) +{ (void)payload; switch (type) { case WStype_DISCONNECTED: - _setState(State::Disconnected); + _setState(GatewayClientState::Disconnected); break; case WStype_CONNECTED: - _setState(State::Connected); + _setState(GatewayClientState::Connected); _sendKeepAlive(); _sendBootStatus(); break; @@ -197,7 +203,7 @@ void GatewayClient::_handleEvent(WStype_t type, uint8_t* payload, std::size_t le OS_LOGV(TAG, "Received pong from API"); break; case WStype_BIN: - EventHandlers::WebSocket::HandleGatewayBinary(payload, length); + MessageHandlers::WebSocket::HandleGatewayBinary(payload, length); break; case WStype_FRAGMENT_BIN_START: OS_LOGE(TAG, "Received binary fragment start from API, this is not supported!"); diff --git a/src/GatewayConnectionManager.cpp b/src/GatewayConnectionManager.cpp index a21dfd94..a42f147f 100644 --- a/src/GatewayConnectionManager.cpp +++ b/src/GatewayConnectionManager.cpp @@ -34,29 +34,31 @@ const uint8_t FLAG_LINKED = 1 << 1; const uint8_t LINK_CODE_LENGTH = 6; -static uint8_t s_flags = 0; +static uint8_t s_flags = 0; static std::unique_ptr s_wsClient = nullptr; -void _evGotIPHandler(arduino_event_t* event) { +void _evGotIPHandler(arduino_event_t* event) +{ (void)event; s_flags |= FLAG_HAS_IP; OS_LOGD(TAG, "Got IP address"); } -void _evWiFiDisconnectedHandler(arduino_event_t* event) { +void _evWiFiDisconnectedHandler(arduino_event_t* event) +{ (void)event; s_flags = FLAG_NONE; s_wsClient = nullptr; OS_LOGD(TAG, "Lost IP address"); - OpenShock::VisualStateManager::SetWebSocketConnected(false); } using namespace OpenShock; namespace JsonAPI = OpenShock::Serialization::JsonAPI; -bool GatewayConnectionManager::Init() { +bool GatewayConnectionManager::Init() +{ WiFi.onEvent(_evGotIPHandler, ARDUINO_EVENT_WIFI_STA_GOT_IP); WiFi.onEvent(_evGotIPHandler, ARDUINO_EVENT_WIFI_STA_GOT_IP6); WiFi.onEvent(_evWiFiDisconnectedHandler, ARDUINO_EVENT_WIFI_STA_DISCONNECTED); @@ -64,19 +66,22 @@ bool GatewayConnectionManager::Init() { return true; } -bool GatewayConnectionManager::IsConnected() { +bool GatewayConnectionManager::IsConnected() +{ if (s_wsClient == nullptr) { return false; } - return s_wsClient->state() == GatewayClient::State::Connected; + return s_wsClient->state() == GatewayClientState::Connected; } -bool GatewayConnectionManager::IsLinked() { +bool GatewayConnectionManager::IsLinked() +{ return (s_flags & FLAG_LINKED) != 0; } -AccountLinkResultCode GatewayConnectionManager::Link(std::string_view linkCode) { +AccountLinkResultCode GatewayConnectionManager::Link(std::string_view linkCode) +{ if ((s_flags & FLAG_HAS_IP) == 0) { return AccountLinkResultCode::NoInternetConnection; } @@ -126,13 +131,15 @@ AccountLinkResultCode GatewayConnectionManager::Link(std::string_view linkCode) return AccountLinkResultCode::Success; } -void GatewayConnectionManager::UnLink() { +void GatewayConnectionManager::UnLink() +{ s_flags &= FLAG_HAS_IP; s_wsClient = nullptr; Config::ClearBackendAuthToken(); } -bool GatewayConnectionManager::SendMessageTXT(std::string_view data) { +bool GatewayConnectionManager::SendMessageTXT(std::string_view data) +{ if (s_wsClient == nullptr) { return false; } @@ -140,7 +147,8 @@ bool GatewayConnectionManager::SendMessageTXT(std::string_view data) { return s_wsClient->sendMessageTXT(data); } -bool GatewayConnectionManager::SendMessageBIN(const uint8_t* data, std::size_t length) { +bool GatewayConnectionManager::SendMessageBIN(const uint8_t* data, std::size_t length) +{ if (s_wsClient == nullptr) { return false; } @@ -148,7 +156,8 @@ bool GatewayConnectionManager::SendMessageBIN(const uint8_t* data, std::size_t l return s_wsClient->sendMessageBIN(data, length); } -bool FetchDeviceInfo(std::string_view authToken) { +bool FetchDeviceInfo(std::string_view authToken) +{ // TODO: this function is very slow, should be optimized! if ((s_flags & FLAG_HAS_IP) == 0) { return false; @@ -188,14 +197,15 @@ bool FetchDeviceInfo(std::string_view authToken) { } static int64_t _lastConnectionAttempt = 0; -bool StartConnectingToLCG() { +bool StartConnectingToLCG() +{ // TODO: this function is very slow, should be optimized! if (s_wsClient == nullptr) { // If wsClient is already initialized, we are already paired or connected OS_LOGD(TAG, "wsClient is null"); return false; } - if (s_wsClient->state() != GatewayClient::State::Disconnected) { + if (s_wsClient->state() != GatewayClientState::Disconnected) { OS_LOGD(TAG, "WebSocketClient is not disconnected, waiting..."); s_wsClient->disconnect(); return false; @@ -255,7 +265,8 @@ bool StartConnectingToLCG() { return true; } -void GatewayConnectionManager::Update() { +void GatewayConnectionManager::Update() +{ if (s_wsClient == nullptr) { // Can't connect to the API without WiFi or an auth token if ((s_flags & FLAG_HAS_IP) == 0 || !Config::HasBackendAuthToken()) { diff --git a/src/OtaUpdateManager.cpp b/src/OtaUpdateManager.cpp index 33247351..4bd8823b 100644 --- a/src/OtaUpdateManager.cpp +++ b/src/OtaUpdateManager.cpp @@ -99,15 +99,33 @@ bool _tryGetRequestedVersion(OpenShock::SemVer& version) return true; } -void _otaEvGotIPHandler(arduino_event_t* event) +void _otaEvWiFiDisconnectedHandler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - (void)event; - xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_CONNECTED, eSetBits); + (void)event_handler_arg; + (void)event_base; + (void)event_id; + (void)event_data; + + xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_DISCONNECTED, eSetBits); } -void _otaEvWiFiDisconnectedHandler(arduino_event_t* event) + +void _otaEvIpEventHandler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { - (void)event; - xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_DISCONNECTED, eSetBits); + (void)event_handler_arg; + (void)event_base; + (void)event_data; + + switch (event_id) { + case IP_EVENT_GOT_IP6: + case IP_EVENT_STA_GOT_IP: + xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_CONNECTED, eSetBits); + break; + case IP_EVENT_STA_LOST_IP: + xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_DISCONNECTED, eSetBits); + break; + default: + return; + } } bool _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask task, float progress) @@ -442,6 +460,8 @@ bool _tryGetStringList(std::string_view url, std::vector& list) bool OtaUpdateManager::Init() { + esp_err_t err; + OS_LOGN(TAG, "Fetching current partition"); // Fetch current partition info. @@ -454,7 +474,7 @@ bool OtaUpdateManager::Init() OS_LOGD(TAG, "Fetching partition state"); // Get OTA state for said partition. - esp_err_t err = esp_ota_get_state_partition(partition, &_otaImageState); + err = esp_ota_get_state_partition(partition, &_otaImageState); if (err != ESP_OK) { OS_PANIC(TAG, "Failed to get partition state: %s", esp_err_to_name(err)); return false; // This will never be reached, but the compiler doesn't know that. @@ -487,9 +507,17 @@ bool OtaUpdateManager::Init() } } - WiFi.onEvent(_otaEvGotIPHandler, ARDUINO_EVENT_WIFI_STA_GOT_IP); - WiFi.onEvent(_otaEvGotIPHandler, ARDUINO_EVENT_WIFI_STA_GOT_IP6); - WiFi.onEvent(_otaEvWiFiDisconnectedHandler, ARDUINO_EVENT_WIFI_STA_DISCONNECTED); + err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, _otaEvIpEventHandler, nullptr); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to register event handler for IP_EVENT: %s", esp_err_to_name(err)); + return false; + } + + err = esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, _otaEvWiFiDisconnectedHandler, nullptr); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to register event handler for WIFI_EVENT: %s", esp_err_to_name(err)); + return false; + } // Start OTA update task. TaskUtils::TaskCreateExpensive(_otaUpdateTask, "OTA Update", 8192, nullptr, 1, &_taskHandle); // PROFILED: 6.2KB stack usage diff --git a/src/VisualStateManager.cpp b/src/VisualStateManager.cpp index c5bacd82..6af6eb30 100644 --- a/src/VisualStateManager.cpp +++ b/src/VisualStateManager.cpp @@ -4,28 +4,51 @@ const char* const TAG = "VisualStateManager"; +#include "EStopState.h" +#include "events/Events.h" +#include "GatewayClientState.h" #include "Logging.h" #include "PinPatternManager.h" #include "RGBPatternManager.h" -#include - #include +#ifndef OPENSHOCK_LED_GPIO +#define OPENSHOCK_LED_GPIO GPIO_NUM_NC +#endif // OPENSHOCK_LED_GPIO +#ifndef OPENSHOCK_LED_WS2812B +#define OPENSHOCK_LED_WS2812B GPIO_NUM_NC +#endif // OPENSHOCK_LED_WS2812B + const uint64_t kCriticalErrorFlag = 1 << 0; const uint64_t kEmergencyStoppedFlag = 1 << 1; const uint64_t kEmergencyStopAwaitingReleaseFlag = 1 << 2; const uint64_t kWebSocketConnectedFlag = 1 << 3; -const uint64_t kWiFiConnectedFlag = 1 << 4; -const uint64_t kWiFiScanningFlag = 1 << 5; +const uint64_t kHasIpAddressFlag = 1 << 4; +const uint64_t kWiFiConnectedFlag = 1 << 5; +const uint64_t kWiFiScanningFlag = 1 << 6; -// Bitmask of when the system is in a "all clear" state. -const uint64_t kStatusOKMask = kWebSocketConnectedFlag | kWiFiConnectedFlag; +// Bitmask of when the system is running normally +const uint64_t kStatusOKMask = kWebSocketConnectedFlag | kHasIpAddressFlag | kWiFiConnectedFlag; static uint64_t s_stateFlags = 0; static std::shared_ptr s_builtInLedManager; static std::shared_ptr s_RGBLedManager; +inline void _setStateFlag(uint64_t flag, bool state) +{ + if (state) { + s_stateFlags |= flag; + } else { + s_stateFlags &= ~flag; + } +} + +inline bool _isStateFlagSet(uint64_t flag) +{ + return s_stateFlags & flag; +} + using namespace OpenShock; const PinPatternManager::State kCriticalErrorPattern[] = { @@ -148,82 +171,47 @@ const PinPatternManager::State kSolidOffPattern[] = { {false, 100'000} }; -template -inline void _updateVisualStateGPIO(const PinPatternManager::State (&override)[N]) { +template +inline void _updateVisualStateGPIO(const PinPatternManager::State (&override)[N]) +{ s_builtInLedManager->SetPattern(override); } -void _updateVisualStateGPIO() { - if (s_stateFlags & kCriticalErrorFlag) { - s_builtInLedManager->SetPattern(kCriticalErrorPattern); - return; - } - - if (s_stateFlags & kEmergencyStopAwaitingReleaseFlag) { - s_builtInLedManager->SetPattern(kEmergencyStopAwaitingReleasePattern); - return; - } - - if (s_stateFlags & kEmergencyStoppedFlag) { - s_builtInLedManager->SetPattern(kEmergencyStoppedPattern); - return; - } - - if (s_stateFlags & kWebSocketConnectedFlag) { - s_builtInLedManager->SetPattern(kWebSocketConnectedPattern); - return; - } - - if (s_stateFlags & kWiFiConnectedFlag) { - s_builtInLedManager->SetPattern(kWiFiConnectedWithoutWSPattern); - return; +// Check-Set-Return pattern for setting a pattern based on a flag +#define CSR_PATTERN(manager, flag, pattern) \ + if (_isStateFlagSet(flag)) { \ + manager->SetPattern(pattern); \ + return; \ } - if (s_stateFlags & kWiFiScanningFlag) { - s_builtInLedManager->SetPattern(kPingNoResponsePattern); - return; - } +void _updateVisualStateGPIO() +{ + CSR_PATTERN(s_builtInLedManager, kCriticalErrorFlag, kCriticalErrorPattern); + CSR_PATTERN(s_builtInLedManager, kEmergencyStopAwaitingReleaseFlag, kEmergencyStopAwaitingReleasePattern); + CSR_PATTERN(s_builtInLedManager, kEmergencyStoppedFlag, kEmergencyStoppedPattern); + CSR_PATTERN(s_builtInLedManager, kWebSocketConnectedFlag, kWebSocketConnectedPattern); + CSR_PATTERN(s_builtInLedManager, kHasIpAddressFlag, kWiFiConnectedWithoutWSPattern); + CSR_PATTERN(s_builtInLedManager, kWiFiScanningFlag, kPingNoResponsePattern); s_builtInLedManager->SetPattern(kWiFiDisconnectedPattern); } -void _updateVisualStateRGB() { - if (s_stateFlags & kCriticalErrorFlag) { - s_RGBLedManager->SetPattern(kCriticalErrorRGBPattern); - return; - } - - if (s_stateFlags & kEmergencyStopAwaitingReleaseFlag) { - s_RGBLedManager->SetPattern(kEmergencyStopAwaitingReleaseRGBPattern); - return; - } - - if (s_stateFlags & kEmergencyStoppedFlag) { - s_RGBLedManager->SetPattern(kEmergencyStoppedRGBPattern); - return; - } - - if (s_stateFlags & kWebSocketConnectedFlag) { - s_RGBLedManager->SetPattern(kWebSocketConnectedRGBPattern); - return; - } - - if (s_stateFlags & kWiFiConnectedFlag) { - s_RGBLedManager->SetPattern(kWiFiConnectedWithoutWSRGBPattern); - return; - } - - if (s_stateFlags & kWiFiScanningFlag) { - s_RGBLedManager->SetPattern(kPingNoResponseRGBPattern); - return; - } +void _updateVisualStateRGB() +{ + CSR_PATTERN(s_RGBLedManager, kCriticalErrorFlag, kCriticalErrorRGBPattern); + CSR_PATTERN(s_RGBLedManager, kEmergencyStopAwaitingReleaseFlag, kEmergencyStopAwaitingReleaseRGBPattern); + CSR_PATTERN(s_RGBLedManager, kEmergencyStoppedFlag, kEmergencyStoppedRGBPattern); + CSR_PATTERN(s_RGBLedManager, kWebSocketConnectedFlag, kWebSocketConnectedRGBPattern); + CSR_PATTERN(s_RGBLedManager, kHasIpAddressFlag, kWiFiConnectedWithoutWSRGBPattern); + CSR_PATTERN(s_RGBLedManager, kWiFiScanningFlag, kPingNoResponseRGBPattern); s_RGBLedManager->SetPattern(kWiFiDisconnectedRGBPattern); } -void _updateVisualState() { +void _updateVisualState() +{ bool gpioActive = s_builtInLedManager != nullptr; - bool rgbActive = s_RGBLedManager != nullptr; + bool rgbActive = s_RGBLedManager != nullptr; if (gpioActive && rgbActive) { if (s_stateFlags == kStatusOKMask) { @@ -248,48 +236,104 @@ void _updateVisualState() { OS_LOGW(TAG, "Trying to update visual state, but no LED is active!"); } -void _handleWiFiConnected(arduino_event_t* event) { - (void)event; +void _handleEspWiFiEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + (void)event_handler_arg; + (void)event_base; + (void)event_data; uint64_t oldState = s_stateFlags; - s_stateFlags |= kWiFiConnectedFlag; + switch (event_id) { + case WIFI_EVENT_STA_CONNECTED: + _setStateFlag(kWiFiConnectedFlag, true); + break; + case WIFI_EVENT_STA_DISCONNECTED: + _setStateFlag(kWiFiConnectedFlag, false); + _setStateFlag(kHasIpAddressFlag, false); + break; + case WIFI_EVENT_SCAN_DONE: + _setStateFlag(kWiFiScanningFlag, false); + break; + default: + return; + } if (oldState != s_stateFlags) { _updateVisualState(); } } -void _handleWiFiDisconnected(arduino_event_t* event) { - (void)event; + +void _handleEspIpEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + (void)event_handler_arg; + (void)event_base; + (void)event_data; uint64_t oldState = s_stateFlags; - s_stateFlags &= ~kWiFiConnectedFlag; + switch (event_id) { + case IP_EVENT_GOT_IP6: + case IP_EVENT_STA_GOT_IP: + case IP_EVENT_ETH_GOT_IP: + case IP_EVENT_PPP_GOT_IP: + _setStateFlag(kHasIpAddressFlag, true); + break; + case IP_EVENT_STA_LOST_IP: + case IP_EVENT_ETH_LOST_IP: + case IP_EVENT_PPP_LOST_IP: + _setStateFlag(kHasIpAddressFlag, false); + break; + default: + return; + } if (oldState != s_stateFlags) { _updateVisualState(); } } -void _handleWiFiScanDone(arduino_event_t* event) { - (void)event; + +void _handleOpenShockEStopStateChanged(void* event_data) +{ + auto state = *reinterpret_cast(event_data); + + _setStateFlag(kEmergencyStoppedFlag, state != EStopState::Idle); + _setStateFlag(kEmergencyStopAwaitingReleaseFlag, state == EStopState::ActiveClearing); +} + +void _handleOpenShockGatewayStateChanged(void* event_data) +{ + auto state = *reinterpret_cast(event_data); + + _setStateFlag(kWebSocketConnectedFlag, state == GatewayClientState::Connected); +} + +void _handleOpenShockEvent(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +{ + (void)event_handler_arg; + (void)event_base; uint64_t oldState = s_stateFlags; - s_stateFlags &= ~kWiFiScanningFlag; + switch (event_id) { + case OPENSHOCK_EVENT_ESTOP_STATE_CHANGED: + _handleOpenShockEStopStateChanged(event_data); + break; + case OPENSHOCK_EVENT_GATEWAY_CLIENT_STATE_CHANGED: + _handleOpenShockGatewayStateChanged(event_data); + break; + default: + ESP_LOGW(TAG, "Received unknown event ID: %i", event_id); + return; + } if (oldState != s_stateFlags) { _updateVisualState(); } } -#ifndef OPENSHOCK_LED_GPIO -#define OPENSHOCK_LED_GPIO GPIO_NUM_NC -#endif // OPENSHOCK_LED_GPIO -#ifndef OPENSHOCK_LED_WS2812B -#define OPENSHOCK_LED_WS2812B GPIO_NUM_NC -#endif // OPENSHOCK_LED_WS2812B - -bool VisualStateManager::Init() { +bool VisualStateManager::Init() +{ bool ledActive = false; if (OPENSHOCK_LED_GPIO != GPIO_NUM_NC) { @@ -315,65 +359,48 @@ bool VisualStateManager::Init() { return true; } - WiFi.onEvent(_handleWiFiConnected, ARDUINO_EVENT_WIFI_STA_GOT_IP); - WiFi.onEvent(_handleWiFiConnected, ARDUINO_EVENT_WIFI_STA_GOT_IP6); - WiFi.onEvent(_handleWiFiDisconnected, ARDUINO_EVENT_WIFI_STA_DISCONNECTED); - WiFi.onEvent(_handleWiFiScanDone, ARDUINO_EVENT_WIFI_SCAN_DONE); - - // Run the update on init, otherwise no inital pattern is set. - _updateVisualState(); - - return true; -} + esp_err_t err; -void VisualStateManager::SetCriticalError() { - uint64_t oldState = s_stateFlags; - - s_stateFlags |= kCriticalErrorFlag; + err = esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, _handleEspWiFiEvent, nullptr); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to register event handler for IP_EVENT: %s", esp_err_to_name(err)); + return false; + } - if (oldState != s_stateFlags) { - _updateVisualState(); + err = esp_event_handler_register(IP_EVENT, ESP_EVENT_ANY_ID, _handleEspIpEvent, nullptr); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to register event handler for IP_EVENT: %s", esp_err_to_name(err)); + return false; } -} -void VisualStateManager::SetScanningStarted() { - uint64_t oldState = s_stateFlags; + err = esp_event_handler_register(OPENSHOCK_EVENTS, ESP_EVENT_ANY_ID, _handleOpenShockEvent, nullptr); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to register event handler for OPENSHOCK_EVENTS: %s", esp_err_to_name(err)); + return false; + } - s_stateFlags |= kWiFiScanningFlag; + // Run the update on init, otherwise no inital pattern is set. + _updateVisualState(); - if (oldState != s_stateFlags) { - _updateVisualState(); - } + return true; } -void VisualStateManager::SetEmergencyStopStatus(bool isActive, bool isAwaitingRelease) { +void VisualStateManager::SetCriticalError() +{ uint64_t oldState = s_stateFlags; - if (isActive) { - s_stateFlags |= kEmergencyStoppedFlag; - } else { - s_stateFlags &= ~kEmergencyStoppedFlag; - } - - if (isAwaitingRelease) { - s_stateFlags |= kEmergencyStopAwaitingReleaseFlag; - } else { - s_stateFlags &= ~kEmergencyStopAwaitingReleaseFlag; - } + _setStateFlag(kCriticalErrorFlag, true); if (oldState != s_stateFlags) { _updateVisualState(); } } -void VisualStateManager::SetWebSocketConnected(bool isConnected) { +void VisualStateManager::SetScanningStarted() +{ uint64_t oldState = s_stateFlags; - if (isConnected) { - s_stateFlags |= kWebSocketConnectedFlag; - } else { - s_stateFlags &= ~kWebSocketConnectedFlag; - } + _setStateFlag(kWiFiScanningFlag, true); if (oldState != s_stateFlags) { _updateVisualState(); diff --git a/src/events/Events.cpp b/src/events/Events.cpp new file mode 100644 index 00000000..579acd9e --- /dev/null +++ b/src/events/Events.cpp @@ -0,0 +1,22 @@ +#include + +#include "events/Events.h" + +#include "Logging.h" + +const char* const TAG = "Events"; + +ESP_EVENT_DEFINE_BASE(OPENSHOCK_EVENTS); + +using namespace OpenShock; + +bool Events::Init() +{ + esp_err_t err = esp_event_loop_create_default(); + if (err != ESP_OK) { + OS_LOGE(TAG, "Failed to create default event loop: %s", esp_err_to_name(err)); + return false; + } + + return true; +} diff --git a/src/main.cpp b/src/main.cpp index 42fa8cb7..aa187ee6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ const char* const TAG = "main"; #include "Common.h" #include "config/Config.h" #include "EStopManager.h" +#include "events/Events.h" #include "GatewayConnectionManager.h" #include "Logging.h" #include "OtaUpdateManager.h" @@ -95,6 +96,10 @@ void setup() OpenShock::Config::Init(); + if (!OpenShock::Events::Init()) { + OS_PANIC(TAG, "Unable to initialize Events"); + } + if (!OpenShock::OtaUpdateManager::Init()) { OS_PANIC(TAG, "Unable to initialize OTA Update Manager"); } diff --git a/src/event_handlers/websocket/Gateway.cpp b/src/message_handlers/websocket/Gateway.cpp similarity index 90% rename from src/event_handlers/websocket/Gateway.cpp rename to src/message_handlers/websocket/Gateway.cpp index 1be52a78..3f6fb1f2 100644 --- a/src/event_handlers/websocket/Gateway.cpp +++ b/src/message_handlers/websocket/Gateway.cpp @@ -1,8 +1,8 @@ -#include "event_handlers/WebSocket.h" +#include "message_handlers/WebSocket.h" const char* const TAG = "ServerMessageHandlers"; -#include "event_handlers/impl/WSGateway.h" +#include "message_handlers/impl/WSGateway.h" #include "Logging.h" @@ -34,7 +34,8 @@ static std::array s_serverHandlers = []() return handlers; }(); -void EventHandlers::WebSocket::HandleGatewayBinary(const uint8_t* data, std::size_t len) { +void MessageHandlers::WebSocket::HandleGatewayBinary(const uint8_t* data, std::size_t len) +{ // Deserialize auto msg = flatbuffers::GetRoot(data); if (msg == nullptr) { diff --git a/src/event_handlers/websocket/Local.cpp b/src/message_handlers/websocket/Local.cpp similarity index 92% rename from src/event_handlers/websocket/Local.cpp rename to src/message_handlers/websocket/Local.cpp index 8c5b0f23..4728fe57 100644 --- a/src/event_handlers/websocket/Local.cpp +++ b/src/message_handlers/websocket/Local.cpp @@ -1,9 +1,9 @@ -#include "event_handlers/WebSocket.h" +#include "message_handlers/WebSocket.h" const char* const TAG = "LocalMessageHandlers"; -#include "event_handlers/impl/WSLocal.h" #include "Logging.h" +#include "message_handlers/impl/WSLocal.h" #include "serialization/_fbs/LocalToHubMessage_generated.h" @@ -39,7 +39,8 @@ static std::array s_localHandlers = []() { return handlers; }(); -void EventHandlers::WebSocket::HandleLocalBinary(uint8_t socketId, const uint8_t* data, std::size_t len) { +void MessageHandlers::WebSocket::HandleLocalBinary(uint8_t socketId, const uint8_t* data, std::size_t len) +{ // Deserialize auto msg = flatbuffers::GetRoot(data); if (msg == nullptr) { diff --git a/src/event_handlers/websocket/gateway/CaptivePortalConfig.cpp b/src/message_handlers/websocket/gateway/CaptivePortalConfig.cpp similarity index 86% rename from src/event_handlers/websocket/gateway/CaptivePortalConfig.cpp rename to src/message_handlers/websocket/gateway/CaptivePortalConfig.cpp index f30327c4..a0f04366 100644 --- a/src/event_handlers/websocket/gateway/CaptivePortalConfig.cpp +++ b/src/message_handlers/websocket/gateway/CaptivePortalConfig.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSGateway.h" +#include "message_handlers/impl/WSGateway.h" const char* const TAG = "ServerMessageHandlers"; @@ -9,7 +9,8 @@ const char* const TAG = "ServerMessageHandlers"; using namespace OpenShock::MessageHandlers::Server; -void _Private::HandleCaptivePortalConfig(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) { +void _Private::HandleCaptivePortalConfig(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) +{ auto msg = root->payload_as_CaptivePortalConfig(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as CaptivePortalConfig"); diff --git a/src/event_handlers/websocket/gateway/OtaInstall.cpp b/src/message_handlers/websocket/gateway/OtaInstall.cpp similarity index 93% rename from src/event_handlers/websocket/gateway/OtaInstall.cpp rename to src/message_handlers/websocket/gateway/OtaInstall.cpp index 55812ce1..8faf5ef4 100644 --- a/src/event_handlers/websocket/gateway/OtaInstall.cpp +++ b/src/message_handlers/websocket/gateway/OtaInstall.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSGateway.h" +#include "message_handlers/impl/WSGateway.h" const char* const TAG = "ServerMessageHandlers"; @@ -10,7 +10,8 @@ const char* const TAG = "ServerMessageHandlers"; using namespace OpenShock::MessageHandlers::Server; -void _Private::HandleOtaInstall(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) { +void _Private::HandleOtaInstall(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) +{ auto msg = root->payload_as_OtaInstall(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as OtaInstall"); diff --git a/src/event_handlers/websocket/gateway/ShockerCommandList.cpp b/src/message_handlers/websocket/gateway/ShockerCommandList.cpp similarity index 82% rename from src/event_handlers/websocket/gateway/ShockerCommandList.cpp rename to src/message_handlers/websocket/gateway/ShockerCommandList.cpp index 620cf07f..306afa80 100644 --- a/src/event_handlers/websocket/gateway/ShockerCommandList.cpp +++ b/src/message_handlers/websocket/gateway/ShockerCommandList.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSGateway.h" +#include "message_handlers/impl/WSGateway.h" const char* const TAG = "ServerMessageHandlers"; @@ -10,7 +10,8 @@ const char* const TAG = "ServerMessageHandlers"; using namespace OpenShock::MessageHandlers::Server; -void _Private::HandleShockerCommandList(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) { +void _Private::HandleShockerCommandList(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) +{ auto msg = root->payload_as_ShockerCommandList(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as ShockerCommandList"); @@ -26,9 +27,9 @@ void _Private::HandleShockerCommandList(const OpenShock::Serialization::Gateway: OS_LOGV(TAG, "Received command list from API (%u commands)", commands->size()); for (auto command : *commands) { - uint16_t id = command->id(); - uint8_t intensity = command->intensity(); - uint16_t durationMs = command->duration(); + uint16_t id = command->id(); + uint8_t intensity = command->intensity(); + uint16_t durationMs = command->duration(); OpenShock::ShockerModelType model = command->model(); OpenShock::ShockerCommandType type = command->type(); diff --git a/src/event_handlers/websocket/gateway/_InvalidMessage.cpp b/src/message_handlers/websocket/gateway/_InvalidMessage.cpp similarity index 79% rename from src/event_handlers/websocket/gateway/_InvalidMessage.cpp rename to src/message_handlers/websocket/gateway/_InvalidMessage.cpp index d6ff4754..15ae23aa 100644 --- a/src/event_handlers/websocket/gateway/_InvalidMessage.cpp +++ b/src/message_handlers/websocket/gateway/_InvalidMessage.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSGateway.h" +#include "message_handlers/impl/WSGateway.h" const char* const TAG = "ServerMessageHandlers"; @@ -6,7 +6,8 @@ const char* const TAG = "ServerMessageHandlers"; using namespace OpenShock::MessageHandlers::Server; -void _Private::HandleInvalidMessage(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) { +void _Private::HandleInvalidMessage(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) +{ if (root == nullptr) { OS_LOGE(TAG, "Message cannot be parsed"); return; diff --git a/src/event_handlers/websocket/local/AccountLinkCommand.cpp b/src/message_handlers/websocket/local/AccountLinkCommand.cpp similarity index 90% rename from src/event_handlers/websocket/local/AccountLinkCommand.cpp rename to src/message_handlers/websocket/local/AccountLinkCommand.cpp index c98683c4..9b019db1 100644 --- a/src/event_handlers/websocket/local/AccountLinkCommand.cpp +++ b/src/message_handlers/websocket/local/AccountLinkCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -8,7 +8,8 @@ const char* const TAG = "LocalMessageHandlers"; #include -void serializeAccountLinkCommandResult(uint8_t socketId, OpenShock::Serialization::Local::AccountLinkResultCode result) { +void serializeAccountLinkCommandResult(uint8_t socketId, OpenShock::Serialization::Local::AccountLinkResultCode result) +{ flatbuffers::FlatBufferBuilder builder(1024); // TODO: Determine a good size auto responseOffset = OpenShock::Serialization::Local::CreateAccountLinkCommandResult(builder, result); @@ -25,7 +26,8 @@ void serializeAccountLinkCommandResult(uint8_t socketId, OpenShock::Serializatio using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleAccountLinkCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleAccountLinkCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ auto msg = root->payload_as_AccountLinkCommand(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as AccountLinkCommand"); diff --git a/src/event_handlers/websocket/local/AccountUnlinkCommand.cpp b/src/message_handlers/websocket/local/AccountUnlinkCommand.cpp similarity index 81% rename from src/event_handlers/websocket/local/AccountUnlinkCommand.cpp rename to src/message_handlers/websocket/local/AccountUnlinkCommand.cpp index 1d91902f..d72ffaf5 100644 --- a/src/event_handlers/websocket/local/AccountUnlinkCommand.cpp +++ b/src/message_handlers/websocket/local/AccountUnlinkCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -9,7 +9,8 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleAccountUnlinkCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleAccountUnlinkCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ (void)socketId; auto msg = root->payload_as_AccountUnlinkCommand(); diff --git a/src/event_handlers/websocket/local/SetEStopPinCommand.cpp b/src/message_handlers/websocket/local/SetEStopPinCommand.cpp similarity index 97% rename from src/event_handlers/websocket/local/SetEStopPinCommand.cpp rename to src/message_handlers/websocket/local/SetEStopPinCommand.cpp index b9e328d9..9f61ec55 100644 --- a/src/event_handlers/websocket/local/SetEStopPinCommand.cpp +++ b/src/message_handlers/websocket/local/SetEStopPinCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" #include "CaptivePortal.h" #include "CommandHandler.h" diff --git a/src/event_handlers/websocket/local/SetRfTxPinCommand.cpp b/src/message_handlers/websocket/local/SetRfTxPinCommand.cpp similarity index 97% rename from src/event_handlers/websocket/local/SetRfTxPinCommand.cpp rename to src/message_handlers/websocket/local/SetRfTxPinCommand.cpp index 490215f9..a21e1e15 100644 --- a/src/event_handlers/websocket/local/SetRfTxPinCommand.cpp +++ b/src/message_handlers/websocket/local/SetRfTxPinCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; diff --git a/src/event_handlers/websocket/local/WiFiNetworkConnectCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkConnectCommand.cpp similarity index 94% rename from src/event_handlers/websocket/local/WiFiNetworkConnectCommand.cpp rename to src/message_handlers/websocket/local/WiFiNetworkConnectCommand.cpp index 80bb0029..eb05e6a5 100644 --- a/src/event_handlers/websocket/local/WiFiNetworkConnectCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkConnectCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -10,9 +10,10 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkConnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleWiFiNetworkConnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ (void)socketId; - + auto msg = root->payload_as_WifiNetworkConnectCommand(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as WiFiNetworkConnectCommand"); diff --git a/src/event_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp similarity index 91% rename from src/event_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp rename to src/message_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp index 52b309fd..1e04aad8 100644 --- a/src/event_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -10,9 +10,10 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkDisconnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleWiFiNetworkDisconnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ (void)socketId; - + auto msg = root->payload_as_WifiNetworkDisconnectCommand(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as WiFiNetworkDisconnectCommand"); diff --git a/src/event_handlers/websocket/local/WiFiNetworkForgetCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkForgetCommand.cpp similarity index 88% rename from src/event_handlers/websocket/local/WiFiNetworkForgetCommand.cpp rename to src/message_handlers/websocket/local/WiFiNetworkForgetCommand.cpp index 6cd1db1c..f1c4f8b5 100644 --- a/src/event_handlers/websocket/local/WiFiNetworkForgetCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkForgetCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -10,9 +10,10 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkForgetCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleWiFiNetworkForgetCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ (void)socketId; - + auto msg = root->payload_as_WifiNetworkForgetCommand(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as WiFiNetworkForgetCommand"); diff --git a/src/event_handlers/websocket/local/WiFiNetworkSaveCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkSaveCommand.cpp similarity index 91% rename from src/event_handlers/websocket/local/WiFiNetworkSaveCommand.cpp rename to src/message_handlers/websocket/local/WiFiNetworkSaveCommand.cpp index 6ddf9fba..70c0b453 100644 --- a/src/event_handlers/websocket/local/WiFiNetworkSaveCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkSaveCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -10,9 +10,10 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkSaveCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleWiFiNetworkSaveCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ (void)socketId; - + auto msg = root->payload_as_WifiNetworkSaveCommand(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as WiFiNetworkSaveCommand"); diff --git a/src/event_handlers/websocket/local/WiFiScanCommand.cpp b/src/message_handlers/websocket/local/WiFiScanCommand.cpp similarity index 83% rename from src/event_handlers/websocket/local/WiFiScanCommand.cpp rename to src/message_handlers/websocket/local/WiFiScanCommand.cpp index 06000867..8a4b3665 100644 --- a/src/event_handlers/websocket/local/WiFiScanCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiScanCommand.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -7,9 +7,10 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiScanCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleWiFiScanCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ (void)socketId; - + auto msg = root->payload_as_WifiScanCommand(); if (msg == nullptr) { OS_LOGE(TAG, "Payload cannot be parsed as WiFiScanCommand"); diff --git a/src/event_handlers/websocket/local/_InvalidMessage.cpp b/src/message_handlers/websocket/local/_InvalidMessage.cpp similarity index 78% rename from src/event_handlers/websocket/local/_InvalidMessage.cpp rename to src/message_handlers/websocket/local/_InvalidMessage.cpp index 59723167..8afe35fa 100644 --- a/src/event_handlers/websocket/local/_InvalidMessage.cpp +++ b/src/message_handlers/websocket/local/_InvalidMessage.cpp @@ -1,4 +1,4 @@ -#include "event_handlers/impl/WSLocal.h" +#include "message_handlers/impl/WSLocal.h" const char* const TAG = "LocalMessageHandlers"; @@ -6,9 +6,10 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleInvalidMessage(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { +void _Private::HandleInvalidMessage(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ (void)socketId; - + if (root == nullptr) { OS_LOGE(TAG, "Message cannot be parsed"); return; From b6e5cea5f901e3b86b5d56fe2687795b04bffde0 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Tue, 12 Nov 2024 16:51:07 +0100 Subject: [PATCH 033/155] More CI stuff --- .github/workflows/ci-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index ef3cf6bc..e2c3cba9 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -43,7 +43,7 @@ jobs: build-staticfs: runs-on: ubuntu-latest - needs: build-frontend + needs: [getvars, build-frontend] steps: - uses: actions/checkout@v4 From 78b0de6db5ef50e0f5f9a9c4cd2d840c04bc8231 Mon Sep 17 00:00:00 2001 From: HeavenVR Date: Tue, 12 Nov 2024 17:01:40 +0100 Subject: [PATCH 034/155] Use V2 schemas (#313) * Implement missing command handlers * Don't generate deprecated schemas * Fix CI issue * Fix empty version in CI * Use V2 endpoint --- .github/workflows/cpp-linter.yml | 2 +- .../configuration/estop-config.ts | 17 +- .../_fbs/open-shock/serialization/gateway.ts | 23 +- .../serialization/gateway/boot-status.ts | 1 + .../gateway/captive-portal-config.ts | 30 -- .../gateway/gateway-to-hub-message-payload.ts | 46 +- .../gateway/gateway-to-hub-message.ts | 1 + .../gateway/hub-to-gateway-message-payload.ts | 60 ++- .../gateway/hub-to-gateway-message.ts | 1 + .../serialization/gateway/keep-alive.ts | 30 -- .../gateway/ota-install-progress.ts | 71 --- .../serialization/gateway/ota-install.ts | 51 --- ...install-failed.ts => ota-update-failed.ts} | 140 +++--- .../gateway/ota-update-progress.ts | 71 +++ .../gateway/ota-update-request.ts | 52 +++ ...stall-started.ts => ota-update-started.ts} | 111 ++--- .../open-shock/serialization/gateway/ping.ts | 48 +++ .../open-shock/serialization/gateway/pong.ts | 58 +++ .../gateway/shocker-command-list.ts | 12 +- .../serialization/gateway/shocker-command.ts | 69 ++- .../serialization/gateway/trigger-type.ts | 25 ++ .../serialization/gateway/trigger.ts | 51 +++ .../_fbs/open-shock/serialization/local.ts | 50 +-- .../_fbs/open-shock/serialization/types.ts | 10 +- .../ota-update-progress-task.ts} | 26 +- include/CommandHandler.h | 3 - include/EStopManager.h | 4 +- include/GatewayClient.h | 2 - include/OtaUpdateManager.h | 2 +- include/message_handlers/impl/WSGateway.h | 17 +- include/message_handlers/impl/WSLocal.h | 38 +- include/serialization/WSGateway.h | 14 +- .../_fbs/GatewayToHubMessage_generated.h | 408 +++++++++++++----- .../serialization/_fbs/HubConfig_generated.h | 15 +- .../_fbs/HubToGatewayMessage_generated.h | 341 +++++++-------- .../_fbs/OtaUpdateProgressTask_generated.h | 69 +++ schemas | 2 +- scripts/embed_env_vars.py | 29 ++ scripts/generate_schemas.py | 2 +- src/CommandHandler.cpp | 25 -- src/EStopManager.cpp | 53 ++- src/GatewayClient.cpp | 21 +- src/OtaUpdateManager.cpp | 58 ++- src/message_handlers/websocket/Gateway.cpp | 11 +- src/message_handlers/websocket/Local.cpp | 30 +- .../websocket/gateway/CaptivePortalConfig.cpp | 25 -- .../{OtaInstall.cpp => OtaUpdateRequest.cpp} | 12 +- .../websocket/gateway/Ping.cpp | 25 ++ .../websocket/gateway/Trigger.cpp | 49 +++ .../local/OtaUpdateCheckForUpdatesCommand.cpp | 20 + .../OtaUpdateHandleUpdateRequestCommand.cpp | 20 + ...UpdateSetAllowBackendManagementCommand.cpp | 20 + .../OtaUpdateSetCheckIntervalCommand.cpp | 20 + .../local/OtaUpdateSetDomainCommand.cpp | 20 + .../local/OtaUpdateSetIsEnabledCommand.cpp | 20 + ...aUpdateSetRequireManualApprovalCommand.cpp | 20 + .../OtaUpdateSetUpdateChannelCommand.cpp | 20 + .../local/OtaUpdateStartUpdateCommand.cpp | 20 + .../local/SetEStopEnabledCommand.cpp | 60 +++ .../websocket/local/SetEStopPinCommand.cpp | 38 +- .../local/WiFiNetworkConnectCommand.cpp | 2 +- .../local/WiFiNetworkDisconnectCommand.cpp | 2 +- .../local/WiFiNetworkForgetCommand.cpp | 2 +- .../local/WiFiNetworkSaveCommand.cpp | 2 +- .../websocket/local/WiFiScanCommand.cpp | 2 +- src/serialization/WSGateway.cpp | 47 +- 66 files changed, 1747 insertions(+), 899 deletions(-) delete mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/captive-portal-config.ts delete mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/keep-alive.ts delete mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-progress.ts delete mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install.ts rename frontend/src/lib/_fbs/open-shock/serialization/gateway/{ota-install-failed.ts => ota-update-failed.ts} (56%) create mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-progress.ts create mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-request.ts rename frontend/src/lib/_fbs/open-shock/serialization/gateway/{ota-install-started.ts => ota-update-started.ts} (62%) create mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/ping.ts create mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/pong.ts create mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger-type.ts create mode 100644 frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger.ts rename frontend/src/lib/_fbs/open-shock/serialization/{gateway/ota-install-progress-task.ts => types/ota-update-progress-task.ts} (82%) create mode 100644 include/serialization/_fbs/OtaUpdateProgressTask_generated.h delete mode 100644 src/message_handlers/websocket/gateway/CaptivePortalConfig.cpp rename src/message_handlers/websocket/gateway/{OtaInstall.cpp => OtaUpdateRequest.cpp} (60%) create mode 100644 src/message_handlers/websocket/gateway/Ping.cpp create mode 100644 src/message_handlers/websocket/gateway/Trigger.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateCheckForUpdatesCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateHandleUpdateRequestCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateSetAllowBackendManagementCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateSetCheckIntervalCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateSetDomainCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateSetIsEnabledCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateSetRequireManualApprovalCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateSetUpdateChannelCommand.cpp create mode 100644 src/message_handlers/websocket/local/OtaUpdateStartUpdateCommand.cpp create mode 100644 src/message_handlers/websocket/local/SetEStopEnabledCommand.cpp diff --git a/.github/workflows/cpp-linter.yml b/.github/workflows/cpp-linter.yml index c014f18c..08989f4f 100644 --- a/.github/workflows/cpp-linter.yml +++ b/.github/workflows/cpp-linter.yml @@ -27,7 +27,7 @@ jobs: - uses: ./.github/actions/build-compilationdb with: - board: OpenShock-Core-V2 # Doesn't matter, just need the compilation database + version: 0.0.0-test+build # Doesn't matter, just need the compilation database skip-checkout: true - uses: cpp-linter/cpp-linter-action@v2 diff --git a/frontend/src/lib/_fbs/open-shock/serialization/configuration/estop-config.ts b/frontend/src/lib/_fbs/open-shock/serialization/configuration/estop-config.ts index b4946777..6eb9b148 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/configuration/estop-config.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/configuration/estop-config.ts @@ -35,8 +35,16 @@ gpioPin():number { return offset ? this.bb!.readInt8(this.bb_pos + offset) : 0; } +/** + * Persistent state of the E-Stop button + */ +active():boolean { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false; +} + static startEStopConfig(builder:flatbuffers.Builder) { - builder.startObject(2); + builder.startObject(3); } static addEnabled(builder:flatbuffers.Builder, enabled:boolean) { @@ -47,15 +55,20 @@ static addGpioPin(builder:flatbuffers.Builder, gpioPin:number) { builder.addFieldInt8(1, gpioPin, 0); } +static addActive(builder:flatbuffers.Builder, active:boolean) { + builder.addFieldInt8(2, +active, +false); +} + static endEStopConfig(builder:flatbuffers.Builder):flatbuffers.Offset { const offset = builder.endObject(); return offset; } -static createEStopConfig(builder:flatbuffers.Builder, enabled:boolean, gpioPin:number):flatbuffers.Offset { +static createEStopConfig(builder:flatbuffers.Builder, enabled:boolean, gpioPin:number, active:boolean):flatbuffers.Offset { EStopConfig.startEStopConfig(builder); EStopConfig.addEnabled(builder, enabled); EStopConfig.addGpioPin(builder, gpioPin); + EStopConfig.addActive(builder, active); return EStopConfig.endEStopConfig(builder); } } diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway.ts index eaaca50d..6e6f688d 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway.ts @@ -1,12 +1,11 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -export { BootStatus } from './gateway/boot-status'; -export { HubToGatewayMessage } from './gateway/hub-to-gateway-message'; -export { HubToGatewayMessagePayload } from './gateway/hub-to-gateway-message-payload'; -export { KeepAlive } from './gateway/keep-alive'; -export { OtaInstallFailed } from './gateway/ota-install-failed'; -export { OtaInstallProgress } from './gateway/ota-install-progress'; -export { OtaInstallProgressTask } from './gateway/ota-install-progress-task'; -export { OtaInstallStarted } from './gateway/ota-install-started'; +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +export { BootStatus } from './gateway/boot-status'; +export { HubToGatewayMessage } from './gateway/hub-to-gateway-message'; +export { HubToGatewayMessagePayload } from './gateway/hub-to-gateway-message-payload'; +export { OtaUpdateFailed } from './gateway/ota-update-failed'; +export { OtaUpdateProgress } from './gateway/ota-update-progress'; +export { OtaUpdateStarted } from './gateway/ota-update-started'; +export { Pong } from './gateway/pong'; diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/boot-status.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/boot-status.ts index f9fe5e9f..beb5c239 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/boot-status.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/boot-status.ts @@ -59,6 +59,7 @@ static addOtaUpdateId(builder:flatbuffers.Builder, otaUpdateId:number) { static endBootStatus(builder:flatbuffers.Builder):flatbuffers.Offset { const offset = builder.endObject(); + builder.requiredField(offset, 6) // firmware_version return offset; } diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/captive-portal-config.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/captive-portal-config.ts deleted file mode 100644 index 14d15463..00000000 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/captive-portal-config.ts +++ /dev/null @@ -1,30 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -import * as flatbuffers from 'flatbuffers'; - -export class CaptivePortalConfig { - bb: flatbuffers.ByteBuffer|null = null; - bb_pos = 0; - __init(i:number, bb:flatbuffers.ByteBuffer):CaptivePortalConfig { - this.bb_pos = i; - this.bb = bb; - return this; -} - -enabled():boolean { - return !!this.bb!.readInt8(this.bb_pos); -} - -static sizeOf():number { - return 1; -} - -static createCaptivePortalConfig(builder:flatbuffers.Builder, enabled: boolean):flatbuffers.Offset { - builder.prep(1, 1); - builder.writeInt8(Number(Boolean(enabled))); - return builder.offset(); -} - -} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message-payload.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message-payload.ts index 7b7ff5cd..2d2b1ec8 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message-payload.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message-payload.ts @@ -2,41 +2,61 @@ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ -import { CaptivePortalConfig } from '../../../open-shock/serialization/gateway/captive-portal-config'; -import { OtaInstall } from '../../../open-shock/serialization/gateway/ota-install'; +import { OtaUpdateRequest } from '../../../open-shock/serialization/gateway/ota-update-request'; +import { Ping } from '../../../open-shock/serialization/gateway/ping'; import { ShockerCommandList } from '../../../open-shock/serialization/gateway/shocker-command-list'; +import { Trigger } from '../../../open-shock/serialization/gateway/trigger'; export enum GatewayToHubMessagePayload { NONE = 0, - ShockerCommandList = 1, - CaptivePortalConfig = 2, - OtaInstall = 3 + + /** + * Ping message, should immediately be responded to with a pong + */ + Ping = 1, + + /** + * Trigger a specific action on the hub + */ + Trigger = 2, + + /** + * Send a list of shocker commands to the hub + */ + ShockerCommandList = 3, + + /** + * Request an OTA update to be performed + */ + OtaUpdateRequest = 4 } export function unionToGatewayToHubMessagePayload( type: GatewayToHubMessagePayload, - accessor: (obj:CaptivePortalConfig|OtaInstall|ShockerCommandList) => CaptivePortalConfig|OtaInstall|ShockerCommandList|null -): CaptivePortalConfig|OtaInstall|ShockerCommandList|null { + accessor: (obj:OtaUpdateRequest|Ping|ShockerCommandList|Trigger) => OtaUpdateRequest|Ping|ShockerCommandList|Trigger|null +): OtaUpdateRequest|Ping|ShockerCommandList|Trigger|null { switch(GatewayToHubMessagePayload[type]) { case 'NONE': return null; + case 'Ping': return accessor(new Ping())! as Ping; + case 'Trigger': return accessor(new Trigger())! as Trigger; case 'ShockerCommandList': return accessor(new ShockerCommandList())! as ShockerCommandList; - case 'CaptivePortalConfig': return accessor(new CaptivePortalConfig())! as CaptivePortalConfig; - case 'OtaInstall': return accessor(new OtaInstall())! as OtaInstall; + case 'OtaUpdateRequest': return accessor(new OtaUpdateRequest())! as OtaUpdateRequest; default: return null; } } export function unionListToGatewayToHubMessagePayload( type: GatewayToHubMessagePayload, - accessor: (index: number, obj:CaptivePortalConfig|OtaInstall|ShockerCommandList) => CaptivePortalConfig|OtaInstall|ShockerCommandList|null, + accessor: (index: number, obj:OtaUpdateRequest|Ping|ShockerCommandList|Trigger) => OtaUpdateRequest|Ping|ShockerCommandList|Trigger|null, index: number -): CaptivePortalConfig|OtaInstall|ShockerCommandList|null { +): OtaUpdateRequest|Ping|ShockerCommandList|Trigger|null { switch(GatewayToHubMessagePayload[type]) { case 'NONE': return null; + case 'Ping': return accessor(index, new Ping())! as Ping; + case 'Trigger': return accessor(index, new Trigger())! as Trigger; case 'ShockerCommandList': return accessor(index, new ShockerCommandList())! as ShockerCommandList; - case 'CaptivePortalConfig': return accessor(index, new CaptivePortalConfig())! as CaptivePortalConfig; - case 'OtaInstall': return accessor(index, new OtaInstall())! as OtaInstall; + case 'OtaUpdateRequest': return accessor(index, new OtaUpdateRequest())! as OtaUpdateRequest; default: return null; } } diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message.ts index 6f565d76..acd8c7a3 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/gateway-to-hub-message.ts @@ -49,6 +49,7 @@ static addPayload(builder:flatbuffers.Builder, payloadOffset:flatbuffers.Offset) static endGatewayToHubMessage(builder:flatbuffers.Builder):flatbuffers.Offset { const offset = builder.endObject(); + builder.requiredField(offset, 6) // payload return offset; } diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message-payload.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message-payload.ts index 40fa1c55..e762854d 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message-payload.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message-payload.ts @@ -3,48 +3,68 @@ /* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ import { BootStatus } from '../../../open-shock/serialization/gateway/boot-status'; -import { KeepAlive } from '../../../open-shock/serialization/gateway/keep-alive'; -import { OtaInstallFailed } from '../../../open-shock/serialization/gateway/ota-install-failed'; -import { OtaInstallProgress } from '../../../open-shock/serialization/gateway/ota-install-progress'; -import { OtaInstallStarted } from '../../../open-shock/serialization/gateway/ota-install-started'; +import { OtaUpdateFailed } from '../../../open-shock/serialization/gateway/ota-update-failed'; +import { OtaUpdateProgress } from '../../../open-shock/serialization/gateway/ota-update-progress'; +import { OtaUpdateStarted } from '../../../open-shock/serialization/gateway/ota-update-started'; +import { Pong } from '../../../open-shock/serialization/gateway/pong'; export enum HubToGatewayMessagePayload { NONE = 0, - KeepAlive = 1, + + /** + * Respond to a ping message + */ + Pong = 1, + + /** + * Report the current boot status, used to report firmware version and OTA update results + */ BootStatus = 2, - OtaInstallStarted = 3, - OtaInstallProgress = 4, - OtaInstallFailed = 5 + + /** + * Report that an OTA update has started + */ + OtaUpdateStarted = 3, + + /** + * Report the progress of an OTA update + */ + OtaUpdateProgress = 4, + + /** + * Report that an OTA update has failed + */ + OtaUpdateFailed = 5 } export function unionToHubToGatewayMessagePayload( type: HubToGatewayMessagePayload, - accessor: (obj:BootStatus|KeepAlive|OtaInstallFailed|OtaInstallProgress|OtaInstallStarted) => BootStatus|KeepAlive|OtaInstallFailed|OtaInstallProgress|OtaInstallStarted|null -): BootStatus|KeepAlive|OtaInstallFailed|OtaInstallProgress|OtaInstallStarted|null { + accessor: (obj:BootStatus|OtaUpdateFailed|OtaUpdateProgress|OtaUpdateStarted|Pong) => BootStatus|OtaUpdateFailed|OtaUpdateProgress|OtaUpdateStarted|Pong|null +): BootStatus|OtaUpdateFailed|OtaUpdateProgress|OtaUpdateStarted|Pong|null { switch(HubToGatewayMessagePayload[type]) { case 'NONE': return null; - case 'KeepAlive': return accessor(new KeepAlive())! as KeepAlive; + case 'Pong': return accessor(new Pong())! as Pong; case 'BootStatus': return accessor(new BootStatus())! as BootStatus; - case 'OtaInstallStarted': return accessor(new OtaInstallStarted())! as OtaInstallStarted; - case 'OtaInstallProgress': return accessor(new OtaInstallProgress())! as OtaInstallProgress; - case 'OtaInstallFailed': return accessor(new OtaInstallFailed())! as OtaInstallFailed; + case 'OtaUpdateStarted': return accessor(new OtaUpdateStarted())! as OtaUpdateStarted; + case 'OtaUpdateProgress': return accessor(new OtaUpdateProgress())! as OtaUpdateProgress; + case 'OtaUpdateFailed': return accessor(new OtaUpdateFailed())! as OtaUpdateFailed; default: return null; } } export function unionListToHubToGatewayMessagePayload( type: HubToGatewayMessagePayload, - accessor: (index: number, obj:BootStatus|KeepAlive|OtaInstallFailed|OtaInstallProgress|OtaInstallStarted) => BootStatus|KeepAlive|OtaInstallFailed|OtaInstallProgress|OtaInstallStarted|null, + accessor: (index: number, obj:BootStatus|OtaUpdateFailed|OtaUpdateProgress|OtaUpdateStarted|Pong) => BootStatus|OtaUpdateFailed|OtaUpdateProgress|OtaUpdateStarted|Pong|null, index: number -): BootStatus|KeepAlive|OtaInstallFailed|OtaInstallProgress|OtaInstallStarted|null { +): BootStatus|OtaUpdateFailed|OtaUpdateProgress|OtaUpdateStarted|Pong|null { switch(HubToGatewayMessagePayload[type]) { case 'NONE': return null; - case 'KeepAlive': return accessor(index, new KeepAlive())! as KeepAlive; + case 'Pong': return accessor(index, new Pong())! as Pong; case 'BootStatus': return accessor(index, new BootStatus())! as BootStatus; - case 'OtaInstallStarted': return accessor(index, new OtaInstallStarted())! as OtaInstallStarted; - case 'OtaInstallProgress': return accessor(index, new OtaInstallProgress())! as OtaInstallProgress; - case 'OtaInstallFailed': return accessor(index, new OtaInstallFailed())! as OtaInstallFailed; + case 'OtaUpdateStarted': return accessor(index, new OtaUpdateStarted())! as OtaUpdateStarted; + case 'OtaUpdateProgress': return accessor(index, new OtaUpdateProgress())! as OtaUpdateProgress; + case 'OtaUpdateFailed': return accessor(index, new OtaUpdateFailed())! as OtaUpdateFailed; default: return null; } } diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message.ts index c90d11bf..ae478d19 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/hub-to-gateway-message.ts @@ -49,6 +49,7 @@ static addPayload(builder:flatbuffers.Builder, payloadOffset:flatbuffers.Offset) static endHubToGatewayMessage(builder:flatbuffers.Builder):flatbuffers.Offset { const offset = builder.endObject(); + builder.requiredField(offset, 6) // payload return offset; } diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/keep-alive.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/keep-alive.ts deleted file mode 100644 index 3a19cbe7..00000000 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/keep-alive.ts +++ /dev/null @@ -1,30 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -import * as flatbuffers from 'flatbuffers'; - -export class KeepAlive { - bb: flatbuffers.ByteBuffer|null = null; - bb_pos = 0; - __init(i:number, bb:flatbuffers.ByteBuffer):KeepAlive { - this.bb_pos = i; - this.bb = bb; - return this; -} - -uptime():bigint { - return this.bb!.readUint64(this.bb_pos); -} - -static sizeOf():number { - return 8; -} - -static createKeepAlive(builder:flatbuffers.Builder, uptime: bigint):flatbuffers.Offset { - builder.prep(8, 8); - builder.writeInt64(BigInt(uptime ?? 0)); - return builder.offset(); -} - -} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-progress.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-progress.ts deleted file mode 100644 index 70f756a0..00000000 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-progress.ts +++ /dev/null @@ -1,71 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -import * as flatbuffers from 'flatbuffers'; - -import { OtaInstallProgressTask } from '../../../open-shock/serialization/gateway/ota-install-progress-task'; - - -export class OtaInstallProgress { - bb: flatbuffers.ByteBuffer|null = null; - bb_pos = 0; - __init(i:number, bb:flatbuffers.ByteBuffer):OtaInstallProgress { - this.bb_pos = i; - this.bb = bb; - return this; -} - -static getRootAsOtaInstallProgress(bb:flatbuffers.ByteBuffer, obj?:OtaInstallProgress):OtaInstallProgress { - return (obj || new OtaInstallProgress()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -static getSizePrefixedRootAsOtaInstallProgress(bb:flatbuffers.ByteBuffer, obj?:OtaInstallProgress):OtaInstallProgress { - bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); - return (obj || new OtaInstallProgress()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -updateId():number { - const offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; -} - -task():OtaInstallProgressTask { - const offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? this.bb!.readInt8(this.bb_pos + offset) : OtaInstallProgressTask.FetchingMetadata; -} - -progress():number { - const offset = this.bb!.__offset(this.bb_pos, 8); - return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; -} - -static startOtaInstallProgress(builder:flatbuffers.Builder) { - builder.startObject(3); -} - -static addUpdateId(builder:flatbuffers.Builder, updateId:number) { - builder.addFieldInt32(0, updateId, 0); -} - -static addTask(builder:flatbuffers.Builder, task:OtaInstallProgressTask) { - builder.addFieldInt8(1, task, OtaInstallProgressTask.FetchingMetadata); -} - -static addProgress(builder:flatbuffers.Builder, progress:number) { - builder.addFieldFloat32(2, progress, 0.0); -} - -static endOtaInstallProgress(builder:flatbuffers.Builder):flatbuffers.Offset { - const offset = builder.endObject(); - return offset; -} - -static createOtaInstallProgress(builder:flatbuffers.Builder, updateId:number, task:OtaInstallProgressTask, progress:number):flatbuffers.Offset { - OtaInstallProgress.startOtaInstallProgress(builder); - OtaInstallProgress.addUpdateId(builder, updateId); - OtaInstallProgress.addTask(builder, task); - OtaInstallProgress.addProgress(builder, progress); - return OtaInstallProgress.endOtaInstallProgress(builder); -} -} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install.ts deleted file mode 100644 index d3d17fc5..00000000 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install.ts +++ /dev/null @@ -1,51 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -import * as flatbuffers from 'flatbuffers'; - -import { SemVer } from '../../../open-shock/serialization/types/sem-ver'; - - -export class OtaInstall { - bb: flatbuffers.ByteBuffer|null = null; - bb_pos = 0; - __init(i:number, bb:flatbuffers.ByteBuffer):OtaInstall { - this.bb_pos = i; - this.bb = bb; - return this; -} - -static getRootAsOtaInstall(bb:flatbuffers.ByteBuffer, obj?:OtaInstall):OtaInstall { - return (obj || new OtaInstall()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -static getSizePrefixedRootAsOtaInstall(bb:flatbuffers.ByteBuffer, obj?:OtaInstall):OtaInstall { - bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); - return (obj || new OtaInstall()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -version(obj?:SemVer):SemVer|null { - const offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? (obj || new SemVer()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; -} - -static startOtaInstall(builder:flatbuffers.Builder) { - builder.startObject(1); -} - -static addVersion(builder:flatbuffers.Builder, versionOffset:flatbuffers.Offset) { - builder.addFieldOffset(0, versionOffset, 0); -} - -static endOtaInstall(builder:flatbuffers.Builder):flatbuffers.Offset { - const offset = builder.endObject(); - return offset; -} - -static createOtaInstall(builder:flatbuffers.Builder, versionOffset:flatbuffers.Offset):flatbuffers.Offset { - OtaInstall.startOtaInstall(builder); - OtaInstall.addVersion(builder, versionOffset); - return OtaInstall.endOtaInstall(builder); -} -} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-failed.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-failed.ts similarity index 56% rename from frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-failed.ts rename to frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-failed.ts index 81571d1d..80eb8b9d 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-failed.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-failed.ts @@ -1,70 +1,70 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -import * as flatbuffers from 'flatbuffers'; - -export class OtaInstallFailed { - bb: flatbuffers.ByteBuffer|null = null; - bb_pos = 0; - __init(i:number, bb:flatbuffers.ByteBuffer):OtaInstallFailed { - this.bb_pos = i; - this.bb = bb; - return this; -} - -static getRootAsOtaInstallFailed(bb:flatbuffers.ByteBuffer, obj?:OtaInstallFailed):OtaInstallFailed { - return (obj || new OtaInstallFailed()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -static getSizePrefixedRootAsOtaInstallFailed(bb:flatbuffers.ByteBuffer, obj?:OtaInstallFailed):OtaInstallFailed { - bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); - return (obj || new OtaInstallFailed()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -updateId():number { - const offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; -} - -message():string|null -message(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null -message(optionalEncoding?:any):string|Uint8Array|null { - const offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; -} - -fatal():boolean { - const offset = this.bb!.__offset(this.bb_pos, 8); - return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false; -} - -static startOtaInstallFailed(builder:flatbuffers.Builder) { - builder.startObject(3); -} - -static addUpdateId(builder:flatbuffers.Builder, updateId:number) { - builder.addFieldInt32(0, updateId, 0); -} - -static addMessage(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, messageOffset, 0); -} - -static addFatal(builder:flatbuffers.Builder, fatal:boolean) { - builder.addFieldInt8(2, +fatal, +false); -} - -static endOtaInstallFailed(builder:flatbuffers.Builder):flatbuffers.Offset { - const offset = builder.endObject(); - return offset; -} - -static createOtaInstallFailed(builder:flatbuffers.Builder, updateId:number, messageOffset:flatbuffers.Offset, fatal:boolean):flatbuffers.Offset { - OtaInstallFailed.startOtaInstallFailed(builder); - OtaInstallFailed.addUpdateId(builder, updateId); - OtaInstallFailed.addMessage(builder, messageOffset); - OtaInstallFailed.addFatal(builder, fatal); - return OtaInstallFailed.endOtaInstallFailed(builder); -} -} +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +import * as flatbuffers from 'flatbuffers'; + +export class OtaUpdateFailed { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):OtaUpdateFailed { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsOtaUpdateFailed(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateFailed):OtaUpdateFailed { + return (obj || new OtaUpdateFailed()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsOtaUpdateFailed(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateFailed):OtaUpdateFailed { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new OtaUpdateFailed()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +updateId():number { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +} + +message():string|null +message(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null +message(optionalEncoding?:any):string|Uint8Array|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null; +} + +fatal():boolean { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false; +} + +static startOtaUpdateFailed(builder:flatbuffers.Builder) { + builder.startObject(3); +} + +static addUpdateId(builder:flatbuffers.Builder, updateId:number) { + builder.addFieldInt32(0, updateId, 0); +} + +static addMessage(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, messageOffset, 0); +} + +static addFatal(builder:flatbuffers.Builder, fatal:boolean) { + builder.addFieldInt8(2, +fatal, +false); +} + +static endOtaUpdateFailed(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createOtaUpdateFailed(builder:flatbuffers.Builder, updateId:number, messageOffset:flatbuffers.Offset, fatal:boolean):flatbuffers.Offset { + OtaUpdateFailed.startOtaUpdateFailed(builder); + OtaUpdateFailed.addUpdateId(builder, updateId); + OtaUpdateFailed.addMessage(builder, messageOffset); + OtaUpdateFailed.addFatal(builder, fatal); + return OtaUpdateFailed.endOtaUpdateFailed(builder); +} +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-progress.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-progress.ts new file mode 100644 index 00000000..de5a0dbe --- /dev/null +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-progress.ts @@ -0,0 +1,71 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +import * as flatbuffers from 'flatbuffers'; + +import { OtaUpdateProgressTask } from '../../../open-shock/serialization/types/ota-update-progress-task'; + + +export class OtaUpdateProgress { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):OtaUpdateProgress { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsOtaUpdateProgress(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateProgress):OtaUpdateProgress { + return (obj || new OtaUpdateProgress()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsOtaUpdateProgress(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateProgress):OtaUpdateProgress { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new OtaUpdateProgress()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +updateId():number { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +} + +task():OtaUpdateProgressTask { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : OtaUpdateProgressTask.FetchingMetadata; +} + +progress():number { + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.readFloat32(this.bb_pos + offset) : 0.0; +} + +static startOtaUpdateProgress(builder:flatbuffers.Builder) { + builder.startObject(3); +} + +static addUpdateId(builder:flatbuffers.Builder, updateId:number) { + builder.addFieldInt32(0, updateId, 0); +} + +static addTask(builder:flatbuffers.Builder, task:OtaUpdateProgressTask) { + builder.addFieldInt8(1, task, OtaUpdateProgressTask.FetchingMetadata); +} + +static addProgress(builder:flatbuffers.Builder, progress:number) { + builder.addFieldFloat32(2, progress, 0.0); +} + +static endOtaUpdateProgress(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createOtaUpdateProgress(builder:flatbuffers.Builder, updateId:number, task:OtaUpdateProgressTask, progress:number):flatbuffers.Offset { + OtaUpdateProgress.startOtaUpdateProgress(builder); + OtaUpdateProgress.addUpdateId(builder, updateId); + OtaUpdateProgress.addTask(builder, task); + OtaUpdateProgress.addProgress(builder, progress); + return OtaUpdateProgress.endOtaUpdateProgress(builder); +} +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-request.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-request.ts new file mode 100644 index 00000000..ba509008 --- /dev/null +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-request.ts @@ -0,0 +1,52 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +import * as flatbuffers from 'flatbuffers'; + +import { SemVer } from '../../../open-shock/serialization/types/sem-ver'; + + +export class OtaUpdateRequest { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):OtaUpdateRequest { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsOtaUpdateRequest(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateRequest):OtaUpdateRequest { + return (obj || new OtaUpdateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsOtaUpdateRequest(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateRequest):OtaUpdateRequest { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new OtaUpdateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +version(obj?:SemVer):SemVer|null { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? (obj || new SemVer()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +} + +static startOtaUpdateRequest(builder:flatbuffers.Builder) { + builder.startObject(1); +} + +static addVersion(builder:flatbuffers.Builder, versionOffset:flatbuffers.Offset) { + builder.addFieldOffset(0, versionOffset, 0); +} + +static endOtaUpdateRequest(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 4) // version + return offset; +} + +static createOtaUpdateRequest(builder:flatbuffers.Builder, versionOffset:flatbuffers.Offset):flatbuffers.Offset { + OtaUpdateRequest.startOtaUpdateRequest(builder); + OtaUpdateRequest.addVersion(builder, versionOffset); + return OtaUpdateRequest.endOtaUpdateRequest(builder); +} +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-started.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-started.ts similarity index 62% rename from frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-started.ts rename to frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-started.ts index bd82a2bd..680cbcd2 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-started.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-update-started.ts @@ -1,55 +1,56 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -import * as flatbuffers from 'flatbuffers'; - -import { SemVer } from '../../../open-shock/serialization/types/sem-ver'; - - -export class OtaInstallStarted { - bb: flatbuffers.ByteBuffer|null = null; - bb_pos = 0; - __init(i:number, bb:flatbuffers.ByteBuffer):OtaInstallStarted { - this.bb_pos = i; - this.bb = bb; - return this; -} - -static getRootAsOtaInstallStarted(bb:flatbuffers.ByteBuffer, obj?:OtaInstallStarted):OtaInstallStarted { - return (obj || new OtaInstallStarted()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -static getSizePrefixedRootAsOtaInstallStarted(bb:flatbuffers.ByteBuffer, obj?:OtaInstallStarted):OtaInstallStarted { - bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); - return (obj || new OtaInstallStarted()).__init(bb.readInt32(bb.position()) + bb.position(), bb); -} - -updateId():number { - const offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; -} - -version(obj?:SemVer):SemVer|null { - const offset = this.bb!.__offset(this.bb_pos, 6); - return offset ? (obj || new SemVer()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; -} - -static startOtaInstallStarted(builder:flatbuffers.Builder) { - builder.startObject(2); -} - -static addUpdateId(builder:flatbuffers.Builder, updateId:number) { - builder.addFieldInt32(0, updateId, 0); -} - -static addVersion(builder:flatbuffers.Builder, versionOffset:flatbuffers.Offset) { - builder.addFieldOffset(1, versionOffset, 0); -} - -static endOtaInstallStarted(builder:flatbuffers.Builder):flatbuffers.Offset { - const offset = builder.endObject(); - return offset; -} - -} +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +import * as flatbuffers from 'flatbuffers'; + +import { SemVer } from '../../../open-shock/serialization/types/sem-ver'; + + +export class OtaUpdateStarted { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):OtaUpdateStarted { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsOtaUpdateStarted(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateStarted):OtaUpdateStarted { + return (obj || new OtaUpdateStarted()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsOtaUpdateStarted(bb:flatbuffers.ByteBuffer, obj?:OtaUpdateStarted):OtaUpdateStarted { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new OtaUpdateStarted()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +updateId():number { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +} + +version(obj?:SemVer):SemVer|null { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? (obj || new SemVer()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null; +} + +static startOtaUpdateStarted(builder:flatbuffers.Builder) { + builder.startObject(2); +} + +static addUpdateId(builder:flatbuffers.Builder, updateId:number) { + builder.addFieldInt32(0, updateId, 0); +} + +static addVersion(builder:flatbuffers.Builder, versionOffset:flatbuffers.Offset) { + builder.addFieldOffset(1, versionOffset, 0); +} + +static endOtaUpdateStarted(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + builder.requiredField(offset, 6) // version + return offset; +} + +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ping.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ping.ts new file mode 100644 index 00000000..d5c44839 --- /dev/null +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/ping.ts @@ -0,0 +1,48 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +import * as flatbuffers from 'flatbuffers'; + +export class Ping { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):Ping { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPing(bb:flatbuffers.ByteBuffer, obj?:Ping):Ping { + return (obj || new Ping()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPing(bb:flatbuffers.ByteBuffer, obj?:Ping):Ping { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Ping()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +unixUtcTime():bigint { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0'); +} + +static startPing(builder:flatbuffers.Builder) { + builder.startObject(1); +} + +static addUnixUtcTime(builder:flatbuffers.Builder, unixUtcTime:bigint) { + builder.addFieldInt64(0, unixUtcTime, BigInt('0')); +} + +static endPing(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createPing(builder:flatbuffers.Builder, unixUtcTime:bigint):flatbuffers.Offset { + Ping.startPing(builder); + Ping.addUnixUtcTime(builder, unixUtcTime); + return Ping.endPing(builder); +} +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/pong.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/pong.ts new file mode 100644 index 00000000..aa9a15d2 --- /dev/null +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/pong.ts @@ -0,0 +1,58 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +import * as flatbuffers from 'flatbuffers'; + +export class Pong { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):Pong { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsPong(bb:flatbuffers.ByteBuffer, obj?:Pong):Pong { + return (obj || new Pong()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsPong(bb:flatbuffers.ByteBuffer, obj?:Pong):Pong { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Pong()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +uptime():bigint { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readUint64(this.bb_pos + offset) : BigInt('0'); +} + +rssi():number { + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0; +} + +static startPong(builder:flatbuffers.Builder) { + builder.startObject(2); +} + +static addUptime(builder:flatbuffers.Builder, uptime:bigint) { + builder.addFieldInt64(0, uptime, BigInt('0')); +} + +static addRssi(builder:flatbuffers.Builder, rssi:number) { + builder.addFieldInt32(1, rssi, 0); +} + +static endPong(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createPong(builder:flatbuffers.Builder, uptime:bigint, rssi:number):flatbuffers.Offset { + Pong.startPong(builder); + Pong.addUptime(builder, uptime); + Pong.addRssi(builder, rssi); + return Pong.endPong(builder); +} +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command-list.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command-list.ts index efdbdc61..f2505004 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command-list.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command-list.ts @@ -27,7 +27,7 @@ static getSizePrefixedRootAsShockerCommandList(bb:flatbuffers.ByteBuffer, obj?:S commands(index: number, obj?:ShockerCommand):ShockerCommand|null { const offset = this.bb!.__offset(this.bb_pos, 4); - return offset ? (obj || new ShockerCommand()).__init(this.bb!.__vector(this.bb_pos + offset) + index * 8, this.bb!) : null; + return offset ? (obj || new ShockerCommand()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null; } commandsLength():number { @@ -43,8 +43,16 @@ static addCommands(builder:flatbuffers.Builder, commandsOffset:flatbuffers.Offse builder.addFieldOffset(0, commandsOffset, 0); } +static createCommandsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset { + builder.startVector(4, data.length, 4); + for (let i = data.length - 1; i >= 0; i--) { + builder.addOffset(data[i]!); + } + return builder.endVector(); +} + static startCommandsVector(builder:flatbuffers.Builder, numElems:number) { - builder.startVector(8, numElems, 2); + builder.startVector(4, numElems, 4); } static endShockerCommandList(builder:flatbuffers.Builder):flatbuffers.Offset { diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command.ts index abf14f61..e073627a 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/shocker-command.ts @@ -17,39 +17,76 @@ export class ShockerCommand { return this; } +static getRootAsShockerCommand(bb:flatbuffers.ByteBuffer, obj?:ShockerCommand):ShockerCommand { + return (obj || new ShockerCommand()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsShockerCommand(bb:flatbuffers.ByteBuffer, obj?:ShockerCommand):ShockerCommand { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new ShockerCommand()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + model():ShockerModelType { - return this.bb!.readUint8(this.bb_pos); + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : ShockerModelType.CaiXianlin; } id():number { - return this.bb!.readUint16(this.bb_pos + 2); + const offset = this.bb!.__offset(this.bb_pos, 6); + return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0; } type():ShockerCommandType { - return this.bb!.readUint8(this.bb_pos + 4); + const offset = this.bb!.__offset(this.bb_pos, 8); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : ShockerCommandType.Stop; } intensity():number { - return this.bb!.readUint8(this.bb_pos + 5); + const offset = this.bb!.__offset(this.bb_pos, 10); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : 0; } duration():number { - return this.bb!.readUint16(this.bb_pos + 6); + const offset = this.bb!.__offset(this.bb_pos, 12); + return offset ? this.bb!.readUint16(this.bb_pos + offset) : 0; +} + +static startShockerCommand(builder:flatbuffers.Builder) { + builder.startObject(5); +} + +static addModel(builder:flatbuffers.Builder, model:ShockerModelType) { + builder.addFieldInt8(0, model, ShockerModelType.CaiXianlin); } -static sizeOf():number { - return 8; +static addId(builder:flatbuffers.Builder, id:number) { + builder.addFieldInt16(1, id, 0); } -static createShockerCommand(builder:flatbuffers.Builder, model: ShockerModelType, id: number, type: ShockerCommandType, intensity: number, duration: number):flatbuffers.Offset { - builder.prep(2, 8); - builder.writeInt16(duration); - builder.writeInt8(intensity); - builder.writeInt8(type); - builder.writeInt16(id); - builder.pad(1); - builder.writeInt8(model); - return builder.offset(); +static addType(builder:flatbuffers.Builder, type:ShockerCommandType) { + builder.addFieldInt8(2, type, ShockerCommandType.Stop); } +static addIntensity(builder:flatbuffers.Builder, intensity:number) { + builder.addFieldInt8(3, intensity, 0); +} + +static addDuration(builder:flatbuffers.Builder, duration:number) { + builder.addFieldInt16(4, duration, 0); +} + +static endShockerCommand(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createShockerCommand(builder:flatbuffers.Builder, model:ShockerModelType, id:number, type:ShockerCommandType, intensity:number, duration:number):flatbuffers.Offset { + ShockerCommand.startShockerCommand(builder); + ShockerCommand.addModel(builder, model); + ShockerCommand.addId(builder, id); + ShockerCommand.addType(builder, type); + ShockerCommand.addIntensity(builder, intensity); + ShockerCommand.addDuration(builder, duration); + return ShockerCommand.endShockerCommand(builder); +} } diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger-type.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger-type.ts new file mode 100644 index 00000000..907a320c --- /dev/null +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger-type.ts @@ -0,0 +1,25 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +export enum TriggerType { + /** + * Restart the hub + */ + Restart = 0, + + /** + * Trigger the emergency stop on the hub, this does however not allow for resetting it + */ + EmergencyStop = 1, + + /** + * Enable the captive portal + */ + CaptivePortalEnable = 2, + + /** + * Disable the captive portal + */ + CaptivePortalDisable = 3 +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger.ts b/frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger.ts new file mode 100644 index 00000000..fa58e0eb --- /dev/null +++ b/frontend/src/lib/_fbs/open-shock/serialization/gateway/trigger.ts @@ -0,0 +1,51 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +import * as flatbuffers from 'flatbuffers'; + +import { TriggerType } from '../../../open-shock/serialization/gateway/trigger-type'; + + +export class Trigger { + bb: flatbuffers.ByteBuffer|null = null; + bb_pos = 0; + __init(i:number, bb:flatbuffers.ByteBuffer):Trigger { + this.bb_pos = i; + this.bb = bb; + return this; +} + +static getRootAsTrigger(bb:flatbuffers.ByteBuffer, obj?:Trigger):Trigger { + return (obj || new Trigger()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +static getSizePrefixedRootAsTrigger(bb:flatbuffers.ByteBuffer, obj?:Trigger):Trigger { + bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH); + return (obj || new Trigger()).__init(bb.readInt32(bb.position()) + bb.position(), bb); +} + +type():TriggerType { + const offset = this.bb!.__offset(this.bb_pos, 4); + return offset ? this.bb!.readUint8(this.bb_pos + offset) : TriggerType.Restart; +} + +static startTrigger(builder:flatbuffers.Builder) { + builder.startObject(1); +} + +static addType(builder:flatbuffers.Builder, type:TriggerType) { + builder.addFieldInt8(0, type, TriggerType.Restart); +} + +static endTrigger(builder:flatbuffers.Builder):flatbuffers.Offset { + const offset = builder.endObject(); + return offset; +} + +static createTrigger(builder:flatbuffers.Builder, type:TriggerType):flatbuffers.Offset { + Trigger.startTrigger(builder); + Trigger.addType(builder, type); + return Trigger.endTrigger(builder); +} +} diff --git a/frontend/src/lib/_fbs/open-shock/serialization/local.ts b/frontend/src/lib/_fbs/open-shock/serialization/local.ts index 0e51906f..a6f68d9e 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/local.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/local.ts @@ -1,25 +1,25 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -export { AccountLinkCommand } from './local/account-link-command'; -export { AccountUnlinkCommand } from './local/account-unlink-command'; -export { LocalToHubMessage } from './local/local-to-hub-message'; -export { LocalToHubMessagePayload } from './local/local-to-hub-message-payload'; -export { OtaUpdateCheckForUpdatesCommand } from './local/ota-update-check-for-updates-command'; -export { OtaUpdateHandleUpdateRequestCommand } from './local/ota-update-handle-update-request-command'; -export { OtaUpdateSetAllowBackendManagementCommand } from './local/ota-update-set-allow-backend-management-command'; -export { OtaUpdateSetCheckIntervalCommand } from './local/ota-update-set-check-interval-command'; -export { OtaUpdateSetDomainCommand } from './local/ota-update-set-domain-command'; -export { OtaUpdateSetIsEnabledCommand } from './local/ota-update-set-is-enabled-command'; -export { OtaUpdateSetRequireManualApprovalCommand } from './local/ota-update-set-require-manual-approval-command'; -export { OtaUpdateSetUpdateChannelCommand } from './local/ota-update-set-update-channel-command'; -export { OtaUpdateStartUpdateCommand } from './local/ota-update-start-update-command'; -export { SetEstopEnabledCommand } from './local/set-estop-enabled-command'; -export { SetEstopPinCommand } from './local/set-estop-pin-command'; -export { SetRfTxPinCommand } from './local/set-rf-tx-pin-command'; -export { WifiNetworkConnectCommand } from './local/wifi-network-connect-command'; -export { WifiNetworkDisconnectCommand } from './local/wifi-network-disconnect-command'; -export { WifiNetworkForgetCommand } from './local/wifi-network-forget-command'; -export { WifiNetworkSaveCommand } from './local/wifi-network-save-command'; -export { WifiScanCommand } from './local/wifi-scan-command'; +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +export { AccountLinkCommand } from './local/account-link-command'; +export { AccountUnlinkCommand } from './local/account-unlink-command'; +export { LocalToHubMessage } from './local/local-to-hub-message'; +export { LocalToHubMessagePayload } from './local/local-to-hub-message-payload'; +export { OtaUpdateCheckForUpdatesCommand } from './local/ota-update-check-for-updates-command'; +export { OtaUpdateHandleUpdateRequestCommand } from './local/ota-update-handle-update-request-command'; +export { OtaUpdateSetAllowBackendManagementCommand } from './local/ota-update-set-allow-backend-management-command'; +export { OtaUpdateSetCheckIntervalCommand } from './local/ota-update-set-check-interval-command'; +export { OtaUpdateSetDomainCommand } from './local/ota-update-set-domain-command'; +export { OtaUpdateSetIsEnabledCommand } from './local/ota-update-set-is-enabled-command'; +export { OtaUpdateSetRequireManualApprovalCommand } from './local/ota-update-set-require-manual-approval-command'; +export { OtaUpdateSetUpdateChannelCommand } from './local/ota-update-set-update-channel-command'; +export { OtaUpdateStartUpdateCommand } from './local/ota-update-start-update-command'; +export { SetEstopEnabledCommand } from './local/set-estop-enabled-command'; +export { SetEstopPinCommand } from './local/set-estop-pin-command'; +export { SetRfTxPinCommand } from './local/set-rf-tx-pin-command'; +export { WifiNetworkConnectCommand } from './local/wifi-network-connect-command'; +export { WifiNetworkDisconnectCommand } from './local/wifi-network-disconnect-command'; +export { WifiNetworkForgetCommand } from './local/wifi-network-forget-command'; +export { WifiNetworkSaveCommand } from './local/wifi-network-save-command'; +export { WifiScanCommand } from './local/wifi-scan-command'; diff --git a/frontend/src/lib/_fbs/open-shock/serialization/types.ts b/frontend/src/lib/_fbs/open-shock/serialization/types.ts index 6e7cf011..efe53f89 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/types.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/types.ts @@ -1,5 +1,5 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -export { WifiScanStatus } from './types/wifi-scan-status'; +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +export { WifiScanStatus } from './types/wifi-scan-status'; diff --git a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-progress-task.ts b/frontend/src/lib/_fbs/open-shock/serialization/types/ota-update-progress-task.ts similarity index 82% rename from frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-progress-task.ts rename to frontend/src/lib/_fbs/open-shock/serialization/types/ota-update-progress-task.ts index e9a25149..1a20adfa 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/gateway/ota-install-progress-task.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/types/ota-update-progress-task.ts @@ -1,13 +1,13 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ - -export enum OtaInstallProgressTask { - FetchingMetadata = 0, - PreparingForInstall = 1, - FlashingFilesystem = 2, - VerifyingFilesystem = 3, - FlashingApplication = 4, - MarkingApplicationBootable = 5, - Rebooting = 6 -} +// automatically generated by the FlatBuffers compiler, do not modify + +/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */ + +export enum OtaUpdateProgressTask { + FetchingMetadata = 0, + PreparingForUpdate = 1, + FlashingFilesystem = 2, + VerifyingFilesystem = 3, + FlashingApplication = 4, + MarkingApplicationBootable = 5, + Rebooting = 6 +} diff --git a/include/CommandHandler.h b/include/CommandHandler.h index 2fe01e04..93f751ab 100644 --- a/include/CommandHandler.h +++ b/include/CommandHandler.h @@ -17,9 +17,6 @@ namespace OpenShock::CommandHandler { gpio_num_t GetRfTxPin(); SetGPIOResultCode SetRfTxPin(gpio_num_t txPin); - SetGPIOResultCode SetEStopPin(gpio_num_t estopPin); - gpio_num_t GetEstopPin(); - bool SetKeepAliveEnabled(bool enabled); bool HandleCommand(ShockerModelType shockerModel, uint16_t shockerId, ShockerCommandType type, uint8_t intensity, uint16_t durationMs); diff --git a/include/EStopManager.h b/include/EStopManager.h index 80a183ed..c229dd57 100644 --- a/include/EStopManager.h +++ b/include/EStopManager.h @@ -7,9 +7,11 @@ #include namespace OpenShock::EStopManager { - bool Init(); + [[nodiscard]] bool Init(); bool SetEStopEnabled(bool enabled); bool SetEStopPin(gpio_num_t pin); bool IsEStopped(); int64_t LastEStopped(); + + void Trigger(); } // namespace OpenShock::EStopManager diff --git a/include/GatewayClient.h b/include/GatewayClient.h index a81a88af..c131c76c 100644 --- a/include/GatewayClient.h +++ b/include/GatewayClient.h @@ -27,12 +27,10 @@ namespace OpenShock { private: void _setState(GatewayClientState state); - void _sendKeepAlive(); void _sendBootStatus(); void _handleEvent(WStype_t type, uint8_t* payload, std::size_t length); WebSocketsClient m_webSocket; - int64_t m_lastKeepAlive; GatewayClientState m_state; }; } // namespace OpenShock diff --git a/include/OtaUpdateManager.h b/include/OtaUpdateManager.h index fc2b6b6a..2d319488 100644 --- a/include/OtaUpdateManager.h +++ b/include/OtaUpdateManager.h @@ -23,7 +23,7 @@ namespace OpenShock::OtaUpdateManager { bool TryGetFirmwareBoards(const OpenShock::SemVer& version, std::vector& boards); bool TryGetFirmwareRelease(const OpenShock::SemVer& version, FirmwareRelease& release); - bool TryStartFirmwareInstallation(const OpenShock::SemVer& version); + bool TryStartFirmwareUpdate(const OpenShock::SemVer& version); FirmwareBootType GetFirmwareBootType(); bool IsValidatingApp(); diff --git a/include/message_handlers/impl/WSGateway.h b/include/message_handlers/impl/WSGateway.h index a01faf9e..d8bbc0a5 100644 --- a/include/message_handlers/impl/WSGateway.h +++ b/include/message_handlers/impl/WSGateway.h @@ -4,12 +4,17 @@ #include -#define WS_EVENT_HANDLER_SIGNATURE(NAME) void NAME(const OpenShock::Serialization::Gateway::GatewayToHubMessage* msg) +#define HANDLER_SIG(NAME) void NAME(const OpenShock::Serialization::Gateway::GatewayToHubMessage* msg) +#define HANDLER_FN(NAME) HANDLER_SIG(Handle##NAME) namespace OpenShock::MessageHandlers::Server::_Private { - typedef WS_EVENT_HANDLER_SIGNATURE((*HandlerType)); - WS_EVENT_HANDLER_SIGNATURE(HandleInvalidMessage); - WS_EVENT_HANDLER_SIGNATURE(HandleShockerCommandList); - WS_EVENT_HANDLER_SIGNATURE(HandleCaptivePortalConfig); - WS_EVENT_HANDLER_SIGNATURE(HandleOtaInstall); + typedef HANDLER_SIG((*HandlerType)); + HANDLER_FN(Ping); + HANDLER_FN(Trigger); + HANDLER_FN(ShockerCommandList); + HANDLER_FN(OtaUpdateRequest); + HANDLER_FN(InvalidMessage); } // namespace OpenShock::MessageHandlers::Server::_Private + +#undef HANDLER_FN +#undef HANDLER_SIG diff --git a/include/message_handlers/impl/WSLocal.h b/include/message_handlers/impl/WSLocal.h index 7ce59f60..84887ba2 100644 --- a/include/message_handlers/impl/WSLocal.h +++ b/include/message_handlers/impl/WSLocal.h @@ -5,18 +5,32 @@ #include -#define WS_EVENT_HANDLER_SIGNATURE(NAME) void NAME(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* msg) +#define HANDLER_SIG(NAME) void NAME(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* msg) +#define HANDLER_FN(NAME) HANDLER_SIG(Handle##NAME) namespace OpenShock::MessageHandlers::Local::_Private { - typedef WS_EVENT_HANDLER_SIGNATURE((*HandlerType)); - WS_EVENT_HANDLER_SIGNATURE(HandleInvalidMessage); - WS_EVENT_HANDLER_SIGNATURE(HandleWiFiScanCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleWiFiNetworkSaveCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleWiFiNetworkForgetCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleWiFiNetworkConnectCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleWiFiNetworkDisconnectCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleAccountLinkCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleAccountUnlinkCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleSetRfTxPinCommand); - WS_EVENT_HANDLER_SIGNATURE(HandleSetEstopPinCommand); + typedef HANDLER_SIG((*HandlerType)); + HANDLER_FN(WifiScanCommand); + HANDLER_FN(WifiNetworkSaveCommand); + HANDLER_FN(WifiNetworkForgetCommand); + HANDLER_FN(WifiNetworkConnectCommand); + HANDLER_FN(WifiNetworkDisconnectCommand); + HANDLER_FN(OtaUpdateSetIsEnabledCommand); + HANDLER_FN(OtaUpdateSetDomainCommand); + HANDLER_FN(OtaUpdateSetUpdateChannelCommand); + HANDLER_FN(OtaUpdateSetCheckIntervalCommand); + HANDLER_FN(OtaUpdateSetAllowBackendManagementCommand); + HANDLER_FN(OtaUpdateSetRequireManualApprovalCommand); + HANDLER_FN(OtaUpdateHandleUpdateRequestCommand); + HANDLER_FN(OtaUpdateCheckForUpdatesCommand); + HANDLER_FN(OtaUpdateStartUpdateCommand); + HANDLER_FN(AccountLinkCommand); + HANDLER_FN(AccountUnlinkCommand); + HANDLER_FN(SetRfTxPinCommand); + HANDLER_FN(SetEstopEnabledCommand); + HANDLER_FN(SetEstopPinCommand); + HANDLER_FN(InvalidMessage); } // namespace OpenShock::MessageHandlers::Local::_Private + +#undef HANDLER_FN +#undef HANDLER_SIG diff --git a/include/serialization/WSGateway.h b/include/serialization/WSGateway.h index 72f52faf..768d7665 100644 --- a/include/serialization/WSGateway.h +++ b/include/serialization/WSGateway.h @@ -8,10 +8,14 @@ #include +#define SERIALIZER_FN(NAME, ...) bool Serialize##NAME##Message(__VA_ARGS__ __VA_OPT__(, ) Common::SerializationCallbackFn callback) + namespace OpenShock::Serialization::Gateway { - bool SerializeKeepAliveMessage(Common::SerializationCallbackFn callback); - bool SerializeBootStatusMessage(int32_t otaUpdateId, OpenShock::FirmwareBootType bootType, const OpenShock::SemVer& version, Common::SerializationCallbackFn callback); - bool SerializeOtaInstallStartedMessage(int32_t updateId, const OpenShock::SemVer& version, Common::SerializationCallbackFn callback); - bool SerializeOtaInstallProgressMessage(int32_t updateId, Gateway::OtaInstallProgressTask task, float progress, Common::SerializationCallbackFn callback); - bool SerializeOtaInstallFailedMessage(int32_t updateId, std::string_view message, bool fatal, Common::SerializationCallbackFn callback); + SERIALIZER_FN(Pong); + SERIALIZER_FN(BootStatus, int32_t updateId, OpenShock::FirmwareBootType bootType); + SERIALIZER_FN(OtaUpdateStarted, int32_t updateId, const OpenShock::SemVer& version); + SERIALIZER_FN(OtaUpdateProgress, int32_t updateId, Types::OtaUpdateProgressTask task, float progress); + SERIALIZER_FN(OtaUpdateFailed, int32_t updateId, std::string_view message, bool fatal); } // namespace OpenShock::Serialization::Gateway + +#undef SERIALZIER_FN diff --git a/include/serialization/_fbs/GatewayToHubMessage_generated.h b/include/serialization/_fbs/GatewayToHubMessage_generated.h index 959b55d2..1480a04b 100644 --- a/include/serialization/_fbs/GatewayToHubMessage_generated.h +++ b/include/serialization/_fbs/GatewayToHubMessage_generated.h @@ -21,51 +21,103 @@ namespace OpenShock { namespace Serialization { namespace Gateway { +struct Ping; +struct PingBuilder; + +struct Trigger; +struct TriggerBuilder; + struct ShockerCommand; +struct ShockerCommandBuilder; struct ShockerCommandList; struct ShockerCommandListBuilder; -struct CaptivePortalConfig; - -struct OtaInstall; -struct OtaInstallBuilder; +struct OtaUpdateRequest; +struct OtaUpdateRequestBuilder; struct GatewayToHubMessage; struct GatewayToHubMessageBuilder; +enum class TriggerType : uint8_t { + /// Restart the hub + Restart = 0, + /// Trigger the emergency stop on the hub, this does however not allow for resetting it + EmergencyStop = 1, + /// Enable the captive portal + CaptivePortalEnable = 2, + /// Disable the captive portal + CaptivePortalDisable = 3, + MIN = Restart, + MAX = CaptivePortalDisable +}; + +inline const TriggerType (&EnumValuesTriggerType())[4] { + static const TriggerType values[] = { + TriggerType::Restart, + TriggerType::EmergencyStop, + TriggerType::CaptivePortalEnable, + TriggerType::CaptivePortalDisable + }; + return values; +} + +inline const char * const *EnumNamesTriggerType() { + static const char * const names[5] = { + "Restart", + "EmergencyStop", + "CaptivePortalEnable", + "CaptivePortalDisable", + nullptr + }; + return names; +} + +inline const char *EnumNameTriggerType(TriggerType e) { + if (::flatbuffers::IsOutRange(e, TriggerType::Restart, TriggerType::CaptivePortalDisable)) return ""; + const size_t index = static_cast(e); + return EnumNamesTriggerType()[index]; +} + enum class GatewayToHubMessagePayload : uint8_t { NONE = 0, - ShockerCommandList = 1, - CaptivePortalConfig = 2, - OtaInstall = 3, + /// Ping message, should immediately be responded to with a pong + Ping = 1, + /// Trigger a specific action on the hub + Trigger = 2, + /// Send a list of shocker commands to the hub + ShockerCommandList = 3, + /// Request an OTA update to be performed + OtaUpdateRequest = 4, MIN = NONE, - MAX = OtaInstall + MAX = OtaUpdateRequest }; -inline const GatewayToHubMessagePayload (&EnumValuesGatewayToHubMessagePayload())[4] { +inline const GatewayToHubMessagePayload (&EnumValuesGatewayToHubMessagePayload())[5] { static const GatewayToHubMessagePayload values[] = { GatewayToHubMessagePayload::NONE, + GatewayToHubMessagePayload::Ping, + GatewayToHubMessagePayload::Trigger, GatewayToHubMessagePayload::ShockerCommandList, - GatewayToHubMessagePayload::CaptivePortalConfig, - GatewayToHubMessagePayload::OtaInstall + GatewayToHubMessagePayload::OtaUpdateRequest }; return values; } inline const char * const *EnumNamesGatewayToHubMessagePayload() { - static const char * const names[5] = { + static const char * const names[6] = { "NONE", + "Ping", + "Trigger", "ShockerCommandList", - "CaptivePortalConfig", - "OtaInstall", + "OtaUpdateRequest", nullptr }; return names; } inline const char *EnumNameGatewayToHubMessagePayload(GatewayToHubMessagePayload e) { - if (::flatbuffers::IsOutRange(e, GatewayToHubMessagePayload::NONE, GatewayToHubMessagePayload::OtaInstall)) return ""; + if (::flatbuffers::IsOutRange(e, GatewayToHubMessagePayload::NONE, GatewayToHubMessagePayload::OtaUpdateRequest)) return ""; const size_t index = static_cast(e); return EnumNamesGatewayToHubMessagePayload()[index]; } @@ -74,98 +126,213 @@ template struct GatewayToHubMessagePayloadTraits { static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::NONE; }; -template<> struct GatewayToHubMessagePayloadTraits { - static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::ShockerCommandList; +template<> struct GatewayToHubMessagePayloadTraits { + static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::Ping; +}; + +template<> struct GatewayToHubMessagePayloadTraits { + static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::Trigger; }; -template<> struct GatewayToHubMessagePayloadTraits { - static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::CaptivePortalConfig; +template<> struct GatewayToHubMessagePayloadTraits { + static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::ShockerCommandList; }; -template<> struct GatewayToHubMessagePayloadTraits { - static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::OtaInstall; +template<> struct GatewayToHubMessagePayloadTraits { + static const GatewayToHubMessagePayload enum_value = GatewayToHubMessagePayload::OtaUpdateRequest; }; bool VerifyGatewayToHubMessagePayload(::flatbuffers::Verifier &verifier, const void *obj, GatewayToHubMessagePayload type); bool VerifyGatewayToHubMessagePayloadVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(2) ShockerCommand FLATBUFFERS_FINAL_CLASS { - private: - uint8_t model_; - int8_t padding0__; - uint16_t id_; - uint8_t type_; - uint8_t intensity_; - uint16_t duration_; +struct Ping FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef PingBuilder Builder; + struct Traits; + static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { + return "OpenShock.Serialization.Gateway.Ping"; + } + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_UNIX_UTC_TIME = 4 + }; + uint64_t unix_utc_time() const { + return GetField(VT_UNIX_UTC_TIME, 0); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_UNIX_UTC_TIME, 8) && + verifier.EndTable(); + } +}; + +struct PingBuilder { + typedef Ping Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_unix_utc_time(uint64_t unix_utc_time) { + fbb_.AddElement(Ping::VT_UNIX_UTC_TIME, unix_utc_time, 0); + } + explicit PingBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; - public: +inline ::flatbuffers::Offset CreatePing( + ::flatbuffers::FlatBufferBuilder &_fbb, + uint64_t unix_utc_time = 0) { + PingBuilder builder_(_fbb); + builder_.add_unix_utc_time(unix_utc_time); + return builder_.Finish(); +} + +struct Ping::Traits { + using type = Ping; + static auto constexpr Create = CreatePing; +}; + +struct Trigger FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef TriggerBuilder Builder; struct Traits; static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { - return "OpenShock.Serialization.Gateway.ShockerCommand"; + return "OpenShock.Serialization.Gateway.Trigger"; } - ShockerCommand() - : model_(0), - padding0__(0), - id_(0), - type_(0), - intensity_(0), - duration_(0) { - (void)padding0__; - } - ShockerCommand(OpenShock::Serialization::Types::ShockerModelType _model, uint16_t _id, OpenShock::Serialization::Types::ShockerCommandType _type, uint8_t _intensity, uint16_t _duration) - : model_(::flatbuffers::EndianScalar(static_cast(_model))), - padding0__(0), - id_(::flatbuffers::EndianScalar(_id)), - type_(::flatbuffers::EndianScalar(static_cast(_type))), - intensity_(::flatbuffers::EndianScalar(_intensity)), - duration_(::flatbuffers::EndianScalar(_duration)) { - (void)padding0__; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_TYPE = 4 + }; + OpenShock::Serialization::Gateway::TriggerType type() const { + return static_cast(GetField(VT_TYPE, 0)); } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_TYPE, 1) && + verifier.EndTable(); + } +}; + +struct TriggerBuilder { + typedef Trigger Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_type(OpenShock::Serialization::Gateway::TriggerType type) { + fbb_.AddElement(Trigger::VT_TYPE, static_cast(type), 0); + } + explicit TriggerBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateTrigger( + ::flatbuffers::FlatBufferBuilder &_fbb, + OpenShock::Serialization::Gateway::TriggerType type = OpenShock::Serialization::Gateway::TriggerType::Restart) { + TriggerBuilder builder_(_fbb); + builder_.add_type(type); + return builder_.Finish(); +} + +struct Trigger::Traits { + using type = Trigger; + static auto constexpr Create = CreateTrigger; +}; + +struct ShockerCommand FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ShockerCommandBuilder Builder; + struct Traits; + static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { + return "OpenShock.Serialization.Gateway.ShockerCommand"; + } + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_MODEL = 4, + VT_ID = 6, + VT_TYPE = 8, + VT_INTENSITY = 10, + VT_DURATION = 12 + }; OpenShock::Serialization::Types::ShockerModelType model() const { - return static_cast(::flatbuffers::EndianScalar(model_)); + return static_cast(GetField(VT_MODEL, 0)); } uint16_t id() const { - return ::flatbuffers::EndianScalar(id_); + return GetField(VT_ID, 0); } OpenShock::Serialization::Types::ShockerCommandType type() const { - return static_cast(::flatbuffers::EndianScalar(type_)); + return static_cast(GetField(VT_TYPE, 0)); } uint8_t intensity() const { - return ::flatbuffers::EndianScalar(intensity_); + return GetField(VT_INTENSITY, 0); } uint16_t duration() const { - return ::flatbuffers::EndianScalar(duration_); + return GetField(VT_DURATION, 0); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_MODEL, 1) && + VerifyField(verifier, VT_ID, 2) && + VerifyField(verifier, VT_TYPE, 1) && + VerifyField(verifier, VT_INTENSITY, 1) && + VerifyField(verifier, VT_DURATION, 2) && + verifier.EndTable(); } }; -FLATBUFFERS_STRUCT_END(ShockerCommand, 8); - -struct ShockerCommand::Traits { - using type = ShockerCommand; -}; - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(1) CaptivePortalConfig FLATBUFFERS_FINAL_CLASS { - private: - uint8_t enabled_; - public: - struct Traits; - static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { - return "OpenShock.Serialization.Gateway.CaptivePortalConfig"; +struct ShockerCommandBuilder { + typedef ShockerCommand Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_model(OpenShock::Serialization::Types::ShockerModelType model) { + fbb_.AddElement(ShockerCommand::VT_MODEL, static_cast(model), 0); } - CaptivePortalConfig() - : enabled_(0) { + void add_id(uint16_t id) { + fbb_.AddElement(ShockerCommand::VT_ID, id, 0); } - CaptivePortalConfig(bool _enabled) - : enabled_(::flatbuffers::EndianScalar(static_cast(_enabled))) { + void add_type(OpenShock::Serialization::Types::ShockerCommandType type) { + fbb_.AddElement(ShockerCommand::VT_TYPE, static_cast(type), 0); + } + void add_intensity(uint8_t intensity) { + fbb_.AddElement(ShockerCommand::VT_INTENSITY, intensity, 0); + } + void add_duration(uint16_t duration) { + fbb_.AddElement(ShockerCommand::VT_DURATION, duration, 0); + } + explicit ShockerCommandBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); } - bool enabled() const { - return ::flatbuffers::EndianScalar(enabled_) != 0; + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; } }; -FLATBUFFERS_STRUCT_END(CaptivePortalConfig, 1); -struct CaptivePortalConfig::Traits { - using type = CaptivePortalConfig; +inline ::flatbuffers::Offset CreateShockerCommand( + ::flatbuffers::FlatBufferBuilder &_fbb, + OpenShock::Serialization::Types::ShockerModelType model = OpenShock::Serialization::Types::ShockerModelType::CaiXianlin, + uint16_t id = 0, + OpenShock::Serialization::Types::ShockerCommandType type = OpenShock::Serialization::Types::ShockerCommandType::Stop, + uint8_t intensity = 0, + uint16_t duration = 0) { + ShockerCommandBuilder builder_(_fbb); + builder_.add_duration(duration); + builder_.add_id(id); + builder_.add_intensity(intensity); + builder_.add_type(type); + builder_.add_model(model); + return builder_.Finish(); +} + +struct ShockerCommand::Traits { + using type = ShockerCommand; + static auto constexpr Create = CreateShockerCommand; }; struct ShockerCommandList FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { @@ -177,13 +344,14 @@ struct ShockerCommandList FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_COMMANDS = 4 }; - const ::flatbuffers::Vector *commands() const { - return GetPointer *>(VT_COMMANDS); + const ::flatbuffers::Vector<::flatbuffers::Offset> *commands() const { + return GetPointer> *>(VT_COMMANDS); } bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_COMMANDS) && verifier.VerifyVector(commands()) && + verifier.VerifyVectorOfTables(commands()) && verifier.EndTable(); } }; @@ -192,7 +360,7 @@ struct ShockerCommandListBuilder { typedef ShockerCommandList Table; ::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::uoffset_t start_; - void add_commands(::flatbuffers::Offset<::flatbuffers::Vector> commands) { + void add_commands(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> commands) { fbb_.AddOffset(ShockerCommandList::VT_COMMANDS, commands); } explicit ShockerCommandListBuilder(::flatbuffers::FlatBufferBuilder &_fbb) @@ -209,7 +377,7 @@ struct ShockerCommandListBuilder { inline ::flatbuffers::Offset CreateShockerCommandList( ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::Vector> commands = 0) { + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> commands = 0) { ShockerCommandListBuilder builder_(_fbb); builder_.add_commands(commands); return builder_.Finish(); @@ -222,18 +390,18 @@ struct ShockerCommandList::Traits { inline ::flatbuffers::Offset CreateShockerCommandListDirect( ::flatbuffers::FlatBufferBuilder &_fbb, - const std::vector *commands = nullptr) { - auto commands__ = commands ? _fbb.CreateVectorOfStructs(*commands) : 0; + const std::vector<::flatbuffers::Offset> *commands = nullptr) { + auto commands__ = commands ? _fbb.CreateVector<::flatbuffers::Offset>(*commands) : 0; return OpenShock::Serialization::Gateway::CreateShockerCommandList( _fbb, commands__); } -struct OtaInstall FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef OtaInstallBuilder Builder; +struct OtaUpdateRequest FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef OtaUpdateRequestBuilder Builder; struct Traits; static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { - return "OpenShock.Serialization.Gateway.OtaInstall"; + return "OpenShock.Serialization.Gateway.OtaUpdateRequest"; } enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_VERSION = 4 @@ -243,41 +411,42 @@ struct OtaInstall FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { } bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_VERSION) && + VerifyOffsetRequired(verifier, VT_VERSION) && verifier.VerifyTable(version()) && verifier.EndTable(); } }; -struct OtaInstallBuilder { - typedef OtaInstall Table; +struct OtaUpdateRequestBuilder { + typedef OtaUpdateRequest Table; ::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::uoffset_t start_; void add_version(::flatbuffers::Offset version) { - fbb_.AddOffset(OtaInstall::VT_VERSION, version); + fbb_.AddOffset(OtaUpdateRequest::VT_VERSION, version); } - explicit OtaInstallBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + explicit OtaUpdateRequestBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - ::flatbuffers::Offset Finish() { + ::flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, OtaUpdateRequest::VT_VERSION); return o; } }; -inline ::flatbuffers::Offset CreateOtaInstall( +inline ::flatbuffers::Offset CreateOtaUpdateRequest( ::flatbuffers::FlatBufferBuilder &_fbb, ::flatbuffers::Offset version = 0) { - OtaInstallBuilder builder_(_fbb); + OtaUpdateRequestBuilder builder_(_fbb); builder_.add_version(version); return builder_.Finish(); } -struct OtaInstall::Traits { - using type = OtaInstall; - static auto constexpr Create = CreateOtaInstall; +struct OtaUpdateRequest::Traits { + using type = OtaUpdateRequest; + static auto constexpr Create = CreateOtaUpdateRequest; }; struct GatewayToHubMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { @@ -297,34 +466,41 @@ struct GatewayToHubMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tabl return GetPointer(VT_PAYLOAD); } template const T *payload_as() const; + const OpenShock::Serialization::Gateway::Ping *payload_as_Ping() const { + return payload_type() == OpenShock::Serialization::Gateway::GatewayToHubMessagePayload::Ping ? static_cast(payload()) : nullptr; + } + const OpenShock::Serialization::Gateway::Trigger *payload_as_Trigger() const { + return payload_type() == OpenShock::Serialization::Gateway::GatewayToHubMessagePayload::Trigger ? static_cast(payload()) : nullptr; + } const OpenShock::Serialization::Gateway::ShockerCommandList *payload_as_ShockerCommandList() const { return payload_type() == OpenShock::Serialization::Gateway::GatewayToHubMessagePayload::ShockerCommandList ? static_cast(payload()) : nullptr; } - const OpenShock::Serialization::Gateway::CaptivePortalConfig *payload_as_CaptivePortalConfig() const { - return payload_type() == OpenShock::Serialization::Gateway::GatewayToHubMessagePayload::CaptivePortalConfig ? static_cast(payload()) : nullptr; - } - const OpenShock::Serialization::Gateway::OtaInstall *payload_as_OtaInstall() const { - return payload_type() == OpenShock::Serialization::Gateway::GatewayToHubMessagePayload::OtaInstall ? static_cast(payload()) : nullptr; + const OpenShock::Serialization::Gateway::OtaUpdateRequest *payload_as_OtaUpdateRequest() const { + return payload_type() == OpenShock::Serialization::Gateway::GatewayToHubMessagePayload::OtaUpdateRequest ? static_cast(payload()) : nullptr; } bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_PAYLOAD_TYPE, 1) && - VerifyOffset(verifier, VT_PAYLOAD) && + VerifyOffsetRequired(verifier, VT_PAYLOAD) && VerifyGatewayToHubMessagePayload(verifier, payload(), payload_type()) && verifier.EndTable(); } }; -template<> inline const OpenShock::Serialization::Gateway::ShockerCommandList *GatewayToHubMessage::payload_as() const { - return payload_as_ShockerCommandList(); +template<> inline const OpenShock::Serialization::Gateway::Ping *GatewayToHubMessage::payload_as() const { + return payload_as_Ping(); } -template<> inline const OpenShock::Serialization::Gateway::CaptivePortalConfig *GatewayToHubMessage::payload_as() const { - return payload_as_CaptivePortalConfig(); +template<> inline const OpenShock::Serialization::Gateway::Trigger *GatewayToHubMessage::payload_as() const { + return payload_as_Trigger(); } -template<> inline const OpenShock::Serialization::Gateway::OtaInstall *GatewayToHubMessage::payload_as() const { - return payload_as_OtaInstall(); +template<> inline const OpenShock::Serialization::Gateway::ShockerCommandList *GatewayToHubMessage::payload_as() const { + return payload_as_ShockerCommandList(); +} + +template<> inline const OpenShock::Serialization::Gateway::OtaUpdateRequest *GatewayToHubMessage::payload_as() const { + return payload_as_OtaUpdateRequest(); } struct GatewayToHubMessageBuilder { @@ -344,6 +520,7 @@ struct GatewayToHubMessageBuilder { ::flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, GatewayToHubMessage::VT_PAYLOAD); return o; } }; @@ -368,15 +545,20 @@ inline bool VerifyGatewayToHubMessagePayload(::flatbuffers::Verifier &verifier, case GatewayToHubMessagePayload::NONE: { return true; } + case GatewayToHubMessagePayload::Ping: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case GatewayToHubMessagePayload::Trigger: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } case GatewayToHubMessagePayload::ShockerCommandList: { auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } - case GatewayToHubMessagePayload::CaptivePortalConfig: { - return verifier.VerifyField(static_cast(obj), 0, 1); - } - case GatewayToHubMessagePayload::OtaInstall: { - auto ptr = reinterpret_cast(obj); + case GatewayToHubMessagePayload::OtaUpdateRequest: { + auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } default: return true; diff --git a/include/serialization/_fbs/HubConfig_generated.h b/include/serialization/_fbs/HubConfig_generated.h index 6a73ae91..0bf2a25d 100644 --- a/include/serialization/_fbs/HubConfig_generated.h +++ b/include/serialization/_fbs/HubConfig_generated.h @@ -189,7 +189,8 @@ struct EStopConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { } enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_ENABLED = 4, - VT_GPIO_PIN = 6 + VT_GPIO_PIN = 6, + VT_ACTIVE = 8 }; bool enabled() const { return GetField(VT_ENABLED, 0) != 0; @@ -198,10 +199,15 @@ struct EStopConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { int8_t gpio_pin() const { return GetField(VT_GPIO_PIN, 0); } + /// Persistent state of the E-Stop button + bool active() const { + return GetField(VT_ACTIVE, 0) != 0; + } bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_ENABLED, 1) && VerifyField(verifier, VT_GPIO_PIN, 1) && + VerifyField(verifier, VT_ACTIVE, 1) && verifier.EndTable(); } }; @@ -216,6 +222,9 @@ struct EStopConfigBuilder { void add_gpio_pin(int8_t gpio_pin) { fbb_.AddElement(EStopConfig::VT_GPIO_PIN, gpio_pin, 0); } + void add_active(bool active) { + fbb_.AddElement(EStopConfig::VT_ACTIVE, static_cast(active), 0); + } explicit EStopConfigBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -230,8 +239,10 @@ struct EStopConfigBuilder { inline ::flatbuffers::Offset CreateEStopConfig( ::flatbuffers::FlatBufferBuilder &_fbb, bool enabled = false, - int8_t gpio_pin = 0) { + int8_t gpio_pin = 0, + bool active = false) { EStopConfigBuilder builder_(_fbb); + builder_.add_active(active); builder_.add_gpio_pin(gpio_pin); builder_.add_enabled(enabled); return builder_.Finish(); diff --git a/include/serialization/_fbs/HubToGatewayMessage_generated.h b/include/serialization/_fbs/HubToGatewayMessage_generated.h index 4dbe20f6..2a64ed88 100644 --- a/include/serialization/_fbs/HubToGatewayMessage_generated.h +++ b/include/serialization/_fbs/HubToGatewayMessage_generated.h @@ -14,93 +14,55 @@ static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && "Non-compatible flatbuffers version included"); #include "FirmwareBootType_generated.h" +#include "OtaUpdateProgressTask_generated.h" #include "SemVer_generated.h" namespace OpenShock { namespace Serialization { namespace Gateway { -struct KeepAlive; +struct Pong; +struct PongBuilder; struct BootStatus; struct BootStatusBuilder; -struct OtaInstallStarted; -struct OtaInstallStartedBuilder; +struct OtaUpdateStarted; +struct OtaUpdateStartedBuilder; -struct OtaInstallProgress; -struct OtaInstallProgressBuilder; +struct OtaUpdateProgress; +struct OtaUpdateProgressBuilder; -struct OtaInstallFailed; -struct OtaInstallFailedBuilder; +struct OtaUpdateFailed; +struct OtaUpdateFailedBuilder; struct HubToGatewayMessage; struct HubToGatewayMessageBuilder; -enum class OtaInstallProgressTask : int8_t { - FetchingMetadata = 0, - PreparingForInstall = 1, - FlashingFilesystem = 2, - VerifyingFilesystem = 3, - FlashingApplication = 4, - MarkingApplicationBootable = 5, - Rebooting = 6, - MIN = FetchingMetadata, - MAX = Rebooting -}; - -inline const OtaInstallProgressTask (&EnumValuesOtaInstallProgressTask())[7] { - static const OtaInstallProgressTask values[] = { - OtaInstallProgressTask::FetchingMetadata, - OtaInstallProgressTask::PreparingForInstall, - OtaInstallProgressTask::FlashingFilesystem, - OtaInstallProgressTask::VerifyingFilesystem, - OtaInstallProgressTask::FlashingApplication, - OtaInstallProgressTask::MarkingApplicationBootable, - OtaInstallProgressTask::Rebooting - }; - return values; -} - -inline const char * const *EnumNamesOtaInstallProgressTask() { - static const char * const names[8] = { - "FetchingMetadata", - "PreparingForInstall", - "FlashingFilesystem", - "VerifyingFilesystem", - "FlashingApplication", - "MarkingApplicationBootable", - "Rebooting", - nullptr - }; - return names; -} - -inline const char *EnumNameOtaInstallProgressTask(OtaInstallProgressTask e) { - if (::flatbuffers::IsOutRange(e, OtaInstallProgressTask::FetchingMetadata, OtaInstallProgressTask::Rebooting)) return ""; - const size_t index = static_cast(e); - return EnumNamesOtaInstallProgressTask()[index]; -} - enum class HubToGatewayMessagePayload : uint8_t { NONE = 0, - KeepAlive = 1, + /// Respond to a ping message + Pong = 1, + /// Report the current boot status, used to report firmware version and OTA update results BootStatus = 2, - OtaInstallStarted = 3, - OtaInstallProgress = 4, - OtaInstallFailed = 5, + /// Report that an OTA update has started + OtaUpdateStarted = 3, + /// Report the progress of an OTA update + OtaUpdateProgress = 4, + /// Report that an OTA update has failed + OtaUpdateFailed = 5, MIN = NONE, - MAX = OtaInstallFailed + MAX = OtaUpdateFailed }; inline const HubToGatewayMessagePayload (&EnumValuesHubToGatewayMessagePayload())[6] { static const HubToGatewayMessagePayload values[] = { HubToGatewayMessagePayload::NONE, - HubToGatewayMessagePayload::KeepAlive, + HubToGatewayMessagePayload::Pong, HubToGatewayMessagePayload::BootStatus, - HubToGatewayMessagePayload::OtaInstallStarted, - HubToGatewayMessagePayload::OtaInstallProgress, - HubToGatewayMessagePayload::OtaInstallFailed + HubToGatewayMessagePayload::OtaUpdateStarted, + HubToGatewayMessagePayload::OtaUpdateProgress, + HubToGatewayMessagePayload::OtaUpdateFailed }; return values; } @@ -108,18 +70,18 @@ inline const HubToGatewayMessagePayload (&EnumValuesHubToGatewayMessagePayload() inline const char * const *EnumNamesHubToGatewayMessagePayload() { static const char * const names[7] = { "NONE", - "KeepAlive", + "Pong", "BootStatus", - "OtaInstallStarted", - "OtaInstallProgress", - "OtaInstallFailed", + "OtaUpdateStarted", + "OtaUpdateProgress", + "OtaUpdateFailed", nullptr }; return names; } inline const char *EnumNameHubToGatewayMessagePayload(HubToGatewayMessagePayload e) { - if (::flatbuffers::IsOutRange(e, HubToGatewayMessagePayload::NONE, HubToGatewayMessagePayload::OtaInstallFailed)) return ""; + if (::flatbuffers::IsOutRange(e, HubToGatewayMessagePayload::NONE, HubToGatewayMessagePayload::OtaUpdateFailed)) return ""; const size_t index = static_cast(e); return EnumNamesHubToGatewayMessagePayload()[index]; } @@ -128,52 +90,87 @@ template struct HubToGatewayMessagePayloadTraits { static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::NONE; }; -template<> struct HubToGatewayMessagePayloadTraits { - static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::KeepAlive; +template<> struct HubToGatewayMessagePayloadTraits { + static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::Pong; }; template<> struct HubToGatewayMessagePayloadTraits { static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::BootStatus; }; -template<> struct HubToGatewayMessagePayloadTraits { - static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::OtaInstallStarted; +template<> struct HubToGatewayMessagePayloadTraits { + static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::OtaUpdateStarted; }; -template<> struct HubToGatewayMessagePayloadTraits { - static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::OtaInstallProgress; +template<> struct HubToGatewayMessagePayloadTraits { + static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::OtaUpdateProgress; }; -template<> struct HubToGatewayMessagePayloadTraits { - static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::OtaInstallFailed; +template<> struct HubToGatewayMessagePayloadTraits { + static const HubToGatewayMessagePayload enum_value = HubToGatewayMessagePayload::OtaUpdateFailed; }; bool VerifyHubToGatewayMessagePayload(::flatbuffers::Verifier &verifier, const void *obj, HubToGatewayMessagePayload type); bool VerifyHubToGatewayMessagePayloadVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) KeepAlive FLATBUFFERS_FINAL_CLASS { - private: - uint64_t uptime_; - - public: +struct Pong FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef PongBuilder Builder; struct Traits; static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { - return "OpenShock.Serialization.Gateway.KeepAlive"; + return "OpenShock.Serialization.Gateway.Pong"; } - KeepAlive() - : uptime_(0) { + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_UPTIME = 4, + VT_RSSI = 6 + }; + uint64_t uptime() const { + return GetField(VT_UPTIME, 0); } - KeepAlive(uint64_t _uptime) - : uptime_(::flatbuffers::EndianScalar(_uptime)) { + int32_t rssi() const { + return GetField(VT_RSSI, 0); } - uint64_t uptime() const { - return ::flatbuffers::EndianScalar(uptime_); + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_UPTIME, 8) && + VerifyField(verifier, VT_RSSI, 4) && + verifier.EndTable(); } }; -FLATBUFFERS_STRUCT_END(KeepAlive, 8); -struct KeepAlive::Traits { - using type = KeepAlive; +struct PongBuilder { + typedef Pong Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_uptime(uint64_t uptime) { + fbb_.AddElement(Pong::VT_UPTIME, uptime, 0); + } + void add_rssi(int32_t rssi) { + fbb_.AddElement(Pong::VT_RSSI, rssi, 0); + } + explicit PongBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreatePong( + ::flatbuffers::FlatBufferBuilder &_fbb, + uint64_t uptime = 0, + int32_t rssi = 0) { + PongBuilder builder_(_fbb); + builder_.add_uptime(uptime); + builder_.add_rssi(rssi); + return builder_.Finish(); +} + +struct Pong::Traits { + using type = Pong; + static auto constexpr Create = CreatePong; }; struct BootStatus FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { @@ -199,7 +196,7 @@ struct BootStatus FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_BOOT_TYPE, 1) && - VerifyOffset(verifier, VT_FIRMWARE_VERSION) && + VerifyOffsetRequired(verifier, VT_FIRMWARE_VERSION) && verifier.VerifyTable(firmware_version()) && VerifyField(verifier, VT_OTA_UPDATE_ID, 4) && verifier.EndTable(); @@ -226,6 +223,7 @@ struct BootStatusBuilder { ::flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, BootStatus::VT_FIRMWARE_VERSION); return o; } }; @@ -247,11 +245,11 @@ struct BootStatus::Traits { static auto constexpr Create = CreateBootStatus; }; -struct OtaInstallStarted FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef OtaInstallStartedBuilder Builder; +struct OtaUpdateStarted FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef OtaUpdateStartedBuilder Builder; struct Traits; static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { - return "OpenShock.Serialization.Gateway.OtaInstallStarted"; + return "OpenShock.Serialization.Gateway.OtaUpdateStarted"; } enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_UPDATE_ID = 4, @@ -266,53 +264,54 @@ struct OtaInstallStarted FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_UPDATE_ID, 4) && - VerifyOffset(verifier, VT_VERSION) && + VerifyOffsetRequired(verifier, VT_VERSION) && verifier.VerifyTable(version()) && verifier.EndTable(); } }; -struct OtaInstallStartedBuilder { - typedef OtaInstallStarted Table; +struct OtaUpdateStartedBuilder { + typedef OtaUpdateStarted Table; ::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::uoffset_t start_; void add_update_id(int32_t update_id) { - fbb_.AddElement(OtaInstallStarted::VT_UPDATE_ID, update_id, 0); + fbb_.AddElement(OtaUpdateStarted::VT_UPDATE_ID, update_id, 0); } void add_version(::flatbuffers::Offset version) { - fbb_.AddOffset(OtaInstallStarted::VT_VERSION, version); + fbb_.AddOffset(OtaUpdateStarted::VT_VERSION, version); } - explicit OtaInstallStartedBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + explicit OtaUpdateStartedBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - ::flatbuffers::Offset Finish() { + ::flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, OtaUpdateStarted::VT_VERSION); return o; } }; -inline ::flatbuffers::Offset CreateOtaInstallStarted( +inline ::flatbuffers::Offset CreateOtaUpdateStarted( ::flatbuffers::FlatBufferBuilder &_fbb, int32_t update_id = 0, ::flatbuffers::Offset version = 0) { - OtaInstallStartedBuilder builder_(_fbb); + OtaUpdateStartedBuilder builder_(_fbb); builder_.add_version(version); builder_.add_update_id(update_id); return builder_.Finish(); } -struct OtaInstallStarted::Traits { - using type = OtaInstallStarted; - static auto constexpr Create = CreateOtaInstallStarted; +struct OtaUpdateStarted::Traits { + using type = OtaUpdateStarted; + static auto constexpr Create = CreateOtaUpdateStarted; }; -struct OtaInstallProgress FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef OtaInstallProgressBuilder Builder; +struct OtaUpdateProgress FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef OtaUpdateProgressBuilder Builder; struct Traits; static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { - return "OpenShock.Serialization.Gateway.OtaInstallProgress"; + return "OpenShock.Serialization.Gateway.OtaUpdateProgress"; } enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_UPDATE_ID = 4, @@ -322,8 +321,8 @@ struct OtaInstallProgress FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table int32_t update_id() const { return GetField(VT_UPDATE_ID, 0); } - OpenShock::Serialization::Gateway::OtaInstallProgressTask task() const { - return static_cast(GetField(VT_TASK, 0)); + OpenShock::Serialization::Types::OtaUpdateProgressTask task() const { + return static_cast(GetField(VT_TASK, 0)); } float progress() const { return GetField(VT_PROGRESS, 0.0f); @@ -331,58 +330,58 @@ struct OtaInstallProgress FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_UPDATE_ID, 4) && - VerifyField(verifier, VT_TASK, 1) && + VerifyField(verifier, VT_TASK, 1) && VerifyField(verifier, VT_PROGRESS, 4) && verifier.EndTable(); } }; -struct OtaInstallProgressBuilder { - typedef OtaInstallProgress Table; +struct OtaUpdateProgressBuilder { + typedef OtaUpdateProgress Table; ::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::uoffset_t start_; void add_update_id(int32_t update_id) { - fbb_.AddElement(OtaInstallProgress::VT_UPDATE_ID, update_id, 0); + fbb_.AddElement(OtaUpdateProgress::VT_UPDATE_ID, update_id, 0); } - void add_task(OpenShock::Serialization::Gateway::OtaInstallProgressTask task) { - fbb_.AddElement(OtaInstallProgress::VT_TASK, static_cast(task), 0); + void add_task(OpenShock::Serialization::Types::OtaUpdateProgressTask task) { + fbb_.AddElement(OtaUpdateProgress::VT_TASK, static_cast(task), 0); } void add_progress(float progress) { - fbb_.AddElement(OtaInstallProgress::VT_PROGRESS, progress, 0.0f); + fbb_.AddElement(OtaUpdateProgress::VT_PROGRESS, progress, 0.0f); } - explicit OtaInstallProgressBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + explicit OtaUpdateProgressBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - ::flatbuffers::Offset Finish() { + ::flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); + auto o = ::flatbuffers::Offset(end); return o; } }; -inline ::flatbuffers::Offset CreateOtaInstallProgress( +inline ::flatbuffers::Offset CreateOtaUpdateProgress( ::flatbuffers::FlatBufferBuilder &_fbb, int32_t update_id = 0, - OpenShock::Serialization::Gateway::OtaInstallProgressTask task = OpenShock::Serialization::Gateway::OtaInstallProgressTask::FetchingMetadata, + OpenShock::Serialization::Types::OtaUpdateProgressTask task = OpenShock::Serialization::Types::OtaUpdateProgressTask::FetchingMetadata, float progress = 0.0f) { - OtaInstallProgressBuilder builder_(_fbb); + OtaUpdateProgressBuilder builder_(_fbb); builder_.add_progress(progress); builder_.add_update_id(update_id); builder_.add_task(task); return builder_.Finish(); } -struct OtaInstallProgress::Traits { - using type = OtaInstallProgress; - static auto constexpr Create = CreateOtaInstallProgress; +struct OtaUpdateProgress::Traits { + using type = OtaUpdateProgress; + static auto constexpr Create = CreateOtaUpdateProgress; }; -struct OtaInstallFailed FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef OtaInstallFailedBuilder Builder; +struct OtaUpdateFailed FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef OtaUpdateFailedBuilder Builder; struct Traits; static FLATBUFFERS_CONSTEXPR_CPP11 const char *GetFullyQualifiedName() { - return "OpenShock.Serialization.Gateway.OtaInstallFailed"; + return "OpenShock.Serialization.Gateway.OtaUpdateFailed"; } enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_UPDATE_ID = 4, @@ -408,54 +407,54 @@ struct OtaInstallFailed FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { } }; -struct OtaInstallFailedBuilder { - typedef OtaInstallFailed Table; +struct OtaUpdateFailedBuilder { + typedef OtaUpdateFailed Table; ::flatbuffers::FlatBufferBuilder &fbb_; ::flatbuffers::uoffset_t start_; void add_update_id(int32_t update_id) { - fbb_.AddElement(OtaInstallFailed::VT_UPDATE_ID, update_id, 0); + fbb_.AddElement(OtaUpdateFailed::VT_UPDATE_ID, update_id, 0); } void add_message(::flatbuffers::Offset<::flatbuffers::String> message) { - fbb_.AddOffset(OtaInstallFailed::VT_MESSAGE, message); + fbb_.AddOffset(OtaUpdateFailed::VT_MESSAGE, message); } void add_fatal(bool fatal) { - fbb_.AddElement(OtaInstallFailed::VT_FATAL, static_cast(fatal), 0); + fbb_.AddElement(OtaUpdateFailed::VT_FATAL, static_cast(fatal), 0); } - explicit OtaInstallFailedBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + explicit OtaUpdateFailedBuilder(::flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); } - ::flatbuffers::Offset Finish() { + ::flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); + auto o = ::flatbuffers::Offset(end); return o; } }; -inline ::flatbuffers::Offset CreateOtaInstallFailed( +inline ::flatbuffers::Offset CreateOtaUpdateFailed( ::flatbuffers::FlatBufferBuilder &_fbb, int32_t update_id = 0, ::flatbuffers::Offset<::flatbuffers::String> message = 0, bool fatal = false) { - OtaInstallFailedBuilder builder_(_fbb); + OtaUpdateFailedBuilder builder_(_fbb); builder_.add_message(message); builder_.add_update_id(update_id); builder_.add_fatal(fatal); return builder_.Finish(); } -struct OtaInstallFailed::Traits { - using type = OtaInstallFailed; - static auto constexpr Create = CreateOtaInstallFailed; +struct OtaUpdateFailed::Traits { + using type = OtaUpdateFailed; + static auto constexpr Create = CreateOtaUpdateFailed; }; -inline ::flatbuffers::Offset CreateOtaInstallFailedDirect( +inline ::flatbuffers::Offset CreateOtaUpdateFailedDirect( ::flatbuffers::FlatBufferBuilder &_fbb, int32_t update_id = 0, const char *message = nullptr, bool fatal = false) { auto message__ = message ? _fbb.CreateString(message) : 0; - return OpenShock::Serialization::Gateway::CreateOtaInstallFailed( + return OpenShock::Serialization::Gateway::CreateOtaUpdateFailed( _fbb, update_id, message__, @@ -479,48 +478,48 @@ struct HubToGatewayMessage FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tabl return GetPointer(VT_PAYLOAD); } template const T *payload_as() const; - const OpenShock::Serialization::Gateway::KeepAlive *payload_as_KeepAlive() const { - return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::KeepAlive ? static_cast(payload()) : nullptr; + const OpenShock::Serialization::Gateway::Pong *payload_as_Pong() const { + return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::Pong ? static_cast(payload()) : nullptr; } const OpenShock::Serialization::Gateway::BootStatus *payload_as_BootStatus() const { return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::BootStatus ? static_cast(payload()) : nullptr; } - const OpenShock::Serialization::Gateway::OtaInstallStarted *payload_as_OtaInstallStarted() const { - return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::OtaInstallStarted ? static_cast(payload()) : nullptr; + const OpenShock::Serialization::Gateway::OtaUpdateStarted *payload_as_OtaUpdateStarted() const { + return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::OtaUpdateStarted ? static_cast(payload()) : nullptr; } - const OpenShock::Serialization::Gateway::OtaInstallProgress *payload_as_OtaInstallProgress() const { - return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::OtaInstallProgress ? static_cast(payload()) : nullptr; + const OpenShock::Serialization::Gateway::OtaUpdateProgress *payload_as_OtaUpdateProgress() const { + return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::OtaUpdateProgress ? static_cast(payload()) : nullptr; } - const OpenShock::Serialization::Gateway::OtaInstallFailed *payload_as_OtaInstallFailed() const { - return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::OtaInstallFailed ? static_cast(payload()) : nullptr; + const OpenShock::Serialization::Gateway::OtaUpdateFailed *payload_as_OtaUpdateFailed() const { + return payload_type() == OpenShock::Serialization::Gateway::HubToGatewayMessagePayload::OtaUpdateFailed ? static_cast(payload()) : nullptr; } bool Verify(::flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_PAYLOAD_TYPE, 1) && - VerifyOffset(verifier, VT_PAYLOAD) && + VerifyOffsetRequired(verifier, VT_PAYLOAD) && VerifyHubToGatewayMessagePayload(verifier, payload(), payload_type()) && verifier.EndTable(); } }; -template<> inline const OpenShock::Serialization::Gateway::KeepAlive *HubToGatewayMessage::payload_as() const { - return payload_as_KeepAlive(); +template<> inline const OpenShock::Serialization::Gateway::Pong *HubToGatewayMessage::payload_as() const { + return payload_as_Pong(); } template<> inline const OpenShock::Serialization::Gateway::BootStatus *HubToGatewayMessage::payload_as() const { return payload_as_BootStatus(); } -template<> inline const OpenShock::Serialization::Gateway::OtaInstallStarted *HubToGatewayMessage::payload_as() const { - return payload_as_OtaInstallStarted(); +template<> inline const OpenShock::Serialization::Gateway::OtaUpdateStarted *HubToGatewayMessage::payload_as() const { + return payload_as_OtaUpdateStarted(); } -template<> inline const OpenShock::Serialization::Gateway::OtaInstallProgress *HubToGatewayMessage::payload_as() const { - return payload_as_OtaInstallProgress(); +template<> inline const OpenShock::Serialization::Gateway::OtaUpdateProgress *HubToGatewayMessage::payload_as() const { + return payload_as_OtaUpdateProgress(); } -template<> inline const OpenShock::Serialization::Gateway::OtaInstallFailed *HubToGatewayMessage::payload_as() const { - return payload_as_OtaInstallFailed(); +template<> inline const OpenShock::Serialization::Gateway::OtaUpdateFailed *HubToGatewayMessage::payload_as() const { + return payload_as_OtaUpdateFailed(); } struct HubToGatewayMessageBuilder { @@ -540,6 +539,7 @@ struct HubToGatewayMessageBuilder { ::flatbuffers::Offset Finish() { const auto end = fbb_.EndTable(start_); auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, HubToGatewayMessage::VT_PAYLOAD); return o; } }; @@ -564,23 +564,24 @@ inline bool VerifyHubToGatewayMessagePayload(::flatbuffers::Verifier &verifier, case HubToGatewayMessagePayload::NONE: { return true; } - case HubToGatewayMessagePayload::KeepAlive: { - return verifier.VerifyField(static_cast(obj), 0, 8); + case HubToGatewayMessagePayload::Pong: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); } case HubToGatewayMessagePayload::BootStatus: { auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } - case HubToGatewayMessagePayload::OtaInstallStarted: { - auto ptr = reinterpret_cast(obj); + case HubToGatewayMessagePayload::OtaUpdateStarted: { + auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } - case HubToGatewayMessagePayload::OtaInstallProgress: { - auto ptr = reinterpret_cast(obj); + case HubToGatewayMessagePayload::OtaUpdateProgress: { + auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } - case HubToGatewayMessagePayload::OtaInstallFailed: { - auto ptr = reinterpret_cast(obj); + case HubToGatewayMessagePayload::OtaUpdateFailed: { + auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } default: return true; diff --git a/include/serialization/_fbs/OtaUpdateProgressTask_generated.h b/include/serialization/_fbs/OtaUpdateProgressTask_generated.h new file mode 100644 index 00000000..f320eba9 --- /dev/null +++ b/include/serialization/_fbs/OtaUpdateProgressTask_generated.h @@ -0,0 +1,69 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_OTAUPDATEPROGRESSTASK_OPENSHOCK_SERIALIZATION_TYPES_H_ +#define FLATBUFFERS_GENERATED_OTAUPDATEPROGRESSTASK_OPENSHOCK_SERIALIZATION_TYPES_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 24 && + FLATBUFFERS_VERSION_MINOR == 3 && + FLATBUFFERS_VERSION_REVISION == 25, + "Non-compatible flatbuffers version included"); + +namespace OpenShock { +namespace Serialization { +namespace Types { + +enum class OtaUpdateProgressTask : uint8_t { + FetchingMetadata = 0, + PreparingForUpdate = 1, + FlashingFilesystem = 2, + VerifyingFilesystem = 3, + FlashingApplication = 4, + MarkingApplicationBootable = 5, + Rebooting = 6, + MIN = FetchingMetadata, + MAX = Rebooting +}; + +inline const OtaUpdateProgressTask (&EnumValuesOtaUpdateProgressTask())[7] { + static const OtaUpdateProgressTask values[] = { + OtaUpdateProgressTask::FetchingMetadata, + OtaUpdateProgressTask::PreparingForUpdate, + OtaUpdateProgressTask::FlashingFilesystem, + OtaUpdateProgressTask::VerifyingFilesystem, + OtaUpdateProgressTask::FlashingApplication, + OtaUpdateProgressTask::MarkingApplicationBootable, + OtaUpdateProgressTask::Rebooting + }; + return values; +} + +inline const char * const *EnumNamesOtaUpdateProgressTask() { + static const char * const names[8] = { + "FetchingMetadata", + "PreparingForUpdate", + "FlashingFilesystem", + "VerifyingFilesystem", + "FlashingApplication", + "MarkingApplicationBootable", + "Rebooting", + nullptr + }; + return names; +} + +inline const char *EnumNameOtaUpdateProgressTask(OtaUpdateProgressTask e) { + if (::flatbuffers::IsOutRange(e, OtaUpdateProgressTask::FetchingMetadata, OtaUpdateProgressTask::Rebooting)) return ""; + const size_t index = static_cast(e); + return EnumNamesOtaUpdateProgressTask()[index]; +} + +} // namespace Types +} // namespace Serialization +} // namespace OpenShock + +#endif // FLATBUFFERS_GENERATED_OTAUPDATEPROGRESSTASK_OPENSHOCK_SERIALIZATION_TYPES_H_ diff --git a/schemas b/schemas index b82468a6..9257c6da 160000 --- a/schemas +++ b/schemas @@ -1 +1 @@ -Subproject commit b82468a6672860dd506f26724265d9bd7dd2d2fb +Subproject commit 9257c6dac8801d13179323dae399039d5d57a4c8 diff --git a/scripts/embed_env_vars.py b/scripts/embed_env_vars.py index fc9444b4..623b97de 100644 --- a/scripts/embed_env_vars.py +++ b/scripts/embed_env_vars.py @@ -145,6 +145,24 @@ def serialize_cpp_define(k: str, v: str | int | bool) -> str | int: return v +def split_semver(version): + # Match the semver pattern + pattern = r'^(?P\d+)\.(?P\d+)\.(?P\d+)(?:-(?P[0-9A-Za-z.-]+))?(?:\+(?P[0-9A-Za-z.-]+))?$' + match = re.match(pattern, version) + + if not match: + raise ValueError("Invalid semver format") + + # Extract components and convert major, minor, patch to integers + major = int(match.group('major')) + minor = int(match.group('minor')) + patch = int(match.group('patch')) + prerelease = match.group('prerelease') # None if not present + build = match.group('build') # None if not present + + return major, minor, patch, prerelease, build + + # Serialize CPP Defines. # Strings are escaped to be a correct CPP macro. # Booleans are turned into integers, True => 1 and False => 0. @@ -202,6 +220,17 @@ def print_dump(name: str, map: Mapping[str, str | int | bool]) -> None: # If not set, get the latest tag. cpp_defines['OPENSHOCK_FW_VERSION'] = version + +version_major, version_minor, version_patch, version_prerelease, version_build = split_semver( + cpp_defines['OPENSHOCK_FW_VERSION'] +) + +cpp_defines['OPENSHOCK_FW_VERSION_MAJOR'] = version_major +cpp_defines['OPENSHOCK_FW_VERSION_MINOR'] = version_minor +cpp_defines['OPENSHOCK_FW_VERSION_PATCH'] = version_patch +cpp_defines['OPENSHOCK_FW_VERSION_PRERELEASE'] = version_prerelease +cpp_defines['OPENSHOCK_FW_VERSION_BUILD'] = version_build + # Gets the log level from environment variables. # TODO: Delete get_loglevel and use... something more generic. log_level_int = dot.get_loglevel('LOG_LEVEL') diff --git a/scripts/generate_schemas.py b/scripts/generate_schemas.py index a2820e7b..64477507 100644 --- a/scripts/generate_schemas.py +++ b/scripts/generate_schemas.py @@ -62,7 +62,7 @@ def resolve_path(path): root = root.replace('\\', '/') for filename in files: filepath = os.path.join(root, filename) - if filename.endswith('.fbs'): + if filename.endswith('.fbs') and not filename.startswith('Deprecated'): schema_files.append(filepath) # Compile the schemas for C++ and TypeScript. diff --git a/src/CommandHandler.cpp b/src/CommandHandler.cpp index d32ae0f7..af79aa25 100644 --- a/src/CommandHandler.cpp +++ b/src/CommandHandler.cpp @@ -41,8 +41,6 @@ struct KnownShocker { static OpenShock::ReadWriteMutex s_rfTransmitterMutex = {}; static std::unique_ptr s_rfTransmitter = nullptr; -static OpenShock::SimpleMutex s_estopManagerMutex = {}; - static OpenShock::ReadWriteMutex s_keepAliveMutex = {}; static QueueHandle_t s_keepAliveQueue = nullptr; static TaskHandle_t s_keepAliveTaskHandle = nullptr; @@ -261,29 +259,6 @@ SetGPIOResultCode CommandHandler::SetRfTxPin(gpio_num_t txPin) return SetGPIOResultCode::Success; } -SetGPIOResultCode CommandHandler::SetEStopPin(gpio_num_t estopPin) -{ - if (OpenShock::IsValidInputPin(static_cast(estopPin))) { - ScopedLock lock__(&s_estopManagerMutex); - - if (!EStopManager::SetEStopPin(estopPin)) { - OS_LOGE(TAG, "Failed to set EStop pin"); - - return SetGPIOResultCode::InternalError; - } - - if (!Config::SetEStopGpioPin(estopPin)) { - OS_LOGE(TAG, "Failed to set EStop pin in config"); - - return SetGPIOResultCode::InternalError; - } - - return SetGPIOResultCode::Success; - } else { - return SetGPIOResultCode::InvalidPin; - } -} - bool CommandHandler::SetKeepAliveEnabled(bool enabled) { if (!_internalSetKeepAliveEnabled(enabled)) { diff --git a/src/EStopManager.cpp b/src/EStopManager.cpp index 910cd99a..a0904e3b 100644 --- a/src/EStopManager.cpp +++ b/src/EStopManager.cpp @@ -30,18 +30,20 @@ static OpenShock::SimpleMutex s_estopMutex = {}; static gpio_num_t s_estopPin = GPIO_NUM_NC; static TaskHandle_t s_estopTask; -EStopState s_estopState = EStopState::Idle; +static EStopState s_estopState = EStopState::Idle; static bool s_estopActive = false; static int64_t s_estopActivatedAt = 0; -void _estopUpdateExternals(bool isActive, bool isAwaitingRelease) +static volatile bool s_externallyTriggered = false; + +static void _estopUpdateExternals(bool isActive, bool isAwaitingRelease) { // Post an event ESP_ERROR_CHECK(esp_event_post(OPENSHOCK_EVENTS, OPENSHOCK_EVENT_ESTOP_STATE_CHANGED, &s_estopState, sizeof(s_estopState), portMAX_DELAY)); } // Samples the estop at a fixed rate and sends messages to the estop event handler task -void _estopCheckerTask(void* pvParameters) +static void _estopCheckerTask(void* pvParameters) { uint16_t history = 0xFFFF; // Bit history of samples, 0 is pressed @@ -54,23 +56,35 @@ void _estopCheckerTask(void* pvParameters) // Sleep for the update rate vTaskDelay(pdMS_TO_TICKS(k_estopUpdateRate)); - // Sample the EStop - history = (history << 1) | gpio_get_level(s_estopPin); - // Get current time int64_t now = OpenShock::millis(); - // Check if the EStop is released (not all bits are 1) - bool btnState = (history & k_estopCheckMask) != k_estopCheckMask; - if (btnState == lastBtnState) { - // If the state hasn't changed, handle timing transitions - if (state == EStopState::ActiveClearing && now > deactivatesAt) { - state = EStopState::AwaitingRelease; - _estopUpdateExternals(s_estopActive, true); + bool btnState; + if (s_externallyTriggered) { + s_externallyTriggered = false; + + // Emulate an EStop activation + history = 0xFFFF; + state = EStopState::Active; + deactivatesAt = 0; + lastBtnState = false; + btnState = false; + } else { + // Sample the EStop + history = (history << 1) | gpio_get_level(s_estopPin); + + // Check if the EStop is released (not all bits are 1) + btnState = (history & k_estopCheckMask) != k_estopCheckMask; + if (btnState == lastBtnState) { + // If the state hasn't changed, handle timing transitions + if (state == EStopState::ActiveClearing && now > deactivatesAt) { + state = EStopState::AwaitingRelease; + _estopUpdateExternals(s_estopActive, true); + } + continue; } - continue; + lastBtnState = btnState; } - lastBtnState = btnState; switch (state) { case EStopState::Idle: @@ -107,7 +121,7 @@ void _estopCheckerTask(void* pvParameters) } } -bool _setEStopEnabledImpl(bool enabled) +static bool _setEStopEnabledImpl(bool enabled) { if (enabled) { if (s_estopTask == nullptr) { @@ -126,7 +140,7 @@ bool _setEStopEnabledImpl(bool enabled) return true; } -bool _setEStopPinImpl(gpio_num_t pin) +static bool _setEStopPinImpl(gpio_num_t pin) { esp_err_t err; @@ -252,3 +266,8 @@ int64_t EStopManager::LastEStopped() { return s_estopActivatedAt; } + +void EStopManager::Trigger() +{ + s_externallyTriggered = true; +} diff --git a/src/GatewayClient.cpp b/src/GatewayClient.cpp index ca445c35..a98267f7 100644 --- a/src/GatewayClient.cpp +++ b/src/GatewayClient.cpp @@ -19,7 +19,6 @@ static bool s_bootStatusSent = false; GatewayClient::GatewayClient(const std::string& authToken) : m_webSocket() - , m_lastKeepAlive(0) , m_state(GatewayClientState::Disconnected) { OS_LOGD(TAG, "Creating GatewayClient"); @@ -61,7 +60,7 @@ void GatewayClient::connect(const char* lcgFqdn) // #warning SSL certificate verification is currently not implemented, by RFC definition this is a security risk, and allows for MITM attacks, but the realistic risk is low - m_webSocket.beginSSL(lcgFqdn, 443, "/1/ws/device"); + m_webSocket.beginSSL(lcgFqdn, 443, "/2/ws/device"); OS_LOGW(TAG, "WEBSOCKET CONNECTION BY RFC DEFINITION IS INSECURE, remote endpoint can not be verified due to lack of CA verification support, theoretically this is a security risk and allows for MITM attacks, but the realistic risk is low"); } @@ -106,15 +105,6 @@ bool GatewayClient::loop() return true; } - int64_t msNow = OpenShock::millis(); - - int64_t timeSinceLastKA = msNow - m_lastKeepAlive; - - if (timeSinceLastKA >= 15'000) { - _sendKeepAlive(); - m_lastKeepAlive = msNow; - } - return true; } @@ -129,12 +119,6 @@ void GatewayClient::_setState(GatewayClientState state) ESP_ERROR_CHECK(esp_event_post(OPENSHOCK_EVENTS, OPENSHOCK_EVENT_GATEWAY_CLIENT_STATE_CHANGED, &m_state, sizeof(m_state), portMAX_DELAY)); } -void GatewayClient::_sendKeepAlive() -{ - OS_LOGV(TAG, "Sending Gateway keep-alive message"); - Serialization::Gateway::SerializeKeepAliveMessage([this](const uint8_t* data, std::size_t len) { return m_webSocket.sendBIN(data, len); }); -} - void GatewayClient::_sendBootStatus() { if (s_bootStatusSent) return; @@ -159,7 +143,7 @@ void GatewayClient::_sendBootStatus() return; } - s_bootStatusSent = Serialization::Gateway::SerializeBootStatusMessage(updateId, OtaUpdateManager::GetFirmwareBootType(), version, [this](const uint8_t* data, std::size_t len) { return m_webSocket.sendBIN(data, len); }); + s_bootStatusSent = Serialization::Gateway::SerializeBootStatusMessage(updateId, OtaUpdateManager::GetFirmwareBootType(), [this](const uint8_t* data, std::size_t len) { return m_webSocket.sendBIN(data, len); }); if (s_bootStatusSent && updateStep != OpenShock::OtaUpdateStep::None) { if (!Config::SetOtaUpdateStep(OpenShock::OtaUpdateStep::None)) { @@ -178,7 +162,6 @@ void GatewayClient::_handleEvent(WStype_t type, uint8_t* payload, std::size_t le break; case WStype_CONNECTED: _setState(GatewayClientState::Connected); - _sendKeepAlive(); _sendBootStatus(); break; case WStype_TEXT: diff --git a/src/OtaUpdateManager.cpp b/src/OtaUpdateManager.cpp index 4bd8823b..2e8b5680 100644 --- a/src/OtaUpdateManager.cpp +++ b/src/OtaUpdateManager.cpp @@ -69,7 +69,7 @@ static OpenShock::SimpleMutex _requestedVersionMutex = {}; using namespace OpenShock; -bool _tryQueueUpdateRequest(const OpenShock::SemVer& version) +static bool _tryQueueUpdateRequest(const OpenShock::SemVer& version) { if (!_requestedVersionMutex.lock(pdMS_TO_TICKS(1000))) { OS_LOGE(TAG, "Failed to take requested version mutex"); @@ -85,7 +85,7 @@ bool _tryQueueUpdateRequest(const OpenShock::SemVer& version) return true; } -bool _tryGetRequestedVersion(OpenShock::SemVer& version) +static bool _tryGetRequestedVersion(OpenShock::SemVer& version) { if (!_requestedVersionMutex.lock(pdMS_TO_TICKS(1000))) { OS_LOGE(TAG, "Failed to take requested version mutex"); @@ -99,7 +99,7 @@ bool _tryGetRequestedVersion(OpenShock::SemVer& version) return true; } -void _otaEvWiFiDisconnectedHandler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +static void _otaEvWiFiDisconnectedHandler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { (void)event_handler_arg; (void)event_base; @@ -109,7 +109,7 @@ void _otaEvWiFiDisconnectedHandler(void* event_handler_arg, esp_event_base_t eve xTaskNotify(_taskHandle, OTA_TASK_EVENT_WIFI_DISCONNECTED, eSetBits); } -void _otaEvIpEventHandler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) +static void _otaEvIpEventHandler(void* event_handler_arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { (void)event_handler_arg; (void)event_base; @@ -128,7 +128,7 @@ void _otaEvIpEventHandler(void* event_handler_arg, esp_event_base_t event_base, } } -bool _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask task, float progress) +static bool _sendProgressMessage(Serialization::Types::OtaUpdateProgressTask task, float progress) { int32_t updateId; if (!Config::GetOtaUpdateId(updateId)) { @@ -136,14 +136,14 @@ bool _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask task, f return false; } - if (!Serialization::Gateway::SerializeOtaInstallProgressMessage(updateId, task, progress, GatewayConnectionManager::SendMessageBIN)) { + if (!Serialization::Gateway::SerializeOtaUpdateProgressMessage(updateId, task, progress, GatewayConnectionManager::SendMessageBIN)) { OS_LOGE(TAG, "Failed to send OTA install progress message"); return false; } return true; } -bool _sendFailureMessage(std::string_view message, bool fatal = false) +static bool _sendFailureMessage(std::string_view message, bool fatal = false) { int32_t updateId; if (!Config::GetOtaUpdateId(updateId)) { @@ -151,7 +151,7 @@ bool _sendFailureMessage(std::string_view message, bool fatal = false) return false; } - if (!Serialization::Gateway::SerializeOtaInstallFailedMessage(updateId, message, fatal, GatewayConnectionManager::SendMessageBIN)) { + if (!Serialization::Gateway::SerializeOtaUpdateFailedMessage(updateId, message, fatal, GatewayConnectionManager::SendMessageBIN)) { OS_LOGE(TAG, "Failed to send OTA install failed message"); return false; } @@ -159,18 +159,18 @@ bool _sendFailureMessage(std::string_view message, bool fatal = false) return true; } -bool _flashAppPartition(const esp_partition_t* partition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) +static bool _flashAppPartition(const esp_partition_t* partition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) { OS_LOGD(TAG, "Flashing app partition"); - if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::FlashingApplication, 0.0f)) { + if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingApplication, 0.0f)) { return false; } auto onProgress = [](std::size_t current, std::size_t total, float progress) -> bool { OS_LOGD(TAG, "Flashing app partition: %u / %u (%.2f%%)", current, total, progress * 100.0f); - _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::FlashingApplication, progress); + _sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingApplication, progress); return true; }; @@ -181,7 +181,7 @@ bool _flashAppPartition(const esp_partition_t* partition, std::string_view remot return false; } - if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::MarkingApplicationBootable, 0.0f)) { + if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::MarkingApplicationBootable, 0.0f)) { return false; } @@ -195,9 +195,9 @@ bool _flashAppPartition(const esp_partition_t* partition, std::string_view remot return true; } -bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) +static bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view remoteUrl, const uint8_t (&remoteHash)[32]) { - if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::PreparingForInstall, 0.0f)) { + if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::PreparingForUpdate, 0.0f)) { return false; } @@ -210,14 +210,14 @@ bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view OS_LOGD(TAG, "Flashing filesystem partition"); - if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::FlashingFilesystem, 0.0f)) { + if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingFilesystem, 0.0f)) { return false; } auto onProgress = [](std::size_t current, std::size_t total, float progress) -> bool { OS_LOGD(TAG, "Flashing filesystem partition: %u / %u (%.2f%%)", current, total, progress * 100.0f); - _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::FlashingFilesystem, progress); + _sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FlashingFilesystem, progress); return true; }; @@ -228,7 +228,7 @@ bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view return false; } - if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::VerifyingFilesystem, 0.0f)) { + if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::VerifyingFilesystem, 0.0f)) { return false; } @@ -241,12 +241,10 @@ bool _flashFilesystemPartition(const esp_partition_t* parition, std::string_view } test.end(); - OpenShock::CaptivePortal::ForceClose(false); - return true; } -void _otaUpdateTask(void* arg) +static void _otaUpdateTask(void* arg) { (void)arg; @@ -352,12 +350,12 @@ void _otaUpdateTask(void* arg) continue; } - if (!Serialization::Gateway::SerializeOtaInstallStartedMessage(updateId, version, GatewayConnectionManager::SendMessageBIN)) { - OS_LOGE(TAG, "Failed to serialize OTA install started message"); + if (!Serialization::Gateway::SerializeOtaUpdateStartedMessage(updateId, version, GatewayConnectionManager::SendMessageBIN)) { + OS_LOGE(TAG, "Failed to serialize OTA update started message"); continue; } - if (!_sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::FetchingMetadata, 0.0f)) { + if (!_sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::FetchingMetadata, 0.0f)) { continue; } @@ -412,7 +410,7 @@ void _otaUpdateTask(void* arg) esp_task_wdt_init(5, true); // Send reboot message. - _sendProgressMessage(Serialization::Gateway::OtaInstallProgressTask::Rebooting, 0.0f); + _sendProgressMessage(Serialization::Types::OtaUpdateProgressTask::Rebooting, 0.0f); // Reboot into new firmware. OS_LOGI(TAG, "Restarting into new firmware..."); @@ -424,7 +422,7 @@ void _otaUpdateTask(void* arg) esp_restart(); } -bool _tryGetStringList(std::string_view url, std::vector& list) +static bool _tryGetStringList(std::string_view url, std::vector& list) { auto response = OpenShock::HTTP::GetString( url, @@ -530,13 +528,13 @@ bool OtaUpdateManager::TryGetFirmwareVersion(OtaUpdateChannel channel, OpenShock std::string_view channelIndexUrl; switch (channel) { case OtaUpdateChannel::Stable: - channelIndexUrl = std::string_view(OPENSHOCK_FW_CDN_STABLE_URL); + channelIndexUrl = OPENSHOCK_FW_CDN_STABLE_URL ""sv; break; case OtaUpdateChannel::Beta: - channelIndexUrl = std::string_view(OPENSHOCK_FW_CDN_BETA_URL); + channelIndexUrl = OPENSHOCK_FW_CDN_BETA_URL ""sv; break; case OtaUpdateChannel::Develop: - channelIndexUrl = std::string_view(OPENSHOCK_FW_CDN_DEVELOP_URL); + channelIndexUrl = OPENSHOCK_FW_CDN_DEVELOP_URL ""sv; break; default: OS_LOGE(TAG, "Unknown channel: %u", channel); @@ -583,7 +581,7 @@ bool OtaUpdateManager::TryGetFirmwareBoards(const OpenShock::SemVer& version, st return true; } -bool _tryParseIntoHash(std::string_view hash, uint8_t (&hashBytes)[32]) +static bool _tryParseIntoHash(std::string_view hash, uint8_t (&hashBytes)[32]) { if (!HexUtils::TryParseHex(hash.data(), hash.size(), hashBytes, 32)) { OS_LOGE(TAG, "Failed to parse hash: %.*s", hash.size(), hash.data()); @@ -678,7 +676,7 @@ bool OtaUpdateManager::TryGetFirmwareRelease(const OpenShock::SemVer& version, F return true; } -bool OtaUpdateManager::TryStartFirmwareInstallation(const OpenShock::SemVer& version) +bool OtaUpdateManager::TryStartFirmwareUpdate(const OpenShock::SemVer& version) { OS_LOGD(TAG, "Requesting firmware version %s", version.toString().c_str()); // TODO: This is abusing the SemVer::toString() method causing alot of string copies, fix this diff --git a/src/message_handlers/websocket/Gateway.cpp b/src/message_handlers/websocket/Gateway.cpp index 3f6fb1f2..4b1e6973 100644 --- a/src/message_handlers/websocket/Gateway.cpp +++ b/src/message_handlers/websocket/Gateway.cpp @@ -21,19 +21,22 @@ using namespace OpenShock; const std::size_t HANDLER_COUNT = static_cast(PayloadType::MAX) + 1; -#define SET_HANDLER(payload, handler) handlers[static_cast(payload)] = handler +#define SET_HANDLER(payload) handlers[static_cast(PayloadType::payload)] = Handlers::Handle##payload static std::array s_serverHandlers = []() { std::array handlers {}; handlers.fill(Handlers::HandleInvalidMessage); - SET_HANDLER(PayloadType::ShockerCommandList, Handlers::HandleShockerCommandList); - SET_HANDLER(PayloadType::CaptivePortalConfig, Handlers::HandleCaptivePortalConfig); - SET_HANDLER(PayloadType::OtaInstall, Handlers::HandleOtaInstall); + SET_HANDLER(Ping); + SET_HANDLER(Trigger); + SET_HANDLER(ShockerCommandList); + SET_HANDLER(OtaUpdateRequest); return handlers; }(); +#undef SET_HANDLER + void MessageHandlers::WebSocket::HandleGatewayBinary(const uint8_t* data, std::size_t len) { // Deserialize diff --git a/src/message_handlers/websocket/Local.cpp b/src/message_handlers/websocket/Local.cpp index 4728fe57..b78c3f56 100644 --- a/src/message_handlers/websocket/Local.cpp +++ b/src/message_handlers/websocket/Local.cpp @@ -20,21 +20,31 @@ using namespace OpenShock; const std::size_t HANDLER_COUNT = static_cast(PayloadType::MAX) + 1; -#define SET_HANDLER(payload, handler) handlers[static_cast(payload)] = handler +#define SET_HANDLER(payload) handlers[static_cast(PayloadType::payload)] = Handlers::Handle##payload static std::array s_localHandlers = []() { std::array handlers {}; handlers.fill(Handlers::HandleInvalidMessage); - SET_HANDLER(PayloadType::WifiScanCommand, Handlers::HandleWiFiScanCommand); - SET_HANDLER(PayloadType::WifiNetworkSaveCommand, Handlers::HandleWiFiNetworkSaveCommand); - SET_HANDLER(PayloadType::WifiNetworkForgetCommand, Handlers::HandleWiFiNetworkForgetCommand); - SET_HANDLER(PayloadType::WifiNetworkConnectCommand, Handlers::HandleWiFiNetworkConnectCommand); - SET_HANDLER(PayloadType::WifiNetworkDisconnectCommand, Handlers::HandleWiFiNetworkDisconnectCommand); - SET_HANDLER(PayloadType::AccountLinkCommand, Handlers::HandleAccountLinkCommand); - SET_HANDLER(PayloadType::AccountUnlinkCommand, Handlers::HandleAccountUnlinkCommand); - SET_HANDLER(PayloadType::SetRfTxPinCommand, Handlers::HandleSetRfTxPinCommand); - SET_HANDLER(PayloadType::SetEstopPinCommand, Handlers::HandleSetEstopPinCommand); + SET_HANDLER(WifiScanCommand); + SET_HANDLER(WifiNetworkSaveCommand); + SET_HANDLER(WifiNetworkForgetCommand); + SET_HANDLER(WifiNetworkConnectCommand); + SET_HANDLER(WifiNetworkDisconnectCommand); + SET_HANDLER(OtaUpdateSetIsEnabledCommand); + SET_HANDLER(OtaUpdateSetDomainCommand); + SET_HANDLER(OtaUpdateSetUpdateChannelCommand); + SET_HANDLER(OtaUpdateSetCheckIntervalCommand); + SET_HANDLER(OtaUpdateSetAllowBackendManagementCommand); + SET_HANDLER(OtaUpdateSetRequireManualApprovalCommand); + SET_HANDLER(OtaUpdateHandleUpdateRequestCommand); + SET_HANDLER(OtaUpdateCheckForUpdatesCommand); + SET_HANDLER(OtaUpdateStartUpdateCommand); + SET_HANDLER(AccountLinkCommand); + SET_HANDLER(AccountUnlinkCommand); + SET_HANDLER(SetRfTxPinCommand); + SET_HANDLER(SetEstopEnabledCommand); + SET_HANDLER(SetEstopPinCommand); return handlers; }(); diff --git a/src/message_handlers/websocket/gateway/CaptivePortalConfig.cpp b/src/message_handlers/websocket/gateway/CaptivePortalConfig.cpp deleted file mode 100644 index a0f04366..00000000 --- a/src/message_handlers/websocket/gateway/CaptivePortalConfig.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "message_handlers/impl/WSGateway.h" - -const char* const TAG = "ServerMessageHandlers"; - -#include "CaptivePortal.h" -#include "Logging.h" - -#include - -using namespace OpenShock::MessageHandlers::Server; - -void _Private::HandleCaptivePortalConfig(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) -{ - auto msg = root->payload_as_CaptivePortalConfig(); - if (msg == nullptr) { - OS_LOGE(TAG, "Payload cannot be parsed as CaptivePortalConfig"); - return; - } - - bool enabled = msg->enabled(); - - OS_LOGD(TAG, "Captive portal is %s", enabled ? "force enabled" : "normal"); - - OpenShock::CaptivePortal::SetAlwaysEnabled(enabled); -} diff --git a/src/message_handlers/websocket/gateway/OtaInstall.cpp b/src/message_handlers/websocket/gateway/OtaUpdateRequest.cpp similarity index 60% rename from src/message_handlers/websocket/gateway/OtaInstall.cpp rename to src/message_handlers/websocket/gateway/OtaUpdateRequest.cpp index 8faf5ef4..669df0eb 100644 --- a/src/message_handlers/websocket/gateway/OtaInstall.cpp +++ b/src/message_handlers/websocket/gateway/OtaUpdateRequest.cpp @@ -10,11 +10,11 @@ const char* const TAG = "ServerMessageHandlers"; using namespace OpenShock::MessageHandlers::Server; -void _Private::HandleOtaInstall(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) +void _Private::HandleOtaUpdateRequest(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) { - auto msg = root->payload_as_OtaInstall(); + auto msg = root->payload_as_OtaUpdateRequest(); if (msg == nullptr) { - OS_LOGE(TAG, "Payload cannot be parsed as OtaInstall"); + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdate"); return; } @@ -34,10 +34,10 @@ void _Private::HandleOtaInstall(const OpenShock::Serialization::Gateway::Gateway OpenShock::SemVer version(semver->major(), semver->minor(), semver->patch(), prerelease, build); - OS_LOGI(TAG, "OTA install requested for version %s", version.toString().c_str()); // TODO: This is abusing the SemVer::toString() method causing alot of string copies, fix this + OS_LOGI(TAG, "OTA update requested for version %s", version.toString().c_str()); // TODO: This is abusing the SemVer::toString() method causing alot of string copies, fix this - if (!OpenShock::OtaUpdateManager::TryStartFirmwareInstallation(version)) { - OS_LOGE(TAG, "Failed to install firmware"); // TODO: Send error message to server + if (!OpenShock::OtaUpdateManager::TryStartFirmwareUpdate(version)) { + OS_LOGE(TAG, "Failed to update firmware"); // TODO: Send error message to server return; } } diff --git a/src/message_handlers/websocket/gateway/Ping.cpp b/src/message_handlers/websocket/gateway/Ping.cpp new file mode 100644 index 00000000..a8a8f752 --- /dev/null +++ b/src/message_handlers/websocket/gateway/Ping.cpp @@ -0,0 +1,25 @@ +#include "message_handlers/impl/WSGateway.h" + +const char* const TAG = "ServerMessageHandlers"; + +#include "GatewayConnectionManager.h" +#include "Logging.h" +#include "serialization/WSGateway.h" + +#include + +using namespace OpenShock::MessageHandlers::Server; + +void _Private::HandlePing(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) +{ + auto msg = root->payload_as_Ping(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as Ping"); + return; + } + + OS_LOGV(TAG, "Unix time: %llu", msg->unix_utc_time()); + + OS_LOGV(TAG, "Sending Gateway pong message"); + Serialization::Gateway::SerializePongMessage(GatewayConnectionManager::SendMessageBIN); +} diff --git a/src/message_handlers/websocket/gateway/Trigger.cpp b/src/message_handlers/websocket/gateway/Trigger.cpp new file mode 100644 index 00000000..731f9f73 --- /dev/null +++ b/src/message_handlers/websocket/gateway/Trigger.cpp @@ -0,0 +1,49 @@ +#include "message_handlers/impl/WSGateway.h" + +const char* const TAG = "ServerMessageHandlers"; + +#include "CaptivePortal.h" +#include "EStopManager.h" +#include "Logging.h" + +#include + +#include + +using namespace OpenShock::MessageHandlers::Server; + +using TriggerType = OpenShock::Serialization::Gateway::TriggerType; + +void _Private::HandleTrigger(const OpenShock::Serialization::Gateway::GatewayToHubMessage* root) +{ + auto msg = root->payload_as_Trigger(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as Trigger"); + return; + } + + if (EStopManager::IsEStopped()) { + OS_LOGD(TAG, "Ignoring trigger command due to EmergencyStop being activated"); + return; + } + + auto triggerType = msg->type(); + + switch (triggerType) { + case TriggerType::Restart: + esp_restart(); + break; + case TriggerType::EmergencyStop: + EStopManager::Trigger(); + break; + case TriggerType::CaptivePortalEnable: + OpenShock::CaptivePortal::SetAlwaysEnabled(true); + break; + case TriggerType::CaptivePortalDisable: + OpenShock::CaptivePortal::SetAlwaysEnabled(false); + break; + default: + OS_LOGW(TAG, "Got unknown trigger type: %hhu", static_cast(triggerType)); + break; + } +} diff --git a/src/message_handlers/websocket/local/OtaUpdateCheckForUpdatesCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateCheckForUpdatesCommand.cpp new file mode 100644 index 00000000..0849357c --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateCheckForUpdatesCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateCheckForUpdatesCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateCheckForUpdatesCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateCheckForUpdatesCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateHandleUpdateRequestCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateHandleUpdateRequestCommand.cpp new file mode 100644 index 00000000..297f46e1 --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateHandleUpdateRequestCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateHandleUpdateRequestCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateHandleUpdateRequestCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateHandleUpdateRequestCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateSetAllowBackendManagementCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateSetAllowBackendManagementCommand.cpp new file mode 100644 index 00000000..d771c5e0 --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateSetAllowBackendManagementCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateSetAllowBackendManagementCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateSetAllowBackendManagementCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateSetAllowBackendManagementCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateSetCheckIntervalCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateSetCheckIntervalCommand.cpp new file mode 100644 index 00000000..b94071ed --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateSetCheckIntervalCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateSetCheckIntervalCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateSetCheckIntervalCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateSetCheckIntervalCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateSetDomainCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateSetDomainCommand.cpp new file mode 100644 index 00000000..640159c1 --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateSetDomainCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateSetDomainCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateSetDomainCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateSetDomainCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateSetIsEnabledCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateSetIsEnabledCommand.cpp new file mode 100644 index 00000000..e57b5108 --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateSetIsEnabledCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateSetIsEnabledCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateSetIsEnabledCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateSetIsEnabledCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateSetRequireManualApprovalCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateSetRequireManualApprovalCommand.cpp new file mode 100644 index 00000000..c403eaa6 --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateSetRequireManualApprovalCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateSetRequireManualApprovalCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateSetRequireManualApprovalCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateSetRequireManualApprovalCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateSetUpdateChannelCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateSetUpdateChannelCommand.cpp new file mode 100644 index 00000000..6000112f --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateSetUpdateChannelCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateSetUpdateChannelCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateSetUpdateChannelCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateSetUpdateChannelCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/OtaUpdateStartUpdateCommand.cpp b/src/message_handlers/websocket/local/OtaUpdateStartUpdateCommand.cpp new file mode 100644 index 00000000..e2f04073 --- /dev/null +++ b/src/message_handlers/websocket/local/OtaUpdateStartUpdateCommand.cpp @@ -0,0 +1,20 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +using namespace OpenShock::MessageHandlers::Local; + +void _Private::HandleOtaUpdateStartUpdateCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_OtaUpdateStartUpdateCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as OtaUpdateStartUpdateCommand"); + return; + } + + // TODO +} diff --git a/src/message_handlers/websocket/local/SetEStopEnabledCommand.cpp b/src/message_handlers/websocket/local/SetEStopEnabledCommand.cpp new file mode 100644 index 00000000..8435d2ba --- /dev/null +++ b/src/message_handlers/websocket/local/SetEStopEnabledCommand.cpp @@ -0,0 +1,60 @@ +#include "message_handlers/impl/WSLocal.h" + +#include "CaptivePortal.h" +#include "config/Config.h" +#include "EStopManager.h" +#include "Logging.h" + +#include + +const char* const TAG = "LocalMessageHandlers"; + +static void serializeResult(uint8_t socketId, bool enabled, bool success) +{ + flatbuffers::FlatBufferBuilder builder(1024); // TODO: Profile this + + auto responseOffset = OpenShock::Serialization::Local::CreateSetEstopEnabledCommandResult(builder, enabled, success); + + auto msg = OpenShock::Serialization::Local::CreateHubToLocalMessage(builder, OpenShock::Serialization::Local::HubToLocalMessagePayload::SetEstopEnabledCommandResult, responseOffset.Union()); + + OpenShock::Serialization::Local::FinishHubToLocalMessageBuffer(builder, msg); + + const uint8_t* buffer = builder.GetBufferPointer(); + uint8_t size = builder.GetSize(); + + OpenShock::CaptivePortal::SendMessageBIN(socketId, buffer, size); +} + +using namespace OpenShock::MessageHandlers::Local; + +static bool setEstopEnabled(bool enabled) +{ + if (!OpenShock::EStopManager::SetEStopEnabled(enabled)) { + OS_LOGE(TAG, "Failed to set EStop enabled"); + + return false; + } + + if (!OpenShock::Config::SetEStopEnabled(enabled)) { + OS_LOGE(TAG, "Failed to set EStop pin in config"); + + return false; + } + + return true; +} + +void _Private::HandleSetEstopEnabledCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +{ + auto msg = root->payload_as_SetEstopEnabledCommand(); + if (msg == nullptr) { + OS_LOGE(TAG, "Payload cannot be parsed as SetEstopEnabledCommand"); + return; + } + + bool enabled = msg->enabled(); + + bool success = setEstopEnabled(enabled); + + serializeResult(socketId, enabled, success); +} diff --git a/src/message_handlers/websocket/local/SetEStopPinCommand.cpp b/src/message_handlers/websocket/local/SetEStopPinCommand.cpp index 9f61ec55..3b06d9e8 100644 --- a/src/message_handlers/websocket/local/SetEStopPinCommand.cpp +++ b/src/message_handlers/websocket/local/SetEStopPinCommand.cpp @@ -1,19 +1,20 @@ #include "message_handlers/impl/WSLocal.h" #include "CaptivePortal.h" -#include "CommandHandler.h" -#include "Common.h" +#include "Chipset.h" +#include "config/Config.h" +#include "EStopManager.h" #include "Logging.h" #include const char* const TAG = "LocalMessageHandlers"; -void serializeSetEStopPinResult(uint8_t socketId, gpio_num_t pin, OpenShock::Serialization::Local::SetGPIOResultCode result) +static void serializeResult(uint8_t socketId, int8_t pin, OpenShock::Serialization::Local::SetGPIOResultCode result) { - flatbuffers::FlatBufferBuilder builder(1024); + flatbuffers::FlatBufferBuilder builder(1024); // TODO: Profile this - auto responseOffset = OpenShock::Serialization::Local::CreateSetEstopPinCommandResult(builder, static_cast(pin), result); + auto responseOffset = OpenShock::Serialization::Local::CreateSetEstopPinCommandResult(builder, pin, result); auto msg = OpenShock::Serialization::Local::CreateHubToLocalMessage(builder, OpenShock::Serialization::Local::HubToLocalMessagePayload::SetEstopPinCommandResult, responseOffset.Union()); @@ -27,6 +28,27 @@ void serializeSetEStopPinResult(uint8_t socketId, gpio_num_t pin, OpenShock::Ser using namespace OpenShock::MessageHandlers::Local; +static OpenShock::Serialization::Local::SetGPIOResultCode setEstopPin(int8_t pin) +{ + if (OpenShock::IsValidInputPin(pin)) { + if (!OpenShock::EStopManager::SetEStopPin(static_cast(pin))) { + OS_LOGE(TAG, "Failed to set EStop pin"); + + return OpenShock::Serialization::Local::SetGPIOResultCode::InternalError; + } + + if (!OpenShock::Config::SetEStopGpioPin(static_cast(pin))) { + OS_LOGE(TAG, "Failed to set EStop pin in config"); + + return OpenShock::Serialization::Local::SetGPIOResultCode::InternalError; + } + + return OpenShock::Serialization::Local::SetGPIOResultCode::Success; + } else { + return OpenShock::Serialization::Local::SetGPIOResultCode::InvalidPin; + } +} + void _Private::HandleSetEstopPinCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { auto msg = root->payload_as_SetEstopPinCommand(); @@ -35,9 +57,9 @@ void _Private::HandleSetEstopPinCommand(uint8_t socketId, const OpenShock::Seria return; } - auto pin = msg->pin(); + int8_t pin = msg->pin(); - auto result = OpenShock::CommandHandler::SetEStopPin(static_cast(pin)); + auto result = setEstopPin(pin); - serializeSetEStopPinResult(socketId, static_cast(pin), result); + serializeResult(socketId, pin, result); } diff --git a/src/message_handlers/websocket/local/WiFiNetworkConnectCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkConnectCommand.cpp index eb05e6a5..3f4a383b 100644 --- a/src/message_handlers/websocket/local/WiFiNetworkConnectCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkConnectCommand.cpp @@ -10,7 +10,7 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkConnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +void _Private::HandleWifiNetworkConnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { (void)socketId; diff --git a/src/message_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp index 1e04aad8..c8806606 100644 --- a/src/message_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkDisconnectCommand.cpp @@ -10,7 +10,7 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkDisconnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +void _Private::HandleWifiNetworkDisconnectCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { (void)socketId; diff --git a/src/message_handlers/websocket/local/WiFiNetworkForgetCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkForgetCommand.cpp index f1c4f8b5..e98672bd 100644 --- a/src/message_handlers/websocket/local/WiFiNetworkForgetCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkForgetCommand.cpp @@ -10,7 +10,7 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkForgetCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +void _Private::HandleWifiNetworkForgetCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { (void)socketId; diff --git a/src/message_handlers/websocket/local/WiFiNetworkSaveCommand.cpp b/src/message_handlers/websocket/local/WiFiNetworkSaveCommand.cpp index 70c0b453..aea2c3ff 100644 --- a/src/message_handlers/websocket/local/WiFiNetworkSaveCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiNetworkSaveCommand.cpp @@ -10,7 +10,7 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiNetworkSaveCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +void _Private::HandleWifiNetworkSaveCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { (void)socketId; diff --git a/src/message_handlers/websocket/local/WiFiScanCommand.cpp b/src/message_handlers/websocket/local/WiFiScanCommand.cpp index 8a4b3665..8d0c94cf 100644 --- a/src/message_handlers/websocket/local/WiFiScanCommand.cpp +++ b/src/message_handlers/websocket/local/WiFiScanCommand.cpp @@ -7,7 +7,7 @@ const char* const TAG = "LocalMessageHandlers"; using namespace OpenShock::MessageHandlers::Local; -void _Private::HandleWiFiScanCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) +void _Private::HandleWifiScanCommand(uint8_t socketId, const OpenShock::Serialization::Local::LocalToHubMessage* root) { (void)socketId; diff --git a/src/serialization/WSGateway.cpp b/src/serialization/WSGateway.cpp index 2791732e..93a1058f 100644 --- a/src/serialization/WSGateway.cpp +++ b/src/serialization/WSGateway.cpp @@ -2,25 +2,34 @@ const char* const TAG = "WSGateway"; +#include + #include "config/Config.h" #include "Logging.h" #include "Time.h" using namespace OpenShock::Serialization; -bool Gateway::SerializeKeepAliveMessage(Common::SerializationCallbackFn callback) { - flatbuffers::FlatBufferBuilder builder(256); // TODO: Profile this and adjust the size accordingly - +bool Gateway::SerializePongMessage(Common::SerializationCallbackFn callback) +{ int64_t uptime = OpenShock::millis(); if (uptime < 0) { OS_LOGE(TAG, "Failed to get uptime"); return false; } - Gateway::KeepAlive keepAlive(static_cast(uptime)); - auto keepAliveOffset = builder.CreateStruct(keepAlive); + int rssi; + esp_err_t err = esp_wifi_sta_get_rssi(&rssi); + if (err != ERR_OK) { + OS_LOGE(TAG, "Failed to get WiFi RSSI: %d", err); + return false; + } + + flatbuffers::FlatBufferBuilder builder(256); // TODO: Profile this and adjust the size accordingly + + auto pong = Gateway::CreatePong(builder, static_cast(uptime), static_cast(rssi)); - auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::KeepAlive, keepAliveOffset.Union()); + auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::Pong, pong.Union()); Gateway::FinishHubToGatewayMessageBuffer(builder, msg); @@ -29,10 +38,11 @@ bool Gateway::SerializeKeepAliveMessage(Common::SerializationCallbackFn callback return callback(span.data(), span.size()); } -bool Gateway::SerializeBootStatusMessage(int32_t updateId, OpenShock::FirmwareBootType bootType, const OpenShock::SemVer& version, Common::SerializationCallbackFn callback) { +bool Gateway::SerializeBootStatusMessage(int32_t updateId, OpenShock::FirmwareBootType bootType, Common::SerializationCallbackFn callback) +{ flatbuffers::FlatBufferBuilder builder(256); // TODO: Profile this and adjust the size accordingly - auto fbsVersion = Types::CreateSemVerDirect(builder, version.major, version.minor, version.patch, version.prerelease.data(), version.build.data()); + auto fbsVersion = Types::CreateSemVerDirect(builder, OPENSHOCK_FW_VERSION_MAJOR, OPENSHOCK_FW_VERSION_MINOR, OPENSHOCK_FW_VERSION_PATCH, OPENSHOCK_FW_VERSION_PRERELEASE, OPENSHOCK_FW_VERSION_BUILD); auto fbsBootStatus = Gateway::CreateBootStatus(builder, bootType, fbsVersion, updateId); @@ -45,14 +55,15 @@ bool Gateway::SerializeBootStatusMessage(int32_t updateId, OpenShock::FirmwareBo return callback(span.data(), span.size()); } -bool Gateway::SerializeOtaInstallStartedMessage(int32_t updateId, const OpenShock::SemVer& version, Common::SerializationCallbackFn callback) { +bool Gateway::SerializeOtaUpdateStartedMessage(int32_t updateId, const OpenShock::SemVer& version, Common::SerializationCallbackFn callback) +{ flatbuffers::FlatBufferBuilder builder(256); // TODO: Profile this and adjust the size accordingly auto versionOffset = Types::CreateSemVerDirect(builder, version.major, version.minor, version.patch, version.prerelease.data(), version.build.data()); - auto otaInstallStartedOffset = Gateway::CreateOtaInstallStarted(builder, updateId, versionOffset); + auto otaUpdateStartedOffset = Gateway::CreateOtaUpdateStarted(builder, updateId, versionOffset); - auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::OtaInstallStarted, otaInstallStartedOffset.Union()); + auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::OtaUpdateStarted, otaUpdateStartedOffset.Union()); Gateway::FinishHubToGatewayMessageBuffer(builder, msg); @@ -61,12 +72,13 @@ bool Gateway::SerializeOtaInstallStartedMessage(int32_t updateId, const OpenShoc return callback(span.data(), span.size()); } -bool Gateway::SerializeOtaInstallProgressMessage(int32_t updateId, Gateway::OtaInstallProgressTask task, float progress, Common::SerializationCallbackFn callback) { +bool Gateway::SerializeOtaUpdateProgressMessage(int32_t updateId, Types::OtaUpdateProgressTask task, float progress, Common::SerializationCallbackFn callback) +{ flatbuffers::FlatBufferBuilder builder(64); // TODO: Profile this and adjust the size accordingly - auto otaInstallProgressOffset = Gateway::CreateOtaInstallProgress(builder, updateId, task, progress); + auto otaUpdateProgressOffset = Gateway::CreateOtaUpdateProgress(builder, updateId, task, progress); - auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::OtaInstallProgress, otaInstallProgressOffset.Union()); + auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::OtaUpdateProgress, otaUpdateProgressOffset.Union()); Gateway::FinishHubToGatewayMessageBuffer(builder, msg); @@ -75,14 +87,15 @@ bool Gateway::SerializeOtaInstallProgressMessage(int32_t updateId, Gateway::OtaI return callback(span.data(), span.size()); } -bool Gateway::SerializeOtaInstallFailedMessage(int32_t updateId, std::string_view message, bool fatal, Common::SerializationCallbackFn callback) { +bool Gateway::SerializeOtaUpdateFailedMessage(int32_t updateId, std::string_view message, bool fatal, Common::SerializationCallbackFn callback) +{ flatbuffers::FlatBufferBuilder builder(256); // TODO: Profile this and adjust the size accordingly auto messageOffset = builder.CreateString(message.data(), message.size()); - auto otaInstallFailedOffset = Gateway::CreateOtaInstallFailed(builder, updateId, messageOffset, fatal); + auto otaUpdateFailedOffset = Gateway::CreateOtaUpdateFailed(builder, updateId, messageOffset, fatal); - auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::OtaInstallFailed, otaInstallFailedOffset.Union()); + auto msg = Gateway::CreateHubToGatewayMessage(builder, Gateway::HubToGatewayMessagePayload::OtaUpdateFailed, otaUpdateFailedOffset.Union()); Gateway::FinishHubToGatewayMessageBuffer(builder, msg); From 611343bb77c3c92d389782afe053160013965b9c Mon Sep 17 00:00:00 2001 From: Wil <98198668+Wilaz@users.noreply.github.com> Date: Tue, 12 Nov 2024 11:03:31 -0500 Subject: [PATCH 035/155] feat: :wrench: Add support for NodeMCU and uPesy (#312) * feat: :wrench: Add support for NodeMCU and uPesy Adds NodeMCU-32S and uPesy-ESP32 as build targets * Omit uPesy --- include/Chipset.h | 3 +++ platformio.ini | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/include/Chipset.h b/include/Chipset.h index 8e548cc8..65727738 100644 --- a/include/Chipset.h +++ b/include/Chipset.h @@ -207,6 +207,9 @@ #ifdef OPENSHOCK_FW_BOARD_DFROBOTFIREBEETLE2ESP32E #define OPENSHOCK_BYPASSED_GPIO(pin) ((pin) == 2 || (pin) == 5) #endif +#ifdef OPENSHOCK_FW_BOARD_NODEMCU32S +#define OPENSHOCK_BYPASSED_GPIO(pin) ((pin) == 2) +#endif #ifndef OPENSHOCK_BYPASSED_GPIO #define OPENSHOCK_BYPASSED_GPIO(pin) (false) #endif diff --git a/platformio.ini b/platformio.ini index 635d84cf..65f58785 100644 --- a/platformio.ini +++ b/platformio.ini @@ -156,6 +156,13 @@ build_flags = ${env.build_flags} -DOPENSHOCK_ESTOP_PIN=38 -DARDUINO_USB_CDC_ON_BOOT=1 +; https://docs.platformio.org/en/stable/boards/espressif32/nodemcu-32s.html +[env:NodeMCU-32S] +board = nodemcu-32s +custom_openshock.chip = ESP32 +build_flags = ${env.build_flags} + -DOPENSHOCK_LED_GPIO=2 + ; TODO: ; https://docs.platformio.org/en/latest/boards/espressif32/upesy_wroom.html;upesy-esp32-wroom-devkit From 5c0eb0998d853b95d4f7adefccb1df0da3dfa490 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Fri, 15 Nov 2024 10:16:03 +0100 Subject: [PATCH 036/155] Handle ratelimiting properly for Account Link request --- frontend/src/lib/MessageHandlers/index.ts | 7 ++++++- .../serialization/local/account-link-result-code.ts | 3 ++- include/serialization/_fbs/HubToLocalMessage_generated.h | 9 ++++++--- schemas | 2 +- src/GatewayConnectionManager.cpp | 3 ++- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/frontend/src/lib/MessageHandlers/index.ts b/frontend/src/lib/MessageHandlers/index.ts index 098d1530..808c54b8 100644 --- a/frontend/src/lib/MessageHandlers/index.ts +++ b/frontend/src/lib/MessageHandlers/index.ts @@ -25,7 +25,9 @@ function handleInvalidMessage() { } const PayloadTypes = Object.keys(HubToLocalMessagePayload).length / 2; -const PayloadHandlers: MessageHandler[] = new Array(PayloadTypes).fill(handleInvalidMessage); +const PayloadHandlers: MessageHandler[] = new Array(PayloadTypes).fill( + handleInvalidMessage +); PayloadHandlers[HubToLocalMessagePayload.ReadyMessage] = (cli, msg) => { const payload = new ReadyMessage(); @@ -109,6 +111,9 @@ PayloadHandlers[HubToLocalMessagePayload.AccountLinkCommandResult] = (cli, msg) case AccountLinkResultCode.InvalidCode: reason = 'Invalid code'; break; + case AccountLinkResultCode.RateLimited: + reason = 'Too many requests'; + break; case AccountLinkResultCode.InternalError: reason = 'Internal error'; break; diff --git a/frontend/src/lib/_fbs/open-shock/serialization/local/account-link-result-code.ts b/frontend/src/lib/_fbs/open-shock/serialization/local/account-link-result-code.ts index 48872d5b..a4a3c9cb 100644 --- a/frontend/src/lib/_fbs/open-shock/serialization/local/account-link-result-code.ts +++ b/frontend/src/lib/_fbs/open-shock/serialization/local/account-link-result-code.ts @@ -8,5 +8,6 @@ export enum AccountLinkResultCode { InvalidCodeLength = 2, NoInternetConnection = 3, InvalidCode = 4, - InternalError = 5 + RateLimited = 5, + InternalError = 6 } diff --git a/include/serialization/_fbs/HubToLocalMessage_generated.h b/include/serialization/_fbs/HubToLocalMessage_generated.h index a6b68fdb..b9b88635 100644 --- a/include/serialization/_fbs/HubToLocalMessage_generated.h +++ b/include/serialization/_fbs/HubToLocalMessage_generated.h @@ -61,30 +61,33 @@ enum class AccountLinkResultCode : uint8_t { InvalidCodeLength = 2, NoInternetConnection = 3, InvalidCode = 4, - InternalError = 5, + RateLimited = 5, + InternalError = 6, MIN = Success, MAX = InternalError }; -inline const AccountLinkResultCode (&EnumValuesAccountLinkResultCode())[6] { +inline const AccountLinkResultCode (&EnumValuesAccountLinkResultCode())[7] { static const AccountLinkResultCode values[] = { AccountLinkResultCode::Success, AccountLinkResultCode::CodeRequired, AccountLinkResultCode::InvalidCodeLength, AccountLinkResultCode::NoInternetConnection, AccountLinkResultCode::InvalidCode, + AccountLinkResultCode::RateLimited, AccountLinkResultCode::InternalError }; return values; } inline const char * const *EnumNamesAccountLinkResultCode() { - static const char * const names[7] = { + static const char * const names[8] = { "Success", "CodeRequired", "InvalidCodeLength", "NoInternetConnection", "InvalidCode", + "RateLimited", "InternalError", nullptr }; diff --git a/schemas b/schemas index 9257c6da..d3dc67c2 160000 --- a/schemas +++ b/schemas @@ -1 +1 @@ -Subproject commit 9257c6dac8801d13179323dae399039d5d57a4c8 +Subproject commit d3dc67c2deab9000d88337b670d2fcea4ae708be diff --git a/src/GatewayConnectionManager.cpp b/src/GatewayConnectionManager.cpp index a42f147f..de2ac417 100644 --- a/src/GatewayConnectionManager.cpp +++ b/src/GatewayConnectionManager.cpp @@ -97,7 +97,8 @@ AccountLinkResultCode GatewayConnectionManager::Link(std::string_view linkCode) auto response = HTTP::JsonAPI::LinkAccount(linkCode); if (response.result == HTTP::RequestResult::RateLimited) { - return AccountLinkResultCode::InternalError; // Just return false, don't spam the console with errors + OS_LOGW(TAG, "Account Link request got ratelimited"); + return AccountLinkResultCode::RateLimited; } if (response.result != HTTP::RequestResult::Success) { OS_LOGE(TAG, "Error while getting auth token: %d %d", response.result, response.code); From 554f36f072de63fd1fe86b5a1adefbf9e98349f9 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Fri, 15 Nov 2024 15:04:15 +0100 Subject: [PATCH 037/155] Fix and abstract away HTTP RateLimiter --- include/RateLimiter.h | 38 ++++++++++ src/RateLimiter.cpp | 121 ++++++++++++++++++++++++++++++++ src/http/HTTPRequestManager.cpp | 116 +++--------------------------- 3 files changed, 170 insertions(+), 105 deletions(-) create mode 100644 include/RateLimiter.h create mode 100644 src/RateLimiter.cpp diff --git a/include/RateLimiter.h b/include/RateLimiter.h new file mode 100644 index 00000000..13654ae1 --- /dev/null +++ b/include/RateLimiter.h @@ -0,0 +1,38 @@ +#pragma once + +#include "Common.h" +#include "SimpleMutex.h" + +#include +#include + +namespace OpenShock { + class RateLimiter { + DISABLE_COPY(RateLimiter); + DISABLE_MOVE(RateLimiter); + + public: + RateLimiter(); + ~RateLimiter(); + + void addLimit(uint32_t durationMs, uint16_t count); + void clearLimits(); + + bool tryRequest(); + void clearRequests(); + + void blockFor(int64_t blockForMs); + + private: + struct Limit { + int64_t durationMs; + uint16_t count; + }; + + OpenShock::SimpleMutex m_mutex; + int64_t m_nextSlot; + int64_t m_nextCleanup; + std::vector m_limits; + std::vector m_requests; + }; +} // namespace OpenShock diff --git a/src/RateLimiter.cpp b/src/RateLimiter.cpp new file mode 100644 index 00000000..b53c4fad --- /dev/null +++ b/src/RateLimiter.cpp @@ -0,0 +1,121 @@ +#include + +#include "RateLimiter.h" + +#include "Time.h" + +#include + +const char* const TAG = "RateLimiter"; + +OpenShock::RateLimiter::RateLimiter() + : m_mutex() + , m_nextSlot(0) + , m_nextCleanup(0) + , m_limits() + , m_requests() +{ +} + +OpenShock::RateLimiter::~RateLimiter() +{ +} + +void OpenShock::RateLimiter::addLimit(uint32_t durationMs, uint16_t count) +{ + m_mutex.lock(portMAX_DELAY); + + // Insert sorted + m_limits.insert(std::upper_bound(m_limits.begin(), m_limits.end(), durationMs, [](int64_t durationMs, const Limit& limit) { return durationMs < limit.durationMs; }), {durationMs, count}); + + m_nextSlot = 0; + m_nextCleanup = 0; + + m_mutex.unlock(); +} + +void OpenShock::RateLimiter::clearLimits() +{ + m_mutex.lock(portMAX_DELAY); + + m_limits.clear(); + + m_mutex.unlock(); +} + +bool OpenShock::RateLimiter::tryRequest() +{ + int64_t now = OpenShock::millis(); + + OpenShock::ScopedLock lock__(&m_mutex); + + if (m_limits.empty()) { + return true; + } + if (m_requests.empty()) { + m_requests.push_back(now); + return true; + } + + if (m_nextCleanup <= now) { + int64_t longestLimit = m_limits.back().durationMs; + int64_t expiresAt = now - longestLimit; + + auto nextToExpire = std::find_if(m_requests.begin(), m_requests.end(), [expiresAt](int64_t requestedAtMs) { return requestedAtMs > expiresAt; }); + if (nextToExpire != m_requests.end()) { + m_requests.erase(m_requests.begin(), nextToExpire); + } + + m_nextCleanup = m_requests.front() + longestLimit; + } + + if (m_nextSlot > now) { + return false; + } + + // Check if we've exceeded any limits, starting with the highest limit first + for (std::size_t i = m_limits.size(); i > 0;) { + const auto& limit = m_limits[--i]; + + // Calculate the window start time + int64_t windowStart = now - limit.durationMs; + + // Check how many requests are inside the limit window + std::size_t insideWindow = 0; + for (int64_t request : m_requests) { + if (request > windowStart) { + insideWindow++; + } + } + + // If the window is full, set the wait time until its available, and reject the request + if (insideWindow >= limit.count) { + m_nextSlot = m_requests.back() + limit.durationMs; + return false; + } + } + + // Add the request + m_requests.push_back(now); + + return true; +} +void OpenShock::RateLimiter::clearRequests() +{ + m_mutex.lock(portMAX_DELAY); + + m_requests.clear(); + + m_mutex.unlock(); +} + +void OpenShock::RateLimiter::blockFor(int64_t blockForMs) +{ + int64_t blockUntil = OpenShock::millis() + blockForMs; + + m_mutex.lock(portMAX_DELAY); + + m_nextSlot = std::max(m_nextSlot, blockUntil); + + m_mutex.unlock(); +} diff --git a/src/http/HTTPRequestManager.cpp b/src/http/HTTPRequestManager.cpp index 9ed9d704..4804d53d 100644 --- a/src/http/HTTPRequestManager.cpp +++ b/src/http/HTTPRequestManager.cpp @@ -4,6 +4,7 @@ const char* const TAG = "HTTPRequestManager"; #include "Common.h" #include "Logging.h" +#include "RateLimiter.h" #include "SimpleMutex.h" #include "Time.h" #include "util/StringUtils.h" @@ -22,100 +23,8 @@ using namespace std::string_view_literals; const std::size_t HTTP_BUFFER_SIZE = 4096LLU; const int HTTP_DOWNLOAD_SIZE_LIMIT = 200 * 1024 * 1024; // 200 MB -struct RateLimit { - RateLimit() - : m_mutex() - , m_blockUntilMs(0) - , m_limits() - , m_requests() - { - } - - void addLimit(uint32_t durationMs, uint16_t count) - { - m_mutex.lock(portMAX_DELAY); - - // Insert sorted - m_limits.insert(std::upper_bound(m_limits.begin(), m_limits.end(), durationMs, [](int64_t durationMs, const Limit& limit) { return durationMs > limit.durationMs; }), {durationMs, count}); - - m_mutex.unlock(); - } - - void clearLimits() - { - m_mutex.lock(portMAX_DELAY); - - m_limits.clear(); - - m_mutex.unlock(); - } - - bool tryRequest() - { - int64_t now = OpenShock::millis(); - - OpenShock::ScopedLock lock__(&m_mutex); - - if (m_blockUntilMs > now) { - return false; - } - - // Remove all requests that are older than the biggest limit - while (!m_requests.empty() && m_requests.front() < now - m_limits.back().durationMs) { - m_requests.erase(m_requests.begin()); - } - - // Check if we've exceeded any limits - auto it = std::find_if(m_limits.begin(), m_limits.end(), [this](const RateLimit::Limit& limit) { return m_requests.size() >= limit.count; }); - if (it != m_limits.end()) { - m_blockUntilMs = now + it->durationMs; - return false; - } - - // Add the request - m_requests.push_back(now); - - return true; - } - void clearRequests() - { - m_mutex.lock(portMAX_DELAY); - - m_requests.clear(); - - m_mutex.unlock(); - } - - void blockUntil(int64_t blockUntilMs) - { - m_mutex.lock(portMAX_DELAY); - - m_blockUntilMs = blockUntilMs; - - m_mutex.unlock(); - } - - uint32_t requestsSince(int64_t sinceMs) - { - OpenShock::ScopedLock lock__(&m_mutex); - - return std::count_if(m_requests.begin(), m_requests.end(), [sinceMs](int64_t requestMs) { return requestMs >= sinceMs; }); - } - -private: - struct Limit { - int64_t durationMs; - uint16_t count; - }; - - OpenShock::SimpleMutex m_mutex; - int64_t m_blockUntilMs; - std::vector m_limits; - std::vector m_requests; -}; - -static OpenShock::SimpleMutex s_rateLimitsMutex = {}; -static std::unordered_map> s_rateLimits = {}; +static OpenShock::SimpleMutex s_rateLimitsMutex = {}; +static std::unordered_map> s_rateLimits = {}; using namespace OpenShock; @@ -156,9 +65,9 @@ std::string_view _getDomain(std::string_view url) return url; } -std::shared_ptr _rateLimitFactory(std::string_view domain) +std::shared_ptr _rateLimiterFactory(std::string_view domain) { - auto rateLimit = std::make_shared(); + auto rateLimit = std::make_shared(); // Add default limits rateLimit->addLimit(1000, 5); // 5 per second @@ -173,7 +82,7 @@ std::shared_ptr _rateLimitFactory(std::string_view domain) return rateLimit; } -std::shared_ptr _getRateLimiter(std::string_view url) +std::shared_ptr _getRateLimiter(std::string_view url) { auto domain = std::string(_getDomain(url)); if (domain.empty()) { @@ -184,7 +93,7 @@ std::shared_ptr _getRateLimiter(std::string_view url) auto it = s_rateLimits.find(domain); if (it == s_rateLimits.end()) { - s_rateLimits.emplace(domain, _rateLimitFactory(domain)); + s_rateLimits.emplace(domain, _rateLimiterFactory(domain)); it = s_rateLimits.find(domain); } @@ -469,7 +378,7 @@ HTTP::Response _doGetStream( std::string_view url, const std::map& headers, const std::vector& acceptedCodes, - std::shared_ptr rateLimiter, + std::shared_ptr rateLimiter, HTTP::GotContentLengthCallback contentLengthCallback, HTTP::DownloadCallback downloadCallback, uint32_t timeoutMs @@ -509,11 +418,8 @@ HTTP::Response _doGetStream( retryAfter = 15; } - // Get the block-until time - int64_t blockUntilMs = OpenShock::millis() + retryAfter * 1000; - - // Apply the block-until time - rateLimiter->blockUntil(blockUntilMs); + // Apply the block-for time + rateLimiter->blockFor(retryAfter * 1000); return {HTTP::RequestResult::RateLimited, responseCode, 0}; } @@ -563,7 +469,7 @@ HTTP::Response _doGetStream( HTTP::Response HTTP::Download(std::string_view url, const std::map& headers, HTTP::GotContentLengthCallback contentLengthCallback, HTTP::DownloadCallback downloadCallback, const std::vector& acceptedCodes, uint32_t timeoutMs) { - std::shared_ptr rateLimiter = _getRateLimiter(url); + std::shared_ptr rateLimiter = _getRateLimiter(url); if (rateLimiter == nullptr) { return {RequestResult::InvalidURL, 0, 0}; } From 137a1992332b99ae08d49a2aa21bbd95c1b03f6d Mon Sep 17 00:00:00 2001 From: hhvrc Date: Fri, 15 Nov 2024 15:54:22 +0100 Subject: [PATCH 038/155] Clean up Hashing.h --- include/Hashing.h | 82 +++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/include/Hashing.h b/include/Hashing.h index 1443a51d..fc68f144 100644 --- a/include/Hashing.h +++ b/include/Hashing.h @@ -1,40 +1,58 @@ #pragma once +#include "Common.h" + #include #include #include -#include +#include // TODO: When we use C++20, change this to +#include namespace OpenShock { -struct MD5 { - MD5() { mbedtls_md5_init(&ctx); } - ~MD5() { mbedtls_md5_free(&ctx); } - - bool begin() { return mbedtls_md5_starts_ret(&ctx) == 0; } - bool update(const uint8_t* data, std::size_t dataLen) { return mbedtls_md5_update_ret(&ctx, data, dataLen) == 0; } - bool finish(std::array& hash) { return mbedtls_md5_finish_ret(&ctx, hash.data()) == 0; } - - mbedtls_md5_context ctx; -}; -struct SHA1 { - SHA1() { mbedtls_sha1_init(&ctx); } - ~SHA1() { mbedtls_sha1_free(&ctx); } - - bool begin() { return mbedtls_sha1_starts_ret(&ctx) == 0; } - bool update(const uint8_t* data, std::size_t dataLen) { return mbedtls_sha1_update_ret(&ctx, data, dataLen) == 0; } - bool finish(std::array& hash) { return mbedtls_sha1_finish_ret(&ctx, hash.data()) == 0; } - - mbedtls_sha1_context ctx; -}; -struct SHA256 { - SHA256() { mbedtls_sha256_init(&ctx); } - ~SHA256() { mbedtls_sha256_free(&ctx); } - - bool begin() { return mbedtls_sha256_starts_ret(&ctx, 0) == 0; } - bool update(const uint8_t* data, std::size_t dataLen) { return mbedtls_sha256_update_ret(&ctx, data, dataLen) == 0; } - bool finish(std::array& hash) { return mbedtls_sha256_finish_ret(&ctx, hash.data()) == 0; } - - mbedtls_sha256_context ctx; -}; -} // namespace OpenShock + class MD5 { + DISABLE_COPY(MD5); + DISABLE_MOVE(MD5); + + public: + MD5() { mbedtls_md5_init(&ctx); } + ~MD5() { mbedtls_md5_free(&ctx); } + + inline bool begin() { return mbedtls_md5_starts_ret(&ctx) == 0; } + inline bool update(const uint8_t* data, std::size_t dataLen) { return mbedtls_md5_update_ret(&ctx, data, dataLen) == 0; } + inline bool finish(std::array& hash) { return mbedtls_md5_finish_ret(&ctx, hash.data()) == 0; } + + private: + mbedtls_md5_context ctx; + }; + class SHA1 { + DISABLE_COPY(SHA1); + DISABLE_MOVE(SHA1); + + public: + SHA1() { mbedtls_sha1_init(&ctx); } + ~SHA1() { mbedtls_sha1_free(&ctx); } + + inline bool begin() { return mbedtls_sha1_starts_ret(&ctx) == 0; } + inline bool update(const uint8_t* data, std::size_t dataLen) { return mbedtls_sha1_update_ret(&ctx, data, dataLen) == 0; } + inline bool finish(std::array& hash) { return mbedtls_sha1_finish_ret(&ctx, hash.data()) == 0; } + + private: + mbedtls_sha1_context ctx; + }; + class SHA256 { + DISABLE_COPY(SHA256); + DISABLE_MOVE(SHA256); + + public: + SHA256() { mbedtls_sha256_init(&ctx); } + ~SHA256() { mbedtls_sha256_free(&ctx); } + + inline bool begin() { return mbedtls_sha256_starts_ret(&ctx, 0) == 0; } + inline bool update(const uint8_t* data, std::size_t dataLen) { return mbedtls_sha256_update_ret(&ctx, data, dataLen) == 0; } + inline bool finish(std::array& hash) { return mbedtls_sha256_finish_ret(&ctx, hash.data()) == 0; } + + private: + mbedtls_sha256_context ctx; + }; +} // namespace OpenShock From c81d86ca95348eabc4db0d694173d47948558f26 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Fri, 15 Nov 2024 17:28:46 +0100 Subject: [PATCH 039/155] Clean up Checksum.h --- include/Checksum.h | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/include/Checksum.h b/include/Checksum.h index 66509115..a190d9a9 100644 --- a/include/Checksum.h +++ b/include/Checksum.h @@ -2,8 +2,23 @@ #include +#if __cplusplus >= 202'002L +#error Take into use C++20 std::integral instead of this macro logic +#endif + +#define SUM8_INT_FN(Type) \ + constexpr uint8_t Sum8(Type data) \ + { \ + uint8_t result = 0; \ + for (int i = 0; i < sizeof(Type); ++i) { \ + result += static_cast((data >> (i * 8)) & 0xFF); \ + } \ + return result; \ + } + namespace OpenShock::Checksum { - constexpr uint8_t Sum8(const uint8_t* data, std::size_t size) { + constexpr uint8_t Sum8(const uint8_t* data, std::size_t size) + { uint8_t checksum = 0; for (std::size_t i = 0; i < size; ++i) { checksum += data[i]; @@ -11,7 +26,17 @@ namespace OpenShock::Checksum { return checksum; } template - constexpr uint8_t Sum8(T data) { - return Sum8(reinterpret_cast(&data), sizeof(T)); + constexpr uint8_t Sum8(const T& data) + { + return Sum8(reinterpret_cast(std::addressof(data)), sizeof(T)); } + + SUM8_INT_FN(int16_t) + SUM8_INT_FN(uint16_t) + SUM8_INT_FN(int32_t) + SUM8_INT_FN(uint32_t) + SUM8_INT_FN(int64_t) + SUM8_INT_FN(uint64_t) } // namespace OpenShock::Checksum + +#undef SUM8_INT_FN From 8aafec9082a2cd1f0a75c6900368012bda02db62 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Fri, 15 Nov 2024 17:38:36 +0100 Subject: [PATCH 040/155] Disable move and copy on classes --- include/CaptivePortalInstance.h | 4 +++ include/GatewayClient.h | 4 +++ include/PinPatternManager.h | 1 + include/RGBPatternManager.h | 1 + include/ReadWriteMutex.h | 44 +++++++++++++++++++-------------- include/WebSocketDeFragger.h | 8 +++--- include/radio/RFTransmitter.h | 4 +++ 7 files changed, 44 insertions(+), 22 deletions(-) diff --git a/include/CaptivePortalInstance.h b/include/CaptivePortalInstance.h index 4b0c4fa5..782c77a5 100644 --- a/include/CaptivePortalInstance.h +++ b/include/CaptivePortalInstance.h @@ -1,5 +1,6 @@ #pragma once +#include "Common.h" #include "WebSocketDeFragger.h" #include @@ -14,6 +15,9 @@ namespace OpenShock { class CaptivePortalInstance { + DISABLE_COPY(CaptivePortalInstance); + DISABLE_MOVE(CaptivePortalInstance); + public: CaptivePortalInstance(); ~CaptivePortalInstance(); diff --git a/include/GatewayClient.h b/include/GatewayClient.h index c131c76c..fa530938 100644 --- a/include/GatewayClient.h +++ b/include/GatewayClient.h @@ -1,5 +1,6 @@ #pragma once +#include "Common.h" #include "GatewayClientState.h" #include @@ -11,6 +12,9 @@ namespace OpenShock { class GatewayClient { + DISABLE_COPY(GatewayClient); + DISABLE_MOVE(GatewayClient); + public: GatewayClient(const std::string& authToken); ~GatewayClient(); diff --git a/include/PinPatternManager.h b/include/PinPatternManager.h index 29dad47f..75f88200 100644 --- a/include/PinPatternManager.h +++ b/include/PinPatternManager.h @@ -13,6 +13,7 @@ namespace OpenShock { class PinPatternManager { DISABLE_COPY(PinPatternManager); + DISABLE_MOVE(PinPatternManager); public: struct State { diff --git a/include/RGBPatternManager.h b/include/RGBPatternManager.h index e98e1760..6d8c15b7 100644 --- a/include/RGBPatternManager.h +++ b/include/RGBPatternManager.h @@ -15,6 +15,7 @@ namespace OpenShock { class RGBPatternManager { DISABLE_COPY(RGBPatternManager); + DISABLE_MOVE(RGBPatternManager); public: RGBPatternManager() = delete; diff --git a/include/ReadWriteMutex.h b/include/ReadWriteMutex.h index 2f4e1ad6..70768e45 100644 --- a/include/ReadWriteMutex.h +++ b/include/ReadWriteMutex.h @@ -8,6 +8,7 @@ namespace OpenShock { class ReadWriteMutex { DISABLE_COPY(ReadWriteMutex); DISABLE_MOVE(ReadWriteMutex); + public: ReadWriteMutex(); ~ReadWriteMutex(); @@ -17,6 +18,7 @@ namespace OpenShock { bool lockWrite(TickType_t xTicksToWait); void unlockWrite(); + private: SemaphoreHandle_t m_mutex; SemaphoreHandle_t m_readSem; @@ -26,8 +28,11 @@ namespace OpenShock { class ScopedReadLock { DISABLE_COPY(ScopedReadLock); DISABLE_MOVE(ScopedReadLock); + public: - ScopedReadLock(ReadWriteMutex* mutex, TickType_t xTicksToWait = portMAX_DELAY) : m_mutex(mutex) { + ScopedReadLock(ReadWriteMutex* mutex, TickType_t xTicksToWait = portMAX_DELAY) + : m_mutex(mutex) + { bool result = false; if (m_mutex != nullptr) { result = m_mutex->lockRead(xTicksToWait); @@ -38,17 +43,17 @@ namespace OpenShock { } } - ~ScopedReadLock() { + ~ScopedReadLock() + { if (m_mutex != nullptr) { m_mutex->unlockRead(); } } - bool isLocked() const { - return m_mutex != nullptr; - } + bool isLocked() const { return m_mutex != nullptr; } - bool unlock() { + bool unlock() + { if (m_mutex != nullptr) { m_mutex->unlockRead(); m_mutex = nullptr; @@ -58,9 +63,8 @@ namespace OpenShock { return false; } - ReadWriteMutex* getMutex() const { - return m_mutex; - } + ReadWriteMutex* getMutex() const { return m_mutex; } + private: ReadWriteMutex* m_mutex; }; @@ -68,8 +72,11 @@ namespace OpenShock { class ScopedWriteLock { DISABLE_COPY(ScopedWriteLock); DISABLE_MOVE(ScopedWriteLock); + public: - ScopedWriteLock(ReadWriteMutex* mutex, TickType_t xTicksToWait = portMAX_DELAY) : m_mutex(mutex) { + ScopedWriteLock(ReadWriteMutex* mutex, TickType_t xTicksToWait = portMAX_DELAY) + : m_mutex(mutex) + { bool result = false; if (m_mutex != nullptr) { result = m_mutex->lockWrite(xTicksToWait); @@ -80,17 +87,17 @@ namespace OpenShock { } } - ~ScopedWriteLock() { + ~ScopedWriteLock() + { if (m_mutex != nullptr) { m_mutex->unlockWrite(); } } - bool isLocked() const { - return m_mutex != nullptr; - } + bool isLocked() const { return m_mutex != nullptr; } - bool unlock() { + bool unlock() + { if (m_mutex != nullptr) { m_mutex->unlockWrite(); m_mutex = nullptr; @@ -100,10 +107,9 @@ namespace OpenShock { return false; } - ReadWriteMutex* getMutex() const { - return m_mutex; - } + ReadWriteMutex* getMutex() const { return m_mutex; } + private: ReadWriteMutex* m_mutex; }; -} // namespace OpenShock +} // namespace OpenShock diff --git a/include/WebSocketDeFragger.h b/include/WebSocketDeFragger.h index 1ad54313..fa85d037 100644 --- a/include/WebSocketDeFragger.h +++ b/include/WebSocketDeFragger.h @@ -5,15 +5,16 @@ #include -#include #include #include +#include namespace OpenShock { class WebSocketDeFragger { DISABLE_COPY(WebSocketDeFragger); - public: + DISABLE_MOVE(WebSocketDeFragger); + public: typedef std::function EventCallback; WebSocketDeFragger(EventCallback callback); @@ -23,6 +24,7 @@ namespace OpenShock { void onEvent(const EventCallback& callback); void clear(uint8_t socketId); void clear(); + private: void start(uint8_t socketId, WebSocketMessageType type, const uint8_t* data, uint32_t length); void append(uint8_t socketId, const uint8_t* data, uint32_t length); @@ -38,4 +40,4 @@ namespace OpenShock { std::map m_messages; EventCallback m_callback; }; -} +} // namespace OpenShock diff --git a/include/radio/RFTransmitter.h b/include/radio/RFTransmitter.h index 80d56d14..893ff951 100644 --- a/include/radio/RFTransmitter.h +++ b/include/radio/RFTransmitter.h @@ -1,5 +1,6 @@ #pragma once +#include "Common.h" #include "ShockerCommandType.h" #include "ShockerModelType.h" @@ -13,6 +14,9 @@ namespace OpenShock { class RFTransmitter { + DISABLE_COPY(RFTransmitter); + DISABLE_MOVE(RFTransmitter); + public: RFTransmitter(gpio_num_t gpioPin); ~RFTransmitter(); From 68732c4b65cd59026d45bc59880a768fa34814c3 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Sat, 16 Nov 2024 00:29:41 +0100 Subject: [PATCH 041/155] Fix timing inaccuracies for CaiXianlin encoder --- src/radio/rmt/CaiXianlinEncoder.cpp | 33 +++++++++++++++-------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/radio/rmt/CaiXianlinEncoder.cpp b/src/radio/rmt/CaiXianlinEncoder.cpp index 18ef4737..fad8f7d2 100644 --- a/src/radio/rmt/CaiXianlinEncoder.cpp +++ b/src/radio/rmt/CaiXianlinEncoder.cpp @@ -9,30 +9,31 @@ // It is based on the following documentation: // https://wiki.openshock.org/hardware/shockers/caixianlin/#rf-specification -const rmt_data_t kRmtPreamble = {1400, 1, 800, 0}; -const rmt_data_t kRmtOne = {800, 1, 300, 0}; -const rmt_data_t kRmtZero = {300, 1, 800, 0}; +const rmt_data_t kRmtPreamble = {1400, 1, 750, 0}; +const rmt_data_t kRmtOne = {750, 1, 250, 0}; +const rmt_data_t kRmtZero = {250, 1, 750, 0}; using namespace OpenShock; -std::vector Rmt::CaiXianlinEncoder::GetSequence(uint16_t transmitterId, uint8_t channelId, ShockerCommandType type, uint8_t intensity) { +std::vector Rmt::CaiXianlinEncoder::GetSequence(uint16_t transmitterId, uint8_t channelId, ShockerCommandType type, uint8_t intensity) +{ // Intensity must be between 0 and 99 intensity = std::min(intensity, static_cast(99)); uint8_t typeVal = 0; switch (type) { - case ShockerCommandType::Shock: - typeVal = 0x01; - break; - case ShockerCommandType::Vibrate: - typeVal = 0x02; - break; - case ShockerCommandType::Sound: - typeVal = 0x03; - intensity = 0; // Sound intensity must be 0 for some shockers, otherwise it wont work, or they soft lock until restarted - break; - default: - return {}; // Invalid type + case ShockerCommandType::Shock: + typeVal = 0x01; + break; + case ShockerCommandType::Vibrate: + typeVal = 0x02; + break; + case ShockerCommandType::Sound: + typeVal = 0x03; + intensity = 0; // Sound intensity must be 0 for some shockers, otherwise it wont work, or they soft lock until restarted + break; + default: + return {}; // Invalid type } // Payload layout: [transmitterId:16][channelId:4][type:4][intensity:8] From 917a5e8f6d6470c35ffd7455b5a810f0ffff1fac Mon Sep 17 00:00:00 2001 From: hhvrc Date: Sat, 16 Nov 2024 00:30:32 +0100 Subject: [PATCH 042/155] Increase stack depth of SerialRX task --- src/serial/SerialInputHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/serial/SerialInputHandler.cpp b/src/serial/SerialInputHandler.cpp index bf65ce17..45bb7819 100644 --- a/src/serial/SerialInputHandler.cpp +++ b/src/serial/SerialInputHandler.cpp @@ -597,7 +597,7 @@ bool SerialInputHandler::Init() return false; } - if (TaskUtils::TaskCreateExpensive(_serialRxTask, "SerialRX", 3200, nullptr, 1, nullptr) != pdPASS) { // Profiled: 2.96KB stack usage + if (TaskUtils::TaskCreateExpensive(_serialRxTask, "SerialRX", 4800, nullptr, 1, nullptr) != pdPASS) { // TODO: Profile stack size OS_LOGE(TAG, "Failed to create serial RX task"); return false; } From ad90a531331e246f5bbe6c5c9ffe6acd5d6e8b9a Mon Sep 17 00:00:00 2001 From: hhvrc Date: Sat, 16 Nov 2024 01:00:55 +0100 Subject: [PATCH 043/155] Remove ping handler logging --- src/message_handlers/websocket/gateway/Ping.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/message_handlers/websocket/gateway/Ping.cpp b/src/message_handlers/websocket/gateway/Ping.cpp index a8a8f752..55d5ddf8 100644 --- a/src/message_handlers/websocket/gateway/Ping.cpp +++ b/src/message_handlers/websocket/gateway/Ping.cpp @@ -18,8 +18,5 @@ void _Private::HandlePing(const OpenShock::Serialization::Gateway::GatewayToHubM return; } - OS_LOGV(TAG, "Unix time: %llu", msg->unix_utc_time()); - - OS_LOGV(TAG, "Sending Gateway pong message"); Serialization::Gateway::SerializePongMessage(GatewayConnectionManager::SendMessageBIN); } From 99da6dd2b74cdb12e513579cbf538c61cb17e81f Mon Sep 17 00:00:00 2001 From: hhvrc Date: Sat, 16 Nov 2024 01:01:47 +0100 Subject: [PATCH 044/155] Fix invalid log call --- src/VisualStateManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStateManager.cpp b/src/VisualStateManager.cpp index 6af6eb30..6a00fb11 100644 --- a/src/VisualStateManager.cpp +++ b/src/VisualStateManager.cpp @@ -323,7 +323,7 @@ void _handleOpenShockEvent(void* event_handler_arg, esp_event_base_t event_base, _handleOpenShockGatewayStateChanged(event_data); break; default: - ESP_LOGW(TAG, "Received unknown event ID: %i", event_id); + OS_LOGW(TAG, "Received unknown event ID: %i", event_id); return; } From 841cec77e353571e938c23cd8625a55134837dac Mon Sep 17 00:00:00 2001 From: hhvrc Date: Sat, 16 Nov 2024 01:47:40 +0100 Subject: [PATCH 045/155] Make FnProxy accept extra arguments --- include/util/FnProxy.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/util/FnProxy.h b/include/util/FnProxy.h index 7b66da5e..179c3fa7 100644 --- a/include/util/FnProxy.h +++ b/include/util/FnProxy.h @@ -17,10 +17,10 @@ namespace OpenShock::Util { } // namespace FnProxyImpl // Proxies a member function pointer to a void(void*) function pointer, allowing it to be passed to C-style APIs that expect a callback. - template - inline void FnProxy(void* p) { + template + inline void FnProxy(void* p, Args... args) { using T = decltype(MemberFunction); using C = typename FnProxyImpl::MemFunTraits::Class; - (reinterpret_cast(p)->*MemberFunction)(); + (reinterpret_cast(p)->*MemberFunction)(std::forward(args)...); } } // namespace OpenShock::Util From 6ee7bcd942f20488ceb88d802b896b7240bcd7e2 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Sat, 16 Nov 2024 01:59:06 +0100 Subject: [PATCH 046/155] More CaiXianlin cleanup --- src/radio/rmt/CaiXianlinEncoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/radio/rmt/CaiXianlinEncoder.cpp b/src/radio/rmt/CaiXianlinEncoder.cpp index fad8f7d2..f185aaf1 100644 --- a/src/radio/rmt/CaiXianlinEncoder.cpp +++ b/src/radio/rmt/CaiXianlinEncoder.cpp @@ -37,7 +37,7 @@ std::vector Rmt::CaiXianlinEncoder::GetSequence(uint16_t transmitter } // Payload layout: [transmitterId:16][channelId:4][type:4][intensity:8] - uint32_t payload = (static_cast(transmitterId & 0xFFFF) << 16) | (static_cast(channelId & 0xF) << 12) | (static_cast(typeVal) << 8) | static_cast(intensity & 0xFF); + uint32_t payload = (static_cast(transmitterId) << 16) | (static_cast(channelId & 0xF) << 12) | (static_cast(typeVal & 0xF) << 8) | static_cast(intensity); // Calculate the checksum of the payload uint8_t checksum = Checksum::Sum8(payload); From 7e1216ed8c4d7becd651d84394fc7e509cb8c201 Mon Sep 17 00:00:00 2001 From: hhvrc Date: Mon, 18 Nov 2024 02:16:09 +0100 Subject: [PATCH 047/155] Renamed "device" to "hub" --- .../WifiNetworkEventHandler.ts | 16 ++++----- frontend/src/lib/MessageHandlers/index.ts | 16 ++++----- .../src/lib/components/GpioPinSelector.svelte | 17 +++++++-- frontend/src/lib/components/WiFiList.svelte | 22 ++++++++---- .../lib/components/modals/WiFiDetails.svelte | 23 ++++++++---- .../{DeviceStateStore.ts => HubStateStore.ts} | 8 ++--- frontend/src/lib/stores/index.ts | 2 +- .../lib/types/{DeviceState.ts => HubState.ts} | 2 +- frontend/src/lib/types/index.ts | 2 +- frontend/src/routes/+page.svelte | 29 ++++++++++++--- include/http/JsonAPI.h | 14 ++++---- include/serialization/JsonAPI.h | 8 ++--- include/wifi/WiFiManager.h | 14 ++++---- src/GatewayClient.cpp | 2 +- src/GatewayConnectionManager.cpp | 14 ++++---- src/http/JsonAPI.cpp | 21 ++++++----- src/serial/command_handlers/factoryreset.cpp | 8 +++-- src/serialization/JsonAPI.cpp | 36 +++++++++++-------- 18 files changed, 157 insertions(+), 97 deletions(-) rename frontend/src/lib/stores/{DeviceStateStore.ts => HubStateStore.ts} (94%) rename frontend/src/lib/types/{DeviceState.ts => HubState.ts} (94%) diff --git a/frontend/src/lib/MessageHandlers/WifiNetworkEventHandler.ts b/frontend/src/lib/MessageHandlers/WifiNetworkEventHandler.ts index 9b5268c5..bd918226 100644 --- a/frontend/src/lib/MessageHandlers/WifiNetworkEventHandler.ts +++ b/frontend/src/lib/MessageHandlers/WifiNetworkEventHandler.ts @@ -1,7 +1,7 @@ import { WifiNetworkEvent } from '$lib/_fbs/open-shock/serialization/local/wifi-network-event'; import { WifiNetwork as FbsWifiNetwork } from '$lib/_fbs/open-shock/serialization/types/wifi-network'; import { WifiNetworkEventType } from '$lib/_fbs/open-shock/serialization/types/wifi-network-event-type'; -import { DeviceStateStore } from '$lib/stores'; +import { HubStateStore } from '$lib/stores'; import { toastDelegator } from '$lib/stores/ToastDelegator'; import type { WiFiNetwork } from '$lib/types/WiFiNetwork'; import type { MessageHandler } from '.'; @@ -27,7 +27,7 @@ function handleDiscoveredEvent(fbsNetwork: FbsWifiNetwork) { saved: fbsNetwork.saved(), }; - DeviceStateStore.setWifiNetwork(network); + HubStateStore.setWifiNetwork(network); } function handleUpdatedEvent(fbsNetwork: FbsWifiNetwork) { const ssid = fbsNetwork.ssid(); @@ -47,7 +47,7 @@ function handleUpdatedEvent(fbsNetwork: FbsWifiNetwork) { saved: fbsNetwork.saved(), }; - DeviceStateStore.setWifiNetwork(network); + HubStateStore.setWifiNetwork(network); } function handleLostEvent(fbsNetwork: FbsWifiNetwork) { const bssid = fbsNetwork.bssid(); @@ -57,7 +57,7 @@ function handleLostEvent(fbsNetwork: FbsWifiNetwork) { return; } - DeviceStateStore.removeWifiNetwork(bssid); + HubStateStore.removeWifiNetwork(bssid); } function handleSavedEvent(fbsNetwork: FbsWifiNetwork) { const ssid = fbsNetwork.ssid(); @@ -68,7 +68,7 @@ function handleSavedEvent(fbsNetwork: FbsWifiNetwork) { return; } - DeviceStateStore.updateWifiNetwork(bssid, (network) => { + HubStateStore.updateWifiNetwork(bssid, (network) => { network.saved = true; return network; }); @@ -87,7 +87,7 @@ function handleRemovedEvent(fbsNetwork: FbsWifiNetwork) { return; } - DeviceStateStore.updateWifiNetwork(bssid, (network) => { + HubStateStore.updateWifiNetwork(bssid, (network) => { network.saved = false; return network; }); @@ -106,7 +106,7 @@ function handleConnectedEvent(fbsNetwork: FbsWifiNetwork) { return; } - DeviceStateStore.setWifiConnectedBSSID(bssid); + HubStateStore.setWifiConnectedBSSID(bssid); toastDelegator.trigger({ message: 'WiFi network connected: ' + ssid, @@ -122,7 +122,7 @@ function handleDisconnectedEvent(fbsNetwork: FbsWifiNetwork) { return; } - DeviceStateStore.setWifiConnectedBSSID(null); + HubStateStore.setWifiConnectedBSSID(null); toastDelegator.trigger({ message: 'WiFi network disconnected: ' + ssid, diff --git a/frontend/src/lib/MessageHandlers/index.ts b/frontend/src/lib/MessageHandlers/index.ts index 808c54b8..ecb19354 100644 --- a/frontend/src/lib/MessageHandlers/index.ts +++ b/frontend/src/lib/MessageHandlers/index.ts @@ -4,7 +4,7 @@ import { HubToLocalMessagePayload } from '$lib/_fbs/open-shock/serialization/loc import { ReadyMessage } from '$lib/_fbs/open-shock/serialization/local/ready-message'; import { WifiScanStatusMessage } from '$lib/_fbs/open-shock/serialization/local/wifi-scan-status-message'; import { ByteBuffer } from 'flatbuffers'; -import { DeviceStateStore } from '$lib/stores'; +import { HubStateStore } from '$lib/stores'; import { SerializeWifiScanCommand } from '$lib/Serializers/WifiScanCommand'; import { toastDelegator } from '$lib/stores/ToastDelegator'; import { SetRfTxPinCommandResult } from '$lib/_fbs/open-shock/serialization/local/set-rf-tx-pin-command-result'; @@ -33,9 +33,9 @@ PayloadHandlers[HubToLocalMessagePayload.ReadyMessage] = (cli, msg) => { const payload = new ReadyMessage(); msg.payload(payload); - console.log('[WS] Connected to device, poggies: ', payload.poggies()); + console.log('[WS] Connected to hub, poggies: ', payload.poggies()); - DeviceStateStore.update((store) => { + HubStateStore.update((store) => { store.wifiConnectedBSSID = payload.connectedWifi()?.bssid() || null; store.accountLinked = payload.accountLinked(); store.config = mapConfig(payload.config()); @@ -50,7 +50,7 @@ PayloadHandlers[HubToLocalMessagePayload.ReadyMessage] = (cli, msg) => { store.gpioValidOutputs = gpioValidOutputs; } - console.log('[WS] Updated device state store: ', store); + console.log('[WS] Updated hub state store: ', store); return store; }); @@ -80,7 +80,7 @@ PayloadHandlers[HubToLocalMessagePayload.WifiScanStatusMessage] = (cli, msg) => const payload = new WifiScanStatusMessage(); msg.payload(payload); - DeviceStateStore.setWifiScanStatus(payload.status()); + HubStateStore.setWifiScanStatus(payload.status()); }; PayloadHandlers[HubToLocalMessagePayload.WifiNetworkEvent] = WifiNetworkEventHandler; @@ -135,7 +135,7 @@ PayloadHandlers[HubToLocalMessagePayload.SetRfTxPinCommandResult] = (cli, msg) = const result = payload.result(); if (result == SetGPIOResultCode.Success) { - DeviceStateStore.setRfTxPin(payload.pin()); + HubStateStore.setRfTxPin(payload.pin()); toastDelegator.trigger({ message: 'Changed RF TX pin to: ' + payload.pin(), background: 'bg-green-500', @@ -168,7 +168,7 @@ PayloadHandlers[HubToLocalMessagePayload.SetEstopEnabledCommandResult] = (cli, m const success = payload.success(); if (success) { - DeviceStateStore.setEstopEnabled(payload.enabled()); + HubStateStore.setEstopEnabled(payload.enabled()); toastDelegator.trigger({ message: 'Changed EStop enabled to: ' + enabled, background: 'bg-green-500', @@ -189,7 +189,7 @@ PayloadHandlers[HubToLocalMessagePayload.SetEstopPinCommandResult] = (cli, msg) if (result == SetGPIOResultCode.Success) { const gpioPin = payload.gpioPin(); - DeviceStateStore.setEstopGpioPin(gpioPin); + HubStateStore.setEstopGpioPin(gpioPin); toastDelegator.trigger({ message: 'Changed EStop pin to: ' + gpioPin, background: 'bg-green-500', diff --git a/frontend/src/lib/components/GpioPinSelector.svelte b/frontend/src/lib/components/GpioPinSelector.svelte index 6c5d1766..e7256b3c 100644 --- a/frontend/src/lib/components/GpioPinSelector.svelte +++ b/frontend/src/lib/components/GpioPinSelector.svelte @@ -1,5 +1,5 @@ + + + + diff --git a/frontend/src/lib/components/GpioPinSelector.svelte b/frontend/src/lib/components/GpioPinSelector.svelte index e7256b3c..56b7abe6 100644 --- a/frontend/src/lib/components/GpioPinSelector.svelte +++ b/frontend/src/lib/components/GpioPinSelector.svelte @@ -1,38 +1,61 @@
-
-

{name}

- {statusText} +
+

{name}

+

{statusText}

- - +
diff --git a/frontend/src/lib/components/Layout/Footer.svelte b/frontend/src/lib/components/Layout/Footer.svelte index 90b9b4c2..d65c320e 100644 --- a/frontend/src/lib/components/Layout/Footer.svelte +++ b/frontend/src/lib/components/Layout/Footer.svelte @@ -1,12 +1,7 @@ - - -
+
Made with by the OpenShock Team
- -
+ diff --git a/frontend/src/lib/components/Layout/Header.svelte b/frontend/src/lib/components/Layout/Header.svelte index 68889f25..25126c3f 100644 --- a/frontend/src/lib/components/Layout/Header.svelte +++ b/frontend/src/lib/components/Layout/Header.svelte @@ -1,15 +1,28 @@ - -
- - - OpenShock Logo - -
- +
+
+
+ + OpenShock Logo + +
+ +
+ - - +
+
diff --git a/frontend/src/lib/components/LightSwitch.svelte b/frontend/src/lib/components/LightSwitch.svelte new file mode 100644 index 00000000..c5ef3252 --- /dev/null +++ b/frontend/src/lib/components/LightSwitch.svelte @@ -0,0 +1,62 @@ + + + pendingScheme !== undefined, handleOpenChanged}> + + + Switch to light mode + + Warning: You are about to switch to light mode. +
+ Are you sure you want to do this? +
+
+ +
+
+ + + + + + Toggle theme + + + evaluateLightSwitch('light')}>Light + evaluateLightSwitch('dark')}>Dark + evaluateLightSwitch('system')}>System + + diff --git a/frontend/src/lib/components/WiFiDetailsDialog.svelte b/frontend/src/lib/components/WiFiDetailsDialog.svelte new file mode 100644 index 00000000..9e858817 --- /dev/null +++ b/frontend/src/lib/components/WiFiDetailsDialog.svelte @@ -0,0 +1,86 @@ + + + + + + + + + Network Info + +
+ {#each rows as row (row.key)} + {row.key}:{row.value} + {/each} +
+ +
+

Access Points

+ +
+ {#each group.networks as network} +
+ {network.bssid} + {network.rssi} dBm + Channel {network.channel} +
+ {/each} +
+
+
+
diff --git a/frontend/src/lib/components/WiFiList.svelte b/frontend/src/lib/components/WiFiList.svelte index 3061a014..1929bb64 100644 --- a/frontend/src/lib/components/WiFiList.svelte +++ b/frontend/src/lib/components/WiFiList.svelte @@ -1,5 +1,4 @@
-
+

Configure WiFi

- +
-
+ {#each strengthSortedGroups as [netgroupKey, netgroup] (netgroupKey)} -
- +
+ {#if netgroup.networks.some((n) => n.bssid === connectedBSSID)} - + {:else} - + {/if} {#if netgroup.ssid} {netgroup.ssid} {:else} - {netgroup.networks[0].bssid}{netgroup.networks[0].bssid}(Hidden) {/if} -
+
{#if netgroup.saved} - + + {:else if netgroup.security === WifiAuthMode.Open} + {:else} - + dialogOpen, handleWifiAuthDialogOpenChange}> + + + + + + Enter password + Enter the password for the network + +
+ + +
+ + + +
+
{/if} - +
{/each} -
+
diff --git a/frontend/src/lib/components/modals/WiFiDetails.svelte b/frontend/src/lib/components/modals/WiFiDetails.svelte deleted file mode 100644 index be03c642..00000000 --- a/frontend/src/lib/components/modals/WiFiDetails.svelte +++ /dev/null @@ -1,146 +0,0 @@ - - -
- {#if group} -
-

Network Info

- -
-
- {#each rows as row (row.key)} - {row.key}:{row.value} - {/each} -
- -
-

Access Points

- -
- {#each group.networks as network} -
- {network.bssid} - {network.rssi} dBm - Channel {network.channel} -
- {/each} -
-
- {#if showPasswordPrompt} - - {/if} -
-
- {#if showPasswordPrompt} - - {/if} - - {#if group.saved} - - {/if} -
-
- {:else} -
-

WiFi Info

- -
-
- -
- {/if} -
diff --git a/frontend/src/lib/components/ui/button/button.svelte b/frontend/src/lib/components/ui/button/button.svelte new file mode 100644 index 00000000..22ab2d0d --- /dev/null +++ b/frontend/src/lib/components/ui/button/button.svelte @@ -0,0 +1,74 @@ + + + + +{#if href} + + {@render children?.()} + +{:else} + +{/if} diff --git a/frontend/src/lib/components/ui/button/index.ts b/frontend/src/lib/components/ui/button/index.ts new file mode 100644 index 00000000..fb585d76 --- /dev/null +++ b/frontend/src/lib/components/ui/button/index.ts @@ -0,0 +1,17 @@ +import Root, { + type ButtonProps, + type ButtonSize, + type ButtonVariant, + buttonVariants, +} from "./button.svelte"; + +export { + Root, + type ButtonProps as Props, + // + Root as Button, + buttonVariants, + type ButtonProps, + type ButtonSize, + type ButtonVariant, +}; diff --git a/frontend/src/lib/components/ui/dialog/dialog-content.svelte b/frontend/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 00000000..7e9868c4 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,38 @@ + + + + + + {@render children?.()} + + + Close + + + diff --git a/frontend/src/lib/components/ui/dialog/dialog-description.svelte b/frontend/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 00000000..bc048e4b --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,16 @@ + + + diff --git a/frontend/src/lib/components/ui/dialog/dialog-footer.svelte b/frontend/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 00000000..91ecaba6 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/frontend/src/lib/components/ui/dialog/dialog-header.svelte b/frontend/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 00000000..8d1abfc4 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte b/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 00000000..05c30ac2 --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,19 @@ + + + diff --git a/frontend/src/lib/components/ui/dialog/dialog-title.svelte b/frontend/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 00000000..9cf592cf --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,16 @@ + + + diff --git a/frontend/src/lib/components/ui/dialog/index.ts b/frontend/src/lib/components/ui/dialog/index.ts new file mode 100644 index 00000000..3286ab7a --- /dev/null +++ b/frontend/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,37 @@ +import { Dialog as DialogPrimitive } from "bits-ui"; + +import Title from "./dialog-title.svelte"; +import Footer from "./dialog-footer.svelte"; +import Header from "./dialog-header.svelte"; +import Overlay from "./dialog-overlay.svelte"; +import Content from "./dialog-content.svelte"; +import Description from "./dialog-description.svelte"; + +const Root = DialogPrimitive.Root; +const Trigger = DialogPrimitive.Trigger; +const Close = DialogPrimitive.Close; +const Portal = DialogPrimitive.Portal; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Close, + // + Root as Dialog, + Title as DialogTitle, + Portal as DialogPortal, + Footer as DialogFooter, + Header as DialogHeader, + Trigger as DialogTrigger, + Overlay as DialogOverlay, + Content as DialogContent, + Description as DialogDescription, + Close as DialogClose, +}; diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 00000000..20e3777b --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,40 @@ + + + + {#snippet children({ checked, indeterminate })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 00000000..fdbaa471 --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,26 @@ + + + + + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 00000000..84d5cca2 --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,19 @@ + + + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 00000000..70a52361 --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,23 @@ + + + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 00000000..9837d5a4 --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 00000000..0f219da2 --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,30 @@ + + + + {#snippet children({ checked })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 00000000..32fac4bc --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,16 @@ + + + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 00000000..053e2a2c --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 00000000..0bb6eea4 --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,19 @@ + + + diff --git a/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 00000000..c2dcd32e --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,28 @@ + + + + {@render children?.()} + + diff --git a/frontend/src/lib/components/ui/dropdown-menu/index.ts b/frontend/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 00000000..40c45027 --- /dev/null +++ b/frontend/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,50 @@ +import { DropdownMenu as DropdownMenuPrimitive } from "bits-ui"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; + +const Sub = DropdownMenuPrimitive.Sub; +const Root = DropdownMenuPrimitive.Root; +const Trigger = DropdownMenuPrimitive.Trigger; +const Group = DropdownMenuPrimitive.Group; +const RadioGroup = DropdownMenuPrimitive.RadioGroup; + +export { + CheckboxItem, + Content, + Root as DropdownMenu, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Group as DropdownMenuGroup, + GroupHeading as DropdownMenuGroupHeading, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/frontend/src/lib/components/ui/input/index.ts b/frontend/src/lib/components/ui/input/index.ts new file mode 100644 index 00000000..f47b6d3f --- /dev/null +++ b/frontend/src/lib/components/ui/input/index.ts @@ -0,0 +1,7 @@ +import Root from "./input.svelte"; + +export { + Root, + // + Root as Input, +}; diff --git a/frontend/src/lib/components/ui/input/input.svelte b/frontend/src/lib/components/ui/input/input.svelte new file mode 100644 index 00000000..328634f7 --- /dev/null +++ b/frontend/src/lib/components/ui/input/input.svelte @@ -0,0 +1,22 @@ + + + diff --git a/frontend/src/lib/components/ui/label/index.ts b/frontend/src/lib/components/ui/label/index.ts new file mode 100644 index 00000000..8bfca0b3 --- /dev/null +++ b/frontend/src/lib/components/ui/label/index.ts @@ -0,0 +1,7 @@ +import Root from "./label.svelte"; + +export { + Root, + // + Root as Label, +}; diff --git a/frontend/src/lib/components/ui/label/label.svelte b/frontend/src/lib/components/ui/label/label.svelte new file mode 100644 index 00000000..247d23cc --- /dev/null +++ b/frontend/src/lib/components/ui/label/label.svelte @@ -0,0 +1,19 @@ + + + diff --git a/frontend/src/lib/components/ui/scroll-area/index.ts b/frontend/src/lib/components/ui/scroll-area/index.ts new file mode 100644 index 00000000..e86a25b2 --- /dev/null +++ b/frontend/src/lib/components/ui/scroll-area/index.ts @@ -0,0 +1,10 @@ +import Scrollbar from "./scroll-area-scrollbar.svelte"; +import Root from "./scroll-area.svelte"; + +export { + Root, + Scrollbar, + //, + Root as ScrollArea, + Scrollbar as ScrollAreaScrollbar, +}; diff --git a/frontend/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte b/frontend/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte new file mode 100644 index 00000000..b4360561 --- /dev/null +++ b/frontend/src/lib/components/ui/scroll-area/scroll-area-scrollbar.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/frontend/src/lib/components/ui/scroll-area/scroll-area.svelte b/frontend/src/lib/components/ui/scroll-area/scroll-area.svelte new file mode 100644 index 00000000..9943f837 --- /dev/null +++ b/frontend/src/lib/components/ui/scroll-area/scroll-area.svelte @@ -0,0 +1,32 @@ + + + + + {@render children?.()} + + {#if orientation === "vertical" || orientation === "both"} + + {/if} + {#if orientation === "horizontal" || orientation === "both"} + + {/if} + + diff --git a/frontend/src/lib/components/ui/sonner/index.ts b/frontend/src/lib/components/ui/sonner/index.ts new file mode 100644 index 00000000..1ad9f4a2 --- /dev/null +++ b/frontend/src/lib/components/ui/sonner/index.ts @@ -0,0 +1 @@ +export { default as Toaster } from "./sonner.svelte"; diff --git a/frontend/src/lib/components/ui/sonner/sonner.svelte b/frontend/src/lib/components/ui/sonner/sonner.svelte new file mode 100644 index 00000000..d2539482 --- /dev/null +++ b/frontend/src/lib/components/ui/sonner/sonner.svelte @@ -0,0 +1,20 @@ + + + diff --git a/frontend/src/lib/stores/ColorSchemeStore.ts b/frontend/src/lib/stores/ColorSchemeStore.ts new file mode 100644 index 00000000..80a4bafb --- /dev/null +++ b/frontend/src/lib/stores/ColorSchemeStore.ts @@ -0,0 +1,117 @@ +import { browser } from '$app/environment'; +import { writable, type Updater } from 'svelte/store'; + +function getLocalStoreState() { + const scheme = localStorage.getItem('theme'); + if (scheme === 'dark' || scheme === 'light' || scheme === 'system') { + return scheme; + } + + localStorage.setItem('theme', 'system'); + + return 'system'; +} + +export function getDarkReaderState() { + const rootHtml = document.documentElement; + + const proxyInjected = rootHtml.getAttribute('data-darkreader-proxy-injected'); + const metaElement = rootHtml.querySelector('head meta[name="darkreader"]'); + + let scheme = rootHtml.getAttribute('data-darkreader-scheme'); + if (scheme === 'auto') { + scheme = 'system'; + } + + return { + isInjected: proxyInjected === 'true', + isActive: metaElement !== null, + scheme, + }; +} + +function getColorSchemePreference() { + // If we are not in a browser environment, return default + if (!browser) { + return 'system'; + } + + // Check if local storage has a theme stored + const localStoreState = getLocalStoreState(); + if (localStoreState !== 'system') { + return localStoreState; + } + + // If a user has Dark Reader extension installed, assume they prefer dark mode + const darkReaderState = getDarkReaderState(); + if (darkReaderState.isInjected) { + return 'dark'; + } + + // Check if the user has a system theme preference for light mode + if (window.matchMedia('(prefers-color-scheme: light)').matches) { + return 'light'; + } + + // Default to dark mode + return 'dark'; +} + +const { set, update, subscribe } = writable<'dark' | 'light' | 'system'>( + getColorSchemePreference() +); + +function setHtmlDarkModeSelector(value: boolean) { + document.documentElement.classList.toggle('dark', value); +} + +function handleSchemePreferenceChange() { + const scheme = getColorSchemePreference(); + setHtmlDarkModeSelector(scheme === 'dark'); +} + +export const ColorSchemeStore = { + set: (value: 'dark' | 'light' | 'system') => { + localStorage.setItem('theme', value); + set(value); + handleSchemePreferenceChange(); + }, + update: (updater: Updater<'dark' | 'light' | 'system'>) => { + update((value) => { + const oldValue = value; + const newValue = updater(value); + if (oldValue !== newValue) { + setHtmlDarkModeSelector(newValue === 'dark'); + localStorage.setItem('theme', newValue); + } + return newValue; + }); + }, + subscribe, +}; + +export function willActivateLightMode(value: 'dark' | 'light' | 'system') { + return ( + value === 'light' || + (value === 'system' && window.matchMedia('(prefers-color-scheme: light)').matches) + ); +} + +export function initializeDarkModeStore() { + const schemePreference = getColorSchemePreference(); + setHtmlDarkModeSelector(schemePreference === 'dark'); + set(schemePreference); + + window + .matchMedia('(prefers-color-scheme: light)') + .addEventListener('change', handleSchemePreferenceChange); + window + .matchMedia('(prefers-color-scheme: dark)') + .addEventListener('change', handleSchemePreferenceChange); + + window.addEventListener('storage', (event) => { + if (event.key !== 'theme') return; + + setHtmlDarkModeSelector(event.newValue === 'dark'); + }); +} diff --git a/frontend/src/lib/stores/HubStateStore.ts b/frontend/src/lib/stores/HubStateStore.ts index 5edc2547..faf05dd1 100644 --- a/frontend/src/lib/stores/HubStateStore.ts +++ b/frontend/src/lib/stores/HubStateStore.ts @@ -28,11 +28,21 @@ function insertSorted(array: T[], value: T, compare: (a: T, b: T) => number) array.splice(low, 0, value); } -function SsidMapReducer(groups: Map, [, value]: [string, WiFiNetwork]): Map { +function SsidMapReducer( + groups: Map, + [, value]: [string, WiFiNetwork] +): Map { const key = `${value.ssid || value.bssid}_${WifiAuthMode[value.security]}`; // Get the group for this SSID, or create a new one - const group = groups.get(key) ?? ({ ssid: value.ssid, saved: false, security: value.security, networks: [] } as WiFiNetworkGroup); + const group = + groups.get(key) ?? + ({ + ssid: value.ssid, + saved: false, + security: value.security, + networks: [], + } as WiFiNetworkGroup); // Update the group's saved status group.saved = group.saved || value.saved; @@ -48,7 +58,10 @@ function SsidMapReducer(groups: Map, [, value]: [strin } function updateWifiNetworkGroups(store: HubState) { - store.wifiNetworkGroups = Array.from(store.wifiNetworks.entries()).reduce(SsidMapReducer, new Map()); + store.wifiNetworkGroups = Array.from(store.wifiNetworks.entries()).reduce( + SsidMapReducer, + new Map() + ); } export const HubStateStore = { diff --git a/frontend/src/lib/stores/ToastDelegator.ts b/frontend/src/lib/stores/ToastDelegator.ts deleted file mode 100644 index 6b23df50..00000000 --- a/frontend/src/lib/stores/ToastDelegator.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { ToastSettings } from '@skeletonlabs/skeleton'; -import { writable } from 'svelte/store'; - -export type DelegatedAction = - | { - type: 'trigger'; - toast: ToastSettings; - } - | { - type: 'clear'; - }; - -const store = writable([]); - -export const toastDelegator = { - subscribe: store.subscribe, - trigger(toast: ToastSettings) { - store.update((toasts) => { - toasts.push({ type: 'trigger', toast }); - return toasts; - }); - }, - clear() { - store.set([{ type: 'clear' }]); - }, - set(toasts: DelegatedAction[]) { - store.set(toasts); - }, -}; diff --git a/frontend/src/lib/stores/UsedPinsStore.ts b/frontend/src/lib/stores/UsedPinsStore.ts index af5fdd20..c95fa0c4 100644 --- a/frontend/src/lib/stores/UsedPinsStore.ts +++ b/frontend/src/lib/stores/UsedPinsStore.ts @@ -1,4 +1,4 @@ -import { writable } from "svelte/store"; +import { writable } from 'svelte/store'; const { subscribe, update } = writable>(new Map()); @@ -6,16 +6,16 @@ export const UsedPinsStore = { subscribe, markPinUsed(pin: number, name: string) { update((store) => { - // Remove any existing entries with the same pin or name - for (const [key, value] of store) { - if (key === pin || value === name) { - store.delete(key); - } + // Remove any existing entries with the same pin or name + for (const [key, value] of store) { + if (key === pin || value === name) { + store.delete(key); } + } - store.set(pin, name); + store.set(pin, name); - return store; + return store; }); - } -}; \ No newline at end of file + }, +}; diff --git a/frontend/src/lib/stores/index.ts b/frontend/src/lib/stores/index.ts index 2d7a1d22..cd21897c 100644 --- a/frontend/src/lib/stores/index.ts +++ b/frontend/src/lib/stores/index.ts @@ -1 +1,3 @@ +export * from './ColorSchemeStore'; export * from './HubStateStore'; +export * from './UsedPinsStore'; diff --git a/frontend/src/lib/types/WiFiNetworkGroup.ts b/frontend/src/lib/types/WiFiNetworkGroup.ts index d68320a6..5df98b41 100644 --- a/frontend/src/lib/types/WiFiNetworkGroup.ts +++ b/frontend/src/lib/types/WiFiNetworkGroup.ts @@ -1,9 +1,12 @@ import type { WifiAuthMode } from '$lib/_fbs/open-shock/serialization/types/wifi-auth-mode'; -import type { WiFiNetwork } from './WiFiNetwork'; export type WiFiNetworkGroup = { ssid: string; saved: boolean; security: WifiAuthMode; - networks: WiFiNetwork[]; + networks: { + bssid: string; + rssi: number; + channel: number; + }[]; }; diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts new file mode 100644 index 00000000..9ad0df42 --- /dev/null +++ b/frontend/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { type ClassValue, clsx } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index 185337f1..91e8bcc9 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -1,39 +1,28 @@ - - + - -
- -