From 05353468be5d806679532b947ef3b6171cb5ac4a Mon Sep 17 00:00:00 2001 From: Boris Brock Date: Mon, 20 Jul 2026 17:19:59 +0200 Subject: [PATCH 1/3] Adding board selection --- README.md | 2 +- data/headers/heidelbridge.css.h | 82 ++++---- data/headers/index.html.h | 268 ++++++++++++++------------ data/headers/index.js.h | 285 +++++++++++++++------------- data/heidelbridge.css | 12 +- data/index.html | 12 ++ data/index.js | 4 +- docs/SoftwareSetup.md | 39 +--- platformio.ini | 31 +-- src/Boards/BoardFactory.cpp | 14 +- src/Components/Modbus/ModbusRTU.cpp | 6 +- src/Components/WiFi/WebServer.cpp | 5 + src/Configuration/Constants.h | 1 + src/Configuration/Settings.cpp | 2 + src/Configuration/Settings.h | 1 + src/Main.cpp | 10 +- 16 files changed, 409 insertions(+), 365 deletions(-) diff --git a/README.md b/README.md index d955629..9a70b44 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Parts list: This should be enough for quickly putting together a fully functioning prototype. Of course a well designed PCB would be much nicer, but this is still work in progress. Once the design is ready, the schematics will be available *right here*. -> *\* This project supports the classic ESP32. It has not been built/tested for newer models, like the S2 and C6. Additionally the LILYGO T-CAN485 board is supported, which already includes an on-board RS485 transceiver.* +> *\* This project supports the classic ESP32 and the LILYGO T-CAN485 board (with on-board RS485 transceiver). The hardware type is selected in the web interface during initial setup. It has not been built/tested for newer ESP32 models like the S2 and C6.* # Getting Started diff --git a/data/headers/heidelbridge.css.h b/data/headers/heidelbridge.css.h index e7325b4..8fe61ba 100644 --- a/data/headers/heidelbridge.css.h +++ b/data/headers/heidelbridge.css.h @@ -25,46 +25,52 @@ const unsigned char heidelbridge_css[] PROGMEM = { 0x20, 0x23, 0x33, 0x66, 0x33, 0x39, 0x38, 0x64, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x6d, - 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x33, - 0x32, 0x70, 0x78, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x68, 0x62, 0x2d, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, - 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, - 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x38, + 0x70, 0x78, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x68, 0x62, 0x2d, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3a, + 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x36, 0x34, 0x36, 0x62, 0x61, 0x66, 0x3b, + 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x36, 0x34, 0x36, 0x62, 0x61, 0x66, - 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, - 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x36, 0x34, 0x36, 0x62, 0x61, - 0x66, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x68, 0x62, 0x2d, 0x62, 0x61, - 0x6e, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x64, 0x69, 0x73, - 0x70, 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x66, 0x6c, 0x65, 0x78, 0x3b, 0x0a, - 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, - 0x25, 0x3b, 0x0a, 0x20, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, - 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x65, - 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, - 0x6e, 0x2d, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x20, 0x63, 0x65, 0x6e, - 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, - 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x32, - 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, - 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x38, 0x70, 0x78, 0x3b, 0x0a, 0x20, - 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, - 0x3a, 0x20, 0x38, 0x70, 0x78, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x68, - 0x62, 0x2d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2d, 0x68, 0x65, 0x61, - 0x64, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x36, 0x34, 0x36, 0x62, 0x61, 0x66, - 0x3b, 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, - 0x65, 0x3a, 0x20, 0x32, 0x2e, 0x34, 0x65, 0x6d, 0x3b, 0x0a, 0x20, 0x20, - 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, - 0x20, 0x34, 0x30, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, - 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x31, 0x30, 0x70, + 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x68, 0x62, 0x2d, 0x62, 0x61, 0x6e, + 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x3a, 0x20, 0x66, 0x6c, 0x65, 0x78, 0x3b, 0x0a, 0x20, + 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x25, + 0x3b, 0x0a, 0x20, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x69, 0x66, 0x79, 0x2d, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x63, 0x65, 0x6e, + 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x2d, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x3a, 0x20, 0x63, 0x65, 0x6e, 0x74, + 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, - 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x0a, 0x20, - 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, - 0x74, 0x3a, 0x20, 0x36, 0x70, 0x78, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, - 0x68, 0x62, 0x2d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2d, 0x69, 0x6d, - 0x61, 0x67, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x3a, 0x20, 0x34, 0x30, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x34, 0x30, 0x70, 0x78, 0x3b, - 0x0a, 0x20, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x66, 0x69, - 0x74, 0x3a, 0x20, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x3b, 0x0a, 0x7d + 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x38, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, + 0x20, 0x38, 0x70, 0x78, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x68, 0x62, + 0x2d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2d, 0x68, 0x65, 0x61, 0x64, + 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x36, 0x34, 0x36, 0x62, 0x61, 0x66, 0x3b, + 0x0a, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, + 0x3a, 0x20, 0x32, 0x2e, 0x34, 0x65, 0x6d, 0x3b, 0x0a, 0x20, 0x20, 0x66, + 0x6f, 0x6e, 0x74, 0x2d, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, + 0x34, 0x30, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, + 0x6e, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, + 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, + 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x20, 0x36, 0x70, 0x78, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x68, + 0x62, 0x2d, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x2d, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x20, 0x34, 0x30, 0x70, 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x34, 0x30, 0x70, 0x78, 0x3b, 0x0a, + 0x20, 0x20, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2d, 0x66, 0x69, 0x74, + 0x3a, 0x20, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, + 0x68, 0x33, 0x7b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x31, 0x36, 0x70, 0x78, 0x3b, 0x0a, + 0x7d, 0x0a, 0x0a, 0x2e, 0x73, 0x70, 0x61, 0x63, 0x65, 0x72, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, + 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x36, 0x70, + 0x78, 0x3b, 0x0a, 0x20, 0x20, 0x7d }; const unsigned int heidelbridge_css_len = sizeof(heidelbridge_css); diff --git a/data/headers/index.html.h b/data/headers/index.html.h index 7730369..951d7e9 100644 --- a/data/headers/index.html.h +++ b/data/headers/index.html.h @@ -70,129 +70,159 @@ const unsigned char index_html[] PROGMEM = { 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x48, 0x65, 0x69, 0x64, 0x65, 0x6c, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, - 0x3e, 0x57, 0x69, 0x46, 0x69, 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x0a, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, - 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, - 0x73, 0x69, 0x64, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x77, - 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, 0x69, 0x64, 0x22, 0x20, 0x70, 0x6c, - 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x4e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x28, 0x53, 0x53, 0x49, 0x44, 0x29, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x70, 0x61, 0x73, 0x73, - 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x77, 0x69, - 0x66, 0x69, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, - 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x70, 0x6c, - 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x50, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x2f, 0x3e, 0x0a, - 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, - 0x33, 0x3e, 0x4d, 0x51, 0x54, 0x54, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x0a, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, 0x72, 0x3d, 0x22, 0x6d, 0x71, 0x74, - 0x74, 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x20, 0x73, - 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, - 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x32, 0x70, - 0x78, 0x3b, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, - 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, - 0x6f, 0x78, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, - 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x20, 0x6e, 0x61, - 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x45, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x64, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x3e, 0x0a, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x73, 0x65, 0x74, 0x20, 0x72, 0x6f, 0x6c, 0x65, 0x3d, 0x22, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, - 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, - 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, - 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, - 0x72, 0x3d, 0x22, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x20, 0x2f, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, - 0x65, 0x3d, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, - 0x64, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x6f, 0x72, 0x74, - 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, - 0x2d, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, - 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x50, 0x6f, 0x72, 0x74, + 0x3e, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x3c, 0x2f, 0x68, + 0x33, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x3c, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x69, 0x64, 0x3d, 0x22, + 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x22, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2d, + 0x74, 0x79, 0x70, 0x65, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x69, 0x63, 0x22, 0x3e, 0x47, 0x65, 0x6e, 0x65, 0x72, + 0x69, 0x63, 0x20, 0x45, 0x53, 0x50, 0x33, 0x32, 0x20, 0x2b, 0x20, 0x4d, + 0x41, 0x58, 0x34, 0x38, 0x35, 0x3c, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x6c, 0x69, 0x6c, 0x79, 0x67, 0x6f, + 0x22, 0x3e, 0x4c, 0x69, 0x6c, 0x79, 0x47, 0x6f, 0x20, 0x54, 0x2d, 0x43, + 0x41, 0x4e, 0x34, 0x38, 0x35, 0x3c, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, + 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, 0x3e, 0x57, 0x69, 0x46, 0x69, 0x20, + 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, + 0x68, 0x33, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, + 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, 0x69, 0x64, 0x22, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, + 0x69, 0x64, 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x3d, 0x22, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x28, 0x53, 0x53, 0x49, 0x44, 0x29, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x3e, - 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, - 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x71, 0x74, - 0x74, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, - 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x22, - 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, - 0x3d, 0x22, 0x55, 0x73, 0x65, 0x72, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x29, 0x22, 0x20, - 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, + 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, + 0x69, 0x64, 0x3d, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, + 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, + 0x64, 0x65, 0x72, 0x3d, 0x22, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, + 0x64, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, 0x3e, 0x4d, 0x51, 0x54, 0x54, + 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x66, 0x6f, + 0x72, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x65, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x22, 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3d, 0x22, + 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74, 0x6f, + 0x6d, 0x3a, 0x20, 0x31, 0x32, 0x70, 0x78, 0x3b, 0x22, 0x3e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, - 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x69, 0x64, - 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, - 0x6f, 0x72, 0x64, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, - 0x71, 0x74, 0x74, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, - 0x72, 0x3d, 0x22, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x20, - 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x29, 0x22, 0x20, - 0x2f, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, - 0x73, 0x3d, 0x22, 0x68, 0x62, 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, - 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x6f, 0x6e, 0x63, 0x6c, - 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x77, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, - 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x28, 0x29, 0x3b, 0x22, 0x3e, 0x41, - 0x70, 0x70, 0x6c, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x72, 0x65, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x3c, 0x2f, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, - 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x6d, 0x61, 0x69, - 0x6e, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, - 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x42, 0x6f, 0x78, - 0x20, 0x2d, 0x2d, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, - 0x61, 0x6c, 0x6f, 0x67, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x61, 0x72, 0x74, 0x69, - 0x63, 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x22, 0x20, 0x69, 0x64, + 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x71, + 0x74, 0x74, 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x20, + 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x6c, 0x61, 0x62, + 0x65, 0x6c, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x65, 0x74, 0x20, 0x72, + 0x6f, 0x6c, 0x65, 0x3d, 0x22, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0x3e, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, + 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, + 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, + 0x75, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x71, 0x74, + 0x74, 0x2d, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x6f, 0x72, 0x74, 0x22, + 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, + 0x3d, 0x22, 0x50, 0x6f, 0x72, 0x74, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x65, 0x74, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x74, + 0x79, 0x70, 0x65, 0x3d, 0x22, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x69, + 0x64, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x75, 0x73, 0x65, 0x72, + 0x22, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, + 0x2d, 0x75, 0x73, 0x65, 0x72, 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, 0x65, + 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x55, 0x73, 0x65, 0x72, + 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x29, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, + 0x74, 0x79, 0x70, 0x65, 0x3d, 0x22, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x22, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, + 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x6e, + 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x61, + 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x20, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x3d, 0x22, 0x50, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x28, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x61, 0x6c, 0x29, 0x22, 0x20, 0x2f, 0x3e, 0x0a, 0x0a, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x70, 0x20, 0x63, 0x6c, + 0x61, 0x73, 0x73, 0x3d, 0x22, 0x73, 0x70, 0x61, 0x63, 0x65, 0x72, 0x22, + 0x3e, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x63, + 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x62, 0x2d, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x22, 0x20, 0x6f, + 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x77, 0x72, 0x69, 0x74, + 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x28, 0x29, 0x3b, + 0x22, 0x3e, 0x41, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, + 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x3c, 0x2f, 0x62, 0x75, 0x74, + 0x74, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x3c, 0x61, 0x20, 0x68, 0x72, 0x65, 0x66, 0x3d, 0x22, 0x2f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0x3e, 0x3c, 0x62, 0x75, 0x74, 0x74, + 0x6f, 0x6e, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x22, 0x68, 0x62, + 0x2d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x2d, 0x62, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x22, 0x3e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x66, 0x69, + 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2e, 0x2e, 0x2e, 0x3c, 0x2f, 0x62, + 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x3c, 0x2f, 0x61, 0x3e, 0x0a, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x3e, 0x0a, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x42, 0x6f, 0x78, 0x20, 0x2d, 0x2d, + 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x61, 0x6c, 0x6f, + 0x67, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x3c, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, 0x20, 0x69, 0x64, - 0x3d, 0x22, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, - 0x78, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x54, 0x69, 0x74, - 0x6c, 0x65, 0x3c, 0x2f, 0x68, 0x33, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, - 0x61, 0x64, 0x65, 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x70, 0x20, 0x69, 0x64, 0x3d, - 0x22, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, - 0x2d, 0x74, 0x65, 0x78, 0x74, 0x22, 0x3e, 0x54, 0x65, 0x78, 0x74, 0x3c, - 0x2f, 0x70, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x3e, + 0x20, 0x20, 0x3c, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x3e, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x68, 0x33, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x22, 0x3e, 0x54, 0x69, 0x74, 0x6c, 0x65, 0x3c, + 0x2f, 0x68, 0x33, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x70, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x3e, 0x54, 0x65, 0x78, 0x74, 0x3c, 0x2f, 0x70, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, - 0x20, 0x61, 0x75, 0x74, 0x6f, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x64, - 0x61, 0x74, 0x61, 0x2d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x22, - 0x20, 0x6f, 0x6e, 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x74, 0x6f, - 0x67, 0x67, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x61, 0x6c, 0x28, 0x65, 0x76, - 0x65, 0x6e, 0x74, 0x29, 0x22, 0x3e, 0x4f, 0x4b, 0x3c, 0x2f, 0x62, 0x75, - 0x74, 0x74, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x6f, 0x6f, 0x74, - 0x65, 0x72, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67, 0x3e, - 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x2e, 0x2f, - 0x20, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x42, 0x6f, 0x78, - 0x20, 0x2d, 0x2d, 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x6d, - 0x6f, 0x64, 0x61, 0x6c, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x62, 0x6f, - 0x64, 0x79, 0x3e, 0x0a, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e + 0x20, 0x3c, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x3e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x3c, 0x62, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x61, 0x75, + 0x74, 0x6f, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x2d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d, 0x22, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x22, 0x20, 0x6f, 0x6e, + 0x63, 0x6c, 0x69, 0x63, 0x6b, 0x3d, 0x22, 0x74, 0x6f, 0x67, 0x67, 0x6c, + 0x65, 0x4d, 0x6f, 0x64, 0x61, 0x6c, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x29, 0x22, 0x3e, 0x4f, 0x4b, 0x3c, 0x2f, 0x62, 0x75, 0x74, 0x74, 0x6f, + 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x66, 0x6f, 0x6f, 0x74, 0x65, 0x72, 0x3e, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x61, + 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x3c, 0x2f, 0x64, 0x69, 0x61, 0x6c, 0x6f, 0x67, 0x3e, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0x2e, 0x2f, 0x20, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x42, 0x6f, 0x78, 0x20, 0x2d, 0x2d, + 0x3e, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x6d, 0x6f, 0x64, 0x61, + 0x6c, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x20, 0x73, 0x72, 0x63, 0x3d, 0x22, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x2e, 0x6a, 0x73, 0x22, 0x3e, 0x3c, 0x2f, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x3e, 0x0a, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, + 0x0a, 0x0a, 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e }; const unsigned int index_html_len = sizeof(index_html); diff --git a/data/headers/index.js.h b/data/headers/index.js.h index d263fec..232e64d 100644 --- a/data/headers/index.js.h +++ b/data/headers/index.js.h @@ -88,150 +88,163 @@ const unsigned char index_js[] PROGMEM = { 0x77, 0x6f, 0x72, 0x64, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, 0x5b, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x5d, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x63, 0x61, 0x74, 0x63, - 0x68, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, - 0x6f, 0x6c, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x60, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x24, 0x7b, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x7d, 0x60, 0x29, - 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x29, 0x3b, 0x0a, - 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x78, 0x28, 0x74, 0x69, 0x74, - 0x6c, 0x65, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x74, 0x29, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, - 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x22, 0x29, + 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, + 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, + 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x62, + 0x6f, 0x61, 0x72, 0x64, 0x2d, 0x74, 0x79, 0x70, 0x65, 0x22, 0x29, 0x2e, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x64, 0x61, 0x74, 0x61, + 0x5b, 0x22, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2d, 0x74, 0x79, 0x70, 0x65, + 0x22, 0x5d, 0x20, 0x7c, 0x7c, 0x20, 0x22, 0x67, 0x65, 0x6e, 0x65, 0x72, + 0x69, 0x63, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x20, 0x63, + 0x61, 0x74, 0x63, 0x68, 0x20, 0x28, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x29, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, + 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x28, 0x60, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x24, 0x7b, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x7d, 0x60, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, + 0x29, 0x3b, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x78, 0x28, + 0x74, 0x69, 0x74, 0x6c, 0x65, 0x2c, 0x20, 0x74, 0x65, 0x78, 0x74, 0x29, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, + 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x22, 0x29, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x2d, 0x74, 0x65, 0x78, 0x74, 0x22, 0x29, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, - 0x20, 0x3d, 0x20, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, - 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, - 0x64, 0x28, 0x22, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, - 0x6f, 0x78, 0x2d, 0x74, 0x65, 0x78, 0x74, 0x22, 0x29, 0x2e, 0x74, 0x65, - 0x78, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x20, 0x3d, 0x20, - 0x74, 0x65, 0x78, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, - 0x67, 0x67, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x61, 0x6c, 0x28, 0x22, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, 0x78, 0x22, 0x29, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x69, - 0x6e, 0x67, 0x73, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x2f, 0x2f, 0x20, 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, - 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x66, 0x72, - 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x49, 0x20, 0x74, 0x6f, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x64, 0x61, - 0x74, 0x61, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2d, 0x6e, - 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x64, 0x65, 0x76, 0x69, 0x63, - 0x65, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, 0x69, 0x64, 0x22, 0x3a, + 0x20, 0x3d, 0x20, 0x74, 0x65, 0x78, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x61, 0x6c, + 0x28, 0x22, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2d, 0x62, 0x6f, + 0x78, 0x22, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x28, 0x29, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, + 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, + 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x20, 0x74, 0x68, 0x65, 0x20, 0x55, 0x49, + 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, + 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x64, 0x65, 0x76, 0x69, 0x63, + 0x65, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x64, 0x65, + 0x76, 0x69, 0x63, 0x65, 0x2d, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x29, 0x2e, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, 0x69, + 0x64, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, + 0x79, 0x49, 0x64, 0x28, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, + 0x69, 0x64, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x77, 0x69, 0x66, + 0x69, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, - 0x28, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x73, 0x73, 0x69, 0x64, 0x22, - 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3a, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x77, - 0x69, 0x66, 0x69, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, - 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, - 0x71, 0x74, 0x74, 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, - 0x29, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, 0x2c, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x71, 0x74, 0x74, - 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, - 0x71, 0x74, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x29, - 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x6f, - 0x72, 0x74, 0x22, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x73, 0x65, 0x49, 0x6e, - 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, - 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, - 0x64, 0x28, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x6f, 0x72, 0x74, - 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x2c, 0x0a, 0x20, + 0x28, 0x22, 0x77, 0x69, 0x66, 0x69, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, + 0x6f, 0x72, 0x64, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x71, + 0x74, 0x74, 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x22, 0x3a, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, + 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x64, 0x22, 0x29, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x65, 0x64, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, + 0x71, 0x74, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x3a, + 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, + 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, + 0x28, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, 0x71, 0x74, 0x74, - 0x2d, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, - 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, 0x71, 0x74, - 0x74, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, - 0x72, 0x64, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x2d, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a, 0x20, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x49, 0x6e, 0x74, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, - 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x29, 0x2e, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x5f, - 0x77, 0x72, 0x69, 0x74, 0x65, 0x22, 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x3a, 0x20, 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x73, 0x3a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, - 0x74, 0x2d, 0x54, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x70, - 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, - 0x6f, 0x6e, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, - 0x6f, 0x64, 0x79, 0x3a, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x69, 0x66, 0x79, 0x28, 0x64, 0x61, 0x74, 0x61, - 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x3d, 0x3e, 0x20, 0x7b, + 0x6f, 0x72, 0x74, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, + 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6d, + 0x71, 0x74, 0x74, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x64, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, + 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, + 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x75, 0x73, 0x65, 0x72, 0x22, 0x29, 0x2e, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x6d, 0x71, 0x74, 0x74, 0x2d, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, + 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x6d, 0x71, 0x74, + 0x74, 0x2d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x29, + 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x2d, 0x74, + 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, + 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x62, 0x6f, 0x61, 0x72, 0x64, + 0x2d, 0x74, 0x79, 0x70, 0x65, 0x22, 0x29, 0x2e, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x3b, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, 0x2f, 0x61, 0x70, 0x69, + 0x2f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x5f, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x22, 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x20, + 0x22, 0x50, 0x4f, 0x53, 0x54, 0x22, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x3a, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, + 0x54, 0x79, 0x70, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x70, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, + 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x2c, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x64, + 0x79, 0x3a, 0x20, 0x4a, 0x53, 0x4f, 0x4e, 0x2e, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x69, 0x66, 0x79, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x0a, + 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x2e, 0x74, 0x68, 0x65, 0x6e, 0x28, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, + 0x66, 0x20, 0x28, 0x21, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x6f, 0x6b, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, + 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, + 0x6f, 0x72, 0x28, 0x60, 0x48, 0x54, 0x54, 0x50, 0x20, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x21, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3a, 0x20, + 0x24, 0x7b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x7d, 0x60, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x6f, 0x6b, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x28, 0x60, 0x48, 0x54, 0x54, 0x50, 0x20, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x21, 0x20, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x3a, 0x20, 0x24, 0x7b, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x7d, 0x60, 0x29, 0x3b, 0x0a, + 0x20, 0x2f, 0x2f, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, 0x20, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x70, 0x0a, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x78, 0x28, 0x22, 0x53, 0x75, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x20, 0x22, 0x54, 0x68, 0x65, 0x20, + 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, + 0x6e, 0x6f, 0x77, 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x20, 0x74, + 0x6f, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x79, 0x6f, 0x75, 0x72, + 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x22, 0x29, 0x3b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x45, 0x73, 0x70, 0x28, + 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, + 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x63, + 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, + 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x60, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x3a, 0x20, 0x24, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x7d, 0x60, 0x29, 0x3b, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, + 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x65, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x45, 0x73, 0x70, 0x28, 0x29, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, 0x28, 0x22, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x22, + 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x20, 0x22, 0x50, 0x4f, 0x53, + 0x54, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x0a, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x63, 0x61, 0x74, 0x63, 0x68, + 0x28, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x53, 0x68, 0x6f, 0x77, 0x20, 0x61, - 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x20, 0x70, 0x6f, 0x70, 0x75, 0x70, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x6f, 0x78, 0x28, 0x22, 0x53, - 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0x2c, 0x20, 0x22, 0x54, 0x68, - 0x65, 0x20, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x77, 0x69, 0x6c, - 0x6c, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, - 0x20, 0x74, 0x6f, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x79, 0x20, 0x79, 0x6f, - 0x75, 0x72, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x2e, 0x22, - 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x45, 0x73, - 0x70, 0x28, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x7d, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x2e, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x20, 0x3d, 0x3e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, - 0x65, 0x2e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x60, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x3a, 0x20, 0x24, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, - 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x7d, 0x60, 0x29, 0x3b, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, - 0x7d, 0x0a, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, - 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x45, 0x73, 0x70, 0x28, 0x29, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x65, 0x74, 0x63, 0x68, - 0x28, 0x22, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x62, 0x6f, 0x6f, - 0x74, 0x22, 0x2c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x3a, 0x20, 0x22, 0x50, - 0x4f, 0x53, 0x54, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x2e, 0x63, 0x61, 0x74, - 0x63, 0x68, 0x28, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x3d, 0x3e, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x28, 0x60, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, - 0x24, 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, - 0x61, 0x67, 0x65, 0x7d, 0x60, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x7d, 0x0a + 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x28, 0x60, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 0x24, 0x7b, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x7d, 0x60, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x7d, 0x29, 0x3b, 0x0a, 0x7d, 0x0a }; const unsigned int index_js_len = sizeof(index_js); diff --git a/data/heidelbridge.css b/data/heidelbridge.css index 85bad30..3c042e2 100644 --- a/data/heidelbridge.css +++ b/data/heidelbridge.css @@ -10,7 +10,7 @@ background-color: #3f398d; border-color: #3f398d; border-radius: 10px; - margin-top: 32px; + margin-top: 8px; } .hb-block-button:hover { @@ -41,4 +41,12 @@ width: 40px; height: 40px; object-fit: cover; -} \ No newline at end of file +} + +h3{ + margin-top: 16px; +} + +.spacer { + margin-bottom: 16px; + } \ No newline at end of file diff --git a/data/index.html b/data/index.html index b75d7b2..bec8154 100644 --- a/data/index.html +++ b/data/index.html @@ -26,6 +26,14 @@

Device Name

+

Hardware

+ + + +

WiFi Connection

@@ -47,7 +55,11 @@

MQTT

+ +

+ + diff --git a/data/index.js b/data/index.js index 921b3b3..e42a7c2 100644 --- a/data/index.js +++ b/data/index.js @@ -20,6 +20,7 @@ document.addEventListener("DOMContentLoaded", async function () { document.getElementById("mqtt-port").value = data["mqtt-port"]; document.getElementById("mqtt-user").value = data["mqtt-user"]; document.getElementById("mqtt-password").value = data["mqtt-password"]; + document.getElementById("board-type").value = data["board-type"] || "generic"; } catch (error) { console.error(`Error: ${error.message}`); } @@ -41,7 +42,8 @@ function writeSettings() { "mqtt-server": document.getElementById("mqtt-server").value, "mqtt-port": parseInt(document.getElementById("mqtt-port").value), "mqtt-user": document.getElementById("mqtt-user").value, - "mqtt-password": document.getElementById("mqtt-password").value + "mqtt-password": document.getElementById("mqtt-password").value, + "board-type": document.getElementById("board-type").value }; fetch("/api/settings_write", { method: "POST", diff --git a/docs/SoftwareSetup.md b/docs/SoftwareSetup.md index 13d240a..d77ea9f 100644 --- a/docs/SoftwareSetup.md +++ b/docs/SoftwareSetup.md @@ -60,48 +60,21 @@ Then follow these steps: ## Build Environments -HeidelBridge supports multiple build environments to accommodate different hardware configurations: +HeidelBridge supports two build environments: -### Standard ESP32 + External RS485 Module (`esp32`) +### Standard Build (`esp32`) -This is the default build environment for regular ESP32 development boards with an external RS485 module. +This is the default build for production use with either a Generic ESP32 + MAX485 module or a LilyGo T-CAN485 board. **To compile:** ```bash -pio run -e esp32 +pio run ``` -**Pin configuration:** +**Hardware selection:** -- GPIO18 → RS485 RO (Receiver Output) -- GPIO19 → RS485 DI (Driver Input) -- GPIO21 → RS485 DE+RE - -### LilyGo T-Can485 Board (`lilygo`) - -This build environment is specifically designed for the LilyGo T-Can485 board, which has built-in RS485 capabilities and **does not require an external MAX485 module**. - -**To compile:** - -```bash -pio run -e lilygo -``` - -**Pin configuration:** - -- GPIO21 → RS485 RO (Receiver Output) -- GPIO22 → RS485 DI (Driver Input) -- GPIO21 → RS485 DE+RE - -**Additional features:** - -- Automatic initialization of onboard RS485 transceivers -- 5V power supply control -- CAN bus support (hardware available but not used in current firmware) -- **No external MAX485 module needed** - RS485 transceiver is built into the board - -For detailed wiring information and hardware setup for the LilyGo T-Can485 board, please refer to the [discussion thread](https://github.com/BorisBrock/HeidelBridge/discussions/4). +The hardware type is selected in the web interface during initial setup. After flashing, connect to the captive portal (`HeidelBridge Setup`) and choose either "Generic ESP32 + MAX485" or "LilyGo T-CAN485" under the Hardware section. ### Dummy Wallbox (`dummy`) diff --git a/platformio.ini b/platformio.ini index 66b4bda..0c93fe4 100644 --- a/platformio.ini +++ b/platformio.ini @@ -9,7 +9,7 @@ ; https://docs.platformio.org/page/projectconf.html [platformio] -default_envs = esp32 +default_envs = esp32, dummy # Common settings [env] @@ -29,34 +29,23 @@ lib_deps = esphome/ESPAsyncWebServer-esphome @^3.4.0 bblanchon/ArduinoJson @ ^7.4.2 -# Build a dummy HeidelBridge with no real wallbox hardware attached. -# This is for testing and simulation only. -[env:dummy] -platform = espressif32@^6.8.1 -board = esp32doit-devkit-v1 -upload_protocol = esptool -build_flags = - -O2 - -D DUMMY_WALLBOX - -D BOARD_ESP32 - -D LOGGING_LEVEL_DEBUG - -# Default environment for regular ESP32 boards. +# Default environment for both ESP32 board types. +# Board type (Generic ESP32 vs LilyGo T-CAN485) is selected in the web interface. [env:esp32] platform = espressif32@^6.8.1 -board = esp32doit-devkit-v1 +board = esp32dev upload_protocol = esptool build_flags = -O2 - -D BOARD_ESP32 -D LOGGING_LEVEL_ERROR -# LILYGO T-CAN485, ESP32 board with on-board RS485 -[env:lilygo] +# Build a dummy HeidelBridge with no real wallbox hardware attached. +# This is for testing and simulation only. +[env:dummy] platform = espressif32@^6.8.1 -board = esp32dev +board = esp32doit-devkit-v1 upload_protocol = esptool build_flags = -O2 - -D BOARD_LILYGO - -D LOGGING_LEVEL_ERROR \ No newline at end of file + -D DUMMY_WALLBOX + -D LOGGING_LEVEL_DEBUG \ No newline at end of file diff --git a/src/Boards/BoardFactory.cpp b/src/Boards/BoardFactory.cpp index 26051c3..30eac70 100644 --- a/src/Boards/BoardFactory.cpp +++ b/src/Boards/BoardFactory.cpp @@ -1,6 +1,7 @@ #include #include "Board.h" #include "BoardFactory.h" +#include "../Configuration/Settings.h" // All supported boards #include "ESP32/BoardESP32.h" @@ -16,11 +17,12 @@ BoardFactory *BoardFactory::Instance() // Gets the currently used board Board *BoardFactory::GetBoard() { -#ifdef BOARD_ESP32 - static BoardESP32 boardInstance; -#elif BOARD_LILYGO - static BoardLilygo boardInstance; -#endif + static BoardESP32 genericBoard; + static BoardLilygo lilygoBoard; - return &boardInstance; + if (Settings::Instance()->BoardType == "lilygo") + { + return &lilygoBoard; + } + return &genericBoard; } \ No newline at end of file diff --git a/src/Components/Modbus/ModbusRTU.cpp b/src/Components/Modbus/ModbusRTU.cpp index 6850fae..0fadbda 100644 --- a/src/Components/Modbus/ModbusRTU.cpp +++ b/src/Components/Modbus/ModbusRTU.cpp @@ -8,9 +8,9 @@ #include "../../Boards/Board.h" #include "ModbusRTU.h" -ModbusClientRTU gModbusRTU(BoardFactory::Instance()->GetBoard()->GetPinRts()); // Create a ModbusRTU client instance -HardwareSerial gRs485Serial(1); // Define a Serial for UART1 -SemaphoreHandle_t gMutex = nullptr; // A mutex object for buss access +ModbusClientRTU gModbusRTU(Constants::ModbusRTU::PinRTS); // Create a ModbusRTU client instance +HardwareSerial gRs485Serial(1); // Define a Serial for UART1 +SemaphoreHandle_t gMutex = nullptr; // A mutex object for buss access // Returns the singleton instance of ModbusRTU ModbusRTU *ModbusRTU::Instance() diff --git a/src/Components/WiFi/WebServer.cpp b/src/Components/WiFi/WebServer.cpp index 07b44a7..bab5b48 100644 --- a/src/Components/WiFi/WebServer.cpp +++ b/src/Components/WiFi/WebServer.cpp @@ -197,6 +197,7 @@ String WebServer::HandleApiRequestSettingsRead(AsyncWebServerRequest *request) doc["mqtt-port"] = Settings::Instance()->MqttPort; doc["mqtt-user"] = Settings::Instance()->MqttUser; doc["mqtt-password"] = Settings::Instance()->MqttPassword; + doc["board-type"] = Settings::Instance()->BoardType; String jsonResponse; serializeJson(doc, jsonResponse); @@ -249,6 +250,10 @@ String WebServer::HandleApiRequestSettingsWrite(AsyncWebServerRequest *request, { Settings::Instance()->MqttPassword = doc["mqtt-password"].as(); } + if (doc["board-type"].is()) + { + Settings::Instance()->BoardType = doc["board-type"].as(); + } Settings::Instance()->WriteToPersistentMemory(); Settings::Instance()->Print(); diff --git a/src/Configuration/Constants.h b/src/Configuration/Constants.h index e9dc495..81ca3ed 100644 --- a/src/Configuration/Constants.h +++ b/src/Configuration/Constants.h @@ -10,6 +10,7 @@ namespace Constants namespace ModbusRTU { + constexpr uint8_t PinRTS = GPIO_NUM_21; constexpr uint8_t RegisterSize = 2; constexpr uint16_t NumReadRetries = 3; constexpr uint16_t NumWriteRetries = 5; diff --git a/src/Configuration/Settings.cpp b/src/Configuration/Settings.cpp index 002e922..e295291 100644 --- a/src/Configuration/Settings.cpp +++ b/src/Configuration/Settings.cpp @@ -38,6 +38,7 @@ void Settings::ReadFromPersistentMemory() MqttServer = gPreferences.getString("mqtt_server"); MqttUser = gPreferences.getString("mqtt_user"); MqttPassword = gPreferences.getString("mqtt_password"); + BoardType = gPreferences.getString("board_type", "generic"); } // Write all settings to storage @@ -53,6 +54,7 @@ void Settings::WriteToPersistentMemory() gPreferences.putString("mqtt_server", MqttServer); gPreferences.putString("mqtt_user", MqttUser); gPreferences.putString("mqtt_password", MqttPassword); + gPreferences.putString("board_type", BoardType); } // Prints all settings to the logger diff --git a/src/Configuration/Settings.h b/src/Configuration/Settings.h index 59f166a..596d868 100644 --- a/src/Configuration/Settings.h +++ b/src/Configuration/Settings.h @@ -33,4 +33,5 @@ class Settings uint16_t MqttPort{1883}; String MqttUser{}; String MqttPassword{}; + String BoardType{"generic"}; }; \ No newline at end of file diff --git a/src/Main.cpp b/src/Main.cpp index 76958b3..97d3f7a 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -39,16 +39,16 @@ void setup() #endif Logger::Print(""); + // Read persistent settings + Settings::Instance()->Init(); + Settings::Instance()->ReadFromPersistentMemory(); + Settings::Instance()->Print(); + // Prepare the board auto* board = BoardFactory::Instance()->GetBoard(); Logger::Print("Used hardware board:"); board->Print(); board->Init(); - - // Read persistent settings - Settings::Instance()->Init(); - Settings::Instance()->ReadFromPersistentMemory(); - Settings::Instance()->Print(); // Make sure WiFi connection is up and running WifiManager::Instance()->Start(); From 67813c2b68f117c7aed0a6e1b8f5219fc28ae0fb Mon Sep 17 00:00:00 2001 From: Boris Brock Date: Mon, 20 Jul 2026 17:31:45 +0200 Subject: [PATCH 2/3] Fixing pin constant --- src/Components/Modbus/ModbusRTU.cpp | 11 +++++------ src/Components/Modbus/ModbusRTU.h | 4 ++++ src/Configuration/Constants.h | 1 - 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Components/Modbus/ModbusRTU.cpp b/src/Components/Modbus/ModbusRTU.cpp index 0fadbda..ed28984 100644 --- a/src/Components/Modbus/ModbusRTU.cpp +++ b/src/Components/Modbus/ModbusRTU.cpp @@ -2,13 +2,11 @@ #include "../Logger/Logger.h" #include "../Statistics/Statistics.h" #include "HardwareSerial.h" -#include "ModbusClientRTU.h" #include "../../Configuration/Constants.h" #include "../../Boards/BoardFactory.h" #include "../../Boards/Board.h" #include "ModbusRTU.h" -ModbusClientRTU gModbusRTU(Constants::ModbusRTU::PinRTS); // Create a ModbusRTU client instance HardwareSerial gRs485Serial(1); // Define a Serial for UART1 SemaphoreHandle_t gMutex = nullptr; // A mutex object for buss access @@ -36,8 +34,9 @@ void ModbusRTU::Init() // Start Modbus RTU Logger::Trace("Creating Modbus RTU instance"); - gModbusRTU.setTimeout(Constants::HeidelbergWallbox::ModbusTimeoutMs); - gModbusRTU.begin(gRs485Serial); // Start ModbusRTU background task + modbusClient = new ModbusClientRTU(BoardFactory::Instance()->GetBoard()->GetPinRts()); + modbusClient->setTimeout(Constants::HeidelbergWallbox::ModbusTimeoutMs); + modbusClient->begin(gRs485Serial); // Start ModbusRTU background task } // Reads multiple registers starting from the specified address @@ -51,7 +50,7 @@ bool ModbusRTU::ReadRegisters(uint16_t startAddress, uint8_t numValues, uint8_t // Try to get the mutex if (xSemaphoreTake(gMutex, portMAX_DELAY)) { - ModbusMessage response = gModbusRTU.syncRequest( + ModbusMessage response = modbusClient->syncRequest( 0, Constants::HeidelbergWallbox::ModbusServerId, (FunctionCode)fc, @@ -103,7 +102,7 @@ bool ModbusRTU::WriteHoldRegister16(uint16_t address, uint16_t value) // Try to get the mutex if (xSemaphoreTake(gMutex, portMAX_DELAY)) { - ModbusMessage response = gModbusRTU.syncRequest( + ModbusMessage response = modbusClient->syncRequest( 0, Constants::HeidelbergWallbox::ModbusServerId, WRITE_HOLD_REGISTER, diff --git a/src/Components/Modbus/ModbusRTU.h b/src/Components/Modbus/ModbusRTU.h index 74efdf6..40d6541 100644 --- a/src/Components/Modbus/ModbusRTU.h +++ b/src/Components/Modbus/ModbusRTU.h @@ -1,11 +1,15 @@ #pragma once +#include "ModbusClientRTU.h" + class ModbusRTU { private: // Private constructor to prevent instantiation ModbusRTU() {}; + ModbusClientRTU* modbusClient = nullptr; + public: // Returns the singleton instance of ModbusRTU static ModbusRTU *Instance(); diff --git a/src/Configuration/Constants.h b/src/Configuration/Constants.h index 81ca3ed..e9dc495 100644 --- a/src/Configuration/Constants.h +++ b/src/Configuration/Constants.h @@ -10,7 +10,6 @@ namespace Constants namespace ModbusRTU { - constexpr uint8_t PinRTS = GPIO_NUM_21; constexpr uint8_t RegisterSize = 2; constexpr uint16_t NumReadRetries = 3; constexpr uint16_t NumWriteRetries = 5; From f529020e14bf8e20e375ca00ea69a68529b490f5 Mon Sep 17 00:00:00 2001 From: Boris Brock Date: Mon, 20 Jul 2026 17:55:35 +0200 Subject: [PATCH 3/3] Removing obsolete build steps --- .github/workflows/build.yml | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cbe5a54..6c86a86 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,20 +33,11 @@ jobs: - name: Installing PlatformIO Core run: pip install --upgrade platformio - - name: Build HeidelBridge ESP32 + - name: Build HeidelBridge run: pio run -e esp32 - - name: Build HeidelBridge Lilygo - run: pio run -e lilygo - - - name: Upload ESP32 Firmware - uses: actions/upload-artifact@v4 - with: - name: firmware-esp32 - path: .pio/build/esp32/firmware.bin - - - name: Upload Lilygo Firmware + - name: Upload Firmware uses: actions/upload-artifact@v4 with: - name: firmware-lilygo - path: .pio/build/lilygo/firmware.bin \ No newline at end of file + name: firmware + path: .pio/build/esp32/firmware.bin \ No newline at end of file