Usermod API enhancements

- data exchage getUMData()
- usermod configuration helper appendConfigData()
- notification on updates onUpdateBegin()
This commit is contained in:
Blaz Kristan 2022-06-13 22:11:55 +02:00
parent 6a69a726f2
commit 2b259f3704
8 changed files with 258 additions and 130 deletions

View File

@ -941,6 +941,23 @@ class FourLineDisplayUsermod : public Usermod {
// if (!initDone) return; // prevent crash on boot applyPreset() // if (!initDone) return; // prevent crash on boot applyPreset()
//} //}
void appendConfigData() {
oappend(SET_F("dd=addDropdown('4LineDisplay','type');"));
oappend(SET_F("addOption(dd,'None',0);"));
oappend(SET_F("addOption(dd,'SSD1306',1);"));
oappend(SET_F("addOption(dd,'SH1106',2);"));
oappend(SET_F("addOption(dd,'SSD1306 128x64',3);"));
oappend(SET_F("addOption(dd,'SSD1305',4);"));
oappend(SET_F("addOption(dd,'SSD1305 128x64',5);"));
oappend(SET_F("addOption(dd,'SSD1306 SPI',6);"));
oappend(SET_F("addOption(dd,'SSD1306 SPI 128x64',7);"));
oappend(SET_F("addInfo('4LineDisplay:pin[]',0,'I2C/SPI CLK');"));
oappend(SET_F("addInfo('4LineDisplay:pin[]',1,'I2C/SPI DTA');"));
oappend(SET_F("addInfo('4LineDisplay:pin[]',2,'SPI CS');"));
oappend(SET_F("addInfo('4LineDisplay:pin[]',3,'SPI DC');"));
oappend(SET_F("addInfo('4LineDisplay:pin[]',4,'SPI RST');"));
}
/* /*
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object. * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
* It will be called by WLED when settings are actually saved (for example, LED settings are saved) * It will be called by WLED when settings are actually saved (for example, LED settings are saved)
@ -960,9 +977,7 @@ class FourLineDisplayUsermod : public Usermod {
top[FPSTR(_enabled)] = enabled; top[FPSTR(_enabled)] = enabled;
JsonArray io_pin = top.createNestedArray("pin"); JsonArray io_pin = top.createNestedArray("pin");
for (byte i=0; i<5; i++) io_pin.add(ioPin[i]); for (byte i=0; i<5; i++) io_pin.add(ioPin[i]);
top["help4Pins"] = F("Clk,Data,CS,DC,RST"); // help for Settings page
top["type"] = type; top["type"] = type;
top["help4Type"] = F("1=SSD1306,2=SH1106,3=SSD1306_128x64,4=SSD1305,5=SSD1305_128x64,6=SSD1306_SPI,7=SSD1306_SPI_128x64"); // help for Settings page
top[FPSTR(_flip)] = (bool) flip; top[FPSTR(_flip)] = (bool) flip;
top[FPSTR(_contrast)] = contrast; top[FPSTR(_contrast)] = contrast;
top[FPSTR(_contrastFix)] = (bool) contrastFix; top[FPSTR(_contrastFix)] = (bool) contrastFix;

View File

@ -26,9 +26,8 @@
localStorage.setItem('locIp', locip); localStorage.setItem('locIp', locip);
} }
} }
GetV(); ldS();
if (numM > 0 || locip) ldS(); if (!numM) gId("um").innerHTML = "No Usermods installed.";
else gId("um").innerHTML = "No Usermods installed.";
} }
// https://stackoverflow.com/questions/3885817/how-do-i-check-that-a-number-is-float-or-integer // https://stackoverflow.com/questions/3885817/how-do-i-check-that-a-number-is-float-or-integer
function isF(n) { return n === +n && n !== (n|0); } function isF(n) { return n === +n && n !== (n|0); }
@ -100,6 +99,47 @@
urows += `<input type="${t==="int"?"number":t}" name="${k}:${f}${a?"[]":""}" ${c} oninput="check(this,'${k.substr(k.indexOf(":")+1)}')"><br>`; urows += `<input type="${t==="int"?"number":t}" name="${k}:${f}${a?"[]":""}" ${c} oninput="check(this,'${k.substr(k.indexOf(":")+1)}')"><br>`;
} }
} }
// https://stackoverflow.com/questions/39729741/javascript-change-input-text-to-select-option
function addDropdown(um,fld) {
let sel = d.createElement('select');
let arr = d.getElementsByName(um+":"+fld);
let inp = arr[1]; // assume 1st field to be hidden (type)
if (inp && inp.tagName === "INPUT" && (inp.type === "text" || inp.type === "number")) { // may also use nodeName
let v = inp.value;
let n = inp.name;
// copy the existing input element's attributes to the new select element
for (var i = 0; i < inp.attributes.length; ++ i) {
var att = inp.attributes[i];
// type and value don't apply, so skip them
// ** you might also want to skip style, or others -- modify as needed **
if (att.name != 'type' && att.name != 'value' && att.name != 'class' && att.name != 'style') {
sel.setAttribute(att.name, att.value);
}
}
sel.setAttribute("data-val", v);
// finally, replace the old input element with the new select element
inp.parentElement.replaceChild(sel, inp);
return sel;
}
return null;
}
function addOption(sel,txt,val) {
if (sel===null) return; // select object missing
let opt = d.createElement("option");
opt.value = val;
opt.text = txt;
sel.appendChild(opt);
for (let i=0; i<sel.childNodes.length; i++) {
let c = sel.childNodes[i];
if (c.value == sel.dataset.val) sel.selectedIndex = i;
}
}
// https://stackoverflow.com/questions/26440494/insert-text-after-this-input-element-with-javascript
function addInfo(name,el,txt) {
let obj = d.getElementsByName(name);
if (obj[el]) obj[el].insertAdjacentHTML('afterend', '&nbsp;'+txt);
}
// load settings and insert values into DOM
function ldS() { function ldS() {
var url = (loc?`http://${locip}`:'') + '/cfg.json'; var url = (loc?`http://${locip}`:'') + '/cfg.json';
fetch(url, { fetch(url, {
@ -121,18 +161,18 @@
} }
if (urows==="") urows = "Usermods configuration not found.<br>Press <i>Save</i> to initialize defaults."; if (urows==="") urows = "Usermods configuration not found.<br>Press <i>Save</i> to initialize defaults.";
gId("um").innerHTML = urows; gId("um").innerHTML = urows;
GetV();
}) })
.catch(function (error) { .catch((error)=>{
gId('lserr').style.display = "inline" gId('lserr').style.display = "inline";
console.log(error); console.log(error);
}); });
} }
function svS(e) { function svS(e) {
e.preventDefault(); e.preventDefault();
console.log(d.Sf);
if (d.Sf.checkValidity()) d.Sf.submit(); //https://stackoverflow.com/q/37323914 if (d.Sf.checkValidity()) d.Sf.submit(); //https://stackoverflow.com/q/37323914
} }
function GetV() {} function GetV() {} // replaced during 'npm run build'
</script> </script>
<style>@import url("style.css");</style> <style>@import url("style.css");</style>
</head> </head>

View File

@ -216,13 +216,52 @@ int getSignalQuality(int rssi);
void WiFiEvent(WiFiEvent_t event); void WiFiEvent(WiFiEvent_t event);
//um_manager.cpp //um_manager.cpp
typedef enum UM_Data_Types {
UMT_BYTE = 0,
UMT_UINT16,
UMT_INT16,
UMT_UINT32,
UMT_INT32,
UMT_FLOAT,
UMT_DOUBLE,
UMT_BYTE_ARR,
UMT_UINT16_ARR,
UMT_INT16_ARR,
UMT_UINT32_ARR,
UMT_INT32_ARR,
UMT_FLOAT_ARR,
UMT_DOUBLE_ARR
} um_types_t;
typedef struct UM_Exchange_Data {
// should just use: size_t arr_size, void **arr_ptr, byte *ptr_type
size_t u_size; // size of u_data array
um_types_t *u_type; // array of data types
void **u_data; // array of pointers to data
UM_Exchange_Data() {
u_size = 0;
u_type = nullptr;
u_data = nullptr;
}
~UM_Exchange_Data() {
if (u_type) delete[] u_type;
if (u_data) delete[] u_data;
}
} um_data_t;
const unsigned int um_data_size = sizeof(um_data_t); // 12 bytes
class Usermod { class Usermod {
protected:
um_data_t *um_data; // um_data should be allocated using new in (derived) Usermod's setup() or constructor
public: public:
virtual void loop() {} Usermod() { um_data = nullptr; }
virtual ~Usermod() { if (um_data) delete um_data; }
virtual void setup() = 0; // pure virtual, has to be overriden
virtual void loop() = 0; // pure virtual, has to be overriden
virtual void handleOverlayDraw() {} virtual void handleOverlayDraw() {}
virtual bool handleButton(uint8_t b) { return false; } virtual bool handleButton(uint8_t b) { return false; }
virtual void setup() {} virtual bool getUMData(um_data_t **data) { if (data) *data = nullptr; return false; };
virtual void connected() {} virtual void connected() {}
virtual void appendConfigData() {}
virtual void addToJsonState(JsonObject& obj) {} virtual void addToJsonState(JsonObject& obj) {}
virtual void addToJsonInfo(JsonObject& obj) {} virtual void addToJsonInfo(JsonObject& obj) {}
virtual void readFromJsonState(JsonObject& obj) {} virtual void readFromJsonState(JsonObject& obj) {}
@ -230,6 +269,7 @@ class Usermod {
virtual bool readFromConfig(JsonObject& obj) { return true; } // Note as of 2021-06 readFromConfig() now needs to return a bool, see usermod_v2_example.h virtual bool readFromConfig(JsonObject& obj) { return true; } // Note as of 2021-06 readFromConfig() now needs to return a bool, see usermod_v2_example.h
virtual void onMqttConnect(bool sessionPresent) {} virtual void onMqttConnect(bool sessionPresent) {}
virtual bool onMqttMessage(char* topic, char* payload) { return false; } virtual bool onMqttMessage(char* topic, char* payload) { return false; }
virtual void onUpdateBegin(bool) {}
virtual uint16_t getId() {return USERMOD_ID_UNSPECIFIED;} virtual uint16_t getId() {return USERMOD_ID_UNSPECIFIED;}
}; };
@ -242,8 +282,10 @@ class UsermodManager {
void loop(); void loop();
void handleOverlayDraw(); void handleOverlayDraw();
bool handleButton(uint8_t b); bool handleButton(uint8_t b);
bool getUMData(um_data_t **um_data, uint8_t mod_id = USERMOD_ID_RESERVED); // USERMOD_ID_RESERVED will poll all usermods
void setup(); void setup();
void connected(); void connected();
void appendConfigData();
void addToJsonState(JsonObject& obj); void addToJsonState(JsonObject& obj);
void addToJsonInfo(JsonObject& obj); void addToJsonInfo(JsonObject& obj);
void readFromJsonState(JsonObject& obj); void readFromJsonState(JsonObject& obj);
@ -251,6 +293,7 @@ class UsermodManager {
bool readFromConfig(JsonObject& obj); bool readFromConfig(JsonObject& obj);
void onMqttConnect(bool sessionPresent); void onMqttConnect(bool sessionPresent);
bool onMqttMessage(char* topic, char* payload); bool onMqttMessage(char* topic, char* payload);
void onUpdateBegin(bool);
bool add(Usermod* um); bool add(Usermod* um);
Usermod* lookup(uint16_t mod_id); Usermod* lookup(uint16_t mod_id);
byte getModCount(); byte getModCount();

View File

@ -1432,119 +1432,138 @@ const uint8_t PAGE_settings_sec[] PROGMEM = {
// Autogenerated from wled00/data/settings_um.htm, do not edit!! // Autogenerated from wled00/data/settings_um.htm, do not edit!!
const uint16_t PAGE_settings_um_length = 1767; const uint16_t PAGE_settings_um_length = 2078;
const uint8_t PAGE_settings_um[] PROGMEM = { const uint8_t PAGE_settings_um[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xa5, 0x57, 0x6d, 0x6f, 0xe3, 0x36, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xa5, 0x58, 0x6b, 0x73, 0xdb, 0xb8,
0x12, 0xfe, 0xee, 0x5f, 0xc1, 0x70, 0x83, 0x44, 0x82, 0x19, 0xd9, 0xde, 0x74, 0xef, 0xb2, 0xb6, 0x15, 0xfd, 0xee, 0x5f, 0x41, 0x23, 0x1e, 0x9b, 0x1c, 0xd1, 0x94, 0x1c, 0x77, 0xdb, 0x44, 0x12,
0x28, 0xb7, 0xd9, 0x97, 0x6e, 0x80, 0xdd, 0x4b, 0x80, 0xec, 0xb5, 0x38, 0x04, 0x41, 0x23, 0x4b, 0xe4, 0xc6, 0x79, 0x34, 0x9e, 0x49, 0x62, 0xcf, 0x38, 0xbb, 0x9d, 0x8e, 0xc7, 0xb3, 0xa6, 0x48,
0x94, 0xcd, 0x46, 0x22, 0x05, 0x92, 0xb2, 0x93, 0x2a, 0xfe, 0xef, 0x37, 0xa4, 0x64, 0xd9, 0xde, 0x48, 0x42, 0x4c, 0x01, 0x1c, 0x00, 0xf4, 0xa3, 0xb2, 0xfe, 0x7b, 0xcf, 0x05, 0x29, 0x4a, 0x4a,
0x4d, 0xda, 0x2b, 0xee, 0x8b, 0x6d, 0x92, 0x33, 0xc3, 0xe1, 0x33, 0xcf, 0xbc, 0x38, 0x3c, 0x78, 0x9c, 0xdd, 0x76, 0xfa, 0xc5, 0x22, 0x80, 0x8b, 0x8b, 0x8b, 0x73, 0xcf, 0x7d, 0xc0, 0xc3, 0xdd,
0x7f, 0xf9, 0xee, 0xeb, 0x7f, 0xae, 0x3e, 0xa0, 0x85, 0x29, 0xf2, 0x28, 0x6c, 0x3f, 0x59, 0x9c, 0x77, 0xe7, 0x6f, 0xbf, 0xfe, 0xeb, 0xe2, 0x7d, 0x30, 0x73, 0xf3, 0x62, 0x34, 0x6c, 0xfe, 0x8a,
0xa2, 0x3c, 0x16, 0x73, 0x8a, 0x99, 0xc0, 0x51, 0x58, 0x30, 0x13, 0xa3, 0x64, 0x11, 0x2b, 0xcd, 0x34, 0x0f, 0x8a, 0x54, 0x4d, 0x39, 0x13, 0x8a, 0x8d, 0x86, 0x73, 0xe1, 0xd2, 0x20, 0x9b, 0xa5,
0x0c, 0xc5, 0x95, 0xc9, 0x4e, 0xce, 0x36, 0xbb, 0x3d, 0x11, 0x17, 0x8c, 0xe2, 0x25, 0x67, 0xab, 0xc6, 0x0a, 0xc7, 0x59, 0xe5, 0x26, 0x87, 0xaf, 0x56, 0xb3, 0x3b, 0x2a, 0x9d, 0x0b, 0xce, 0xee,
0x52, 0x2a, 0x83, 0x51, 0x22, 0x85, 0x61, 0x02, 0xc4, 0x56, 0x3c, 0x35, 0x0b, 0xfa, 0x66, 0x38, 0xa4, 0xb8, 0x2f, 0xb5, 0x71, 0x2c, 0xc8, 0xb4, 0x72, 0x42, 0x41, 0xec, 0x5e, 0xe6, 0x6e, 0xc6,
0xec, 0x44, 0xbf, 0x39, 0x4a, 0xd9, 0x92, 0x27, 0xec, 0xc4, 0x2d, 0x08, 0x17, 0xdc, 0xf0, 0x38, 0x7f, 0xe9, 0xf5, 0x5a, 0xd1, 0xef, 0x96, 0x72, 0x71, 0x27, 0x33, 0x71, 0xe8, 0x07, 0xb1, 0x54,
0x3f, 0xd1, 0x49, 0x9c, 0x33, 0x3a, 0x22, 0x45, 0xfc, 0xc0, 0x8b, 0xaa, 0xe8, 0xd6, 0x95, 0x66, 0xd2, 0xc9, 0xb4, 0x38, 0xb4, 0x59, 0x5a, 0x08, 0x7e, 0x14, 0xcf, 0xd3, 0x07, 0x39, 0xaf, 0xe6,
0xca, 0x2d, 0xe2, 0x19, 0xac, 0x85, 0xc4, 0xdf, 0xdd, 0x1c, 0x85, 0x86, 0x9b, 0x9c, 0x45, 0xff, 0xed, 0xb8, 0xb2, 0xc2, 0xf8, 0x41, 0x3a, 0xc6, 0x58, 0x69, 0xf6, 0xc3, 0xc9, 0xa3, 0xa1, 0x93,
0x06, 0xc9, 0x42, 0xa6, 0xe8, 0x9a, 0x19, 0xc3, 0xc5, 0x5c, 0x87, 0x83, 0x66, 0x3f, 0xd4, 0x89, 0xae, 0x10, 0xa3, 0x5f, 0x21, 0x39, 0xd7, 0x79, 0x70, 0x29, 0x9c, 0x93, 0x6a, 0x6a, 0x87, 0xdd,
0xe2, 0xa5, 0x89, 0x7a, 0xcb, 0x58, 0x21, 0xb9, 0x12, 0x4c, 0x91, 0x5c, 0x26, 0xbc, 0x24, 0x95, 0x7a, 0x7e, 0x68, 0x33, 0x23, 0x4b, 0x37, 0xda, 0xb9, 0x4b, 0x4d, 0xa0, 0xef, 0x95, 0x30, 0x71,
0x92, 0x2b, 0x4d, 0x52, 0x9a, 0xca, 0xa4, 0x2a, 0xc0, 0x3f, 0x52, 0x15, 0xef, 0xb2, 0x39, 0xad, 0xa1, 0x33, 0x59, 0xc6, 0x95, 0xd1, 0xf7, 0x36, 0xce, 0x79, 0xae, 0xb3, 0x6a, 0x0e, 0xfb, 0xe2,
0xd7, 0xa4, 0xe4, 0x42, 0xd3, 0x9b, 0x7f, 0x90, 0x7f, 0x92, 0x33, 0xf2, 0x96, 0x8c, 0x86, 0x64, 0x6a, 0xfe, 0x76, 0x32, 0xe5, 0x8b, 0x65, 0x5c, 0x4a, 0x65, 0xf9, 0xd5, 0x5f, 0xe3, 0xbf, 0xc5,
0x34, 0xba, 0xb5, 0x9b, 0x97, 0xf4, 0x06, 0x2b, 0xbd, 0x4c, 0x31, 0xf9, 0xeb, 0xaf, 0x5b, 0x7b, 0xaf, 0xe2, 0xd7, 0xf1, 0x51, 0x2f, 0x3e, 0x3a, 0xba, 0xa6, 0xc9, 0x73, 0x7e, 0xc5, 0x8c, 0xbd,
0x0b, 0x3d, 0x18, 0x11, 0x51, 0x15, 0x5f, 0xe8, 0x70, 0x92, 0x55, 0x22, 0x31, 0x5c, 0x0a, 0x34, 0xcb, 0x59, 0xfc, 0xe7, 0x3f, 0xd7, 0x74, 0x0a, 0xdf, 0x3d, 0x8a, 0x55, 0x35, 0xff, 0xcc, 0x7b,
0xbf, 0x48, 0x3d, 0xe6, 0xd7, 0x8a, 0x99, 0x4a, 0x09, 0x94, 0x06, 0x73, 0x66, 0x3e, 0xe4, 0xcc, 0x83, 0x49, 0xa5, 0x32, 0x27, 0xb5, 0x0a, 0xa6, 0x67, 0x79, 0x28, 0xa2, 0x85, 0x11, 0xae, 0x32,
0x3a, 0x70, 0xfe, 0xe8, 0x8e, 0xd6, 0x9d, 0x28, 0xd7, 0x97, 0x3b, 0xa2, 0xec, 0xe8, 0x08, 0xcb, 0x2a, 0xc8, 0x93, 0xa9, 0x70, 0xef, 0x0b, 0x41, 0x06, 0x9c, 0x3e, 0xfa, 0xa5, 0x65, 0x2b, 0x2a,
0xd9, 0xef, 0x2c, 0x31, 0x98, 0x52, 0xf3, 0x58, 0x32, 0x99, 0xd9, 0xbd, 0x83, 0x9f, 0x94, 0x8a, 0xed, 0xf9, 0x86, 0xa8, 0xd8, 0xdf, 0x67, 0x7a, 0xfc, 0x4d, 0x64, 0x8e, 0x71, 0xee, 0x1e, 0x4b,
0x1f, 0x03, 0xae, 0xdd, 0xf7, 0x9e, 0xfe, 0x27, 0xcf, 0xaf, 0x57, 0x5c, 0xa4, 0x72, 0x15, 0xc8, 0xa1, 0x27, 0x34, 0xb7, 0xfb, 0xc6, 0x98, 0xf4, 0x31, 0x91, 0xd6, 0xff, 0x6e, 0xed, 0xff, 0x18,
0x92, 0x09, 0x0f, 0x2f, 0x8c, 0x29, 0xf5, 0x78, 0x30, 0x98, 0x73, 0xb3, 0xa8, 0x66, 0x41, 0x22, 0x46, 0x8b, 0x7b, 0xa9, 0x72, 0x7d, 0x9f, 0xe8, 0x52, 0xa8, 0x90, 0xcd, 0x9c, 0x2b, 0x6d, 0xbf,
0x8b, 0xc1, 0x4f, 0x5c, 0x25, 0x52, 0xca, 0x7b, 0xce, 0x06, 0xbf, 0x7e, 0xfe, 0xf0, 0x7e, 0xb0, 0xdb, 0x9d, 0x4a, 0x37, 0xab, 0xc6, 0x49, 0xa6, 0xe7, 0xdd, 0x37, 0xd2, 0x64, 0x5a, 0xeb, 0x5b,
0xe2, 0xf7, 0x7c, 0xb0, 0xc1, 0xf0, 0x55, 0xd5, 0x80, 0x7a, 0xa2, 0xdb, 0x0d, 0xbc, 0x63, 0xfd, 0x29, 0xba, 0xff, 0xfc, 0xf4, 0xfe, 0x5d, 0xf7, 0x5e, 0xde, 0xca, 0xee, 0x0a, 0xc3, 0x17, 0x55,
0xfc, 0x5b, 0xeb, 0x83, 0x4e, 0x8a, 0xe0, 0xdf, 0x34, 0xcb, 0xb3, 0x5d, 0xe9, 0x6b, 0x90, 0xc6, 0x0d, 0xea, 0xa1, 0x6d, 0x26, 0xd8, 0x86, 0xf6, 0xd3, 0xef, 0xb5, 0x77, 0x5b, 0xa9, 0x98, 0xfd,
0x19, 0xcf, 0xd9, 0x18, 0xbc, 0x6f, 0xd5, 0x00, 0xa1, 0xd8, 0x1e, 0x06, 0xa5, 0x92, 0x46, 0x26, 0x6e, 0x45, 0x31, 0xd9, 0x94, 0xbe, 0x84, 0x34, 0x9b, 0xc8, 0x42, 0xf4, 0x61, 0x7d, 0xb3, 0x0d,
0x32, 0x3f, 0x3a, 0xf2, 0x1c, 0x6a, 0x43, 0xe2, 0xb9, 0x18, 0x51, 0x2b, 0x91, 0x5f, 0x1b, 0xa9, 0x08, 0xa5, 0xb4, 0x98, 0x94, 0x46, 0x3b, 0x9d, 0xe9, 0x62, 0x7f, 0x3f, 0xf4, 0xa8, 0xf5, 0xe2,
0xe2, 0x39, 0xb3, 0x48, 0x5d, 0x18, 0x56, 0x78, 0x18, 0x76, 0x2f, 0x4a, 0xec, 0xfb, 0x4f, 0x4f, 0xd0, 0xfb, 0x88, 0x93, 0x44, 0x71, 0xe9, 0xb4, 0x49, 0xa7, 0x82, 0x90, 0x3a, 0x73, 0x62, 0x1e,
0xad, 0x18, 0xe8, 0x17, 0xa5, 0xf1, 0xf0, 0x47, 0xb0, 0x8f, 0xbe, 0xc8, 0x94, 0x05, 0xe8, 0x2a, 0x32, 0xcc, 0x9e, 0x95, 0x2c, 0x8a, 0x9e, 0x9e, 0x1a, 0x31, 0xec, 0x9f, 0x97, 0x2e, 0x64, 0x1f,
0x67, 0xb1, 0x66, 0x08, 0x60, 0x65, 0x0a, 0xd9, 0x97, 0xa1, 0x8b, 0xab, 0x03, 0xec, 0x93, 0x3d, 0xa0, 0x3f, 0xf8, 0xac, 0x73, 0x91, 0x04, 0x17, 0x85, 0x48, 0xad, 0x08, 0x00, 0xab, 0x30, 0x01,
0x8b, 0x7a, 0xdf, 0x62, 0x43, 0x0c, 0xdf, 0xf7, 0xc9, 0xcf, 0xcc, 0xfc, 0xe2, 0xf9, 0x2e, 0x76, 0xdd, 0x2c, 0x38, 0xbb, 0xd8, 0x65, 0x51, 0xbc, 0xa5, 0xd1, 0x6e, 0x6b, 0xac, 0x89, 0x11, 0x45,
0xd1, 0xf0, 0xe9, 0xc9, 0xed, 0x4f, 0xf3, 0x14, 0x1e, 0x31, 0xb6, 0xf1, 0xc3, 0x55, 0x81, 0xfd, 0x90, 0xca, 0x61, 0xaf, 0x77, 0x1d, 0xce, 0x20, 0x8f, 0xb1, 0x6a, 0xce, 0xa2, 0x44, 0x2a, 0xd0,
0x80, 0x0b, 0x20, 0xd3, 0xa7, 0xaf, 0x5f, 0x3e, 0x53, 0xfc, 0x2f, 0x89, 0x5a, 0xfe, 0x69, 0x04, 0xe7, 0xe3, 0xd7, 0xcf, 0x9f, 0x38, 0xfb, 0xa2, 0x83, 0x86, 0x71, 0x36, 0x00, 0x5d, 0x5c, 0x5a,
0xe4, 0x31, 0x71, 0x9e, 0xb3, 0x34, 0xc0, 0xbb, 0xa1, 0xfc, 0xb8, 0x1b, 0x4a, 0x4a, 0x69, 0x1f, 0x14, 0x22, 0x4f, 0xd8, 0x96, 0xf7, 0x3e, 0x6c, 0x7a, 0x8f, 0x73, 0xde, 0x81, 0xbb, 0xc4, 0x2e,
0x62, 0xc7, 0x0e, 0x28, 0xf5, 0x86, 0x4f, 0xfb, 0x31, 0xbf, 0x78, 0x4e, 0x90, 0x7e, 0x27, 0x98, 0xe7, 0x61, 0xef, 0x69, 0xdb, 0xcd, 0x67, 0xcf, 0x09, 0xf2, 0x1f, 0x04, 0xb3, 0x99, 0xc8, 0x6e,
0x2c, 0x58, 0x72, 0xef, 0x31, 0x22, 0xfc, 0xda, 0x32, 0x9b, 0x53, 0x16, 0xd8, 0xcc, 0x08, 0x14, 0x43, 0x11, 0xbb, 0x68, 0x41, 0x64, 0x56, 0x5c, 0x24, 0x14, 0x0c, 0x89, 0x11, 0x65, 0x91, 0x66,
0x2b, 0xf3, 0x38, 0x61, 0x1e, 0xbe, 0xb9, 0x85, 0x38, 0x80, 0x9b, 0xba, 0x9a, 0x69, 0xa3, 0xbc, 0x22, 0x64, 0x57, 0xd7, 0x80, 0x1e, 0x76, 0xda, 0x6a, 0x6c, 0x9d, 0x09, 0x0f, 0x8f, 0xa3, 0x81,
0x93, 0x53, 0x7f, 0xc2, 0x33, 0x0f, 0xc3, 0x9b, 0x66, 0x4c, 0x41, 0x10, 0x58, 0x60, 0x49, 0x04, 0x9c, 0x84, 0x0c, 0xf7, 0x18, 0x0b, 0x03, 0xdc, 0x45, 0x42, 0xbc, 0x01, 0x8f, 0x40, 0x66, 0x0c,
0xa4, 0x02, 0x66, 0xc3, 0x92, 0x6f, 0x04, 0x87, 0xe4, 0xd4, 0xf7, 0x33, 0xa9, 0x3c, 0x6b, 0x56, 0xd5, 0x4a, 0xb0, 0x17, 0x1f, 0x47, 0xd1, 0x44, 0x9b, 0x90, 0xd4, 0x4a, 0xb0, 0x55, 0x0e, 0x29,
0x03, 0x75, 0x75, 0x68, 0x13, 0x22, 0xc8, 0x99, 0x98, 0x9b, 0xc5, 0x44, 0xf7, 0xfb, 0x3e, 0xd8, 0x06, 0x92, 0x42, 0xa8, 0xa9, 0x9b, 0x0d, 0x64, 0xa7, 0x13, 0x41, 0x8f, 0xdb, 0xe5, 0x14, 0x04,
0x11, 0x07, 0xd4, 0x66, 0xc4, 0x8d, 0xbe, 0xf5, 0x6b, 0x58, 0xb2, 0x60, 0x19, 0xe7, 0x15, 0xb8, 0x57, 0xf2, 0x3a, 0x5a, 0x60, 0x28, 0x92, 0xbb, 0xb4, 0xa8, 0x60, 0x26, 0x89, 0x62, 0xf2, 0xe9,
0x69, 0x45, 0x61, 0xf3, 0xe9, 0xa9, 0xdd, 0x09, 0x4f, 0x46, 0xdd, 0xef, 0xe8, 0xf4, 0xad, 0x5f, 0xa9, 0x99, 0x19, 0x1e, 0x1e, 0xb5, 0xdf, 0xa3, 0xe3, 0xd7, 0xd1, 0x02, 0x40, 0xbb, 0xc7, 0x42,
0x03, 0xea, 0xe6, 0x31, 0x67, 0x40, 0xbe, 0x5c, 0x2a, 0x8a, 0x15, 0x4b, 0xf1, 0x64, 0xa6, 0x58, 0x80, 0x6f, 0x85, 0x36, 0x9c, 0x19, 0x91, 0xb3, 0xc1, 0xd8, 0x88, 0xf4, 0x76, 0xb9, 0xbd, 0xd2,
0x7c, 0xbf, 0xde, 0x3f, 0xe9, 0x74, 0x4e, 0xa7, 0x18, 0xa2, 0x25, 0xe6, 0x0c, 0x8f, 0xf1, 0xab, 0xee, 0x39, 0x3e, 0x61, 0x70, 0x90, 0x9a, 0x0a, 0xd6, 0x67, 0x2f, 0x26, 0x93, 0x09, 0x5b, 0xae,
0x2c, 0xcb, 0xf0, 0x7a, 0x0b, 0x02, 0x50, 0xe2, 0x0a, 0x2e, 0xb4, 0x88, 0x81, 0x13, 0x4d, 0xbe, 0x41, 0x00, 0x0b, 0x2e, 0x70, 0x20, 0x21, 0x06, 0x23, 0xea, 0x10, 0xf1, 0xb6, 0x23, 0xcd, 0x58,
0x38, 0xdf, 0xa1, 0xe6, 0x68, 0x73, 0xc3, 0x89, 0xbe, 0x85, 0x2c, 0xb9, 0x74, 0x59, 0x13, 0x00, 0x77, 0xa5, 0x62, 0x79, 0x8d, 0xc0, 0x38, 0xf7, 0x81, 0x92, 0xc0, 0xfd, 0x46, 0x0a, 0x12, 0x8e,
0x17, 0x14, 0x67, 0x56, 0xd8, 0x6f, 0x85, 0xb5, 0xef, 0xbb, 0x8a, 0x40, 0x39, 0xd9, 0x58, 0xd2, 0x1a, 0x61, 0x19, 0x45, 0x3e, 0x09, 0x70, 0x15, 0xaf, 0x34, 0xc9, 0x68, 0x20, 0x0a, 0x70, 0x85,
0xfe, 0x84, 0xe5, 0x40, 0x1c, 0x0b, 0xd5, 0x06, 0x98, 0x3f, 0x81, 0xd4, 0x5a, 0xda, 0x4f, 0x40, 0xa0, 0x5a, 0x01, 0xf3, 0x07, 0x90, 0x92, 0xa6, 0xed, 0x98, 0x93, 0x6b, 0xf0, 0x1c, 0xc0, 0x73,
0xbd, 0x05, 0x4f, 0x00, 0x78, 0x22, 0xec, 0x90, 0x13, 0x80, 0x9c, 0xbe, 0x11, 0xb7, 0x11, 0x1d, 0x43, 0xb9, 0x42, 0xce, 0x11, 0x72, 0x57, 0xee, 0x7a, 0xc4, 0x7b, 0xe0, 0xb6, 0xc7, 0xb4, 0xac,
0x02, 0xd1, 0x1d, 0xa6, 0x65, 0xa5, 0x17, 0x9e, 0xdd, 0xf3, 0x5d, 0x7d, 0x69, 0xd6, 0xce, 0x25, 0xec, 0x2c, 0xa4, 0xb9, 0xc8, 0xa7, 0x94, 0x7a, 0xec, 0x4d, 0x8a, 0x56, 0x76, 0xfc, 0x20, 0xfd,
0xbf, 0xf5, 0x43, 0x7f, 0x27, 0xfd, 0xa2, 0xe8, 0x4b, 0xae, 0x3c, 0xe3, 0x46, 0xf7, 0x5a, 0x7b, 0x73, 0xd1, 0x9f, 0x98, 0xf2, 0x8c, 0x19, 0xed, 0x6d, 0xe9, 0xe8, 0x35, 0x9c, 0x69, 0x9e, 0x7f,
0xf5, 0x16, 0xce, 0x38, 0x4d, 0x3f, 0x72, 0x96, 0xa7, 0x96, 0x56, 0x04, 0xc0, 0x83, 0xfa, 0xd5, 0x90, 0xa2, 0xc8, 0x89, 0x56, 0x31, 0xc0, 0x43, 0xca, 0x6a, 0x81, 0x55, 0x9b, 0xc0, 0xca, 0xd8,
0x01, 0xcb, 0x77, 0x81, 0xd5, 0x44, 0x3e, 0x03, 0x2c, 0x88, 0xe0, 0x4a, 0xdc, 0x0b, 0xf0, 0x0a, 0x3e, 0x03, 0x2c, 0x44, 0x58, 0xa5, 0x6e, 0x15, 0xac, 0x02, 0x6e, 0xdc, 0x91, 0xe3, 0xa5, 0xca,
0x70, 0xa3, 0xc2, 0x06, 0x9e, 0x8b, 0x24, 0xaf, 0x52, 0x38, 0x84, 0xe8, 0xf9, 0xd3, 0x9d, 0x0b, 0x8a, 0x2a, 0xc7, 0x22, 0xbc, 0x17, 0x9d, 0x6c, 0x1c, 0x00, 0x15, 0x51, 0x7f, 0x3d, 0xee, 0x60,
0xc0, 0x84, 0x3f, 0xde, 0xae, 0xfb, 0x70, 0xde, 0x17, 0x6e, 0xf7, 0x85, 0xd7, 0xf0, 0x2d, 0xb0, 0xbd, 0xe3, 0xfc, 0xec, 0x4f, 0x6e, 0xa3, 0xd6, 0xc0, 0x5a, 0xdc, 0xc8, 0x0e, 0xd5, 0xea, 0x46,
0x12, 0x5e, 0x24, 0x43, 0xbe, 0x79, 0x91, 0x84, 0x17, 0xed, 0xbb, 0x7e, 0x23, 0x6f, 0xc9, 0xc1, 0x16, 0x37, 0xda, 0x36, 0xfd, 0xca, 0x5e, 0xc7, 0xbb, 0xbd, 0x5a, 0x93, 0x0f, 0x0f, 0x13, 0xeb,
0xb0, 0xb1, 0xe4, 0xd2, 0xc3, 0x10, 0xb5, 0xa9, 0x99, 0x7c, 0xa2, 0x57, 0xdc, 0x24, 0x0b, 0x4f, 0x55, 0x9a, 0x54, 0x03, 0x7b, 0x2f, 0x5d, 0x06, 0xf0, 0xa2, 0x45, 0x86, 0xb4, 0xc0, 0xc6, 0x5a,
0xf9, 0x75, 0x02, 0x35, 0x02, 0xcf, 0xa4, 0x84, 0x62, 0x21, 0xf0, 0x18, 0xe8, 0xe8, 0xb2, 0x6a, 0x23, 0x3f, 0x28, 0xd6, 0xd7, 0x9c, 0xf9, 0xa8, 0x1a, 0xeb, 0x07, 0x16, 0x1b, 0x7e, 0x50, 0x53,
0x26, 0x1f, 0x30, 0x31, 0xf4, 0xb8, 0xa1, 0x34, 0x36, 0xaa, 0x62, 0xf8, 0xb8, 0xef, 0xf1, 0x29, 0x9a, 0x39, 0x53, 0x09, 0x76, 0xd0, 0x09, 0xd5, 0x09, 0xab, 0xa3, 0x0e, 0x94, 0xed, 0x83, 0x06,
0x6e, 0xb2, 0x0e, 0x28, 0x3b, 0x06, 0x1a, 0x34, 0xb4, 0x9d, 0x38, 0x1b, 0x6d, 0x56, 0x8d, 0x0d, 0x35, 0x6d, 0x07, 0x5e, 0x47, 0x13, 0x55, 0x7d, 0xc3, 0x6f, 0x9a, 0x5d, 0x7b, 0x0b, 0xb5, 0x64,
0xbd, 0x6b, 0xb5, 0x0e, 0x6b, 0xbe, 0xc6, 0x77, 0xa4, 0x25, 0x11, 0x15, 0x3b, 0xa4, 0x99, 0x7a, 0x37, 0x71, 0x43, 0x22, 0xee, 0x36, 0x48, 0x73, 0x12, 0x9a, 0x0e, 0x3f, 0x08, 0x50, 0xde, 0x38,
0xa6, 0x4f, 0x8f, 0x11, 0xf4, 0x3a, 0x8a, 0x4f, 0xdf, 0x62, 0x54, 0x70, 0x41, 0xf1, 0xc9, 0x08, 0x3b, 0x7e, 0xcd, 0x82, 0xb9, 0x54, 0x9c, 0x1d, 0x1e, 0x41, 0x7b, 0x91, 0x5a, 0xcb, 0x99, 0x65,
0xac, 0xe7, 0xb1, 0xd6, 0x14, 0x6b, 0x7c, 0x0c, 0xee, 0x62, 0x2e, 0x0c, 0xf6, 0xc7, 0x4e, 0x54, 0x07, 0x30, 0x97, 0x49, 0xe5, 0x58, 0xd4, 0xf7, 0xa2, 0xd6, 0x89, 0x92, 0xb3, 0x54, 0x3d, 0xb6,
0x1b, 0x56, 0x52, 0x1c, 0x8b, 0xc7, 0x4e, 0xe6, 0xe1, 0x21, 0xc7, 0xc7, 0xad, 0x07, 0x29, 0xcb, 0x32, 0x0f, 0x0f, 0x05, 0x3b, 0x68, 0x2c, 0xc8, 0xc5, 0x24, 0xad, 0x0a, 0x47, 0xf6, 0x3b, 0xf1,
0xe2, 0x2a, 0x37, 0xd6, 0x7f, 0xc3, 0x1e, 0x8c, 0xf5, 0x7d, 0xcf, 0x0b, 0xe4, 0xf2, 0xaa, 0xed, 0xe0, 0xc8, 0xf6, 0x2d, 0x2b, 0x02, 0x1f, 0x57, 0x4d, 0xc9, 0xed, 0xbf, 0xfc, 0xa5, 0x57, 0x3e,
0xbf, 0xe3, 0xd7, 0x6f, 0x86, 0xe5, 0xc3, 0x04, 0xdf, 0xad, 0xbf, 0x09, 0x0e, 0xb0, 0xcc, 0xb5, 0x0c, 0xd8, 0xcd, 0xf2, 0x3b, 0xe7, 0x80, 0x65, 0xbe, 0x0a, 0x76, 0x10, 0x7a, 0x8d, 0xad, 0x24,
0xc4, 0x3e, 0xa4, 0x5e, 0xeb, 0xab, 0x95, 0x48, 0xd9, 0xc3, 0x65, 0xe6, 0x04, 0xfa, 0x23, 0xa8, 0x91, 0x8b, 0x87, 0xf3, 0x89, 0x17, 0xe8, 0x1c, 0x21, 0x19, 0x36, 0x22, 0x37, 0xc1, 0xde, 0xc2,
0x8c, 0xad, 0xc8, 0x1d, 0x3a, 0xac, 0xc5, 0x7a, 0x8c, 0xe0, 0x81, 0x1d, 0x64, 0x94, 0xaa, 0xe9, 0x2d, 0xfb, 0x01, 0x2e, 0xd8, 0x42, 0xc6, 0xb9, 0x3e, 0x59, 0x2d, 0x0f, 0xa5, 0x2a, 0x2b, 0x17,
0xe6, 0x38, 0xe4, 0xa2, 0xac, 0x0c, 0xb2, 0x90, 0x53, 0xbc, 0xe0, 0x69, 0x0a, 0x03, 0x05, 0x6a, 0x10, 0xe4, 0x9c, 0xcd, 0x64, 0x9e, 0xa3, 0x87, 0x08, 0xea, 0x62, 0xbd, 0xb7, 0x10, 0xcb, 0x3e,
0x3a, 0xf7, 0x61, 0xcd, 0xd6, 0x63, 0xab, 0x7d, 0x58, 0xeb, 0xa9, 0x4d, 0x29, 0xc0, 0x12, 0x7c, 0xed, 0xde, 0x5b, 0xc8, 0x13, 0x0a, 0x29, 0x60, 0x09, 0x1b, 0x1b, 0x83, 0x27, 0x29, 0x5c, 0xc6,
0x6c, 0x1d, 0xce, 0x62, 0x08, 0x19, 0x8e, 0xee, 0xc6, 0x1a, 0xaa, 0xfb, 0xff, 0x6d, 0xed, 0xb0, 0x46, 0x37, 0x7d, 0x89, 0x64, 0xfb, 0x7f, 0x6b, 0xdb, 0x5b, 0xe8, 0x25, 0x94, 0xad, 0xcd, 0xde,
0x56, 0x6b, 0x30, 0xb6, 0x75, 0x7b, 0xcf, 0xd2, 0x61, 0xed, 0x30, 0xa6, 0xd6, 0xf1, 0x2e, 0x82, 0xd2, 0xb4, 0xb7, 0xf0, 0x18, 0x73, 0x32, 0xbc, 0xf5, 0x20, 0x36, 0xfc, 0xb1, 0xea, 0xbd, 0x85,
0xa0, 0xf0, 0xe7, 0xa6, 0x0f, 0x6b, 0xb3, 0x46, 0x52, 0x38, 0x43, 0x2d, 0x61, 0x3c, 0xb3, 0xe0, 0x59, 0x06, 0x5a, 0x79, 0x45, 0x0d, 0x61, 0x42, 0x37, 0x93, 0x36, 0x3e, 0xd8, 0x5b, 0xfc, 0x1c,
0x9a, 0x1c, 0x1f, 0xd6, 0x2f, 0x23, 0xb7, 0x3e, 0xf6, 0x61, 0x54, 0x99, 0xa9, 0xe8, 0x6e, 0xa7, 0xb9, 0xe5, 0x41, 0x84, 0xee, 0x64, 0x6c, 0x46, 0x37, 0xcb, 0xad, 0x78, 0x7b, 0x67, 0x74, 0x89,
0x7c, 0xb9, 0x8e, 0x52, 0x67, 0xcc, 0xb2, 0xd1, 0xb6, 0xb2, 0xa9, 0xeb, 0xd0, 0xd0, 0xa0, 0x71, 0xf2, 0xa7, 0xea, 0x4c, 0x5e, 0x08, 0x87, 0x4c, 0x9e, 0x27, 0x19, 0xfc, 0xea, 0x44, 0xd3, 0x0a,
0xdf, 0xb5, 0x1c, 0xcb, 0xb2, 0x3e, 0x1e, 0x24, 0xd9, 0x3c, 0xf8, 0x5d, 0x4b, 0x81, 0x49, 0x0d, 0x84, 0x0c, 0xf5, 0x93, 0x2a, 0x7d, 0x84, 0x88, 0xdc, 0xec, 0x11, 0xec, 0xe9, 0xe3, 0x17, 0x58,
0x13, 0xd5, 0x42, 0xa6, 0x63, 0x0c, 0x09, 0x8c, 0xd7, 0x7e, 0x60, 0x16, 0xd0, 0x78, 0x19, 0x8d, 0xba, 0x0a, 0x9e, 0xe8, 0xea, 0xe8, 0x9a, 0x52, 0xbc, 0x44, 0x4e, 0x3f, 0xfb, 0x72, 0xf1, 0xeb,
0xe0, 0x3e, 0x79, 0x0f, 0x80, 0xb9, 0xe6, 0x04, 0x00, 0x2a, 0x65, 0xab, 0x94, 0xab, 0xa6, 0x29, 0x57, 0xba, 0x99, 0x4c, 0x5c, 0x3a, 0x25, 0x29, 0xb8, 0xb7, 0x66, 0x47, 0x3d, 0x09, 0x00, 0x9e,
0xd7, 0x50, 0xbd, 0x1e, 0x2d, 0x9d, 0x72, 0x2e, 0x18, 0xb4, 0x40, 0xe6, 0x8c, 0x79, 0xd0, 0xe7, 0x9e, 0xd6, 0xc5, 0xa0, 0x99, 0x8a, 0x6a, 0x13, 0x04, 0x86, 0x1e, 0xc1, 0x81, 0xf4, 0x45, 0x65,
0x3a, 0x7d, 0x9b, 0xe4, 0xcd, 0xf8, 0xc3, 0x82, 0xaa, 0x20, 0xdb, 0xb2, 0xda, 0x00, 0x47, 0x31, 0xb0, 0x1d, 0x78, 0x32, 0x49, 0x1d, 0x22, 0x7e, 0x5c, 0x39, 0xd1, 0x96, 0x85, 0x4e, 0xc7, 0xd6,
0x26, 0xb6, 0x06, 0x38, 0x91, 0xdd, 0x3a, 0x00, 0xc9, 0xf6, 0x4c, 0x1d, 0x68, 0xc5, 0x3a, 0xcc, 0x85, 0xc8, 0xf0, 0xcd, 0x65, 0x04, 0xe2, 0x80, 0x91, 0x66, 0xb6, 0xcb, 0x8d, 0xd7, 0x05, 0xe3,
0x17, 0x0a, 0x66, 0xcb, 0xd3, 0xc8, 0xe2, 0x19, 0x0e, 0xe0, 0xc7, 0x1d, 0xd9, 0xc9, 0xd6, 0xae, 0xbc, 0xea, 0xcd, 0x09, 0xcf, 0xe9, 0xcd, 0x09, 0x4f, 0xd8, 0x8d, 0x09, 0x45, 0xd5, 0xf9, 0xcd,
0x62, 0x40, 0x27, 0x9b, 0x60, 0x1b, 0x0c, 0xa7, 0xb7, 0x61, 0x23, 0xc5, 0x5d, 0x63, 0x85, 0x2b, 0x4a, 0x6b, 0x58, 0x4f, 0xc7, 0xa6, 0x36, 0x32, 0x5a, 0x36, 0xd5, 0xf2, 0x3b, 0x29, 0x96, 0xa7,
0x33, 0x3e, 0xaf, 0x94, 0x9b, 0x19, 0x90, 0x90, 0x06, 0x65, 0xb2, 0x12, 0x69, 0x60, 0x51, 0xbd, 0x2e, 0x3d, 0x84, 0x08, 0x8b, 0x05, 0xa0, 0x4b, 0xca, 0xd4, 0x00, 0xb4, 0x06, 0xbb, 0x55, 0x52,
0x52, 0x4c, 0x6b, 0x14, 0xf2, 0xe8, 0x3a, 0x5e, 0xb2, 0x70, 0xc0, 0x23, 0x64, 0x24, 0x6a, 0x87, 0x7f, 0x3b, 0x93, 0x48, 0x1a, 0xc8, 0x75, 0xa8, 0xf0, 0xad, 0x9e, 0xaa, 0x28, 0xb6, 0x9c, 0x74,
0x4b, 0xfe, 0x07, 0x43, 0x6d, 0x8a, 0xe8, 0x00, 0xde, 0xff, 0x5c, 0x07, 0x77, 0x77, 0x01, 0xa0, 0x5e, 0xd2, 0x57, 0x9d, 0x5a, 0x7c, 0x42, 0x24, 0x09, 0x80, 0x26, 0xa2, 0x7a, 0xc7, 0x80, 0x40,
0x30, 0x90, 0xd8, 0x58, 0x6c, 0x22, 0x64, 0x1b, 0xcb, 0xff, 0x80, 0x29, 0xb1, 0x68, 0x40, 0x11, 0x93, 0x3f, 0xfa, 0x4d, 0xfb, 0x7d, 0xc8, 0x14, 0x0d, 0x9c, 0xa8, 0x33, 0xc0, 0x19, 0x4e, 0xe0,
0x81, 0x89, 0x66, 0x6e, 0x27, 0x30, 0x7f, 0xa7, 0xa6, 0xea, 0xe5, 0xb5, 0xb5, 0xc2, 0x60, 0xc8, 0x2e, 0x16, 0x49, 0x5a, 0xa2, 0x53, 0xca, 0x6b, 0x03, 0x50, 0x76, 0x08, 0x63, 0xd2, 0x53, 0xa7,
0x61, 0x4b, 0x40, 0xe8, 0x7d, 0xe3, 0x09, 0x4c, 0x17, 0xbb, 0x4a, 0x69, 0x70, 0x9d, 0xf9, 0xc4, 0x6b, 0x94, 0x41, 0x5a, 0xf8, 0x82, 0xfe, 0xc5, 0x6e, 0x66, 0xee, 0xc5, 0xe6, 0x02, 0xb2, 0xf7,
0x7e, 0x06, 0x8e, 0x51, 0xbf, 0x80, 0xdb, 0x29, 0x37, 0x8f, 0x1e, 0xa4, 0xa5, 0xdb, 0x05, 0x5e, 0xaa, 0xee, 0x8a, 0x84, 0x6e, 0x8b, 0xfb, 0xd3, 0x04, 0x7c, 0x4d, 0xfd, 0x0c, 0x91, 0x46, 0xe4,
0x15, 0x1c, 0xb4, 0xd6, 0xbd, 0x70, 0xd0, 0x4e, 0xb4, 0xed, 0x64, 0x8b, 0xb4, 0x4a, 0xe8, 0x76, 0x67, 0x44, 0x44, 0xee, 0xa2, 0x6d, 0xde, 0x9d, 0xa9, 0x89, 0x5e, 0x5d, 0x68, 0x65, 0xfd, 0x33,
0xf8, 0x1a, 0x68, 0x08, 0xef, 0xb4, 0xa4, 0x76, 0x54, 0xdf, 0x4a, 0x5a, 0xb7, 0xa3, 0xde, 0x8f, 0xcc, 0x82, 0xe9, 0x38, 0x64, 0x7f, 0x9f, 0xfe, 0x82, 0xd2, 0x68, 0x72, 0xdc, 0x9b, 0xfc, 0x1b,
0xbc, 0xb0, 0x33, 0x33, 0xaa, 0x54, 0xee, 0xe1, 0xb6, 0xd9, 0x6a, 0x18, 0xea, 0x26, 0x20, 0xe9, 0x70, 0x53, 0x8e, 0x5a, 0x9f, 0x90, 0xa5, 0x13, 0xf4, 0x54, 0xb8, 0x06, 0x0a, 0xe3, 0xbe, 0x1a,
0x24, 0x20, 0x3c, 0xf0, 0x1f, 0x00, 0x78, 0x2a, 0xd3, 0x47, 0xe0, 0x78, 0x2e, 0xe3, 0x94, 0x62, 0xdb, 0x72, 0xc0, 0x3a, 0x6a, 0xa3, 0xa2, 0xf8, 0xde, 0x69, 0x31, 0x11, 0x94, 0x6f, 0xa9, 0x3f,
0xe0, 0x28, 0xd8, 0x82, 0xa0, 0x17, 0x88, 0xc3, 0xd2, 0xfe, 0xf8, 0x4d, 0x77, 0x83, 0xf8, 0x75, 0x3b, 0xf1, 0x6d, 0x27, 0xba, 0x4e, 0xd6, 0xf1, 0xfd, 0x15, 0xe5, 0xd1, 0x0e, 0xeb, 0x66, 0x93,
0x06, 0x05, 0xcc, 0xb1, 0x92, 0xe2, 0x52, 0x6a, 0xf8, 0x2b, 0x00, 0xcf, 0x72, 0xce, 0x42, 0x21, 0x69, 0xf2, 0xcd, 0x02, 0xaa, 0x78, 0x81, 0x67, 0xc2, 0x4c, 0xe7, 0x7d, 0x06, 0x63, 0xd8, 0x32,
0xb3, 0x6f, 0xb7, 0x8f, 0xb6, 0x06, 0x52, 0xbe, 0xdc, 0x14, 0x2f, 0x23, 0x61, 0x62, 0x5b, 0xb5, 0x4a, 0xdc, 0x0c, 0xdd, 0xa4, 0xe0, 0x23, 0x5c, 0x48, 0xdf, 0xae, 0xfa, 0x2f, 0xa4, 0x08, 0x63,
0x7b, 0xbd, 0x76, 0x73, 0xc1, 0xf2, 0xf2, 0xdc, 0xe6, 0x48, 0x65, 0x0c, 0xe0, 0xd6, 0xa4, 0x68, 0xa8, 0x0e, 0xfb, 0x7e, 0x21, 0x97, 0x16, 0xae, 0x7c, 0xa4, 0x84, 0x59, 0x48, 0x25, 0x10, 0x26,
0xb3, 0xb0, 0x36, 0x93, 0x9c, 0x27, 0xf7, 0x14, 0x7f, 0xb2, 0xce, 0x4c, 0xc3, 0x41, 0x73, 0x00, 0xc2, 0x2b, 0x0b, 0xd1, 0xbc, 0xb5, 0xfb, 0xc9, 0x6b, 0x75, 0x4f, 0x2f, 0x92, 0x6a, 0x1e, 0xaf,
0x0e, 0x83, 0x89, 0x4e, 0xa7, 0xf7, 0x82, 0xd2, 0xb9, 0x55, 0x3a, 0x8f, 0x93, 0xfb, 0xad, 0xde, 0x1b, 0x87, 0x3a, 0x35, 0x70, 0xc6, 0x62, 0xaa, 0x72, 0x5e, 0x64, 0xb3, 0xd2, 0x01, 0xa2, 0x67,
0xde, 0x2d, 0x8d, 0xbf, 0xb8, 0x25, 0x4f, 0x27, 0xa2, 0xa2, 0x5e, 0xa8, 0xcb, 0x58, 0xb8, 0x67, 0x2a, 0x5d, 0x23, 0xd6, 0x66, 0x95, 0x99, 0xc1, 0x83, 0xe9, 0x78, 0x44, 0x19, 0x63, 0xd8, 0xc5,
0xe7, 0x5a, 0x57, 0x49, 0x57, 0x4a, 0xdd, 0x8c, 0x32, 0x9e, 0x2b, 0xc6, 0xc4, 0xa4, 0x65, 0xc3, 0xc7, 0x4d, 0xbc, 0x51, 0x8f, 0xda, 0x9a, 0x88, 0x08, 0x1f, 0x30, 0x0a, 0x36, 0xbf, 0x6f, 0x95,
0x58, 0x48, 0xa0, 0x42, 0x74, 0xf4, 0x6a, 0x34, 0x1c, 0x0e, 0x7f, 0x98, 0xa0, 0x77, 0x7b, 0x74, 0x6f, 0x39, 0x6b, 0x7b, 0x47, 0x1c, 0x39, 0x91, 0xd3, 0xca, 0xf8, 0x46, 0x38, 0x50, 0xda, 0x05,
0xd5, 0x60, 0x3a, 0x3d, 0xb0, 0xc1, 0x03, 0x83, 0x11, 0xda, 0xb5, 0x6b, 0x99, 0xb5, 0x6f, 0x17, 0x13, 0x5d, 0xa9, 0x3c, 0xa1, 0xbc, 0x71, 0x61, 0x84, 0xb5, 0xc1, 0x50, 0x8e, 0x2e, 0xd3, 0x3b,
0x86, 0xa2, 0x6f, 0xac, 0xf6, 0x8e, 0x5e, 0xbd, 0x3d, 0x3b, 0x3b, 0xb3, 0x56, 0xab, 0x3c, 0x75, 0x31, 0xec, 0xca, 0x51, 0xe0, 0x74, 0xd0, 0xbc, 0x98, 0xe4, 0xbf, 0x45, 0xd0, 0x14, 0x01, 0x8b,
0xe4, 0xb7, 0xc1, 0xd9, 0xcf, 0x89, 0xa0, 0xb5, 0xee, 0x12, 0xae, 0x01, 0x66, 0xf1, 0x7a, 0xf7, 0xb6, 0x33, 0x7e, 0xae, 0x49, 0xad, 0x5f, 0x38, 0xff, 0x10, 0xee, 0xb7, 0x30, 0x02, 0xae, 0x68,
0x8f, 0x51, 0x55, 0x42, 0x80, 0x5f, 0x3b, 0xd8, 0x7b, 0xee, 0x72, 0xc8, 0x82, 0xe8, 0x33, 0xd8, 0xb6, 0xe1, 0x12, 0x02, 0xe6, 0xbf, 0x40, 0x34, 0x26, 0x2c, 0x50, 0x24, 0xd1, 0xa4, 0x4f, 0xe9,
0x01, 0xe2, 0xa0, 0x0d, 0x81, 0x82, 0x20, 0xd8, 0x28, 0xab, 0xbf, 0x8a, 0x46, 0x07, 0x6c, 0xef, 0x51, 0xb1, 0xe1, 0x60, 0x7b, 0x77, 0x49, 0xdd, 0x97, 0x40, 0xdb, 0x2e, 0xee, 0x00, 0xcf, 0xbb,
0x6f, 0x21, 0x3b, 0xb0, 0x1c, 0x82, 0x2f, 0x4b, 0x33, 0xcb, 0x39, 0xfb, 0xef, 0xf3, 0xbf, 0xcd, 0xda, 0x0c, 0x34, 0xcc, 0x79, 0x72, 0x39, 0x49, 0x7c, 0x7a, 0xfc, 0x0d, 0x16, 0xe6, 0xd2, 0x3d,
0x92, 0xf9, 0x6c, 0x93, 0x0e, 0x00, 0x00 0x86, 0xa8, 0x31, 0x7e, 0x16, 0x49, 0x72, 0x2e, 0x21, 0xb3, 0xdc, 0x19, 0x76, 0x9b, 0x17, 0x59,
0xf3, 0x32, 0x0b, 0xac, 0xc9, 0xf8, 0xfa, 0xf1, 0xd0, 0xb5, 0xf0, 0xe4, 0x49, 0xc9, 0xe9, 0xa9,
0xb9, 0x96, 0x24, 0x1b, 0x47, 0x3b, 0x7f, 0x97, 0x73, 0x7a, 0xf3, 0x05, 0x95, 0x29, 0x42, 0xd6,
0x74, 0x8e, 0xc8, 0x22, 0xd1, 0x00, 0x92, 0x5e, 0x02, 0x9e, 0xc0, 0x1b, 0x16, 0x49, 0x57, 0xe7,
0x8f, 0x48, 0xd8, 0x85, 0x4e, 0x73, 0xce, 0x40, 0x47, 0xe8, 0x82, 0x7f, 0xe7, 0x81, 0xc4, 0x90,
0x3e, 0x7e, 0xb7, 0xed, 0x43, 0xf2, 0x72, 0x82, 0x6a, 0xec, 0x09, 0xc8, 0x59, 0xa9, 0x2d, 0x9e,
0xb2, 0xb8, 0xb8, 0x37, 0x16, 0x55, 0x99, 0x6e, 0x4a, 0x57, 0x24, 0x05, 0xb9, 0xbc, 0x5b, 0x55,
0x62, 0xa7, 0xf1, 0xe2, 0xb8, 0x6f, 0xe6, 0x76, 0x9a, 0xc9, 0x99, 0x28, 0xca, 0x53, 0x4a, 0xf8,
0x95, 0x73, 0x40, 0xa9, 0xae, 0x37, 0xf5, 0x80, 0x74, 0x66, 0x85, 0xcc, 0x6e, 0x39, 0xfb, 0x48,
0xc6, 0x9c, 0x0c, 0xbb, 0xf5, 0x02, 0x0c, 0x86, 0x8a, 0x76, 0xcf, 0xce, 0x4f, 0x36, 0x9d, 0xd2,
0xa6, 0xd3, 0x34, 0xbb, 0x5d, 0xef, 0xdb, 0x3a, 0xa5, 0xb6, 0x97, 0x35, 0x3c, 0x69, 0x45, 0xcc,
0x68, 0x67, 0x68, 0xcb, 0x54, 0xf9, 0x6b, 0x17, 0xd6, 0x56, 0x59, 0xdb, 0x17, 0xf8, 0x86, 0xbb,
0x3f, 0x35, 0x42, 0xa8, 0x41, 0xe3, 0xfa, 0xbe, 0xd2, 0xf0, 0xfb, 0x68, 0xff, 0xc5, 0x51, 0xaf,
0xd7, 0xfb, 0xcb, 0x20, 0x78, 0xbb, 0xc5, 0x4c, 0x0b, 0xd5, 0xf9, 0x2e, 0x39, 0x0f, 0x0a, 0x47,
0xc1, 0xa6, 0x5e, 0xa2, 0xd1, 0xb6, 0x5e, 0x74, 0xf8, 0xdf, 0x69, 0xdd, 0xd9, 0x7f, 0xf1, 0xfa,
0xd5, 0xab, 0x57, 0xa4, 0xb5, 0x2a, 0x72, 0xcf, 0x73, 0x72, 0xce, 0x36, 0xfd, 0x93, 0x46, 0xbb,
0x8f, 0xad, 0x1a, 0x98, 0xd9, 0xcb, 0xcd, 0x87, 0x7d, 0x55, 0xc2, 0xc1, 0x2f, 0x3d, 0xec, 0x3b,
0xfe, 0x70, 0x10, 0x7e, 0xf4, 0x09, 0x7a, 0x40, 0x9c, 0x60, 0x45, 0xa0, 0x24, 0x49, 0x56, 0x9b,
0xcd, 0x9f, 0x79, 0xa3, 0x05, 0x76, 0xe7, 0x7f, 0x42, 0xb6, 0x4b, 0x1c, 0xc2, 0x0f, 0xd1, 0x8c,
0x38, 0x47, 0xff, 0x3d, 0xf9, 0x0f, 0x1d, 0x2a, 0x59, 0xe7, 0x53, 0x11, 0x00, 0x00
}; };

View File

@ -4,8 +4,11 @@
*/ */
//Usermod Manager internals //Usermod Manager internals
void UsermodManager::setup() { for (byte i = 0; i < numMods; i++) ums[i]->setup(); }
void UsermodManager::connected() { for (byte i = 0; i < numMods; i++) ums[i]->connected(); }
void UsermodManager::loop() { for (byte i = 0; i < numMods; i++) ums[i]->loop(); } void UsermodManager::loop() { for (byte i = 0; i < numMods; i++) ums[i]->loop(); }
void UsermodManager::handleOverlayDraw() { for (byte i = 0; i < numMods; i++) ums[i]->handleOverlayDraw(); } void UsermodManager::handleOverlayDraw() { for (byte i = 0; i < numMods; i++) ums[i]->handleOverlayDraw(); }
void UsermodManager::appendConfigData() { for (byte i = 0; i < numMods; i++) ums[i]->appendConfigData(); }
bool UsermodManager::handleButton(uint8_t b) { bool UsermodManager::handleButton(uint8_t b) {
bool overrideIO = false; bool overrideIO = false;
for (byte i = 0; i < numMods; i++) { for (byte i = 0; i < numMods; i++) {
@ -13,10 +16,13 @@ bool UsermodManager::handleButton(uint8_t b) {
} }
return overrideIO; return overrideIO;
} }
bool UsermodManager::getUMData(um_data_t **data, uint8_t mod_id) {
void UsermodManager::setup() { for (byte i = 0; i < numMods; i++) ums[i]->setup(); } for (byte i = 0; i < numMods; i++) {
void UsermodManager::connected() { for (byte i = 0; i < numMods; i++) ums[i]->connected(); } if (mod_id > 0 && ums[i]->getId() != mod_id) continue; // only get data form requested usermod if provided
if (ums[i]->getUMData(data)) return true; // if usermod does provide data return immediately (only one usermod can povide data at one time)
}
return false;
}
void UsermodManager::addToJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonState(obj); } void UsermodManager::addToJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonState(obj); }
void UsermodManager::addToJsonInfo(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonInfo(obj); } void UsermodManager::addToJsonInfo(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->addToJsonInfo(obj); }
void UsermodManager::readFromJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->readFromJsonState(obj); } void UsermodManager::readFromJsonState(JsonObject& obj) { for (byte i = 0; i < numMods; i++) ums[i]->readFromJsonState(obj); }
@ -33,6 +39,7 @@ bool UsermodManager::onMqttMessage(char* topic, char* payload) {
for (byte i = 0; i < numMods; i++) if (ums[i]->onMqttMessage(topic, payload)) return true; for (byte i = 0; i < numMods; i++) if (ums[i]->onMqttMessage(topic, payload)) return true;
return false; return false;
} }
void UsermodManager::onUpdateBegin(bool init) { for (byte i = 0; i < numMods; i++) ums[i]->onUpdateBegin(init); } // notify usermods that update is to begin
/* /*
* Enables usermods to lookup another Usermod. * Enables usermods to lookup another Usermod.
@ -49,8 +56,7 @@ Usermod* UsermodManager::lookup(uint16_t mod_id) {
bool UsermodManager::add(Usermod* um) bool UsermodManager::add(Usermod* um)
{ {
if (numMods >= WLED_MAX_USERMODS || um == nullptr) return false; if (numMods >= WLED_MAX_USERMODS || um == nullptr) return false;
ums[numMods] = um; ums[numMods++] = um;
numMods++;
return true; return true;
} }

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2205291 #define VERSION 2206131
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG

View File

@ -173,11 +173,13 @@ void initServer()
const String& url = request->url(); const String& url = request->url();
isConfig = url.indexOf("cfg") > -1; isConfig = url.indexOf("cfg") > -1;
if (!isConfig) { if (!isConfig) {
/*
#ifdef WLED_DEBUG #ifdef WLED_DEBUG
DEBUG_PRINTLN(F("Serialized HTTP")); DEBUG_PRINTLN(F("Serialized HTTP"));
serializeJson(root,Serial); serializeJson(root,Serial);
DEBUG_PRINTLN(); DEBUG_PRINTLN();
#endif #endif
*/
verboseResponse = deserializeState(root); verboseResponse = deserializeState(root);
} else { } else {
verboseResponse = deserializeConfig(root); //use verboseResponse to determine whether cfg change should be saved immediately verboseResponse = deserializeConfig(root); //use verboseResponse to determine whether cfg change should be saved immediately
@ -281,6 +283,7 @@ void initServer()
if (!correctPIN || otaLock) return; if (!correctPIN || otaLock) return;
if(!index){ if(!index){
DEBUG_PRINTLN(F("OTA Update Start")); DEBUG_PRINTLN(F("OTA Update Start"));
usermods.onUpdateBegin(true); // notify usermods that update is about to begin (some may require task de-init)
lastEditTime = millis(); // make sure PIN does not lock during update lastEditTime = millis(); // make sure PIN does not lock during update
#ifdef ESP8266 #ifdef ESP8266
Update.runAsync(true); Update.runAsync(true);
@ -293,6 +296,7 @@ void initServer()
DEBUG_PRINTLN(F("Update Success")); DEBUG_PRINTLN(F("Update Success"));
} else { } else {
DEBUG_PRINTLN(F("Update Failed")); DEBUG_PRINTLN(F("Update Failed"));
usermods.onUpdateBegin(false); // notify usermods that update has failed (some may require task init)
} }
} }
}); });

View File

@ -615,6 +615,7 @@ void getSettingsJS(byte subPage, char* dest)
oappend(SET_F("numM=")); oappend(SET_F("numM="));
oappendi(usermods.getModCount()); oappendi(usermods.getModCount());
oappend(";"); oappend(";");
usermods.appendConfigData();
} }
if (subPage == 9) // update if (subPage == 9) // update