3.1.0.ALPHA2

* Version Bump to 3.1.0.ALPHA2
 * further code changes
 * further integration of multi segments
 * integration of multi segments to GUI
This commit is contained in:
bpohvoodoo
2019-10-03 19:28:39 +02:00
parent fb4cfe3a3e
commit a0a8fe72b5
17 changed files with 3828 additions and 3510 deletions
+37 -135
View File
@@ -1,4 +1,8 @@
#include "definitions.h"
// ***************************************************************************
// Load library "ticker" for blinking status led, mqtt send and save state
// ***************************************************************************
#include <Ticker.h>
#include "version.h"
// ***************************************************************************
@@ -10,10 +14,10 @@
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h> //https://github.com/tzapu/WiFiManager
#include <FS.h>
#include <WiFiClient.h>
#include <ESP8266mDNS.h>
#include <FS.h>
#include <WebSockets.h> //https://github.com/Links2004/arduinoWebSockets
#include <WebSocketsServer.h>
@@ -25,8 +29,6 @@
GY33_MCU tcs;
#endif
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
// MQTT
#if defined(ENABLE_MQTT)
#if ENABLE_MQTT == 0
@@ -47,12 +49,11 @@
AsyncMqttClient * mqtt_client;
WiFiEventHandler wifiConnectHandler;
WiFiEventHandler wifiDisconnectHandler;
Ticker mqttReconnectTimer;
Ticker wifiReconnectTimer;
#endif
#endif
#if defined(ARDUINOJSON_VERSION)
#if !(ARDUINOJSON_VERSION_MAJOR == 6 and ARDUINOJSON_VERSION_MINOR >= 8)
#error "Install ArduinoJson v6.8.x or higher"
#if defined(ENABLE_HOMEASSISTANT)
Ticker ha_send_data;
#endif
#endif
@@ -166,21 +167,9 @@ WS2812FX * strip = NULL;
}
#endif
// ***************************************************************************
// Load library "ticker" for blinking status led, mqtt send and save state
// ***************************************************************************
#include <Ticker.h>
Ticker ticker;
#if defined(ENABLE_MQTT)
#if ENABLE_MQTT == 1
Ticker mqttReconnectTimer;
Ticker wifiReconnectTimer;
#endif
#if defined(ENABLE_HOMEASSISTANT)
Ticker ha_send_data;
#endif
#endif
void tick() {
//toggle state
@@ -193,9 +182,6 @@ void tick() {
decode_results results;
#endif
Ticker settings_save_state;
Ticker settings_save_conf;
// ***************************************************************************
// Saved state handling in WifiManager
// ***************************************************************************
@@ -242,97 +228,22 @@ void saveConfigCallback () {
// ***************************************************************************
#include "spiffs_webserver.h"
// ***************************************************************************
// Include: Request handlers
// ***************************************************************************
#include "request_handlers.h"
// ***************************************************************************
// Include: Custom animations
// ***************************************************************************
#include "mode_custom_ws2812fx_animations.h" // Add animations in this file
// function to Initialize the strip
void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, char RGBOrder[5] = WS2812FXStripSettings.RGBOrder, uint8_t pin = WS2812FXStripSettings.pin, uint8_t fxoptions = WS2812FXStripSettings.fxoptions ){
DBG_OUTPUT_PORT.println("Initializing strip!");
/*#if defined(USE_WS2812FX_DMA)
if (dma != NULL) {
delete(dma);
}
#endif*/
if (strip != NULL) {
delete(strip);
WS2812FXStripSettings.stripSize = stripSize;
strcpy(WS2812FXStripSettings.RGBOrder, RGBOrder);
WS2812FXStripSettings.pin = pin;
WS2812FXStripSettings.fxoptions = fxoptions;
}
// ***************************************************************************
// Include: helper functions
// ***************************************************************************
#include "helper_functions.h"
if (ledstates != NULL) {
delete(ledstates);
}
ledstates = new uint8_t [WS2812FXStripSettings.stripSize];
#if !defined(LED_TYPE_WS2811)
strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ800);
#else
strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ400);
#endif
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.
strip->init();
#if defined(USE_WS2812FX_DMA)
initDMA(stripSize);
strip->setCustomShow(DMA_Show);
#endif
//parameters: index, start, stop, mode, color, speed, options
for (uint8_t seg=0; seg < num_segments; seg++) {
(readStateSegmentFS(seg)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!");
strip->setSegment(seg, seg_start, seg_stop , ws2812fx_mode, hex_colors_trans, convertSpeed(ws2812fx_speed), fxoptions);
}
//strip->setSegment(0, 0, (stripSize - 1)/2, ws2812fx_mode, hex_colors_trans, convertSpeed(ws2812fx_speed), fxoptions);
//strip->setSegment(1, ((stripSize - 1)/2) + 1, (stripSize - 1), ws2812fx_mode, hex_colors_trans, convertSpeed(ws2812fx_speed), fxoptions);
strip->setCustomMode(0, F("Autoplay"), myCustomEffect0);
strip->setCustomMode(1, F("Custom WS"), myCustomEffect1);
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
strip->setCustomMode(2, F("TV"), myCustomEffect2);
strip->setCustomMode(3, F("E1.31"), myCustomEffect3);
strip->setCustomMode(4, F("Fire 2012"), myCustomEffect4);
strip->setCustomMode(5, F("Gradient"), myCustomEffect5);
gReverseDirection = (WS2812FXStripSettings.fxoptions & 128);
DBG_OUTPUT_PORT.print("Number of Segments: ");
DBG_OUTPUT_PORT.println(strip->getNumSegments());
if (e131 != NULL) { delete(e131); }
e131 = new ESPAsyncE131(END_UNIVERSE - START_UNIVERSE + 1);
float universe_leds = 170.0; // a universe has only 512 (0..511) channels: 3*170 or 4*128 <= 512
if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) {
//universe_leds = 128.0;
}
float float_enduni = stripSize/universe_leds;
uint8_t END_UNIVERSE = stripSize/universe_leds;
if (float_enduni > END_UNIVERSE) {
END_UNIVERSE = END_UNIVERSE +1;
}
// if (e131.begin(E131_UNICAST)) // Listen via Unicast
if (e131->begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) {// Listen via Multicast
DBG_OUTPUT_PORT.println(F("Listening for data..."));
} else {
DBG_OUTPUT_PORT.println(F("*** e131.begin failed ***"));
}
#endif
}
// ***************************************************************************
// Include: other functions
// ***************************************************************************
#include "json_functions.h"
#include "filesystem_functions.h"
#include "request_handlers.h"
#if defined(ENABLE_MQTT)
void initMqtt() {
@@ -713,6 +624,7 @@ void loop() {
// ***************************************************************************
// Simple statemachine that handles the different modes
// ***************************************************************************
if ((mode == OFF) && ((strip->getBrightness() == 0) || !transEffect)) {
if(strip->isRunning()) {
strip->strip_off(); // Workaround: to be shure,
@@ -743,15 +655,6 @@ void loop() {
}
}
if (mode == INIT_STRIP) {
mode = prevmode;
strip->strip_off();
delay(10);
if(strip->isRunning()) strip->stop();
initStrip();
prevmode = INIT_STRIP;
}
if (mode == SET) {
mode = HOLD;
// Segment
@@ -792,6 +695,14 @@ void loop() {
strip->trigger();
}
if ((mode == HOLD) || ((mode == OFF) && (strip->getBrightness() > 0) && transEffect)) {
if (ws2812fx_mode == FX_MODE_CUSTOM_0) {
handleAutoPlay();
}
if(!strip->isRunning()) strip->start();
strip->service();
}
if (prevmode != mode) {
convertColors();
if (memcmp(hex_colors_trans, strip->getColors(segment), sizeof(hex_colors_trans)) != 0) {
@@ -800,13 +711,6 @@ void loop() {
}
strip->setSpeed(segment, convertSpeed(ws2812fx_speed_actual));
//strip->setBrightness(brightness_actual);
if (prevmode != INIT_STRIP) { // do not save if INIT_STRIP mode was set
#if defined(ENABLE_STATE_SAVE)
if(!settings_save_state.active()) settings_save_state.once(3, tickerSaveState);
#endif
snprintf(last_state, sizeof(last_state), "STA|%2d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d|%3d", prevmode, ws2812fx_mode, ws2812fx_speed, brightness, main_color.red, main_color.green, main_color.blue, main_color.white, back_color.red, back_color.green, back_color.blue, back_color.white, xtra_color.red, xtra_color.green, xtra_color.blue, xtra_color.white);
last_state[sizeof(last_state) - 1] = 0x00;
}
#if defined(ENABLE_MQTT)
#if ENABLE_MQTT == 0
mqtt_client->publish(mqtt_outtopic, mqtt_buf);
@@ -819,23 +723,22 @@ void loop() {
#endif
#endif
}
prevmode = mode;
#if defined(ENABLE_STATE_SAVE)
if (updateState){
(writeStateFS(updateState)) ? DBG_OUTPUT_PORT.println(" State FS Save Success!") : DBG_OUTPUT_PORT.println("State FS Save failure!");
(writeStateFS(updateState)) ? DBG_OUTPUT_PORT.println("State FS Save Success!") : DBG_OUTPUT_PORT.println("State FS Save failure!");
}
if (updateSegState) {
(writeSegmentStateFS(updateSegState, segment)) ? DBG_OUTPUT_PORT.println("Segment State FS Save Success!") : DBG_OUTPUT_PORT.println("Segment State FS Save failure!");
initStrip();
}
if (updateConfig) {
(writeConfigFS(updateConfig)) ? DBG_OUTPUT_PORT.println("Config FS Save success!"): DBG_OUTPUT_PORT.println("Config FS Save failure!");
}
#endif
if ((mode == HOLD) || ((mode == OFF) && (strip->getBrightness() > 0) && transEffect)) {
if (ws2812fx_mode == FX_MODE_CUSTOM_0) {
handleAutoPlay();
}
if(!strip->isRunning()) strip->start();
strip->service();
}
// Async color transition
if (memcmp(hex_colors_trans, strip->getColors(segment), sizeof(hex_colors_trans)) != 0) {
if (transEffect) {
@@ -917,7 +820,6 @@ void loop() {
}
}
*/
prevmode = mode;
#if defined(ENABLE_REMOTE)
handleRemote();
+3 -1
View File
@@ -182,7 +182,9 @@
var mkfile = document.createElement("button");
mkfile.innerHTML = 'MkFile';
document.getElementById(element).appendChild(mkfile);
var para = document.createElement("text");
para.innerHTML = " Press Ctrl-S for save, Ctrl-Z for undo, Ctrl-Shift-Z for redo";
document.getElementById(element).appendChild(para);
function httpPostProcessRequest(){
if (xmlHttp.readyState == 4){
if(xmlHttp.status != 200) alert("ERROR["+xmlHttp.status+"]: "+xmlHttp.responseText);
Binary file not shown.
+128 -31
View File
@@ -877,7 +877,7 @@ input[type=number], label{
</div>
</div>
</div>
<div class="flex xs12 sm7">
<div class="flex xs12 sm8">
<div class="sliders container">
<div class="color-wrap" style="display:none">
<div id="color-display"></div>
@@ -912,6 +912,13 @@ input[type=number], label{
<input type="number" id="speedNum">
<input value="255" type="range" min="0" max="255" id="speed">
</div>
<div id="segments" class="container" style="text-align: left;">
<div class="layout row wrap">
<div class="flex xs12 sm2" id="selectSegLbl" style="text-align: left;"><p>selectSeg</p>
<select id="selectseg" class="custom-select" style="border: 2px solid #aaaaaa; border-radius: 6px; width:90%; "></select>
</div>
</div>
</div>
<div id="message" class="container hidden" style="text-align: left;">
<div id="wsmessageLbl" style="text-align: left;"><p>wsMessage</p>
<input type="text" id="wsmessage" style="border: 2px solid #aaaaaa; border-radius: 6px; width:100%;" />
@@ -959,14 +966,17 @@ input[type=number], label{
</div>
</div>
<div class="layout row wrap">
<div class="flex xs12 sm4"><p>selectCount</p>
<input type="number" min="0" max="65535" id="selectcount" style="border: 2px solid #aaaaaa; border-radius: 6px; width:100%;" />
<div class="flex xs12 sm3"><p>selectSegCnt</p>
<input type="number" min="1" max="9" id="selectsegcnt" style="border: 2px solid #aaaaaa; border-radius: 6px; width:50%;" />
</div>
<div class="flex xs12 sm4"><p>selectRGBO</p>
<div class="flex xs12 sm3"><p>selectCount</p>
<input type="number" min="0" max="65535" id="selectcount" style="border: 2px solid #aaaaaa; border-radius: 6px; width:50%;" />
</div>
<div class="flex xs12 sm3"><p>selectRGBO</p>
<select id="selectrgbo" class="custom-select"></select>
</div>
<div class="flex xs12 sm4"><p>selectPin</p>
<input type="number" min="0" max="16" id="selectpin" style="border: 2px solid #aaaaaa; border-radius: 6px; width:100%;" />
<div class="flex xs12 sm3"><p>selectPin</p>
<input type="number" min="0" max="16" id="selectpin" style="border: 2px solid #aaaaaa; border-radius: 6px; width:50%;" />
</div>
</div>
<div class="layout row wrap">
@@ -983,6 +993,14 @@ input[type=number], label{
<select id="selectoptsize" class="custom-select"></select>
</div>
</div>
<div class="layout row wrap">
<div class="flex xs12 sm6"><p>segStart</p>
<input type="number" min="0" max="*jsvariable" id="segstart" style="border: 2px solid #aaaaaa; border-radius: 6px; width:90%;" />
</div>
<div class="flex xs12 sm6"><p>segStop</p>
<input type="number" min="0" max="*jsvariable" id="segstop" style="border: 2px solid #aaaaaa; border-radius: 6px; width:90%;" />
</div>
</div>
<div class="layout row wrap">
<div class="flex xs12" style="text-align: left; margin:20px 0;"><p>selectColors</p>
<span style="white-space: nowrap;">
@@ -1043,6 +1061,9 @@ var language = {
white: "White",
not_greater: "cannot enter numbers greater than 255",
not_less: "cannot enter numbers less than 0",
selectSeg: "Select segment",
segStart: "First LED of selected segment",
segStop: "Last LED of selected segment",
wsMessage: "Websocket Message:",
selectLanguage: "Select Language:",
selectHostname: "Hostname:",
@@ -1050,6 +1071,7 @@ var language = {
selectMQTTPort: "and Port:",
selectMQTTUser: "MQTT Username:",
selectMQTTPass: "MQTT Password:",
selectSegCnt: "Number of Segments:",
selectCount: "Strip LED Count:",
selectRGBO: "RGB Order:",
selectPin: "Strip GPIO Pin:",
@@ -1099,6 +1121,9 @@ var language = {
white: "Wit",
not_greater: "Geen nummers hoger dan 255",
not_less: "Geen nummers lager dan 0",
selectSeg: "Selecteer segment",
segStart: "Eerste LED van huidige segmenten",
segStop: "Laatste LED van huidige segmenten",
wsMessage: "Websocket message:",
selectLanguage: "Selecteer Taal:",
selectHostname: "Hostname:",
@@ -1106,6 +1131,7 @@ var language = {
selectMQTTPort: "en Port:",
selectMQTTUser: "MQTT gebruikersnaam:",
selectMQTTPass: "MQTT wachtwoord:",
selectSegCnt: "Number of Segments:",
selectCount: "LED nummer:",
selectPin: "Strip GPIO Pin:",
selectRGBO: "RGB Order:",
@@ -1155,6 +1181,9 @@ var language = {
white: "Weiß",
not_greater: "Akzeptiere keine Nummern größer 255",
not_less: "Akzeptiere keine Nummern kleiner 0",
selectSeg: "Segment wählen",
segStart: "Erste LED des gewählten Segments",
segStop: "Letzte LED des gewählten Segments",
wsMessage: "Websocket Message:",
selectLanguage: "Sprache auswählen:",
selectHostname: "Hostname:",
@@ -1162,6 +1191,7 @@ var language = {
selectMQTTPort: "und Port:",
selectMQTTUser: "MQTT Username:",
selectMQTTPass: "MQTT Password:",
selectSegCnt: "Anzahl Segmente:",
selectCount: "Strip LED Anzahl:",
selectRGBO: "RGB Reihenfolge:",
selectPin: "Strip GPIO Pin:",
@@ -1281,6 +1311,7 @@ var config = {
mqtt_port: 0,
mqtt_user: "",
mqtt_pass: "",
ws_seg: 1,
ws_cnt: 0,
ws_rgbo: "",
ws_pin: 0,
@@ -1289,6 +1320,9 @@ var config = {
transitionEffects: true
};
var data = {
segment: 0,
start: 0,
stop: 0,
mode: 0,
color: {w:0, r:0, g:0, b:0, hex:"00000000", w2:0, r2:0, g2:0, b2:0, hex2:"00000000", w3:0, r3:0, g3:0, b3:0, hex3:"00000000"},
brightness: 192,
@@ -1341,7 +1375,7 @@ function displayColors(all = false) {
}
// initial color val numbers when DOM is loaded
function colorNumrVals(){
function colorNumVals(){
redNumVal.value = red.value;
greenNumVal.value = green.value;
blueNumVal.value = blue.value;
@@ -1447,7 +1481,7 @@ function initcolorSliders(){
displayColors();
initSliderColors();
changeRangeNumVal();
colorNumrVals();
colorNumVals();
// Trigger onChange event to send value
redNumVal.dispatchEvent(event);
});
@@ -1456,7 +1490,7 @@ function initcolorSliders(){
displayColors();
initSliderColors();
changeRangeNumVal();
colorNumrVals();
colorNumVals();
// Trigger onChange event to send value
greenNumVal.dispatchEvent(event);
});
@@ -1465,7 +1499,7 @@ function initcolorSliders(){
displayColors();
initSliderColors();
changeRangeNumVal();
colorNumrVals();
colorNumVals();
// Trigger onChange event to send value
blueNumVal.dispatchEvent(event);
});
@@ -1474,7 +1508,7 @@ function initcolorSliders(){
displayColors();
initSliderColors();
changeRangeNumVal();
colorNumrVals();
colorNumVals();
// Trigger onChange event to send value
whiteNumVal.dispatchEvent(event);
});
@@ -1482,14 +1516,14 @@ function initcolorSliders(){
bright.addEventListener('input', () => {
initSliderColors();
changeRangeNumVal();
colorNumrVals();
colorNumVals();
// Trigger onChange event to send value
brightNumVal.dispatchEvent(event);
});
speed.addEventListener('input', () => {
changeRangeNumVal();
colorNumrVals();
colorNumVals();
// Trigger onChange event to send value
speedNumVal.dispatchEvent(event);
});
@@ -1548,6 +1582,7 @@ function getConfig() {
if (typeof res.mqtt_port !== "undefined") config.mqtt_port = res.mqtt_port;
if (typeof res.mqtt_user !== "undefined") config.mqtt_user = res.mqtt_user;
if (typeof res.mqtt_pass !== "undefined") config.mqtt_pass = res.mqtt_pass;
if (typeof res.ws_seg !== "undefined") config.ws_seg = res.ws_seg;
if (typeof res.ws_cnt !== "undefined") config.ws_cnt = res.ws_cnt;
if (typeof res.ws_rgbo !== "undefined") {
config.ws_rgbo = res.ws_rgbo;
@@ -1612,8 +1647,12 @@ function readSettings() {
if (typeof(tmpsettings[set]) !== "undefined") settings[set] = tmpsettings[set];
}
applySettings();
if (e && e.substring(0,6) !== "ERROR!") connectAdditionalNodes();
else console.warn("ERROR loading settings", e);
if (e && e.substring(0,6) !== "ERROR!") {
connectAdditionalNodes();
} else {
console.warn("ERROR loading settings", e);
saveSettings();
}
});
}
function applySettings() {
@@ -1684,7 +1723,7 @@ function onSelectColNum(colnum) {
white.value = data.color["w" + (colnum > 1 ? colnum : "")];
initSliderColors();
changeRangeNumVal();
colorNumrVals();
colorNumVals();
}
function initSettings() {
// Add languages to language select
@@ -1736,11 +1775,33 @@ function initSettings() {
config.mqtt_pass = mqtt_pass.value;
ws_send("Cmw" + config.mqtt_pass);
});
var count = document.getElementById("selectcount");
count.value = config.ws_cnt;
count.addEventListener('change', ()=>{
config.ws_cnt = count.value;
ws_send("Csc" + config.ws_cnt);
var selsegment = document.getElementById("selectseg");
for(var i = 0; i < config.ws_seg; i++) {
var option = document.createElement("OPTION");
option.setAttribute("value", i);
option.innerHTML = i;
selsegment.appendChild(option);
}
selsegment.value = data.segment;
selsegment.addEventListener('change', ()=>{
data.segment = selsegment.value;
ws_send("Ss" + data.segment);
});
var num_segments = document.getElementById("selectsegcnt");
num_segments.value = config.ws_seg;
num_segments.addEventListener('change', ()=>{
config.ws_seg = num_segments.value;
ws_send("Css" + config.ws_seg);
while (selsegment.firstChild) {
selsegment.removeChild(selsegment.firstChild);
}
for(var i = 0; i < config.ws_seg; i++) {
var option = document.createElement("OPTION");
option.setAttribute("value", i);
option.innerHTML = i;
selsegment.appendChild(option);
}
selsegment.value = data.segment;
});
var pin = document.getElementById("selectpin");
pin.value = config.ws_pin;
@@ -1760,6 +1821,28 @@ function initSettings() {
config.ws_rgbo = rgbo.value;
ws_send("Csr" + config.ws_rgbo);
});
var start = document.getElementById("segstart");
start.setAttribute("max",config.ws_cnt-1);
start.value = data.start;
start.addEventListener('change', ()=>{
data.start = start.value;
ws_send("S[" + data.start);
});
var stop = document.getElementById("segstop");
stop.setAttribute("max",config.ws_cnt-1);
stop.value = data.stop;
stop.addEventListener('change', ()=>{
data.stop = stop.value;
ws_send("S]" + data.stop);
});
var count = document.getElementById("selectcount");
count.value = config.ws_cnt;
count.addEventListener('change', ()=>{
config.ws_cnt = count.value;
ws_send("Csc" + config.ws_cnt);
start.setAttribute("max",config.ws_cnt-1);
stop.setAttribute("max",config.ws_cnt-1);
});
var optrev = document.getElementById("selectoptrev");
for (var code in selectoptrev) {
var option = document.createElement("OPTION");
@@ -1855,6 +1938,7 @@ function initSettings() {
settings.theme_back = colback.value;
document.getElementById("container").style.backgroundColor = settings.theme_back;
document.getElementById("language").style.backgroundColor = settings.theme_back;
document.getElementById("selectseg").style.backgroundColor = settings.theme_back;
document.getElementById("selectrgbo").style.backgroundColor = settings.theme_back;
document.getElementById("selectoptrev").style.backgroundColor = settings.theme_back;
document.getElementById("selectoptfade").style.backgroundColor = settings.theme_back;
@@ -1867,6 +1951,7 @@ function initSettings() {
for (var i = 0; i < icons.length; i++) {
icons[i].style.color = (yiq >= 125) ? '#222' : '#EEE';
}
document.getElementById("selectSegLbl").style.color = (yiq >= 125) ? '#111' : '#EEE';
document.getElementById("wsmessageLbl").style.color = (yiq >= 125) ? '#111' : '#EEE';
document.getElementById("redNum").style.color = (yiq >= 125) ? '#111' : '#EEE';
document.getElementById("greenNum").style.color = (yiq >= 125) ? '#111' : '#EEE';
@@ -2069,19 +2154,22 @@ function ws_connect() {
// document.getElementById('modal').style.display = "none";
// console.log("res", res);
if (res) {
// Status starts here
if (typeof res.mode !== "undefined") data.mode = res.mode;
if (typeof res.brightness !== "undefined") {
data.brightness = res.brightness;
// init ColorSliderVals
bright.value = res.brightness;
}
// Segment Status starts here
if (typeof res.segment !== "undefined") { data.segment= res.segment; document.getElementById("selectseg").value = data.segment; }
if (typeof res.start !== "undefined") { data.start= res.start; document.getElementById("segstart").value = data.start; }
if (typeof res.stop !== "undefined") { data.stop = res.stop; document.getElementById("segstop").value = data.stop; }
if (typeof res.ws2812fx_mode !== "undefined") data.ws2812fx_mode = res.ws2812fx_mode;
if (typeof res.speed !== "undefined") {
data.speed = res.speed;
// init SliderVals
speed.value = res.speed;
}
if (typeof res.brightness !== "undefined") {
data.brightness = res.brightness;
// init ColorSliderVals
bright.value = res.brightness;
}
if (typeof res.color !== "undefined") {
data.color.w = res.color[0];
data.color.r = res.color[1];
@@ -2115,7 +2203,7 @@ function ws_connect() {
red.value = data.color.r3;
green.value = data.color.g3;
blue.value = data.color.b3;
white.value = data.color.w3;
white.value = data.color.w3;
}
}
// Config starts here
@@ -2124,6 +2212,7 @@ function ws_connect() {
if (typeof res.mqtt_port !== "undefined") { config.mqtt_port = res.mqtt_port; document.getElementById("mqtt_port").value = config.mqtt_port; }
if (typeof res.mqtt_user !== "undefined") { config.mqtt_user = res.mqtt_user; document.getElementById("mqtt_user").value = config.mqtt_user; }
if (typeof res.mqtt_pass !== "undefined") { config.mqtt_pass = res.mqtt_pass; document.getElementById("mqtt_pass").value = config.mqtt_pass; }
if (typeof res.ws_seg !== "undefined") { config.ws_seg = res.ws_seg; document.getElementById("selectsegcnt").value = config.ws_seg; }
if (typeof res.ws_cnt !== "undefined") { config.ws_cnt = res.ws_cnt; document.getElementById("selectcount").value = config.ws_cnt; }
if (typeof res.ws_rgbo !== "undefined") {
config.ws_rgbo = res.ws_rgbo;
@@ -2148,6 +2237,7 @@ function ws_connect() {
document.getElementById("selectoptgamma").value = (config.ws_fxopt & 8);
document.getElementById("selectoptsize").value = (config.ws_fxopt & 6);
}
if (typeof res.transEffect !== "undefined") { config.transitionEffects = res.transEffect; document.getElementById("set-transitionEffects").value = config.transitionEffects; }
// Modes starts here
if (typeof res[0] !== "undefined") {
res.forEach(item => {
@@ -2157,7 +2247,7 @@ function ws_connect() {
});
}
// init Color Vals
colorNumrVals();
colorNumVals();
initSliderColors();
// init Change Range Val
changeRangeNumVal();
@@ -2218,6 +2308,8 @@ function select_active_button() {
if (arr.indexOf("hidden") === -1) {
wsmess.className += " hidden";
}
segments = document.getElementById("segments");
segments.className = segments.className.replace(/\b hidden\b/g, "");
}
if (data.mode >= 1) {
document.getElementById(data.ws2812fx_mode).style.backgroundColor = settings.theme_btnsel;
@@ -2229,6 +2321,11 @@ function select_active_button() {
} else if (data.ws2812fx_mode === 57) { //CUSTOM_WS
wsmess = document.getElementById("message");
wsmess.className = wsmess.className.replace(/\b hidden\b/g, "");
sements = document.getElementById("segments");
var arr = segments.className.split(" ");
if (arr.indexOf("hidden") === -1) {
segments.className += " hidden";
}
disable_modebuttons(false);
disable_color_selection(true);
disable_bright_selection(false);
@@ -2357,7 +2454,7 @@ function onSelectColor(event) {
displayColors();
initSliderColors();
changeRangeNumVal();
colorNumrVals();
colorNumVals();
}
}
function redrawColorPicker() {
@@ -2525,7 +2622,7 @@ document.addEventListener("DOMContentLoaded", function(event) {
getModes();
readSettings();
ws_connect();
ws_send("$")
ws_send("$");
document.getElementById("modal-content").innerHTML = language.en.loadModes;
//ws_send("C");
getConfig();
Binary file not shown.
+3 -4
View File
@@ -18,6 +18,7 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just
#define ENABLE_OTA 1 // If defined, enable Arduino OTA code. If set to 0 enable Arduino OTA code, if set to 1 enable ESP8266HTTPUpdateServer OTA code.
#define ENABLE_MQTT 1 // If defined use MQTT OR AMQTT, if set to 0 enable MQTT client code, see: https://github.com/toblum/McLighting/wiki/MQTT-API, if set to 1, enable Async MQTT code, see: https://github.com/marvinroger/async-mqtt-client
//#define ENABLE_MQTT_HOSTNAME_CHIPID // Uncomment/comment to add ESPChipID to end of MQTT hostname
//#define ENABLE_MQTT_INCLUDE_IP // uncomment/comment to add the IP-adress to the MQTT message
#define ENABLE_HOMEASSISTANT // If defined, enable Homeassistant integration, ENABLE_MQTT must be active
#define MQTT_HOME_ASSISTANT_SUPPORT // If defined, use AMQTT and select Tools -> IwIP Variant -> Higher Bandwidth
#define ENABLE_BUTTON 14 // If defined, enable button handling code, see: https://github.com/toblum/McLighting/wiki/Button-control, the value defines the input pin (14 / D5) for switching the LED strip on / off, connect this PIN to ground to trigger button.
@@ -30,7 +31,7 @@ char HOSTNAME[65] = "McLightingRGBW"; // Friedly hostname is configurable just
#define ENABLE_STATE_SAVE // If defined, load saved state on reboot and save state on SPIFFS
#define CUSTOM_WS2812FX_ANIMATIONS // uncomment and put animations in "custom_ws2812fx_animations.h"
//#define USE_HTML_MIN_GZ // uncomment for using index.htm & edit.htm from PROGMEM instead of SPIFFS
#define USE_HTML_MIN_GZ // uncomment for using index.htm & edit.htm from PROGMEM instead of SPIFFS
#define TRANS_COLOR_DELAY 5 // Delay for color transition
#define TRANS_DELAY 10 // Delay for brightness and speed transition
@@ -146,7 +147,7 @@ uint32_t autoParams[][6] = { // main_color, back_color, xtra_color, speed, mod
#define DBG_OUTPUT_PORT Serial // Set debug output port
// List of all color modes
enum MODE {OFF, HOLD, SET, INIT_STRIP};
enum MODE {OFF, HOLD, SET};
MODE mode = SET; // Standard mode that is active when software starts
MODE prevmode = HOLD; // Do not change
@@ -175,8 +176,6 @@ LEDState back_color = { 0, 0, 0, 0 }; // Store the "2nd color" of the strip u
LEDState xtra_color = { 0, 0, 0, 0 }; // Store the "3rd color" of the strip used in single color modes
bool updateConfig = false; // For WiFiManger custom config and config
char last_state[67]; // Keeps the state representation before auto or off mode
bool updateState = false;
// Button handling
+262
View File
@@ -0,0 +1,262 @@
#if defined(ENABLE_STATE_SAVE)
Ticker save_state;
Ticker save_seg_state;
Ticker save_conf;
bool updateState = false;
bool updateSegState = false;
void tickerSaveState(){
updateState = true;
}
void tickerSaveConfig(){
updateConfig = true;
}
void tickerSaveSegmentState(){
updateSegState = true;
}
// Write configuration to FS JSON
bool writeConfigFS(bool save){
if (save) {
//FS save
DBG_OUTPUT_PORT.println("Saving config: ");
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
DBG_OUTPUT_PORT.println("Failed!");
save_conf.detach();
updateConfig = false;
return false;
}
DBG_OUTPUT_PORT.println(listConfigJSON());
configFile.print(listConfigJSON());
configFile.close();
save_conf.detach();
updateConfig = false;
return true;
//end save
} else {
DBG_OUTPUT_PORT.println("SaveConfig is false!");
return false;
}
}
// Read search_str to FS
bool readConfigFS() {
//read configuration from FS JSON
if (SPIFFS.exists("/config.json")) {
//file exists, reading and loading
DBG_OUTPUT_PORT.print("Reading config file... ");
File configFile = SPIFFS.open("/config.json", "r");
if (configFile) {
DBG_OUTPUT_PORT.println("Opened!");
size_t size = configFile.size();
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
configFile.close();
#if defined(ENABLE_MQTT)
const size_t bufferSize = JSON_OBJECT_SIZE(11) + 150;
#else
const size_t bufferSize = JSON_OBJECT_SIZE(7) + 100;
#endif
DynamicJsonDocument jsonBuffer(bufferSize);
DeserializationError error = deserializeJson(jsonBuffer, buf.get());
DBG_OUTPUT_PORT.print("Config: ");
if (!error) {
DBG_OUTPUT_PORT.println("Parsed!");
JsonObject root = jsonBuffer.as<JsonObject>();
serializeJson(root, DBG_OUTPUT_PORT);
DBG_OUTPUT_PORT.println("");
strcpy(HOSTNAME, root["hostname"]);
#if defined(ENABLE_MQTT)
strcpy(mqtt_host, root["mqtt_host"]);
mqtt_port = root["mqtt_port"].as<uint16_t>();
strcpy(mqtt_user, root["mqtt_user"]);
strcpy(mqtt_pass, root["mqtt_pass"]);
#endif
num_segments = constrain(root["ws_seg"].as<uint8_t>(), 1, MAX_NUM_SEGMENTS - 1);
WS2812FXStripSettings.stripSize = constrain(root["ws_cnt"].as<uint16_t>(), 1, MAXLEDS);
char tmp_rgbOrder[5];
strcpy(tmp_rgbOrder, root["ws_rgbo"]);
checkRGBOrder(tmp_rgbOrder);
uint8_t temp_pin;
checkPin((uint8_t) root["ws_pin"]);
WS2812FXStripSettings.fxoptions = constrain(root["ws_fxopt"].as<uint8_t>(), 0, 255) & 0xFE;
transEffect = root["transEffect"].as<bool>();
jsonBuffer.clear();
return true;
} else {
DBG_OUTPUT_PORT.print("Failed to load json config: ");
DBG_OUTPUT_PORT.println(error.c_str());
jsonBuffer.clear();
}
} else {
DBG_OUTPUT_PORT.println("Failed to open /config.json");
}
} else {
DBG_OUTPUT_PORT.println("Coudnt find config.json");
writeConfigFS(true);
}
//end read
return false;
}
bool writeStateFS(bool save){
if (save) {
//save the strip state to FS JSON
DBG_OUTPUT_PORT.print("Saving state: ");
//SPIFFS.remove("/stripstate.json") ? DBG_OUTPUT_PORT.println("removed file") : DBG_OUTPUT_PORT.println("failed removing file");
File configFile = SPIFFS.open("/stripstate.json", "w");
if (!configFile) {
DBG_OUTPUT_PORT.println("Failed!");
save_state.detach();
updateState = false;
return false;
}
DBG_OUTPUT_PORT.println(listStateJSON());
configFile.print(listStateJSON());
configFile.close();
char filename[28];
save_state.detach();
updateState = false;
return true;
//end save
} else {
DBG_OUTPUT_PORT.println("SaveState is false!");
return false;
}
}
bool readStateFS() {
//read strip state from FS JSON
if (SPIFFS.exists("/stripstate.json")) {
//file exists, reading and loading
DBG_OUTPUT_PORT.print("Reading state file... ");
File configFile = SPIFFS.open("/stripstate.json", "r");
if (configFile) {
DBG_OUTPUT_PORT.println("Opened!");
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
configFile.close();
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 50;
DynamicJsonDocument jsonBuffer(bufferSize);
DeserializationError error = deserializeJson(jsonBuffer, buf.get());
DBG_OUTPUT_PORT.print("Config: ");
if (!error) {
DBG_OUTPUT_PORT.print("Parsed");
JsonObject root = jsonBuffer.as<JsonObject>();
serializeJson(root, DBG_OUTPUT_PORT);
DBG_OUTPUT_PORT.println("");
segment = root["segment"];
mode = static_cast<MODE>(root["mode"].as<uint8_t>());
brightness = root["brightness"];
jsonBuffer.clear();
return true;
} else {
DBG_OUTPUT_PORT.print("Failed to load json config: ");
DBG_OUTPUT_PORT.println(error.c_str());
jsonBuffer.clear();
}
} else {
DBG_OUTPUT_PORT.println("Failed to open \"/stripstate.json\"");
}
} else {
DBG_OUTPUT_PORT.println("Couldn't find \"/stripstate.json\"");
writeStateFS(true);
}
//end read
return false;
}
bool writeSegmentStateFS(bool save, uint8_t seg){
if (save) {
//save the segment state to FS JSON
DBG_OUTPUT_PORT.print("Saving segment state: ");
char filename[28];
snprintf(filename, 28, "/stripstate_segment_%02i.json", seg);
filename[27] = 0x00;
File configFile = SPIFFS.open(filename, "w");
if (!configFile) {
DBG_OUTPUT_PORT.println("Failed!");
save_seg_state.detach();
updateSegState = false;
return false;
}
DBG_OUTPUT_PORT.println(listSegmentStateJSON(seg));
configFile.print(listSegmentStateJSON(seg));
configFile.close();
save_seg_state.detach();
updateSegState = false;
return true;
//end save
} else {
DBG_OUTPUT_PORT.println("SaveSegmentState is false!");
return false;
}
}
bool readSegmentStateFS(uint8_t seg) {
//read strip state from FS JSON
char filename[28];
snprintf(filename, 28, "/stripstate_segment_%02i.json", seg);
filename[27] = 0x00;
if (SPIFFS.exists(filename)) {
//file exists, reading and loading
DBG_OUTPUT_PORT.printf("Reading segmentstate file: %s\r\n", filename);
File configFile = SPIFFS.open(filename, "r");
if (configFile) {
DBG_OUTPUT_PORT.println("Opened!");
size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
configFile.close();
const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(7) + 100;
DynamicJsonDocument jsonBuffer(bufferSize);
DeserializationError error = deserializeJson(jsonBuffer, buf.get());
DBG_OUTPUT_PORT.print("Config: ");
if (!error) {
DBG_OUTPUT_PORT.print("Parsed");
JsonObject root = jsonBuffer.as<JsonObject>();
serializeJson(root, DBG_OUTPUT_PORT);
DBG_OUTPUT_PORT.println("");
seg_start = root["start"].as<uint16_t>();
seg_stop = root["stop"].as<uint16_t>();
ws2812fx_mode = root["ws2812fx_mode"].as<uint8_t>();
ws2812fx_speed = root["speed"].as<uint8_t>();
main_color.white = root["color"][0].as<uint8_t>();
main_color.red = root["color"][1].as<uint8_t>();
main_color.green = root["color"][2].as<uint8_t>();
main_color.blue = root["color"][3].as<uint8_t>();
back_color.white = root["color"][4].as<uint8_t>();
back_color.red = root["color"][5].as<uint8_t>();
back_color.green = root["color"][6].as<uint8_t>();
back_color.blue = root["color"][7].as<uint8_t>();
xtra_color.white = root["color"][8].as<uint8_t>();
xtra_color.red = root["color"][9].as<uint8_t>();
xtra_color.green = root["color"][10].as<uint8_t>();
xtra_color.blue = root["color"][11].as<uint8_t>();
convertColors();
jsonBuffer.clear();
return true;
} else {
DBG_OUTPUT_PORT.print("Failed to load json config: ");
DBG_OUTPUT_PORT.println(error.c_str());
jsonBuffer.clear();
}
} else {
DBG_OUTPUT_PORT.printf("Failed to open \"/%s\"\r\n", filename);
}
} else {
DBG_OUTPUT_PORT.printf("Couldn't find \"/%s\"", filename);
writeSegmentStateFS(true, seg);
}
//end read
return false;
}
#endif
+283
View File
@@ -0,0 +1,283 @@
// Prototypes
bool readSegmentStateFS(uint8_t seg);
// End Prototypes
uint16_t convertSpeed(uint8_t mcl_speed) {
uint16_t ws2812_speed = 61760 * (exp(0.0002336 * mcl_speed) - exp(-0.03181 * mcl_speed));
ws2812_speed = SPEED_MAX - ws2812_speed;
ws2812_speed = constrain(ws2812_speed, SPEED_MIN, SPEED_MAX);
return ws2812_speed;
}
uint8_t unconvertSpeed(uint16_t ws2812_speed) {
//log((SPEED_MAX - ws2812_speed)/61760) = (0.0002336 * mcl_speed) - (-0.03181 * mcl_speed);
//log((SPEED_MAX - ws2812_speed)/61760) = (0.0002336 + 0.03181) * mcl_speed;
uint16_t mcl_speed = (log((SPEED_MAX - ws2812_speed)/61760))/ (0.0002336 + 0.03181);
//uint16_t mcl_speed = 61760 * (exp(0.0002336 * mcl_speed) - exp(-0.03181 * mcl_speed));
mcl_speed = 255 - mcl_speed;
mcl_speed = constrain(mcl_speed, 0, 255);
return mcl_speed;
}
bool checkPin(uint8_t pin) {
#if defined(USE_WS2812FX_DMA)
#if USE_WS2812FX_DMA == 0
pin = 3;
#endif
#if USE_WS2812FX_DMA == 1
pin = 1;
#endif
#if USE_WS2812FX_DMA == 2
pin = 2;
#endif
#endif
if (((pin >= 0 && pin <= 5) || (pin >= 12 && pin <= 16)) && (pin != WS2812FXStripSettings.pin)) {
WS2812FXStripSettings.pin = pin;
return true;
}
return false;
}
neoPixelType checkRGBOrder(char rgbOrder[5]) {
for( uint8_t i=0 ; i < sizeof(rgbOrder) ; ++i ) rgbOrder[i] = toupper(rgbOrder[i]) ;
DBG_OUTPUT_PORT.printf("Checking RGB Order: %s ...", rgbOrder);
neoPixelType returnOrder = 0;
if (strcmp(rgbOrder, "GRB") == 0) {
returnOrder = NEO_GRB;
} else if (strcmp(rgbOrder, "GBR") == 0) {
returnOrder = NEO_GBR;
} else if (strcmp(rgbOrder, "RGB") == 0) {
returnOrder = NEO_RGB;
} else if (strcmp(rgbOrder, "RBG") == 0) {
returnOrder = NEO_RBG;
} else if (strcmp(rgbOrder, "BRG") == 0) {
returnOrder = NEO_BRG;
} else if (strcmp(rgbOrder, "BGR") == 0) {
returnOrder = NEO_BGR;
} else if (strcmp(rgbOrder, "WGRB") == 0) {
returnOrder = NEO_WGRB;
} else if (strcmp(rgbOrder, "WGBR") == 0) {
returnOrder = NEO_WGBR;
} else if (strcmp(rgbOrder, "WRGB") == 0) {
returnOrder = NEO_WRGB;
} else if (strcmp(rgbOrder, "WRBG") == 0) {
returnOrder = NEO_WRBG;
} else if (strcmp(rgbOrder, "WBRG") == 0) {
returnOrder = NEO_WBRG;
} else if (strcmp(rgbOrder, "WBGR") == 0) {
returnOrder = NEO_WBGR;
} else if (strcmp(rgbOrder, "GWRB") == 0) {
returnOrder = NEO_GWRB;
} else if (strcmp(rgbOrder, "GWBR") == 0) {
returnOrder = NEO_GWBR;
} else if (strcmp(rgbOrder, "RWGB") == 0) {
returnOrder = NEO_RWGB;
} else if (strcmp(rgbOrder, "RWBG") == 0) {
returnOrder = NEO_RWBG;
} else if (strcmp(rgbOrder, "BWRG") == 0) {
returnOrder = NEO_BWRG;
} else if (strcmp(rgbOrder, "BWGR") == 0) {
returnOrder = NEO_BWGR;
} else if (strcmp(rgbOrder, "GRWB") == 0) {
returnOrder = NEO_GRWB;
} else if (strcmp(rgbOrder, "GBWR") == 0) {
returnOrder = NEO_GBWR;
} else if (strcmp(rgbOrder, "RGWB") == 0) {
returnOrder = NEO_RGWB;
} else if (strcmp(rgbOrder, "RBWG") == 0) {
returnOrder = NEO_RBWG;
} else if (strcmp(rgbOrder, "BRWG") == 0){
returnOrder = NEO_BRWG;
} else if (strcmp(rgbOrder, "BGWR") == 0) {
returnOrder = NEO_GRBW;
} else if (strcmp(rgbOrder, "GRBW") == 0) {
returnOrder = NEO_GRBW;
} else if (strcmp(rgbOrder, "GBWR") == 0) {
returnOrder = NEO_GBRW;
} else if (strcmp(rgbOrder, "RGBW") == 0) {
returnOrder = NEO_RGBW;
} else if (strcmp(rgbOrder, "RBGW") == 0) {
returnOrder = NEO_RBGW;
} else if (strcmp(rgbOrder, "BRGW") == 0) {
returnOrder = NEO_BRGW;
} else if (strcmp(rgbOrder, "BGRW") == 0) {
returnOrder = NEO_BGRW;
} else {
DBG_OUTPUT_PORT.print("invalid input!");
uint16_t check = checkRGBOrder(WS2812FXStripSettings.RGBOrder);
if (check != 0) {
returnOrder = static_cast<neoPixelType>(check);
strcpy(rgbOrder, WS2812FXStripSettings.RGBOrder);
} else {
returnOrder = static_cast<neoPixelType>(checkRGBOrder(RGBORDER));
strcpy(rgbOrder, RGBORDER);
}
}
DBG_OUTPUT_PORT.println("success!");
strcpy(WS2812FXStripSettings.RGBOrder, rgbOrder);
return returnOrder;
}
// function to Initialize the strip
void initStrip(uint16_t stripSize = WS2812FXStripSettings.stripSize, char RGBOrder[5] = WS2812FXStripSettings.RGBOrder, uint8_t pin = WS2812FXStripSettings.pin, uint8_t fxoptions = WS2812FXStripSettings.fxoptions ){
DBG_OUTPUT_PORT.println("Initializing strip!");
/*#if defined(USE_WS2812FX_DMA)
if (dma != NULL) {
delete(dma);
}
#endif*/
if (strip != NULL) {
strip->strip_off();
delay(10);
if(strip->isRunning()) strip->stop();
strip->resetSegments();
strip->resetSegmentRuntimes();
delete(strip);
WS2812FXStripSettings.stripSize = stripSize;
strcpy(WS2812FXStripSettings.RGBOrder, RGBOrder);
WS2812FXStripSettings.pin = pin;
WS2812FXStripSettings.fxoptions = fxoptions;
}
if (ledstates != NULL) {
delete(ledstates);
}
ledstates = new uint8_t [WS2812FXStripSettings.stripSize];
#if !defined(LED_TYPE_WS2811)
strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ800);
#else
strip = new WS2812FX(stripSize, pin, checkRGBOrder(RGBOrder) + NEO_KHZ400);
#endif
// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.
strip->init();
#if defined(USE_WS2812FX_DMA)
initDMA(stripSize);
strip->setCustomShow(DMA_Show);
#endif
//parameters: index, start, stop, mode, color, speed, options
for (uint8_t seg=0; seg < num_segments; seg++) {
if (seg != segment) { // Read actual segment last
(readSegmentStateFS(seg)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!");
strip->setSegment(seg, seg_start, seg_stop , ws2812fx_mode, hex_colors_trans, convertSpeed(ws2812fx_speed), fxoptions);
}
}
//read actual segment last to set all vars correctly
(readSegmentStateFS(segment)) ? DBG_OUTPUT_PORT.println("Segment state config FS read Success!") : DBG_OUTPUT_PORT.println("Segment state config FS read failure!");
strip->setSegment(segment, seg_start, seg_stop , ws2812fx_mode, hex_colors_trans, convertSpeed(ws2812fx_speed), fxoptions);
strip->setCustomMode(0, F("Autoplay"), myCustomEffect0);
strip->setCustomMode(1, F("Custom WS"), myCustomEffect1);
#if defined(CUSTOM_WS2812FX_ANIMATIONS)
strip->setCustomMode(2, F("TV"), myCustomEffect2);
strip->setCustomMode(3, F("E1.31"), myCustomEffect3);
strip->setCustomMode(4, F("Fire 2012"), myCustomEffect4);
strip->setCustomMode(5, F("Gradient"), myCustomEffect5);
gReverseDirection = (WS2812FXStripSettings.fxoptions & 128);
DBG_OUTPUT_PORT.print("Number of Segments: ");
DBG_OUTPUT_PORT.println(strip->getNumSegments());
if (e131 != NULL) { delete(e131); }
e131 = new ESPAsyncE131(END_UNIVERSE - START_UNIVERSE + 1);
float universe_leds = 170.0; // a universe has only 512 (0..511) channels: 3*170 or 4*128 <= 512
if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) {
//universe_leds = 128.0;
}
float float_enduni = stripSize/universe_leds;
uint8_t END_UNIVERSE = stripSize/universe_leds;
if (float_enduni > END_UNIVERSE) {
END_UNIVERSE = END_UNIVERSE +1;
}
// if (e131.begin(E131_UNICAST)) // Listen via Unicast
if (e131->begin(E131_MULTICAST, START_UNIVERSE, END_UNIVERSE)) {// Listen via Multicast
DBG_OUTPUT_PORT.println(F("Listening for data..."));
} else {
DBG_OUTPUT_PORT.println(F("*** e131.begin failed ***"));
}
#endif
}
// Call convertColors whenever main_color, back_color or xtra_color changes.
void convertColors() {
hex_colors_trans[0] = (uint32_t)(main_color.white << 24) | (main_color.red << 16) | (main_color.green << 8) | main_color.blue;
hex_colors_trans[1] = (uint32_t)(back_color.white << 24) | (back_color.red << 16) | (back_color.green << 8) | back_color.blue;
hex_colors_trans[2] = (uint32_t)(xtra_color.white << 24) | (xtra_color.red << 16) | (xtra_color.green << 8) | xtra_color.blue;
}
uint32_t* convertColors2(uint8_t w, uint8_t r, uint8_t g, uint8_t b, uint8_t w2, uint8_t r2, uint8_t g2, uint8_t b2, uint8_t w3, uint8_t r3, uint8_t g3, uint8_t b3) {
uint32_t hexcolors[3] = {};
hexcolors[0] = (uint32_t)(w << 24) | (r << 16) | (g << 8) | b;
hexcolors[1] = (uint32_t)(w2 << 24) | (r2 << 16) | (g2 << 8) | b2;
hexcolors[2] = (uint32_t)(w3 << 24) | (r3 << 16) | (g3 << 8) | b3;
return hexcolors;
}
void getSegmentParams(uint8_t seg) {
seg_start = strip->getSegment(seg)->start;;
seg_stop = strip->getSegment(seg)->stop;;
ws2812fx_mode = strip->getMode(seg);
main_color.white = ((strip->getColors(seg)[0] >> 24) & 0xFF);
main_color.red = ((strip->getColors(seg)[0] >> 16) & 0xFF);
main_color.green = ((strip->getColors(seg)[0] >> 8) & 0xFF);
main_color.blue = ((strip->getColors(seg)[0]) & 0xFF);
back_color.white = ((strip->getColors(seg)[1] >> 24) & 0xFF);
back_color.red = ((strip->getColors(seg)[1] >> 16) & 0xFF);
back_color.green = ((strip->getColors(seg)[1] >> 8) & 0xFF);
back_color.blue = ((strip->getColors(seg)[1]) & 0xFF);
xtra_color.white = ((strip->getColors(seg)[2] >> 24) & 0xFF);
xtra_color.red = ((strip->getColors(seg)[2] >> 16) & 0xFF);
xtra_color.green = ((strip->getColors(seg)[2] >> 8) & 0xFF);
xtra_color.blue = ((strip->getColors(seg)[2] >> 0) & 0xFF);
}
void calculateColorTransitionSteps() {
//compare all colors and calculate steps
trans_cnt_max = 0;
int calculate_max[4] = {};
for (uint8_t i=0; i<3; i++){
for (uint8_t j=0; j<4; j++) {
calculate_max[j] = ((hex_colors[i] >> ((3-j)*8)) & 0xFF) - ((hex_colors_trans[i] >> ((3-j)*8)) & 0xFF);
calculate_max[j] = abs(calculate_max[j]);
trans_cnt_max = max(trans_cnt_max, calculate_max[j]);
}
}
}
void convertColorsFade() {
if (transEffect) {
if (trans_cnt > 1) {
memcpy(hex_colors, strip->getColors(segment), sizeof(hex_colors));
DBG_OUTPUT_PORT.println("Color transistion aborted. Restarting...!");
trans_cnt = 1;
}
calculateColorTransitionSteps();
}
}
uint32_t scale_wrgb(uint32_t wrgb, uint8_t level) {
uint8_t w = ((wrgb >> 24) & 0xFF) * level / 255;
uint8_t r = ((wrgb >> 16) & 0xFF) * level / 255;
uint8_t g = ((wrgb >> 8) & 0xFF) * level / 255;
uint8_t b = ((wrgb) & 0xFF) * level / 255;
return (w << 24) | (r << 16) | (g << 8) | b;
}
uint32_t trans(uint32_t newcolor, uint32_t oldcolor, uint8_t level) {
level = (level * (255/trans_cnt_max));
newcolor = scale_wrgb(newcolor, level);
oldcolor = scale_wrgb(oldcolor, 255-level);
return newcolor + oldcolor;
}
+465 -459
View File
@@ -1,463 +1,469 @@
#include <pgmspace.h>
#define edit_htm_gz_len 5489
#define edit_htm_gz_len 5563
static const char edit_htm_gz[] PROGMEM ={
0x1f, 0x8b, 0x08, 0x08, 0x10, 0x9c, 0x83, 0x5c, 0x04, 0x00, 0x65, 0x64,
0x69, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x00, 0xed, 0x1c, 0x67, 0x7b, 0xf2,
0x36, 0xf0, 0x7b, 0x7f, 0x85, 0xeb, 0x8e, 0x40, 0x99, 0x21, 0x24, 0x6f,
0x66, 0x5b, 0x76, 0x12, 0xa0, 0x84, 0x91, 0x84, 0xa4, 0xeb, 0x31, 0xb6,
0x00, 0x27, 0xc6, 0x76, 0x6c, 0x13, 0x20, 0x69, 0xfa, 0xdb, 0x7b, 0x92,
0xbc, 0x07, 0x38, 0xa3, 0xf3, 0x29, 0xef, 0x00, 0x4b, 0x77, 0xa7, 0xbb,
0xd3, 0xe9, 0x74, 0x3a, 0x49, 0x3e, 0xfe, 0xbc, 0xda, 0xa9, 0x0c, 0x6e,
0x2e, 0x6a, 0xcc, 0xd4, 0x98, 0x49, 0xdf, 0x7e, 0x76, 0x8c, 0xbf, 0x18,
0x89, 0x93, 0x27, 0x27, 0x2c, 0x92, 0xd9, 0x6f, 0x3f, 0x63, 0x98, 0xe3,
0x29, 0xe2, 0x04, 0xfc, 0x03, 0x7e, 0x1a, 0xa2, 0x21, 0xa1, 0x6f, 0xfb,
0x17, 0x67, 0xf5, 0x7a, 0x9f, 0xa9, 0x09, 0xa2, 0xa1, 0x68, 0xc7, 0x39,
0x52, 0x68, 0x02, 0xe8, 0xc6, 0x4a, 0x42, 0x8c, 0xb1, 0x52, 0xd1, 0x09,
0x6b, 0xa0, 0xa5, 0x91, 0xe3, 0x75, 0x9d, 0x65, 0x66, 0x48, 0x10, 0xb9,
0x13, 0x56, 0xe7, 0x35, 0x44, 0x89, 0x92, 0x4f, 0x96, 0x57, 0x64, 0x0c,
0xd3, 0x46, 0xf2, 0x9c, 0x79, 0x86, 0x42, 0xfa, 0x79, 0xca, 0x88, 0xb2,
0x80, 0x96, 0x87, 0xcc, 0x4e, 0x3e, 0x7f, 0x64, 0x97, 0xaa, 0x8a, 0x2e,
0x1a, 0xa2, 0x22, 0x1f, 0x32, 0xdc, 0x48, 0x57, 0xa4, 0xb9, 0x81, 0x9c,
0x3a, 0x09, 0x8d, 0x8d, 0x43, 0x66, 0x57, 0x5d, 0x3a, 0x45, 0x23, 0x45,
0x13, 0x90, 0x76, 0xc8, 0x6c, 0xab, 0x4b, 0x06, 0xc0, 0x45, 0x81, 0xf9,
0xa2, 0x58, 0x2c, 0xba, 0xea, 0x39, 0xfe, 0x7e, 0xa2, 0x29, 0x73, 0x59,
0xc8, 0xf0, 0x8a, 0xa4, 0x00, 0xe4, 0x17, 0xf5, 0x5d, 0xfc, 0xc7, 0x01,
0x11, 0x44, 0x5d, 0x95, 0xb8, 0xd5, 0x21, 0x23, 0x2b, 0x32, 0x72, 0x53,
0x5e, 0x66, 0xf4, 0x29, 0x27, 0x28, 0x8b, 0x43, 0x26, 0x0f, 0x7f, 0xb6,
0xf3, 0xd0, 0x84, 0x36, 0x19, 0x71, 0x09, 0x26, 0x9f, 0x36, 0xff, 0x66,
0x8b, 0x4c, 0xd2, 0xc1, 0x18, 0x83, 0x98, 0x19, 0x5d, 0x7c, 0x42, 0xc0,
0x4e, 0xc1, 0x64, 0xd2, 0xa9, 0x18, 0x73, 0x33, 0x51, 0x82, 0x56, 0x74,
0x4e, 0xd6, 0x33, 0x3a, 0xd2, 0xc4, 0xb1, 0x0f, 0x60, 0x81, 0xc4, 0xc9,
0xd4, 0x38, 0x1c, 0x29, 0x92, 0x60, 0xd5, 0xbc, 0x84, 0x69, 0x70, 0x2e,
0xb9, 0x94, 0x28, 0x89, 0x3a, 0xb4, 0x89, 0x3b, 0xc3, 0xcf, 0xbf, 0xa1,
0xa8, 0xc0, 0xb8, 0x57, 0x79, 0x9e, 0x82, 0x19, 0xa7, 0x4d, 0x44, 0xd9,
0x53, 0xa4, 0x72, 0x82, 0x20, 0xca, 0x13, 0x28, 0x5b, 0xc7, 0x01, 0x34,
0x0a, 0x1c, 0x04, 0x3b, 0x4c, 0x43, 0x12, 0x67, 0x88, 0x8f, 0xc8, 0xd5,
0x84, 0x28, 0x67, 0x16, 0xa2, 0x60, 0x4c, 0x0f, 0x99, 0xbd, 0xbc, 0x5b,
0x23, 0xfc, 0x5c, 0xd3, 0xa1, 0x33, 0x00, 0x59, 0x04, 0xb2, 0xda, 0xda,
0xd6, 0x74, 0x95, 0x93, 0x5d, 0xed, 0xd1, 0x6e, 0xa4, 0xdd, 0x1c, 0xec,
0x43, 0x51, 0x96, 0x44, 0x19, 0x65, 0x46, 0x92, 0xc2, 0xdf, 0x87, 0xc8,
0xb5, 0xa7, 0x2e, 0x37, 0x48, 0x76, 0x38, 0x55, 0x1e, 0x91, 0xc6, 0x3c,
0xbb, 0x2c, 0xc7, 0x6c, 0x6c, 0x3d, 0x86, 0xc9, 0xa6, 0xcd, 0x5e, 0xad,
0x56, 0xb3, 0x30, 0x6c, 0x34, 0x5d, 0xcf, 0x18, 0x30, 0x32, 0x1e, 0x45,
0xb4, 0x80, 0x5e, 0x4c, 0xfb, 0x4a, 0x1c, 0xad, 0x3a, 0x1c, 0x47, 0x74,
0xd8, 0xc6, 0xee, 0x7f, 0xf9, 0x2c, 0xb4, 0x51, 0x51, 0x56, 0xe7, 0x06,
0xf3, 0x1c, 0x6b, 0xb0, 0x29, 0x2a, 0xc7, 0x8b, 0xc6, 0x0a, 0x9a, 0xdb,
0x40, 0xf4, 0xd9, 0x63, 0xc6, 0x98, 0x0f, 0x6d, 0xc6, 0x49, 0xcc, 0x36,
0x1e, 0x92, 0x57, 0x48, 0x13, 0x38, 0x99, 0x4b, 0x33, 0x25, 0x4d, 0xe4,
0x40, 0xe2, 0x7e, 0x88, 0xf1, 0x67, 0x66, 0xca, 0x53, 0x66, 0x0e, 0x85,
0x50, 0x21, 0x21, 0xde, 0xf0, 0x1b, 0x32, 0x0c, 0x8c, 0xd1, 0xbd, 0x68,
0xac, 0x03, 0x71, 0x55, 0xc5, 0xd2, 0x43, 0x84, 0x49, 0xe5, 0xf3, 0xe3,
0x18, 0x26, 0x1a, 0x49, 0xd1, 0x34, 0x04, 0x87, 0x2e, 0x36, 0x92, 0x8c,
0x80, 0x78, 0x45, 0xe3, 0xa8, 0x96, 0xc1, 0x98, 0x90, 0x26, 0x89, 0x1b,
0xf9, 0xa3, 0xfd, 0x94, 0x02, 0xff, 0x3c, 0x42, 0x12, 0x7c, 0xe3, 0x21,
0x1f, 0x34, 0x03, 0xf2, 0xa7, 0x00, 0x9e, 0x26, 0x16, 0xb5, 0xdf, 0x09,
0x15, 0xff, 0x88, 0x89, 0xa5, 0x2e, 0xc2, 0x46, 0x3a, 0xac, 0xf0, 0xf0,
0x70, 0x84, 0xc6, 0x8a, 0x86, 0x98, 0xe7, 0x37, 0xea, 0x8d, 0xf0, 0x76,
0x08, 0xcc, 0x70, 0x23, 0x09, 0x09, 0xb6, 0xc8, 0x41, 0x72, 0x02, 0x1a,
0x73, 0x73, 0xc9, 0x08, 0xb1, 0xcf, 0xec, 0x5e, 0xac, 0x36, 0xf8, 0x29,
0xe2, 0xef, 0x91, 0x70, 0x28, 0x2b, 0x46, 0xc2, 0x6e, 0x30, 0x19, 0xa9,
0x16, 0xe2, 0x41, 0x3e, 0x52, 0x2f, 0x6e, 0x7f, 0x32, 0xd7, 0xa4, 0x04,
0x2b, 0x70, 0x06, 0x77, 0x28, 0xce, 0xb8, 0x09, 0xca, 0xa9, 0xf2, 0xe4,
0x68, 0xc4, 0xe9, 0x68, 0xaf, 0x98, 0x16, 0xaf, 0xca, 0x9d, 0xde, 0x22,
0xdf, 0x6c, 0x4c, 0x94, 0x12, 0x7c, 0x7e, 0xe8, 0x5f, 0x4e, 0x6b, 0x97,
0x13, 0xf8, 0x55, 0xc6, 0x8f, 0x95, 0x49, 0xa5, 0x74, 0x83, 0x7f, 0xd4,
0x3b, 0x68, 0x71, 0x89, 0x7f, 0x34, 0x86, 0xbd, 0xfa, 0xf5, 0x69, 0x6f,
0x30, 0x2a, 0xdc, 0xe6, 0x85, 0x42, 0x7d, 0x75, 0xdb, 0x2d, 0x97, 0x6f,
0x1b, 0x07, 0xe2, 0x6d, 0xbf, 0x7c, 0x3e, 0xba, 0xae, 0xcb, 0xb7, 0x57,
0xe7, 0xd2, 0xcd, 0x75, 0x6f, 0x97, 0xe7, 0x25, 0xe9, 0x02, 0x23, 0xa8,
0xcb, 0xf3, 0x5e, 0xad, 0x7e, 0x89, 0x7e, 0xd0, 0x74, 0xa9, 0xbd, 0x3d,
0xcf, 0xe7, 0x4b, 0xdd, 0x49, 0x03, 0x5c, 0xf4, 0x8a, 0x93, 0xea, 0xf5,
0x4e, 0x33, 0x55, 0x91, 0xce, 0xce, 0x9a, 0xdd, 0xe6, 0xea, 0xe1, 0xf2,
0xaa, 0xfb, 0x38, 0xa8, 0xd5, 0x76, 0xaa, 0xb3, 0xd2, 0xb4, 0xb5, 0x28,
0x4d, 0x2f, 0xf7, 0xbb, 0xb7, 0xca, 0x69, 0xb1, 0x54, 0xe8, 0x16, 0x26,
0xed, 0x7e, 0x9d, 0xe3, 0x51, 0xb1, 0x5d, 0x31, 0xce, 0xf7, 0xfb, 0x17,
0xe5, 0xfa, 0xa2, 0x74, 0xdf, 0x9b, 0x8b, 0xa7, 0x4d, 0xb5, 0xb4, 0xa7,
0xf7, 0x7e, 0xc8, 0xb5, 0xe6, 0x9f, 0x9e, 0x1a, 0xbb, 0xe2, 0x76, 0xf1,
0x9e, 0x37, 0xb8, 0xcb, 0x87, 0x5e, 0x63, 0xda, 0x18, 0xca, 0xf3, 0x83,
0x4e, 0xee, 0xc2, 0xf8, 0xd4, 0x7e, 0xd2, 0xdb, 0xe2, 0xbd, 0xf4, 0x58,
0x4f, 0x1d, 0x18, 0x85, 0xfb, 0xeb, 0x41, 0xf5, 0x71, 0x75, 0xa6, 0x95,
0xf4, 0x52, 0x9e, 0x6b, 0xf6, 0x7a, 0xe2, 0xf6, 0x20, 0x5f, 0xc9, 0x4d,
0xcf, 0x8b, 0xad, 0xcb, 0x91, 0xb1, 0x9b, 0xdb, 0xd7, 0x7e, 0x50, 0xaf,
0xaf, 0x24, 0x75, 0xbf, 0xd7, 0xd7, 0x0e, 0xce, 0x8b, 0xf9, 0x51, 0x71,
0x7f, 0xbc, 0xac, 0x73, 0x83, 0xee, 0x41, 0x6a, 0x6c, 0xec, 0xd7, 0x6e,
0xf7, 0xda, 0xe7, 0x37, 0xa3, 0x7c, 0xe7, 0x3e, 0x25, 0xc8, 0x37, 0x0d,
0x75, 0x76, 0x31, 0x19, 0x2e, 0x9a, 0x67, 0xa5, 0xc7, 0xd6, 0x72, 0xff,
0xf1, 0x66, 0xc8, 0xef, 0x36, 0x84, 0x76, 0xa9, 0x7b, 0x3e, 0xe9, 0xd6,
0xee, 0xd5, 0xbb, 0xde, 0x60, 0xba, 0xb3, 0x37, 0xe8, 0x17, 0x2e, 0x53,
0xd5, 0xeb, 0xeb, 0x5c, 0x75, 0xfb, 0xd3, 0xf5, 0xfc, 0x66, 0x32, 0xdb,
0x57, 0x17, 0xe7, 0xab, 0x9b, 0x6d, 0x59, 0xbd, 0xd5, 0x6f, 0x9b, 0x9d,
0xe5, 0xd9, 0xac, 0x73, 0xb5, 0x7d, 0x96, 0x9b, 0x16, 0x53, 0x9d, 0xbd,
0xc7, 0xda, 0x64, 0xb7, 0x51, 0xb9, 0x2d, 0xab, 0x93, 0x59, 0x69, 0x6f,
0x3a, 0xdc, 0x5f, 0x9c, 0x36, 0x2f, 0x4f, 0xab, 0xbd, 0xf2, 0xb0, 0x7b,
0x23, 0xf2, 0xdd, 0xa2, 0x26, 0xf1, 0x3b, 0x83, 0x71, 0xfe, 0xaa, 0xad,
0xef, 0x57, 0x4f, 0xcb, 0xfd, 0xfd, 0xbd, 0x62, 0xbd, 0x70, 0x53, 0xd7,
0xd5, 0xbb, 0xc9, 0xe5, 0xcd, 0x5d, 0x73, 0x98, 0x2b, 0x3d, 0xed, 0x4c,
0x74, 0xa1, 0x2b, 0x14, 0x10, 0x2a, 0x9f, 0x2e, 0x66, 0x42, 0xe3, 0x7a,
0x78, 0xca, 0x4f, 0xca, 0x8d, 0xfe, 0xfd, 0xed, 0xb0, 0x33, 0x54, 0xa6,
0x7c, 0x6d, 0x88, 0x46, 0x3d, 0xa5, 0xcb, 0x97, 0x26, 0x77, 0x0f, 0x10,
0x36, 0xfd, 0x70, 0x93, 0x2a, 0x5d, 0xad, 0xe6, 0x3b, 0xb7, 0x3b, 0x7a,
0xa9, 0xf9, 0x30, 0x6e, 0x2a, 0x8d, 0xb6, 0x8e, 0x16, 0x65, 0x54, 0x3b,
0xeb, 0x5c, 0x4c, 0xba, 0xcb, 0xe5, 0xc5, 0xf9, 0xd9, 0x1d, 0xdf, 0x38,
0xdd, 0x7b, 0x30, 0x5a, 0xb9, 0x7c, 0x49, 0x28, 0x55, 0x9f, 0x9a, 0x0d,
0x79, 0x3e, 0xaf, 0xa6, 0x0a, 0x46, 0xab, 0xf9, 0xa9, 0xbb, 0x5f, 0x9d,
0x9e, 0x9e, 0x8e, 0x3a, 0xe5, 0xeb, 0x54, 0xb3, 0xf6, 0xc4, 0x9f, 0xb6,
0xe6, 0x37, 0xfc, 0x7e, 0xa1, 0x7d, 0x5f, 0xbb, 0x44, 0xf7, 0x2d, 0x71,
0x31, 0x7f, 0xbc, 0x3a, 0x4d, 0x4d, 0xe6, 0xdd, 0x72, 0xf7, 0xa9, 0xd3,
0x28, 0x0e, 0x85, 0xd2, 0x68, 0xbf, 0xd6, 0xe1, 0x7b, 0xfc, 0x43, 0xf7,
0xb1, 0x7a, 0x7f, 0x53, 0x10, 0x2b, 0xad, 0xf9, 0xb2, 0x56, 0x39, 0x2f,
0xee, 0x9c, 0x2b, 0xa3, 0xf6, 0x50, 0x99, 0x1b, 0x0f, 0x8d, 0x49, 0x95,
0x2b, 0x0c, 0x3e, 0x5d, 0x3e, 0xb4, 0x9a, 0x0b, 0xe3, 0xa0, 0xd9, 0x5b,
0xcd, 0x97, 0xcd, 0xab, 0xf2, 0xea, 0xe1, 0x6a, 0x38, 0x7c, 0x38, 0x53,
0x2a, 0x95, 0xcb, 0x4a, 0xe9, 0x61, 0x7a, 0xd9, 0x11, 0x95, 0xc1, 0x75,
0xe5, 0x53, 0xa3, 0x38, 0xe8, 0xd6, 0x3a, 0xd5, 0x7c, 0xe9, 0x62, 0x55,
0xc8, 0x7d, 0x6a, 0x14, 0x86, 0xea, 0x7c, 0xfb, 0xbc, 0x98, 0x92, 0x96,
0xa8, 0x5b, 0x1c, 0x0c, 0xcb, 0xa3, 0xb3, 0x41, 0x55, 0x55, 0xae, 0x90,
0x04, 0x96, 0x51, 0xbe, 0xaa, 0x8f, 0x16, 0xf3, 0x5d, 0xa5, 0xdd, 0x3e,
0xbf, 0x2c, 0x4f, 0x95, 0xe1, 0x6a, 0xd7, 0x98, 0x09, 0x3d, 0xbe, 0xbd,
0x58, 0xcd, 0x2e, 0x0a, 0x9d, 0x56, 0x97, 0x6b, 0xdd, 0x2d, 0x0f, 0x72,
0x8f, 0x72, 0x59, 0xd9, 0xbb, 0xda, 0x69, 0xee, 0x89, 0x4f, 0xa5, 0xc1,
0xac, 0x2f, 0xb7, 0xb9, 0x7c, 0xf5, 0xe1, 0xd3, 0x18, 0x69, 0x67, 0xca,
0xf4, 0x7c, 0xaa, 0x6d, 0xab, 0xf9, 0xed, 0x27, 0x4d, 0x7a, 0x2a, 0x1e,
0x68, 0xb7, 0xf5, 0x62, 0x07, 0xba, 0xe0, 0xfc, 0x7e, 0x58, 0xd8, 0x79,
0xbc, 0xea, 0x3e, 0xdd, 0xa8, 0xa9, 0xc5, 0xe8, 0xa6, 0x71, 0x95, 0x6b,
0xaa, 0xc3, 0xe6, 0xdd, 0x23, 0x0c, 0xe6, 0x7d, 0x43, 0x3f, 0x6b, 0x56,
0xb4, 0xf6, 0x0f, 0xa5, 0x9b, 0xfa, 0xf2, 0xae, 0xd0, 0x68, 0xf6, 0x77,
0x6f, 0xaf, 0x97, 0x93, 0x22, 0x5a, 0x34, 0xf5, 0xf3, 0x31, 0xd7, 0x68,
0x9f, 0xdd, 0xec, 0x36, 0x87, 0x0f, 0x17, 0x4f, 0xfb, 0xad, 0x72, 0xf9,
0x6e, 0x2f, 0xb5, 0xaa, 0x3e, 0x5e, 0x5d, 0x7c, 0x3a, 0x80, 0x6f, 0x35,
0x77, 0x50, 0x3f, 0x50, 0xce, 0x96, 0x3b, 0x1d, 0x51, 0x3f, 0xbd, 0x5e,
0xa0, 0x4f, 0x1d, 0x4e, 0xca, 0x9f, 0x2e, 0x2b, 0x30, 0x88, 0xba, 0x30,
0x22, 0x6b, 0x67, 0x5d, 0x18, 0x90, 0xb5, 0x33, 0x18, 0x9a, 0xa4, 0x68,
0x0a, 0xff, 0x9d, 0xe1, 0x0a, 0x5a, 0x54, 0x83, 0xc7, 0x29, 0x85, 0x5d,
0x54, 0xf7, 0x6b, 0xb9, 0xf2, 0xed, 0xa4, 0x74, 0x91, 0x7f, 0x98, 0x36,
0xef, 0x76, 0xb4, 0x61, 0xe7, 0x53, 0x09, 0x7f, 0x6a, 0x52, 0x7d, 0x70,
0xdf, 0x9f, 0x77, 0x67, 0x95, 0x0a, 0x9b, 0x04, 0x4f, 0x9c, 0xd1, 0x90,
0x8a, 0x38, 0xe3, 0x2d, 0x6e, 0x07, 0x4f, 0x40, 0x71, 0x5d, 0xd1, 0x86,
0x68, 0x69, 0x4a, 0x03, 0x51, 0x66, 0x7b, 0xcf, 0x1d, 0xb2, 0x11, 0xc8,
0xf0, 0x2a, 0x98, 0xf5, 0x0c, 0x91, 0xe7, 0xa4, 0x0c, 0x27, 0x89, 0x13,
0x98, 0x99, 0x66, 0xa2, 0x20, 0x48, 0xb1, 0x26, 0x95, 0x50, 0xff, 0x98,
0x71, 0xc2, 0x92, 0xed, 0x7d, 0x75, 0xb9, 0x31, 0x00, 0x89, 0x12, 0x93,
0x84, 0x69, 0x38, 0x22, 0x61, 0x59, 0x87, 0x57, 0x12, 0x8e, 0x9a, 0x02,
0xf8, 0xa7, 0x54, 0x73, 0x3a, 0xc5, 0xf3, 0x6a, 0x5c, 0xe1, 0xc2, 0xf8,
0x26, 0x84, 0x32, 0x3b, 0x31, 0x27, 0x66, 0x6b, 0x62, 0x62, 0x52, 0x31,
0xa6, 0x0e, 0x6f, 0x13, 0x20, 0x44, 0xb0, 0x89, 0xdc, 0x37, 0x0c, 0x0d,
0x98, 0x18, 0x4e, 0xb8, 0xe3, 0x78, 0x50, 0x00, 0x03, 0x81, 0xd1, 0x0c,
0x7f, 0xd3, 0x08, 0x49, 0xd1, 0x98, 0xd1, 0x7c, 0x32, 0x16, 0x97, 0xcc,
0x37, 0x39, 0x13, 0xe7, 0x7b, 0xb2, 0x70, 0x63, 0xe8, 0xba, 0x8d, 0xe1,
0x64, 0x81, 0x49, 0x58, 0x51, 0x17, 0x0e, 0xe1, 0x05, 0x60, 0x97, 0x47,
0x19, 0x55, 0x5c, 0x22, 0x29, 0x43, 0x62, 0x99, 0xc3, 0x7c, 0x92, 0xa2,
0x52, 0x2e, 0x83, 0xb2, 0x39, 0xc5, 0x4e, 0x00, 0xc7, 0xc9, 0x30, 0xdb,
0x51, 0xe6, 0xcd, 0x12, 0x8b, 0xc3, 0x8c, 0xc9, 0x61, 0xc6, 0xe2, 0x30,
0x63, 0x72, 0x28, 0xca, 0x63, 0x51, 0x16, 0x0d, 0xc4, 0x6c, 0xeb, 0x44,
0x50, 0x47, 0x54, 0x93, 0x71, 0x8b, 0xf6, 0x3d, 0x5a, 0x8d, 0x35, 0x6e,
0x86, 0xf4, 0xd8, 0xa4, 0x6d, 0x1a, 0x6e, 0x56, 0xc7, 0x9a, 0x32, 0x83,
0x12, 0xa7, 0x32, 0x18, 0x8b, 0xdb, 0x5c, 0xb8, 0x81, 0x0c, 0x25, 0x2e,
0x96, 0x23, 0x85, 0xbf, 0xe3, 0xbe, 0x98, 0xab, 0x92, 0xc2, 0x09, 0x64,
0xf1, 0x11, 0x2b, 0x42, 0xf7, 0xaf, 0xf0, 0x34, 0x3a, 0x36, 0x83, 0x6b,
0xbe, 0xc0, 0xd0, 0x2e, 0xec, 0x47, 0x8e, 0xec, 0x42, 0xd1, 0xae, 0x72,
0x84, 0xc8, 0x10, 0x42, 0x64, 0x09, 0x1c, 0x6a, 0xf8, 0xa1, 0x6b, 0x32,
0x5a, 0x88, 0x17, 0x42, 0xfe, 0x25, 0xd7, 0x17, 0xd8, 0x4a, 0x5e, 0x25,
0xa5, 0x97, 0xe1, 0x91, 0x62, 0x18, 0xca, 0x2c, 0x5a, 0x52, 0x67, 0x9c,
0x17, 0xf2, 0x84, 0xe5, 0x40, 0x9f, 0x38, 0xe4, 0x1c, 0xa6, 0x10, 0x49,
0x73, 0xa4, 0x99, 0x2f, 0x54, 0x8d, 0x98, 0xf0, 0x3b, 0x18, 0xb4, 0x7a,
0x22, 0x06, 0xcb, 0x0e, 0x87, 0x0e, 0x2f, 0x2e, 0x16, 0xd6, 0x68, 0x1b,
0x6b, 0x36, 0x28, 0xda, 0xae, 0x9f, 0xda, 0x71, 0x0e, 0xd6, 0x87, 0x4e,
0xde, 0x86, 0xd7, 0x44, 0xd5, 0xb0, 0x32, 0x33, 0xe3, 0xb9, 0xcc, 0x63,
0xb1, 0x18, 0x18, 0xf8, 0x9c, 0x81, 0xea, 0xa2, 0x84, 0x2e, 0x4d, 0x23,
0x4c, 0x98, 0xe3, 0x26, 0xcd, 0xe0, 0xce, 0x4a, 0x33, 0x54, 0x3b, 0x49,
0x87, 0xa1, 0x47, 0x4e, 0x63, 0x96, 0x33, 0xe9, 0xd4, 0x30, 0xd4, 0x23,
0x77, 0xa1, 0xb9, 0xdc, 0x38, 0x61, 0x04, 0x85, 0x9f, 0x63, 0x0a, 0x59,
0x4a, 0xbc, 0x46, 0xe9, 0x25, 0x58, 0x52, 0xcf, 0x3a, 0x79, 0x13, 0x8a,
0x90, 0xc5, 0xb9, 0x24, 0xc0, 0x62, 0xc7, 0xc0, 0x04, 0xeb, 0xaf, 0x9c,
0x41, 0xe8, 0x2f, 0xaa, 0x12, 0x06, 0x18, 0x73, 0x92, 0x8e, 0xfc, 0xf5,
0x32, 0x37, 0xc3, 0x75, 0x24, 0xa6, 0x76, 0x90, 0x1d, 0x16, 0x26, 0xc8,
0x30, 0xdb, 0x2f, 0xaf, 0xce, 0x04, 0x4b, 0xb6, 0x64, 0x96, 0x53, 0x55,
0x24, 0x0b, 0x95, 0xa9, 0x28, 0x09, 0x09, 0x42, 0x29, 0xe9, 0x95, 0x45,
0xe5, 0x8c, 0xe9, 0x6b, 0x44, 0xc1, 0xf0, 0x59, 0x51, 0xc0, 0xac, 0xd0,
0xd1, 0x9c, 0xc1, 0x25, 0xac, 0x17, 0xc0, 0x16, 0x15, 0xaf, 0x0f, 0x7d,
0x75, 0xb6, 0x24, 0x61, 0x78, 0xe6, 0x1a, 0xe8, 0x8a, 0x93, 0xe6, 0x04,
0x26, 0xf7, 0x56, 0x51, 0x31, 0x35, 0x9f, 0xa4, 0xa3, 0x39, 0x18, 0xa8,
0xbc, 0x46, 0x56, 0x0a, 0xe0, 0x16, 0x96, 0x96, 0x64, 0x45, 0x59, 0x46,
0xda, 0xe9, 0xa0, 0xdd, 0x02, 0xe4, 0x2d, 0x6a, 0x3e, 0x5b, 0x6f, 0xe4,
0x8b, 0x52, 0xf4, 0x71, 0x36, 0xbb, 0x17, 0x44, 0xed, 0x55, 0x8c, 0x11,
0x0c, 0x2f, 0x5f, 0xed, 0xfb, 0xaa, 0xa8, 0xbd, 0x95, 0x2d, 0x42, 0x2f,
0xc0, 0x15, 0x36, 0xd4, 0x57, 0xb2, 0x85, 0x51, 0xfc, 0x7c, 0xe1, 0x41,
0xf7, 0x76, 0xc6, 0x30, 0x45, 0xd2, 0x04, 0xfc, 0xf5, 0x8d, 0xe9, 0x29,
0x8c, 0xcc, 0x0b, 0x45, 0x37, 0x2e, 0x34, 0x85, 0x47, 0xba, 0xde, 0x43,
0x0f, 0x73, 0xa4, 0x1b, 0x09, 0x32, 0x84, 0xed, 0xd1, 0x33, 0x66, 0x12,
0xe6, 0x20, 0xce, 0x02, 0xfb, 0xc2, 0xaa, 0x6f, 0x70, 0x06, 0x48, 0x75,
0xc2, 0x14, 0x4d, 0x38, 0x07, 0xd2, 0x06, 0xd4, 0x01, 0x66, 0xae, 0x33,
0x9f, 0x9f, 0x60, 0xe7, 0x95, 0x64, 0x38, 0x09, 0x69, 0x20, 0x6f, 0xad,
0xd7, 0xeb, 0xf4, 0x7e, 0x64, 0x53, 0x5e, 0xa8, 0x14, 0xfb, 0x33, 0xc4,
0x5f, 0x29, 0xa7, 0x0d, 0x5d, 0x55, 0x64, 0x1d, 0x0d, 0xd0, 0x92, 0x0e,
0x35, 0xe7, 0x83, 0x24, 0xdd, 0x8c, 0x79, 0x9c, 0x0f, 0xf1, 0x3d, 0x80,
0x34, 0x06, 0xbc, 0xe9, 0x05, 0x18, 0x6d, 0x82, 0x8c, 0x83, 0x47, 0x3c,
0x00, 0x7c, 0xe8, 0x2f, 0xeb, 0x26, 0xd9, 0xa0, 0xab, 0xa3, 0xc4, 0x3c,
0x32, 0x9a, 0x3c, 0x42, 0xaf, 0xc8, 0xe0, 0x79, 0x87, 0xed, 0x16, 0x7e,
0xb2, 0xb5, 0x76, 0x14, 0x84, 0xcc, 0x2a, 0x32, 0xd1, 0x19, 0x96, 0x14,
0xf1, 0x53, 0xc8, 0xa5, 0x83, 0xe6, 0x22, 0xd4, 0x4e, 0xd1, 0x1d, 0xf3,
0x81, 0x08, 0x6f, 0x56, 0x05, 0x67, 0x65, 0xb6, 0x56, 0x37, 0x1f, 0x3d,
0xed, 0xd8, 0x40, 0x66, 0x9f, 0x27, 0xa8, 0x53, 0x48, 0x33, 0x6a, 0x38,
0x37, 0x00, 0x93, 0x60, 0x2f, 0x2e, 0x07, 0x00, 0xc1, 0xe6, 0xb0, 0xbf,
0x66, 0x43, 0xe1, 0x74, 0x4c, 0xca, 0x22, 0x0d, 0x10, 0x41, 0x5d, 0xf9,
0x2c, 0x16, 0xe4, 0xe4, 0x25, 0x91, 0xbf, 0x67, 0x4e, 0x6c, 0x2d, 0x26,
0x90, 0xcf, 0x8c, 0x5c, 0x1d, 0x93, 0x25, 0x69, 0xfd, 0xce, 0x38, 0xc1,
0x66, 0xd9, 0x24, 0x98, 0xd2, 0x09, 0x04, 0xaa, 0x49, 0x48, 0x0e, 0x1b,
0x73, 0x4d, 0x76, 0xf1, 0x63, 0x76, 0xc4, 0x9a, 0x5e, 0x35, 0xe7, 0x9c,
0x2c, 0xf6, 0x28, 0x97, 0x9a, 0x14, 0x0e, 0xf5, 0xe2, 0x1b, 0xf6, 0xaf,
0x65, 0x56, 0x42, 0xf2, 0x04, 0x7c, 0xfc, 0x31, 0x53, 0xb0, 0x78, 0xf4,
0x77, 0x15, 0xf5, 0x3e, 0x0e, 0x8a, 0x97, 0x14, 0xd4, 0x7a, 0x05, 0xfe,
0x9c, 0x08, 0x4c, 0x5a, 0x0c, 0x00, 0x4a, 0x9c, 0x6e, 0x9c, 0x59, 0xc0,
0x39, 0x53, 0x3b, 0xf9, 0xb0, 0x86, 0x19, 0xb3, 0x59, 0x8c, 0xa5, 0xcf,
0x47, 0xba, 0xa1, 0xc1, 0xe4, 0x9e, 0x80, 0x2d, 0x87, 0x30, 0x32, 0x1e,
0xa5, 0xbd, 0x84, 0xab, 0xd8, 0xeb, 0xc1, 0x5e, 0xfc, 0x5e, 0x3c, 0x96,
0xda, 0xe8, 0x5c, 0x8b, 0x4d, 0x42, 0x37, 0xf5, 0x46, 0x05, 0xf0, 0x09,
0x1b, 0x94, 0xe6, 0xe5, 0xdf, 0x35, 0xcc, 0x48, 0x14, 0x91, 0x66, 0x5c,
0xe2, 0xfe, 0x98, 0xff, 0x39, 0xed, 0x32, 0x81, 0x75, 0xe3, 0xaf, 0xd3,
0x7f, 0xff, 0x00, 0x24, 0x2d, 0x83, 0xdc, 0x54, 0xda, 0xb7, 0xf5, 0x49,
0x84, 0x35, 0x63, 0x48, 0x1a, 0x63, 0xf8, 0xe4, 0x23, 0x91, 0x87, 0x1f,
0x1a, 0xdc, 0x34, 0x00, 0xe6, 0x12, 0xdf, 0x1d, 0xfe, 0x94, 0x4d, 0xfc,
0xf8, 0x4b, 0xf6, 0xe7, 0x54, 0x32, 0xf9, 0xdd, 0x97, 0xb9, 0x2c, 0x5a,
0x22, 0x3e, 0x61, 0x91, 0x4a, 0xfe, 0xb8, 0xfd, 0xb3, 0x1f, 0x11, 0x97,
0x13, 0xcc, 0xec, 0x37, 0xc9, 0x9f, 0xb2, 0x04, 0x33, 0x12, 0xcd, 0x11,
0x06, 0x07, 0x46, 0xca, 0x98, 0x20, 0xe3, 0x71, 0x44, 0xf2, 0xe5, 0x63,
0x58, 0x9d, 0x08, 0xc1, 0xe1, 0x84, 0x61, 0x2c, 0x81, 0xbf, 0x65, 0xf6,
0x93, 0x66, 0x8b, 0xe4, 0xcb, 0x3b, 0x62, 0xf6, 0xbd, 0x33, 0x85, 0x5b,
0x03, 0x7e, 0x91, 0x5f, 0xc2, 0xd8, 0xc1, 0x4a, 0xd8, 0xc4, 0x0d, 0x80,
0x10, 0xb5, 0xb3, 0x78, 0x5b, 0x95, 0x4d, 0x12, 0x14, 0xfa, 0xc4, 0x06,
0x67, 0x39, 0x0f, 0xc2, 0x9d, 0x8a, 0x26, 0x26, 0x02, 0x79, 0x9a, 0xb0,
0x51, 0xdc, 0x3a, 0x3f, 0x53, 0x0c, 0x78, 0x1a, 0xf8, 0x1f, 0x90, 0xd6,
0x70, 0xef, 0x98, 0x2b, 0x6d, 0x29, 0xc7, 0x32, 0xbf, 0xfd, 0xe6, 0x32,
0xe2, 0x08, 0x6f, 0xe4, 0x13, 0xce, 0x45, 0x85, 0xd0, 0x48, 0x59, 0x5c,
0x78, 0x5a, 0xa6, 0x72, 0x45, 0x63, 0x3a, 0x0f, 0xde, 0xce, 0x59, 0xc7,
0x4e, 0x6a, 0x3b, 0x69, 0x37, 0x16, 0x73, 0x09, 0xed, 0x9b, 0xe4, 0x07,
0x10, 0x3d, 0x58, 0x81, 0x53, 0xc4, 0x0a, 0xc6, 0x5a, 0x68, 0x9d, 0x44,
0x06, 0x5e, 0xac, 0x09, 0xc2, 0x7a, 0x03, 0x40, 0x12, 0x9a, 0xf4, 0x14,
0x65, 0xdd, 0x4a, 0x47, 0x10, 0x1f, 0x5d, 0x58, 0x16, 0x06, 0x80, 0x81,
0xa8, 0xfa, 0x0f, 0x66, 0xa0, 0xef, 0xce, 0x9a, 0xbc, 0x35, 0x9e, 0xb7,
0x28, 0x47, 0x44, 0x82, 0x78, 0x02, 0xad, 0x2a, 0x0b, 0x19, 0x7f, 0x13,
0xb3, 0x20, 0x4a, 0xd8, 0xd4, 0xd2, 0x96, 0x60, 0xa2, 0x64, 0x48, 0x66,
0x65, 0x2b, 0x99, 0xd5, 0x35, 0xde, 0xec, 0xca, 0x14, 0xfb, 0x9d, 0x55,
0x7b, 0x62, 0x68, 0x73, 0xf7, 0x82, 0xed, 0x25, 0x92, 0x85, 0x0b, 0xaa,
0xc8, 0xf8, 0x1c, 0xb0, 0xb4, 0xcb, 0x58, 0x68, 0x19, 0x2f, 0x61, 0xb3,
0x66, 0xde, 0x12, 0x6b, 0x0d, 0xef, 0x5a, 0xb9, 0x47, 0x8a, 0xd5, 0x91,
0x41, 0x48, 0x92, 0xdc, 0x0c, 0x03, 0xf5, 0x06, 0xe2, 0xc7, 0xe2, 0x6c,
0xc2, 0x80, 0x80, 0x27, 0xec, 0x56, 0x8a, 0x48, 0xb8, 0xc5, 0x32, 0x84,
0xd6, 0x09, 0x3b, 0xe3, 0x96, 0xe6, 0x2e, 0xf6, 0x76, 0x3e, 0xff, 0xd5,
0x11, 0x03, 0xcf, 0x66, 0xba, 0x84, 0x16, 0x58, 0xe9, 0x43, 0x6e, 0x6e,
0x28, 0x47, 0x76, 0x72, 0x95, 0x26, 0x55, 0x59, 0x26, 0xf7, 0xed, 0xd6,
0x06, 0xe5, 0xe0, 0x81, 0x2d, 0xd5, 0x15, 0x09, 0x56, 0xdd, 0x78, 0x4b,
0x39, 0x81, 0x93, 0xbb, 0x8e, 0x8e, 0x1c, 0x93, 0xc3, 0xbb, 0xbd, 0xeb,
0xcc, 0x6d, 0x2e, 0x79, 0xe7, 0x1b, 0x24, 0x79, 0x8c, 0x04, 0x63, 0x27,
0xfd, 0x7e, 0x9a, 0x23, 0x1c, 0xac, 0x21, 0x2a, 0x89, 0x5e, 0xa2, 0x98,
0x8a, 0x87, 0x2c, 0xa5, 0x10, 0x20, 0x2c, 0xea, 0x15, 0x9a, 0xd7, 0x5c,
0x33, 0xb4, 0x88, 0x90, 0x59, 0x33, 0xff, 0x19, 0x9c, 0x7a, 0x54, 0x59,
0x78, 0x0f, 0x63, 0x84, 0x40, 0xd2, 0x37, 0xc3, 0x98, 0x6c, 0x05, 0x7c,
0x38, 0x01, 0xf6, 0x58, 0x04, 0x7b, 0x8c, 0x53, 0xea, 0xdf, 0x56, 0x14,
0x49, 0xe2, 0x54, 0x1d, 0x1d, 0xe7, 0xc8, 0x23, 0x7b, 0x14, 0x44, 0xdb,
0x1c, 0x3b, 0xc1, 0x27, 0x9e, 0x12, 0x02, 0xf9, 0x0d, 0x87, 0x73, 0x1b,
0x7f, 0xa4, 0x08, 0x2b, 0x17, 0x11, 0xbd, 0xbc, 0xaa, 0x58, 0xfe, 0x24,
0xb1, 0xe5, 0x3a, 0x9a, 0xb0, 0x95, 0xb4, 0xe7, 0x47, 0x1c, 0x0e, 0x78,
0xf1, 0x35, 0x34, 0x83, 0xcd, 0x6a, 0x53, 0x51, 0x92, 0x7f, 0x2d, 0x65,
0x3d, 0x3a, 0xbd, 0x81, 0xd7, 0x60, 0xfa, 0xf4, 0x15, 0xdd, 0x11, 0xd2,
0x21, 0x94, 0x86, 0x0f, 0x8a, 0x16, 0x86, 0x69, 0xbe, 0x47, 0x97, 0x7d,
0x8e, 0xe2, 0x83, 0x68, 0xf1, 0x34, 0x4f, 0x86, 0x0e, 0xe2, 0xc6, 0x1b,
0x2d, 0x51, 0xe5, 0x34, 0x28, 0xf8, 0x41, 0x11, 0xc2, 0xf4, 0x8f, 0x29,
0x64, 0x79, 0x2c, 0x08, 0x00, 0xb8, 0x83, 0x2d, 0x66, 0x27, 0x49, 0xc8,
0xbb, 0x75, 0xea, 0x87, 0xfe, 0xb1, 0xf0, 0x73, 0xd2, 0x47, 0x93, 0x44,
0xb0, 0x0d, 0x64, 0x10, 0x50, 0x73, 0xc0, 0xff, 0x83, 0xba, 0xdd, 0x9c,
0xd2, 0x63, 0x8e, 0x92, 0xda, 0x12, 0xfe, 0x17, 0xfe, 0xb2, 0x31, 0x82,
0xa7, 0x9c, 0xa3, 0xff, 0x7b, 0xf9, 0x03, 0x7a, 0xd9, 0xe7, 0x74, 0x49,
0xd2, 0xf2, 0x5d, 0x5e, 0x97, 0x52, 0xf0, 0xc0, 0x90, 0xa2, 0x50, 0xb3,
0x21, 0xd9, 0x42, 0xdb, 0x6c, 0x02, 0x38, 0xb1, 0xac, 0xc6, 0x4a, 0xd3,
0xd6, 0xa4, 0x35, 0x3d, 0xef, 0xce, 0xc6, 0xda, 0x02, 0x38, 0xea, 0xa7,
0xf8, 0xa1, 0x8e, 0x03, 0xa2, 0xd5, 0x0b, 0x9a, 0x04, 0xa6, 0x40, 0x34,
0x58, 0x0d, 0xe9, 0x42, 0x13, 0x30, 0x18, 0x55, 0x1f, 0x33, 0xdb, 0x49,
0x0f, 0xb2, 0x15, 0x43, 0x99, 0x18, 0x3e, 0x5a, 0x64, 0xdc, 0x85, 0xc1,
0x3b, 0x81, 0x73, 0x64, 0x5b, 0x49, 0x2f, 0x4d, 0xa7, 0x97, 0xff, 0x2e,
0x73, 0x7b, 0x09, 0x24, 0x53, 0x90, 0x84, 0x13, 0x9e, 0xef, 0xb1, 0x30,
0x93, 0x84, 0x07, 0xc8, 0x2c, 0x0b, 0xb3, 0xb1, 0x2a, 0x44, 0xcc, 0x86,
0x3d, 0x7d, 0xfb, 0x91, 0x62, 0xa5, 0xb7, 0xe8, 0x28, 0xa6, 0x84, 0xcc,
0xdc, 0xf9, 0x3f, 0x41, 0xa3, 0x91, 0xc1, 0x24, 0x11, 0xeb, 0xbf, 0x11,
0x4a, 0x92, 0x90, 0x0d, 0x67, 0x8b, 0x41, 0x24, 0x53, 0xf7, 0xbe, 0xae,
0xa1, 0x48, 0x61, 0x3d, 0x8f, 0xcf, 0x2d, 0xdb, 0xfd, 0x1e, 0xc0, 0x89,
0x93, 0xf3, 0x0a, 0x49, 0x42, 0xfe, 0xe3, 0x3c, 0x38, 0xf1, 0x17, 0x54,
0x4f, 0x67, 0xf8, 0x30, 0xd9, 0x1b, 0x14, 0x65, 0x2e, 0xcc, 0xde, 0xaf,
0x2b, 0xd7, 0x2a, 0xef, 0x9f, 0xa7, 0x28, 0x9f, 0xb9, 0xe2, 0xf5, 0xeb,
0x7b, 0x27, 0x3b, 0x8b, 0x86, 0x07, 0xca, 0x2a, 0x0c, 0x75, 0x46, 0x66,
0x9d, 0xa5, 0x6a, 0x3f, 0x5e, 0xdc, 0x49, 0xcf, 0xbd, 0xa2, 0xff, 0x07,
0x79, 0xa4, 0xff, 0x7d, 0xfc, 0x47, 0x6b, 0x34, 0xdc, 0xc7, 0xeb, 0x53,
0x65, 0x51, 0x71, 0xda, 0x49, 0x20, 0xea, 0xe5, 0xd3, 0xb0, 0xea, 0x26,
0x1b, 0x82, 0xcf, 0x81, 0x2d, 0x8c, 0x47, 0x0a, 0xfe, 0x8a, 0x6c, 0x15,
0xc1, 0xc4, 0x47, 0x82, 0x60, 0x01, 0x3c, 0x50, 0x20, 0x5f, 0xef, 0xe3,
0xdf, 0xa9, 0xf9, 0x2e, 0xb2, 0xe6, 0xd0, 0xa9, 0xb1, 0x7e, 0x98, 0xcd,
0x39, 0x40, 0xe1, 0x2d, 0xb6, 0xe0, 0x70, 0x44, 0xb0, 0x49, 0xa7, 0xea,
0xbb, 0xc8, 0xaa, 0xcd, 0x8d, 0x62, 0x28, 0x7f, 0xab, 0x12, 0x6d, 0x0f,
0x65, 0xc1, 0x4c, 0x00, 0x72, 0x08, 0xd9, 0xd5, 0x48, 0x60, 0x7c, 0xe2,
0xc3, 0x05, 0x7b, 0x43, 0x60, 0x83, 0xd2, 0x38, 0x5a, 0xf7, 0x66, 0xfc,
0x3c, 0x16, 0x12, 0x0e, 0x1f, 0xc8, 0x62, 0x6d, 0x91, 0x6c, 0xd2, 0x7a,
0x68, 0x53, 0x04, 0xfc, 0x05, 0x1c, 0x6d, 0xa9, 0xcb, 0xf5, 0xe0, 0x54,
0x08, 0xf8, 0xdf, 0x06, 0xf6, 0x18, 0xbb, 0x69, 0x49, 0xde, 0x70, 0xc2,
0x21, 0x12, 0x5c, 0xca, 0xd0, 0x79, 0xc8, 0x49, 0x65, 0x6d, 0x46, 0xf0,
0xf4, 0xa0, 0x67, 0xf8, 0x3b, 0x68, 0x01, 0x83, 0x24, 0x89, 0x38, 0xe6,
0xc4, 0x2d, 0x8f, 0x32, 0x1e, 0xeb, 0xc8, 0xb8, 0xc6, 0x15, 0x7e, 0x68,
0x9a, 0xa6, 0x0b, 0x03, 0x3f, 0x25, 0x35, 0x11, 0x1a, 0x52, 0xe4, 0x99,
0x02, 0x77, 0x0a, 0xe0, 0x20, 0x6c, 0xd0, 0x61, 0x78, 0xb4, 0xe4, 0xd8,
0xcb, 0x31, 0x51, 0x3c, 0xce, 0xb0, 0x3b, 0x65, 0xdf, 0x32, 0x09, 0xda,
0x1b, 0x94, 0xeb, 0xa4, 0xbb, 0xf6, 0x06, 0x30, 0x40, 0xf9, 0x9e, 0x22,
0x8c, 0x40, 0x3a, 0xc4, 0xe4, 0x1b, 0x66, 0xf0, 0xbf, 0x72, 0xfe, 0xf4,
0x69, 0xdd, 0xf9, 0xbc, 0xbc, 0xc6, 0x37, 0x39, 0xa9, 0xf7, 0x16, 0xe2,
0xe8, 0xd2, 0x2a, 0x4d, 0x36, 0x5a, 0xd2, 0x0c, 0xbe, 0x1b, 0x15, 0x8c,
0x44, 0x01, 0xea, 0x35, 0x53, 0x05, 0x80, 0xd3, 0x13, 0x36, 0x89, 0x04,
0x21, 0xce, 0xd0, 0xbd, 0x8d, 0xe4, 0x77, 0x2c, 0x7b, 0x48, 0x4c, 0x2c,
0x05, 0x4f, 0x29, 0xb2, 0xc1, 0x04, 0x36, 0xde, 0x52, 0x16, 0x48, 0xab,
0xc0, 0xd1, 0xfa, 0x84, 0xdf, 0x92, 0xe8, 0x69, 0xcb, 0x35, 0x2d, 0xe3,
0xc9, 0xc4, 0xd3, 0x36, 0xc5, 0xc8, 0x62, 0x05, 0x55, 0xe8, 0xd1, 0x52,
0x73, 0x0b, 0xc9, 0xd3, 0x4e, 0x80, 0x5b, 0x8f, 0x65, 0x13, 0x12, 0x01,
0x90, 0x38, 0xd3, 0x93, 0x37, 0x12, 0x36, 0xd5, 0x90, 0xdc, 0x10, 0xae,
0x5a, 0x70, 0xa4, 0xc5, 0x0d, 0x41, 0xa3, 0x0d, 0xbb, 0x2e, 0xac, 0xb3,
0x80, 0xe2, 0x59, 0x88, 0x2d, 0x9d, 0x69, 0x8e, 0xa0, 0xd8, 0xf9, 0x3a,
0x19, 0x51, 0x16, 0xe7, 0xe6, 0x41, 0xb1, 0x55, 0x7a, 0xd2, 0xc9, 0x52,
0xa6, 0x53, 0xaf, 0xc3, 0xf8, 0x80, 0x2d, 0x5f, 0x95, 0x9b, 0x90, 0x93,
0xa4, 0x3e, 0x80, 0xb0, 0x89, 0xd1, 0x64, 0x38, 0x4d, 0x92, 0x46, 0xfe,
0x69, 0xd6, 0xbf, 0x69, 0x4d, 0xa0, 0xe3, 0x5b, 0x78, 0x59, 0xe3, 0x60,
0x8f, 0xd6, 0x63, 0xe3, 0xd6, 0xcd, 0x92, 0xf7, 0xda, 0x39, 0x46, 0x21,
0x09, 0xaf, 0xd7, 0x1c, 0x3f, 0x63, 0x28, 0x8a, 0x7d, 0xc0, 0x8c, 0x3c,
0xc1, 0x45, 0x46, 0x36, 0x00, 0xf2, 0xfe, 0x21, 0xe4, 0xec, 0x8f, 0xda,
0xb7, 0x77, 0x3e, 0xc7, 0x74, 0xec, 0x5d, 0x52, 0x96, 0xf9, 0xfa, 0x6b,
0x47, 0x1d, 0x66, 0xb3, 0xd6, 0x33, 0xe6, 0xce, 0xfa, 0xcd, 0xae, 0x1d,
0x31, 0x04, 0xef, 0xd5, 0x83, 0x97, 0xd4, 0x87, 0x8d, 0x5e, 0xd8, 0x77,
0x07, 0x34, 0x4b, 0x07, 0x7f, 0xfa, 0xe8, 0x26, 0x0d, 0xc5, 0xd8, 0xc9,
0x27, 0xfa, 0xa4, 0xc0, 0xbc, 0xb5, 0x41, 0xf1, 0x97, 0x67, 0x27, 0x49,
0xcb, 0xaf, 0x19, 0xdc, 0x58, 0xdc, 0x98, 0xbe, 0xeb, 0xf3, 0xf5, 0xc2,
0xd9, 0xb5, 0x4e, 0x86, 0xf7, 0x6f, 0x48, 0xcf, 0x92, 0xf6, 0x23, 0xdd,
0xe5, 0x1a, 0x9e, 0x9d, 0x9d, 0x9b, 0xb8, 0xaa, 0xfb, 0xdb, 0xfd, 0xa2,
0x25, 0x6b, 0x9a, 0xf0, 0xed, 0xf3, 0x8c, 0x6f, 0x73, 0x8c, 0x70, 0x04,
0xb9, 0x05, 0x2b, 0xb9, 0x04, 0xcd, 0xb0, 0xdb, 0x6b, 0x12, 0x03, 0xcd,
0xf4, 0xf7, 0x26, 0xa0, 0x28, 0xc9, 0xcd, 0x49, 0x28, 0x09, 0x9c, 0x02,
0x69, 0xd1, 0xb2, 0x0d, 0xdf, 0x41, 0x9f, 0x04, 0xd9, 0x9b, 0x04, 0x98,
0xfc, 0x11, 0x7c, 0x1d, 0x03, 0x3c, 0x7c, 0xa7, 0x52, 0xc1, 0x9c, 0x32,
0x21, 0x62, 0xd1, 0xfa, 0x51, 0xfc, 0xf9, 0x28, 0x14, 0xa0, 0x26, 0x05,
0x56, 0x89, 0xb8, 0xd8, 0x74, 0xc0, 0x27, 0xd6, 0x71, 0x66, 0xbf, 0xb9,
0x9b, 0xb8, 0x40, 0x3e, 0x34, 0x5a, 0x22, 0x24, 0xb0, 0xeb, 0x31, 0x7f,
0xe2, 0xb8, 0x29, 0x9e, 0x49, 0x5a, 0x74, 0x03, 0x73, 0x94, 0x8f, 0x72,
0x80, 0xdc, 0xfa, 0x9d, 0x3b, 0x4a, 0x36, 0xc4, 0x44, 0x36, 0x18, 0x84,
0x3f, 0x75, 0xf7, 0xfc, 0x9a, 0xe3, 0x45, 0x18, 0x83, 0x9c, 0x11, 0x7a,
0xd3, 0xa1, 0x1c, 0x7d, 0x21, 0x1a, 0x20, 0x36, 0x80, 0x05, 0x7d, 0x0d,
0x38, 0x72, 0x38, 0x7c, 0x0d, 0x67, 0xaf, 0x0f, 0x43, 0x6a, 0xc8, 0xa9,
0x9d, 0xe8, 0x1a, 0x29, 0xa2, 0xea, 0x4e, 0x8f, 0xac, 0x50, 0xe4, 0x88,
0x2a, 0x3e, 0xaa, 0x99, 0x28, 0x78, 0x55, 0x8d, 0xaa, 0xd1, 0xa3, 0x9a,
0x5f, 0x06, 0x38, 0x76, 0x06, 0x35, 0xf1, 0xb2, 0x71, 0x8e, 0xd1, 0x5a,
0x08, 0xa6, 0x8b, 0xdb, 0xd8, 0xeb, 0x24, 0xa6, 0xfc, 0x67, 0x76, 0x3b,
0x5c, 0xb5, 0x8d, 0xea, 0x28, 0x35, 0xaa, 0x66, 0x22, 0x8e, 0x23, 0x6a,
0x44, 0x5e, 0xf9, 0x8b, 0xb4, 0x6b, 0x4c, 0x45, 0xdd, 0x7d, 0x12, 0xda,
0x35, 0x5d, 0x58, 0x4a, 0xf6, 0x6e, 0x69, 0xf9, 0xf7, 0x87, 0xb6, 0x72,
0x5b, 0x64, 0x2f, 0xca, 0x7f, 0xbe, 0x8b, 0xd2, 0x82, 0x5a, 0xda, 0xb0,
0xff, 0xb0, 0x92, 0x67, 0x42, 0xb5, 0x0a, 0xdd, 0x93, 0x6a, 0x9e, 0x4c,
0xaa, 0xc1, 0x29, 0xd5, 0x06, 0x4e, 0x93, 0xd8, 0x72, 0xe3, 0xde, 0x32,
0x65, 0x84, 0x7c, 0x05, 0x8e, 0x88, 0x05, 0x25, 0x01, 0x7a, 0x1f, 0xba,
0xf9, 0xfb, 0xf1, 0xb1, 0x45, 0xd4, 0xc6, 0x6f, 0xf0, 0x14, 0x5b, 0xe8,
0xa1, 0x2d, 0x9c, 0xb9, 0xac, 0x8c, 0xcc, 0xae, 0x0d, 0x98, 0x8a, 0xd3,
0xf7, 0xa4, 0xf2, 0x2d, 0x07, 0xfa, 0xa3, 0x8f, 0xf4, 0x07, 0x00, 0x99,
0x8f, 0x3a, 0xe3, 0x1f, 0xe8, 0xfa, 0x37, 0x99, 0x6c, 0x94, 0xe1, 0x7e,
0x8c, 0xf9, 0xc6, 0x35, 0xe2, 0x50, 0x79, 0x3e, 0xcc, 0xa0, 0x3f, 0xc8,
0xac, 0xff, 0x2c, 0xe3, 0x8e, 0x65, 0xe2, 0x96, 0xa1, 0xfb, 0x9e, 0x63,
0x78, 0xc4, 0xf0, 0x79, 0xc5, 0x49, 0xd0, 0xdb, 0x67, 0x88, 0xff, 0x8c,
0x0b, 0x1c, 0x64, 0xe0, 0x39, 0x2d, 0x7c, 0xcc, 0x91, 0x72, 0xf3, 0xe6,
0x86, 0x49, 0x75, 0xdd, 0x01, 0xf2, 0x6a, 0xad, 0x55, 0x1b, 0xd4, 0xde,
0x71, 0x84, 0x3c, 0xa8, 0x38, 0x30, 0x99, 0xca, 0xc8, 0x8e, 0xca, 0xff,
0x4c, 0x97, 0x92, 0xcb, 0xf1, 0x60, 0x0c, 0x1a, 0xc9, 0x18, 0x81, 0xb5,
0x6f, 0x74, 0x38, 0x27, 0xd4, 0xe1, 0x44, 0xac, 0x1c, 0xce, 0xfb, 0x9d,
0x1f, 0xb0, 0x69, 0xc3, 0xba, 0x3b, 0xd4, 0xb9, 0xc4, 0xbe, 0x02, 0x14,
0x50, 0x89, 0x69, 0xba, 0xde, 0x06, 0xe3, 0x1b, 0x93, 0x1b, 0x2b, 0xbe,
0x61, 0x91, 0x6e, 0x88, 0x81, 0x4b, 0xcc, 0xa0, 0x51, 0xa3, 0xd7, 0x08,
0x70, 0x2c, 0xfe, 0x1d, 0x5c, 0xde, 0x38, 0x61, 0xc9, 0xb1, 0x54, 0x9a,
0xc6, 0x8a, 0xb6, 0x09, 0x79, 0x2e, 0xd1, 0x38, 0xdd, 0xe9, 0x11, 0x60,
0x42, 0x33, 0xac, 0x1e, 0xf1, 0xaa, 0x25, 0xae, 0xb7, 0xa3, 0x16, 0x42,
0x62, 0x90, 0xa3, 0x0d, 0x67, 0xae, 0xc9, 0xcb, 0xc2, 0xec, 0xdb, 0xa3,
0xd4, 0xe2, 0xd3, 0xe4, 0x45, 0x63, 0x69, 0xc0, 0x87, 0x42, 0xf8, 0x5a,
0xa9, 0x74, 0xe0, 0x06, 0xcd, 0xb4, 0x05, 0x70, 0x75, 0xb8, 0x83, 0x5d,
0xa7, 0xe3, 0xc4, 0x3f, 0xd0, 0x9d, 0x61, 0x48, 0x28, 0x92, 0x7b, 0x92,
0x12, 0x27, 0xca, 0xec, 0x87, 0xdc, 0x5b, 0xf8, 0xc0, 0x28, 0x93, 0x2c,
0x2e, 0xfc, 0x3c, 0x32, 0x23, 0xd0, 0xd0, 0xfd, 0x51, 0xd4, 0xca, 0xc2,
0x46, 0xa0, 0xeb, 0x8c, 0xf5, 0xf0, 0x77, 0xba, 0x0b, 0xfc, 0x8e, 0x7b,
0xe4, 0xe8, 0xc5, 0xde, 0xf5, 0x48, 0xbc, 0x0b, 0x87, 0xff, 0x15, 0x56,
0x13, 0xeb, 0xc1, 0x01, 0xe0, 0x95, 0x08, 0x91, 0xab, 0x10, 0x3d, 0xba,
0x4a, 0x9d, 0xaa, 0x6f, 0x59, 0x6d, 0x29, 0xf2, 0xab, 0x16, 0x3c, 0x54,
0x0a, 0xdc, 0xb1, 0x71, 0x7c, 0x86, 0x65, 0xf1, 0x04, 0xcd, 0xe7, 0x5d,
0x83, 0xd6, 0x42, 0x2f, 0x82, 0x7a, 0x73, 0x9f, 0x49, 0xb3, 0x14, 0x06,
0x12, 0xb9, 0x1d, 0x96, 0xb5, 0xae, 0x82, 0x04, 0xf1, 0x49, 0x23, 0x01,
0xfc, 0xe7, 0xcf, 0xfc, 0xcc, 0x47, 0x8e, 0x8f, 0xe4, 0x46, 0x0e, 0xc9,
0xc0, 0x0b, 0x34, 0x41, 0x8a, 0xed, 0x8b, 0xc8, 0x33, 0x18, 0xbc, 0x51,
0x1c, 0xe2, 0xaf, 0xb5, 0x1c, 0xba, 0x6f, 0x34, 0x43, 0xea, 0xd8, 0x56,
0x9b, 0x43, 0xc9, 0x14, 0xd2, 0x36, 0xa4, 0xa4, 0x17, 0x87, 0x0e, 0x91,
0x80, 0x20, 0xce, 0x88, 0x76, 0xfc, 0x31, 0x76, 0x71, 0x47, 0xee, 0x3a,
0x73, 0xcf, 0x03, 0xaa, 0xe0, 0x8d, 0x0f, 0x59, 0xfc, 0x60, 0xdf, 0x92,
0xf0, 0xc8, 0x93, 0xcb, 0xa9, 0x70, 0x61, 0xec, 0x5f, 0x7e, 0x51, 0xd6,
0x35, 0xb1, 0x45, 0x4b, 0x62, 0xbb, 0xb8, 0x34, 0x83, 0xef, 0xb2, 0x11,
0x97, 0xfb, 0xa7, 0xc4, 0x4a, 0x7f, 0xc1, 0x2d, 0x3c, 0x8c, 0x51, 0x96,
0x94, 0x51, 0xe2, 0x47, 0x5c, 0x00, 0xd7, 0xf0, 0x9e, 0x89, 0x34, 0x87,
0xd4, 0x7e, 0x5e, 0x92, 0xb1, 0x82, 0xaa, 0x0f, 0xb9, 0x95, 0x97, 0xcb,
0xc1, 0x08, 0x8c, 0x0a, 0x25, 0x3e, 0xc8, 0x7a, 0x36, 0xdf, 0x42, 0x8a,
0x71, 0x17, 0xe6, 0x4d, 0x37, 0x6a, 0xac, 0x7b, 0x32, 0xf1, 0x02, 0x36,
0x4a, 0x07, 0x94, 0x46, 0xdf, 0x46, 0x90, 0xd8, 0x68, 0xb7, 0xf4, 0x7c,
0x40, 0x00, 0x8f, 0xf5, 0x2d, 0xaa, 0x2c, 0x00, 0x12, 0x46, 0xf6, 0x61,
0x18, 0xd3, 0x90, 0xf4, 0x75, 0x43, 0x80, 0x84, 0x32, 0x53, 0x74, 0xa9,
0xd1, 0x23, 0xbd, 0x6f, 0xb1, 0xfa, 0x18, 0x76, 0x1f, 0xe8, 0x73, 0x8c,
0xbf, 0x3e, 0x9c, 0xa3, 0x4c, 0xb9, 0x62, 0xb8, 0x78, 0x51, 0x1c, 0x71,
0x86, 0x7e, 0x5f, 0xfa, 0xf9, 0x89, 0x1d, 0x59, 0x58, 0xdd, 0x81, 0x7b,
0xbb, 0x0f, 0xfc, 0x10, 0x8d, 0x61, 0x1d, 0xb7, 0x15, 0x01, 0x54, 0x0c,
0x5e, 0x31, 0x37, 0x83, 0x5f, 0xa6, 0x63, 0x76, 0x08, 0xbb, 0x7a, 0x63,
0x00, 0x53, 0x81, 0x09, 0x8a, 0x67, 0x05, 0x0c, 0x4b, 0xbe, 0x83, 0xc0,
0x5f, 0x12, 0x43, 0xe9, 0x93, 0x03, 0x2f, 0x22, 0x99, 0x97, 0xce, 0xe8,
0x4b, 0x7a, 0x56, 0x36, 0x68, 0x14, 0x3b, 0x97, 0x3a, 0xea, 0x2b, 0x63,
0x63, 0x00, 0xef, 0x50, 0x49, 0x10, 0x15, 0x6c, 0xc4, 0x00, 0xd0, 0x3e,
0x24, 0xbf, 0x13, 0x85, 0x50, 0xa6, 0x4f, 0xe1, 0x90, 0x84, 0x04, 0xff,
0x8c, 0x12, 0x8f, 0xdf, 0x3b, 0xda, 0x82, 0x79, 0xc9, 0xa2, 0x1b, 0x04,
0xee, 0xc3, 0x16, 0xc8, 0x05, 0x2c, 0xc1, 0x8d, 0x36, 0xb9, 0xad, 0x95,
0xb0, 0x76, 0x3d, 0xfc, 0x86, 0xa7, 0xcc, 0x66, 0x70, 0x95, 0x41, 0xcf,
0xc2, 0x92, 0xa4, 0x42, 0x7f, 0x27, 0xbc, 0x46, 0x84, 0x5d, 0xcd, 0x21,
0xb3, 0xa5, 0x73, 0x8f, 0xc8, 0x04, 0xd8, 0x4a, 0x7b, 0x00, 0x46, 0x30,
0xe3, 0x37, 0x11, 0xbc, 0x5e, 0xeb, 0x79, 0x21, 0xca, 0x00, 0x59, 0x31,
0x34, 0x29, 0xd3, 0xdf, 0x4a, 0xe3, 0xf7, 0x4c, 0xf1, 0xf0, 0x6c, 0x62,
0x41, 0xd1, 0x8b, 0x17, 0x11, 0x47, 0xa7, 0x87, 0xce, 0x3a, 0xcc, 0xbc,
0xb0, 0xe8, 0x4f, 0x2e, 0x78, 0xbd, 0x7c, 0xda, 0x56, 0x9d, 0x35, 0xa4,
0x60, 0xf7, 0x96, 0x25, 0x1e, 0xdf, 0x6f, 0x62, 0xbe, 0xd6, 0xb0, 0x59,
0x77, 0x64, 0xfc, 0x4a, 0x5a, 0xa2, 0x0a, 0xc7, 0xda, 0xde, 0xa1, 0x14,
0x08, 0x0f, 0x94, 0x57, 0x28, 0xe5, 0x36, 0xa8, 0x94, 0xdb, 0x37, 0x2a,
0x25, 0xc4, 0x80, 0xf0, 0xc3, 0x25, 0x30, 0xd4, 0xe6, 0x64, 0x48, 0x47,
0x6b, 0x50, 0x80, 0xd9, 0x23, 0x1d, 0xff, 0x37, 0xa8, 0x46, 0x43, 0xaf,
0x52, 0x4d, 0x7f, 0x2a, 0x8e, 0x8d, 0x10, 0x05, 0xd1, 0x8a, 0x3f, 0x57,
0x4d, 0x1a, 0xfa, 0x38, 0x35, 0x99, 0x9e, 0xd2, 0x0a, 0x54, 0xc3, 0x8f,
0xa9, 0xb8, 0x92, 0xd9, 0xa1, 0x2b, 0x3e, 0x2b, 0x98, 0xb6, 0xea, 0x8e,
0xde, 0x14, 0x1c, 0xc7, 0x0e, 0x53, 0x3f, 0xc2, 0xb5, 0x46, 0x4a, 0xfe,
0xe2, 0x5b, 0x55, 0x9b, 0x0d, 0x38, 0xeb, 0x6a, 0xdf, 0x84, 0xa6, 0xc8,
0x65, 0x38, 0xa8, 0xd5, 0xc2, 0x07, 0x7d, 0xbd, 0x77, 0x97, 0xf1, 0x3f,
0x1d, 0xa4, 0x79, 0x7e, 0xf1, 0xbf, 0xb3, 0x48, 0x33, 0x70, 0x39, 0x18,
0x13, 0x1c, 0x29, 0x06, 0x15, 0xf3, 0x64, 0x4b, 0x38, 0x3b, 0xd5, 0x10,
0xce, 0xf2, 0xa9, 0x12, 0x30, 0x9d, 0xc8, 0xfd, 0xf8, 0xdd, 0xd7, 0x3f,
0xa7, 0x60, 0x69, 0x7c, 0x02, 0x5f, 0xc9, 0x13, 0xf8, 0xf1, 0xf5, 0xcf,
0xdf, 0x24, 0x73, 0x13, 0x31, 0xed, 0xf4, 0xc4, 0x2c, 0x0d, 0x6f, 0x55,
0x4b, 0xd3, 0x17, 0x1e, 0x30, 0xcf, 0xa4, 0xb9, 0x1f, 0xa1, 0xe4, 0x67,
0xa0, 0x4d, 0x0a, 0x8f, 0xcc, 0x8e, 0x0e, 0x06, 0xe2, 0x9e, 0x5c, 0x80,
0x1d, 0x74, 0xa4, 0x09, 0x09, 0xf2, 0xc2, 0x01, 0xf3, 0x27, 0xd6, 0x99,
0xf9, 0x93, 0xce, 0x36, 0xc1, 0x2b, 0xd6, 0x9e, 0xbd, 0xcc, 0x04, 0x8b,
0x8b, 0x58, 0xcb, 0xe7, 0x39, 0xe0, 0x61, 0x2f, 0xb0, 0x62, 0xe7, 0xe6,
0x2f, 0x80, 0xc7, 0x68, 0x01, 0x2c, 0x53, 0x6f, 0xc7, 0x39, 0xba, 0x76,
0xf6, 0xbc, 0x21, 0x8b, 0x5e, 0x05, 0xc6, 0x5d, 0xa8, 0x1f, 0x42, 0x52,
0x4b, 0x90, 0xef, 0x74, 0x88, 0x49, 0x94, 0xb9, 0x30, 0x96, 0x20, 0x7f,
0x83, 0x47, 0x7d, 0x8e, 0xbb, 0xe3, 0x96, 0x90, 0x9e, 0x19, 0xe9, 0x39,
0x6c, 0x05, 0xdb, 0xd9, 0xed, 0xec, 0x01, 0xfe, 0x95, 0x85, 0xa5, 0xb9,
0xfb, 0xc5, 0xe8, 0xae, 0xc5, 0x39, 0xec, 0xb9, 0xe3, 0x64, 0x96, 0x71,
0xc2, 0xce, 0x8d, 0x71, 0x66, 0x9f, 0xfd, 0xd6, 0x69, 0x1a, 0xb3, 0x61,
0xbd, 0x7f, 0xfd, 0x18, 0x9f, 0xcc, 0x63, 0x14, 0x7a, 0xbb, 0x9a, 0x75,
0xf7, 0xff, 0x11, 0x6b, 0x32, 0x09, 0x47, 0xf5, 0x18, 0x11, 0x2a, 0x2d,
0x11, 0x31, 0x29, 0x28, 0xf3, 0xd5, 0x62, 0xa9, 0x43, 0x6b, 0xcc, 0x1e,
0x09, 0xad, 0xb3, 0x22, 0x4d, 0xfb, 0xfa, 0xb3, 0x75, 0xa1, 0x99, 0xbc,
0x28, 0xd8, 0x8b, 0x22, 0x92, 0x9b, 0xe1, 0x18, 0xcb, 0x7b, 0x57, 0xdc,
0x44, 0xdd, 0xf2, 0xa0, 0x6e, 0x01, 0x2a, 0x45, 0xa0, 0xe2, 0x62, 0x29,
0xe1, 0x45, 0xf4, 0x39, 0xfa, 0x42, 0xfa, 0x3f, 0x00, 0x33, 0xfc, 0x14,
0xf6, 0xa1, 0x5e, 0x00, 0x00
0x1f, 0x8b, 0x08, 0x08, 0x79, 0x1c, 0x96, 0x5d, 0x04, 0x00, 0x65, 0x64,
0x69, 0x74, 0x2e, 0x68, 0x74, 0x6d, 0x00, 0xed, 0x1d, 0x6b, 0x57, 0xea,
0x46, 0xf0, 0x7b, 0xcf, 0xe9, 0x7f, 0x48, 0xd3, 0x87, 0x50, 0x9e, 0xa2,
0xd7, 0x2a, 0x6a, 0x5b, 0x40, 0x40, 0x45, 0x8a, 0x08, 0x2a, 0xda, 0xd7,
0x09, 0xc9, 0x02, 0xd1, 0x90, 0xc4, 0x24, 0x08, 0x7a, 0x6b, 0x7f, 0x7b,
0x67, 0x1f, 0x79, 0x27, 0x10, 0xd4, 0x3e, 0x4f, 0xb9, 0xed, 0x25, 0xec,
0xce, 0xcc, 0xce, 0xcc, 0xce, 0xce, 0xce, 0xce, 0xee, 0xe6, 0x1e, 0x7c,
0x76, 0xd4, 0xa9, 0xf5, 0x6f, 0xce, 0xeb, 0xdc, 0xc4, 0x9a, 0x2a, 0xdf,
0x7e, 0xfa, 0xc9, 0x01, 0xfe, 0xe6, 0x14, 0x41, 0x1d, 0x1f, 0xf2, 0x48,
0xe5, 0xa1, 0x84, 0xe3, 0x0e, 0x26, 0x48, 0x90, 0xc8, 0x13, 0x3c, 0x5b,
0xb2, 0xa5, 0xa0, 0x6f, 0x7b, 0xe7, 0x27, 0x8d, 0x46, 0x8f, 0xab, 0x4b,
0xb2, 0xa5, 0x19, 0x07, 0x05, 0x52, 0x68, 0x43, 0x98, 0xd6, 0x93, 0x82,
0x38, 0xeb, 0x49, 0x47, 0x87, 0xbc, 0x85, 0x16, 0x56, 0x41, 0x34, 0x4d,
0x9e, 0x9b, 0x22, 0x49, 0x16, 0x0e, 0x79, 0x53, 0x34, 0x10, 0xa3, 0x4b,
0x3e, 0x79, 0x51, 0x53, 0x31, 0x50, 0x1b, 0xa9, 0x33, 0xee, 0x23, 0x94,
0xb2, 0xcf, 0x73, 0x4e, 0x56, 0x25, 0xb4, 0x28, 0x73, 0x5b, 0xc5, 0xe2,
0xbe, 0x5b, 0xac, 0x6b, 0xa6, 0x6c, 0xc9, 0x9a, 0x5a, 0xe6, 0x84, 0xa1,
0xa9, 0x29, 0x33, 0x0b, 0x79, 0x2a, 0x15, 0x34, 0xb2, 0xca, 0xdc, 0x07,
0x7d, 0xe1, 0x29, 0x1b, 0x6a, 0x86, 0x84, 0x8c, 0x32, 0xb7, 0xa9, 0x2f,
0x38, 0x40, 0x90, 0x25, 0xee, 0xf3, 0xed, 0xed, 0x6d, 0x2f, 0x80, 0x20,
0xde, 0x8f, 0x0d, 0x6d, 0xa6, 0x4a, 0x39, 0x51, 0x53, 0x34, 0x00, 0xfd,
0xbc, 0xf1, 0x01, 0xff, 0xf1, 0xc0, 0x48, 0xb2, 0xa9, 0x2b, 0xc2, 0x53,
0x99, 0x53, 0x35, 0x15, 0xf9, 0x88, 0x2f, 0x72, 0xe6, 0x44, 0x90, 0xb4,
0x79, 0x99, 0x2b, 0xc2, 0x9f, 0xcd, 0x22, 0xb4, 0x62, 0x8c, 0x87, 0x42,
0x8a, 0x2b, 0x66, 0xd9, 0x7f, 0xf9, 0x6d, 0x2e, 0xed, 0x41, 0x19, 0x81,
0xb8, 0x39, 0x53, 0x7e, 0x46, 0xc0, 0x52, 0xc9, 0xe6, 0xd4, 0xad, 0x19,
0x09, 0x53, 0x59, 0x81, 0x86, 0x4c, 0x41, 0x35, 0x73, 0x26, 0x32, 0xe4,
0x51, 0x10, 0x62, 0x8e, 0xe4, 0xf1, 0xc4, 0x2a, 0x0f, 0x35, 0x45, 0x72,
0xaa, 0x5e, 0x22, 0xb5, 0x39, 0x53, 0xbc, 0x0a, 0x55, 0x64, 0x13, 0x1a,
0xc6, 0x5d, 0x13, 0x12, 0xc3, 0xd2, 0x74, 0xe0, 0x3f, 0xa0, 0x48, 0x7f,
0xc9, 0x54, 0x30, 0xc6, 0xb2, 0xea, 0x2f, 0xd3, 0x05, 0x49, 0x92, 0xd5,
0x31, 0x14, 0x2e, 0x67, 0x04, 0x9a, 0xc6, 0x8c, 0x84, 0xbb, 0xd0, 0x40,
0x8a, 0x60, 0xc9, 0x8f, 0xc8, 0xdb, 0x8e, 0xac, 0xe6, 0xe6, 0xb2, 0x64,
0x4d, 0xca, 0xdc, 0x4e, 0xd1, 0xa7, 0x1e, 0x71, 0x66, 0x98, 0xd0, 0x3b,
0x80, 0x2e, 0x03, 0x65, 0x63, 0x45, 0x93, 0xa6, 0x2e, 0xa8, 0xde, 0x46,
0x69, 0xd7, 0xb2, 0xbe, 0x0f, 0xf7, 0xab, 0xac, 0x2a, 0xb2, 0x8a, 0x72,
0x43, 0x45, 0x13, 0xef, 0xa3, 0x24, 0xdc, 0xd1, 0x17, 0x2b, 0x65, 0x2c,
0x4f, 0xb4, 0x47, 0x64, 0x70, 0x1f, 0x3d, 0x16, 0xc5, 0x1a, 0x5c, 0x81,
0xc2, 0x98, 0x75, 0x78, 0xac, 0xd7, 0xeb, 0x0e, 0x8a, 0x8b, 0x68, 0x9a,
0x39, 0x0b, 0x86, 0xce, 0xa3, 0x8c, 0xe6, 0xd0, 0xb3, 0x59, 0x7f, 0x09,
0x51, 0x71, 0x88, 0xef, 0xd5, 0x5d, 0x18, 0x36, 0x0a, 0x57, 0xc8, 0xe8,
0xa6, 0x65, 0x55, 0x9f, 0x59, 0xdc, 0xc7, 0x84, 0x23, 0x52, 0xd3, 0x05,
0x51, 0xb6, 0x9e, 0xa0, 0xd1, 0xd5, 0x94, 0x3f, 0xfa, 0x0d, 0x1d, 0x33,
0x64, 0x4c, 0x05, 0x85, 0xdb, 0xc4, 0x43, 0xf7, 0x0a, 0x19, 0x92, 0xa0,
0x0a, 0x59, 0xae, 0x62, 0xc8, 0x02, 0x48, 0xdf, 0x8b, 0x1a, 0x1f, 0xb9,
0xa9, 0xf6, 0x9c, 0x9b, 0x41, 0x29, 0xd4, 0x28, 0x48, 0xb4, 0x42, 0x86,
0x0e, 0x83, 0x67, 0x78, 0x2f, 0x5b, 0x4b, 0x61, 0x3c, 0x75, 0x49, 0x75,
0x12, 0x67, 0x6c, 0xc5, 0xe2, 0x28, 0x99, 0x01, 0xc7, 0x93, 0xb5, 0x8d,
0xca, 0x25, 0x83, 0xcd, 0x27, 0x27, 0x21, 0x51, 0x33, 0x04, 0xaa, 0x76,
0xb0, 0x33, 0x64, 0x28, 0x72, 0x12, 0x46, 0x69, 0xe7, 0x65, 0xc0, 0xbd,
0x0f, 0x91, 0x02, 0xdf, 0xc4, 0x43, 0x84, 0x0d, 0x84, 0xfc, 0x29, 0x81,
0x77, 0x4a, 0x4a, 0xf1, 0x77, 0x42, 0x29, 0x34, 0xae, 0x92, 0xea, 0x8f,
0xb0, 0x93, 0x8d, 0x2a, 0x2c, 0x97, 0x87, 0x68, 0xa4, 0x19, 0x88, 0xfb,
0xf8, 0x06, 0x3d, 0x12, 0x1e, 0xcb, 0xc0, 0x93, 0x30, 0x54, 0x90, 0x64,
0x8b, 0x1f, 0x45, 0x52, 0x42, 0x23, 0x61, 0xa6, 0x58, 0x51, 0x06, 0x9c,
0xdf, 0x49, 0xda, 0x90, 0x38, 0x41, 0xe2, 0x3d, 0x92, 0xca, 0xaa, 0x66,
0xa5, 0x9c, 0x56, 0xd3, 0xf1, 0x3a, 0x22, 0x4e, 0x67, 0x35, 0xf1, 0xf5,
0x94, 0xe4, 0xf5, 0x41, 0x33, 0x43, 0x49, 0xf1, 0x92, 0x60, 0x09, 0x65,
0x79, 0x2a, 0x8c, 0x51, 0x41, 0x57, 0xc7, 0xfb, 0x43, 0xc1, 0x44, 0x3b,
0xdb, 0x59, 0xf9, 0xaa, 0xda, 0xb9, 0x98, 0x17, 0x5b, 0xcd, 0xb1, 0x56,
0x81, 0xcf, 0x0f, 0xbd, 0xcb, 0x49, 0xfd, 0x72, 0x0c, 0x4f, 0x55, 0xfc,
0xb3, 0x36, 0xae, 0x55, 0x6e, 0xf0, 0x43, 0xa3, 0x83, 0xe6, 0x97, 0xf8,
0xa1, 0x39, 0xb8, 0x68, 0x5c, 0x1f, 0x5f, 0xf4, 0x87, 0xa5, 0xdb, 0xa2,
0x54, 0x6a, 0x3c, 0xdd, 0x76, 0xab, 0xd5, 0xdb, 0xe6, 0x9e, 0x7c, 0xdb,
0xab, 0x9e, 0x0e, 0xaf, 0x1b, 0xea, 0xed, 0xd5, 0xa9, 0x72, 0x73, 0x7d,
0xf1, 0x41, 0x14, 0x15, 0xe5, 0x1c, 0x23, 0xe8, 0x8b, 0xd3, 0x8b, 0x7a,
0xe3, 0x12, 0xfd, 0x60, 0x98, 0x4a, 0x7b, 0x73, 0x56, 0x2c, 0x56, 0xba,
0xe3, 0x26, 0xb8, 0xf7, 0x27, 0x41, 0x69, 0x34, 0x3a, 0xad, 0x4c, 0x4d,
0x39, 0x39, 0x69, 0x75, 0x5b, 0x4f, 0x0f, 0x97, 0x57, 0xdd, 0xc7, 0x7e,
0xbd, 0xbe, 0x75, 0x34, 0xad, 0x4c, 0xce, 0xe6, 0x95, 0xc9, 0xe5, 0x6e,
0xf7, 0x56, 0x3b, 0xde, 0xae, 0x94, 0xba, 0xa5, 0x71, 0xbb, 0xd7, 0x10,
0x44, 0xb4, 0xdd, 0xae, 0x59, 0xa7, 0xbb, 0xbd, 0xf3, 0x6a, 0x63, 0x5e,
0xb9, 0xbf, 0x98, 0xc9, 0xc7, 0x2d, 0xbd, 0xb2, 0x63, 0x5e, 0xfc, 0x50,
0x38, 0x9b, 0x7d, 0xf3, 0xdc, 0xfc, 0x20, 0x6f, 0x6e, 0xdf, 0x8b, 0x96,
0x70, 0xf9, 0x70, 0xd1, 0x9c, 0x34, 0x07, 0xea, 0x6c, 0xaf, 0x53, 0x38,
0xb7, 0xbe, 0x69, 0x3f, 0x9b, 0x6d, 0xf9, 0x5e, 0x79, 0x6c, 0x64, 0xf6,
0xac, 0xd2, 0xfd, 0x75, 0xff, 0xe8, 0xf1, 0xe9, 0xc4, 0xa8, 0x98, 0x95,
0xa2, 0xd0, 0xba, 0xb8, 0x90, 0x37, 0xfb, 0xc5, 0x5a, 0x61, 0x72, 0xba,
0x7d, 0x76, 0x39, 0xb4, 0x3e, 0x14, 0x76, 0x8d, 0x1f, 0xf4, 0xeb, 0x2b,
0x45, 0xdf, 0xbd, 0xe8, 0x19, 0x7b, 0xa7, 0xdb, 0xc5, 0xe1, 0xf6, 0xee,
0x68, 0xd1, 0x10, 0xfa, 0xdd, 0xbd, 0xcc, 0xc8, 0xda, 0xad, 0xdf, 0xee,
0xb4, 0x4f, 0x6f, 0x86, 0xc5, 0xce, 0x7d, 0x46, 0x52, 0x6f, 0x9a, 0xfa,
0xf4, 0x7c, 0x3c, 0x98, 0xb7, 0x4e, 0x2a, 0x8f, 0x67, 0x8b, 0xdd, 0xc7,
0x9b, 0x81, 0xf8, 0xa1, 0x29, 0xb5, 0x2b, 0xdd, 0xd3, 0x71, 0xb7, 0x7e,
0xaf, 0xdf, 0x5d, 0xf4, 0x27, 0x5b, 0x3b, 0xfd, 0x5e, 0xe9, 0x32, 0x73,
0x74, 0x7d, 0x5d, 0x38, 0xda, 0xfc, 0xe6, 0x7a, 0x76, 0x33, 0x9e, 0xee,
0xea, 0xf3, 0xd3, 0xa7, 0x9b, 0x4d, 0x55, 0xbf, 0x35, 0x6f, 0x5b, 0x9d,
0xc5, 0xc9, 0xb4, 0x73, 0xb5, 0x79, 0x52, 0x98, 0x6c, 0x67, 0x3a, 0x3b,
0x8f, 0xf5, 0xf1, 0x87, 0x66, 0xed, 0xb6, 0xaa, 0x8f, 0xa7, 0x95, 0x9d,
0xc9, 0x60, 0x77, 0x7e, 0xdc, 0xba, 0x3c, 0x3e, 0xba, 0xa8, 0x0e, 0xba,
0x37, 0xb2, 0xd8, 0xdd, 0x36, 0x14, 0x71, 0xab, 0x3f, 0x2a, 0x5e, 0xb5,
0xcd, 0xdd, 0xa3, 0xe3, 0x6a, 0x6f, 0x77, 0x67, 0xbb, 0x51, 0xba, 0x69,
0x98, 0xfa, 0xdd, 0xf8, 0xf2, 0xe6, 0xae, 0x35, 0x28, 0x54, 0x9e, 0xb7,
0xc6, 0xa6, 0xd4, 0x95, 0x4a, 0x08, 0x55, 0x8f, 0xe7, 0x53, 0xa9, 0x79,
0x3d, 0x38, 0x16, 0xc7, 0xd5, 0x66, 0xef, 0xfe, 0x76, 0xd0, 0x19, 0x68,
0x13, 0xb1, 0x3e, 0x40, 0xc3, 0x0b, 0xad, 0x2b, 0x56, 0xc6, 0x77, 0x0f,
0x10, 0x88, 0xfd, 0x70, 0x93, 0xa9, 0x5c, 0x3d, 0xcd, 0xb6, 0x6e, 0xb7,
0xcc, 0x4a, 0xeb, 0x61, 0xd4, 0xd2, 0x9a, 0x6d, 0x13, 0xcd, 0xab, 0xa8,
0x7e, 0xd2, 0x39, 0x1f, 0x77, 0x17, 0x8b, 0xf3, 0xd3, 0x93, 0x3b, 0xb1,
0x79, 0xbc, 0xf3, 0x60, 0x9d, 0x15, 0x8a, 0x15, 0xa9, 0x72, 0xf4, 0xdc,
0x6a, 0xaa, 0xb3, 0xd9, 0x51, 0xa6, 0x64, 0x9d, 0xb5, 0xbe, 0xe9, 0xee,
0x1e, 0x4d, 0x8e, 0x8f, 0x87, 0x9d, 0xea, 0x75, 0xa6, 0x55, 0x7f, 0x16,
0x8f, 0xcf, 0x66, 0x37, 0xe2, 0x6e, 0xa9, 0x7d, 0x5f, 0xbf, 0x44, 0xf7,
0x67, 0xf2, 0x7c, 0xf6, 0x78, 0x75, 0x9c, 0x19, 0xcf, 0xba, 0xd5, 0xee,
0x73, 0xa7, 0xb9, 0x3d, 0x90, 0x2a, 0xc3, 0xdd, 0x7a, 0x47, 0xbc, 0x10,
0x1f, 0xba, 0x8f, 0x47, 0xf7, 0x37, 0x25, 0xb9, 0x76, 0x36, 0x5b, 0xd4,
0x6b, 0xa7, 0xdb, 0x5b, 0xa7, 0xda, 0xb0, 0x3d, 0xd0, 0x66, 0xd6, 0x43,
0x73, 0x7c, 0x24, 0x94, 0xfa, 0xdf, 0x5c, 0x3e, 0x9c, 0xb5, 0xe6, 0xd6,
0x5e, 0xeb, 0xe2, 0x69, 0xb6, 0x68, 0x5d, 0x55, 0x9f, 0x1e, 0xae, 0x06,
0x83, 0x87, 0x13, 0xad, 0x56, 0xbb, 0xac, 0x55, 0x1e, 0x26, 0x97, 0x1d,
0x59, 0xeb, 0x5f, 0xd7, 0xbe, 0x69, 0x6e, 0xf7, 0xbb, 0xf5, 0xce, 0x51,
0xb1, 0x72, 0xfe, 0x54, 0x2a, 0x7c, 0xd3, 0x2c, 0x0d, 0xf4, 0xd9, 0xe6,
0xe9, 0x76, 0x46, 0x59, 0xa0, 0xee, 0x76, 0x7f, 0x50, 0x1d, 0x9e, 0xf4,
0x8f, 0x74, 0xed, 0x0a, 0x29, 0x60, 0x19, 0xd5, 0xab, 0xc6, 0x70, 0x3e,
0xfb, 0xa0, 0xb5, 0xdb, 0xa7, 0x97, 0xd5, 0x89, 0x36, 0x78, 0xfa, 0x60,
0x4d, 0xa5, 0x0b, 0xb1, 0x3d, 0x7f, 0x9a, 0x9e, 0x97, 0x3a, 0x67, 0x5d,
0xe1, 0xec, 0x6e, 0xb1, 0x57, 0x78, 0x54, 0xab, 0xda, 0xce, 0xd5, 0x56,
0x6b, 0x47, 0x7e, 0xae, 0xf4, 0xa7, 0x3d, 0xb5, 0x2d, 0x14, 0x8f, 0x1e,
0xbe, 0x19, 0x21, 0xe3, 0x44, 0x9b, 0x9c, 0x4e, 0x8c, 0x4d, 0xbd, 0xb8,
0xf9, 0x6c, 0x28, 0xcf, 0xdb, 0x7b, 0xc6, 0x6d, 0x63, 0xbb, 0x03, 0x5d,
0x70, 0x7a, 0x3f, 0x28, 0x6d, 0x3d, 0x5e, 0x75, 0x9f, 0x6f, 0xf4, 0xcc,
0x7c, 0x78, 0xd3, 0xbc, 0x2a, 0xb4, 0xf4, 0x41, 0xeb, 0xee, 0x11, 0x06,
0xf4, 0xae, 0x65, 0x9e, 0xb4, 0x6a, 0x46, 0xfb, 0x87, 0xca, 0x4d, 0x63,
0x71, 0x57, 0x6a, 0xb6, 0x7a, 0x1f, 0x6e, 0xaf, 0x17, 0xe3, 0x6d, 0x34,
0x6f, 0x99, 0xa7, 0x23, 0xa1, 0xd9, 0x3e, 0xb9, 0xf9, 0xd0, 0x1a, 0x3c,
0x9c, 0x3f, 0xef, 0x9e, 0x55, 0xab, 0x77, 0x3b, 0x99, 0xa7, 0xa3, 0xc7,
0xab, 0xf3, 0x6f, 0xf6, 0xe0, 0x5b, 0x2f, 0xec, 0x35, 0xf6, 0xb4, 0x93,
0xc5, 0x56, 0x47, 0x36, 0x8f, 0xaf, 0xe7, 0xe8, 0x9b, 0x8e, 0xa0, 0x14,
0x8f, 0x17, 0x35, 0x18, 0x44, 0x5d, 0x18, 0x91, 0xf5, 0x93, 0x2e, 0x0c,
0xc8, 0xfa, 0x09, 0x0c, 0x4d, 0x52, 0x34, 0x81, 0xbf, 0x4e, 0x70, 0x05,
0x2d, 0xaa, 0xc3, 0xcf, 0x09, 0x85, 0x9d, 0x1f, 0xed, 0xd6, 0x0b, 0xd5,
0xdb, 0x71, 0xe5, 0xbc, 0xf8, 0x30, 0x69, 0xdd, 0x6d, 0x19, 0x83, 0xce,
0x37, 0x15, 0xfc, 0xa9, 0x2b, 0x8d, 0xfe, 0x7d, 0x6f, 0xd6, 0x9d, 0xd6,
0x6a, 0x7c, 0x1a, 0x5c, 0x73, 0xce, 0x40, 0x3a, 0x12, 0xac, 0x57, 0xba,
0x1e, 0x3c, 0x3b, 0x25, 0x76, 0x47, 0xab, 0x02, 0xad, 0x09, 0x0d, 0x6a,
0xb9, 0xcd, 0x1d, 0x5f, 0xcc, 0x47, 0x60, 0x63, 0xea, 0x60, 0x5a, 0xb4,
0x64, 0x51, 0x50, 0x72, 0x82, 0x22, 0x8f, 0x61, 0xd6, 0x9a, 0xca, 0x92,
0xa4, 0x24, 0x9d, 0x6c, 0xa2, 0x5d, 0x65, 0xce, 0x8d, 0x65, 0x36, 0x77,
0xf5, 0x45, 0x92, 0xa0, 0x25, 0x56, 0x62, 0x12, 0xe8, 0xe1, 0x28, 0x86,
0xe7, 0x3d, 0x4c, 0x93, 0xd0, 0x96, 0x89, 0x12, 0x9a, 0x78, 0xd9, 0xa4,
0x8b, 0x67, 0xdf, 0xe4, 0x72, 0x46, 0xf1, 0x4f, 0x48, 0xe5, 0xb6, 0x92,
0x4f, 0xe0, 0xf6, 0x9c, 0xc5, 0x65, 0x92, 0xcc, 0x28, 0xfe, 0x66, 0xa8,
0x2c, 0xe1, 0x66, 0x0a, 0x5f, 0x73, 0x34, 0xda, 0xe2, 0x04, 0xe9, 0x4e,
0x10, 0x41, 0x17, 0x1c, 0x04, 0x55, 0x53, 0xfc, 0x4d, 0xa3, 0x2b, 0xcd,
0xe0, 0x86, 0xb3, 0xf1, 0x48, 0x5e, 0x70, 0x5f, 0x17, 0x6c, 0xa4, 0xef,
0xc9, 0x2a, 0x91, 0xa3, 0x8b, 0x44, 0x4e, 0x50, 0x25, 0x2e, 0x65, 0xc7,
0x6c, 0x78, 0x65, 0x20, 0x01, 0xcf, 0x22, 0xca, 0xe9, 0xf2, 0x02, 0x29,
0x39, 0x12, 0xff, 0x94, 0x8b, 0x69, 0x86, 0xcb, 0x78, 0x0d, 0x8b, 0x48,
0xca, 0x83, 0x11, 0xa0, 0xa0, 0xc2, 0x5c, 0x48, 0x65, 0x60, 0x25, 0x36,
0x97, 0x39, 0xc6, 0x65, 0xce, 0xe6, 0x32, 0xc7, 0xb8, 0x94, 0xd5, 0x91,
0xac, 0xca, 0x16, 0xe2, 0x36, 0x4d, 0x5b, 0x5e, 0x57, 0x62, 0xc6, 0xbe,
0x4d, 0xfe, 0x1e, 0x3d, 0x8d, 0x0c, 0x61, 0x8a, 0xcc, 0xc4, 0xd4, 0x5d,
0x22, 0x3e, 0x7e, 0x47, 0x86, 0x36, 0x85, 0x22, 0x56, 0x1d, 0x13, 0xdf,
0x3b, 0xbc, 0xf8, 0xc0, 0x2c, 0x2d, 0x39, 0xa2, 0x4f, 0x9e, 0x90, 0x60,
0x9f, 0xcf, 0x74, 0x45, 0x13, 0x24, 0xb2, 0xb8, 0x49, 0x18, 0xf8, 0x87,
0x96, 0x94, 0x06, 0x1e, 0xc4, 0xab, 0x56, 0x99, 0x6c, 0xa8, 0x97, 0x76,
0xe3, 0xbd, 0x40, 0x69, 0xdb, 0xad, 0x73, 0x05, 0xca, 0x11, 0x5a, 0x64,
0xfd, 0x1d, 0x3d, 0x32, 0xa2, 0xd7, 0x7f, 0xb4, 0x14, 0x2f, 0xb8, 0xc2,
0xab, 0xbb, 0xcf, 0xb1, 0xfd, 0xac, 0x29, 0x70, 0x80, 0xf1, 0xa1, 0x66,
0x59, 0xda, 0x74, 0x99, 0xd0, 0xae, 0x4f, 0x28, 0x15, 0x29, 0xef, 0xa1,
0x9e, 0xc2, 0x24, 0xc3, 0xcc, 0x21, 0x92, 0x78, 0xc9, 0x72, 0x9f, 0xeb,
0x06, 0x31, 0xf2, 0xb7, 0x31, 0x6a, 0x77, 0x4e, 0x22, 0xde, 0x09, 0xa7,
0x61, 0x96, 0x5c, 0x4e, 0x96, 0x75, 0x00, 0xd1, 0x75, 0x58, 0xca, 0x0f,
0x61, 0x8a, 0x07, 0x05, 0xbc, 0x2e, 0x75, 0x93, 0x4a, 0xa2, 0x21, 0xeb,
0x96, 0x93, 0x36, 0x1a, 0xcd, 0x54, 0x11, 0x8b, 0xc8, 0x89, 0x06, 0x4c,
0x61, 0xa8, 0x21, 0x2b, 0xe8, 0x92, 0x19, 0x69, 0x8a, 0x0d, 0xb1, 0x2c,
0x87, 0x7b, 0x30, 0xcb, 0x51, 0x55, 0xa5, 0x3d, 0x6c, 0x3d, 0x0a, 0x06,
0xb7, 0x98, 0x2a, 0xc7, 0x96, 0xa5, 0xef, 0xfb, 0x4a, 0xd9, 0x72, 0xe6,
0x90, 0x93, 0x34, 0x71, 0x86, 0x69, 0xe4, 0x29, 0xf9, 0x3a, 0xa5, 0x98,
0xe2, 0x49, 0x3d, 0xef, 0xcd, 0xe7, 0x90, 0x92, 0x3c, 0x4e, 0x76, 0x01,
0x1a, 0x3f, 0x02, 0x3e, 0xf8, 0x50, 0xed, 0x14, 0xd6, 0x14, 0xb2, 0xae,
0x60, 0x88, 0x91, 0xa0, 0x98, 0x28, 0x04, 0xa0, 0x0a, 0x53, 0x5c, 0x49,
0x82, 0x74, 0x0f, 0xba, 0xcb, 0xc6, 0x18, 0x59, 0x8c, 0x87, 0xea, 0xd3,
0x89, 0x64, 0x4b, 0x98, 0xce, 0x0b, 0xba, 0x8e, 0x54, 0xa9, 0x36, 0x91,
0x15, 0x29, 0x45, 0x48, 0xa5, 0x03, 0x02, 0xe9, 0x82, 0x35, 0x59, 0x4b,
0x1e, 0x8c, 0x90, 0x97, 0x25, 0xcc, 0x0d, 0x1d, 0xf5, 0x39, 0x5c, 0xc2,
0x07, 0x20, 0x1c, 0x81, 0xf1, 0x6a, 0x34, 0x58, 0xe9, 0x88, 0x13, 0x89,
0xc9, 0xd6, 0x58, 0x57, 0x82, 0x32, 0x23, 0x40, 0x85, 0x57, 0x0b, 0x8c,
0xc9, 0x05, 0xe5, 0x1d, 0xce, 0xc0, 0x6c, 0xd5, 0x25, 0x12, 0x53, 0x00,
0x9f, 0xc8, 0xb4, 0x28, 0x2f, 0xab, 0x2a, 0x32, 0x8e, 0xfb, 0xed, 0x33,
0xc0, 0xde, 0xa0, 0xc6, 0xb4, 0xf1, 0x5a, 0xd6, 0x28, 0xc9, 0x20, 0x73,
0xd3, 0x7b, 0x49, 0x36, 0xd6, 0xe3, 0x8d, 0xa0, 0xf8, 0x59, 0x6b, 0xdf,
0x1f, 0xc9, 0xc6, 0xab, 0x39, 0x23, 0x04, 0xc3, 0x8c, 0x61, 0xc3, 0x5d,
0x97, 0x33, 0x8c, 0x13, 0x64, 0x0d, 0x0f, 0xc4, 0x37, 0xf0, 0x86, 0x49,
0x86, 0x4d, 0xd8, 0x10, 0xe2, 0x59, 0xa3, 0x16, 0xe8, 0xc1, 0x21, 0xf0,
0x3e, 0xb6, 0x78, 0x8e, 0x3b, 0x37, 0x90, 0x69, 0x72, 0x35, 0xcb, 0x50,
0x72, 0x3d, 0x0e, 0x22, 0x1b, 0xc8, 0xaf, 0x3e, 0xa2, 0x2c, 0x2d, 0xb8,
0x25, 0x05, 0xe0, 0xa3, 0x34, 0x56, 0xd0, 0x9b, 0xc8, 0x23, 0x8b, 0x15,
0x1b, 0x48, 0xd2, 0xde, 0x60, 0xa0, 0x86, 0x40, 0x39, 0x0b, 0x38, 0xad,
0x09, 0x78, 0x9e, 0x73, 0xcd, 0xb4, 0xce, 0x0d, 0x4d, 0x04, 0xc6, 0x2e,
0xd0, 0xc3, 0x0c, 0x99, 0x56, 0x2a, 0xed, 0x9b, 0xfa, 0xe5, 0x11, 0x97,
0x62, 0x5e, 0x2a, 0x0f, 0x22, 0x4b, 0x4f, 0x3d, 0x0b, 0xe4, 0xe6, 0x0e,
0x0f, 0xb9, 0x6d, 0x1b, 0xd0, 0x05, 0x75, 0x20, 0x4d, 0x00, 0x9a, 0x99,
0xdc, 0x67, 0x87, 0xd8, 0x4f, 0xa7, 0x39, 0x41, 0x41, 0x06, 0x28, 0xa9,
0x7e, 0x71, 0xd1, 0xb9, 0xf8, 0x91, 0xcf, 0xf8, 0xa1, 0x32, 0xfc, 0xcf,
0x65, 0xce, 0x2d, 0x04, 0x1d, 0xe9, 0x9a, 0x6a, 0xa2, 0x3e, 0x68, 0x94,
0xb2, 0xed, 0x7e, 0x90, 0x62, 0xda, 0xd1, 0xa0, 0xfb, 0x21, 0x0e, 0x16,
0xd0, 0x46, 0x80, 0x39, 0x39, 0x87, 0xd1, 0x98, 0x22, 0x23, 0xfc, 0x11,
0x0f, 0xed, 0x20, 0x81, 0x97, 0x15, 0xf1, 0x46, 0xd8, 0xa7, 0x53, 0x82,
0x7e, 0x51, 0x19, 0xab, 0xd0, 0xa9, 0x2a, 0xcc, 0x34, 0x83, 0xf6, 0x19,
0xfe, 0x65, 0xab, 0xcf, 0xdf, 0xa4, 0x2d, 0x95, 0xa6, 0x12, 0xe5, 0x61,
0x89, 0x91, 0x38, 0x81, 0x7d, 0x0d, 0x50, 0x61, 0x4c, 0x07, 0x50, 0x7c,
0xd7, 0xf4, 0xb0, 0x05, 0x4c, 0x8f, 0xc0, 0x27, 0xb3, 0xf6, 0x1a, 0xec,
0xa7, 0xbf, 0x25, 0x07, 0x8a, 0xf5, 0x7d, 0x8a, 0xfa, 0xbd, 0x2c, 0xa7,
0xc7, 0x30, 0x04, 0x40, 0x29, 0xfe, 0xfc, 0xb2, 0x0f, 0x20, 0x7c, 0x01,
0xcf, 0x4e, 0x7c, 0x34, 0xa0, 0x89, 0x89, 0xd9, 0xc4, 0x09, 0x48, 0x58,
0x67, 0xc1, 0xf1, 0x08, 0xe2, 0x8a, 0x8a, 0x2c, 0xde, 0x73, 0x87, 0x8e,
0x3a, 0x53, 0x28, 0x68, 0x57, 0x9e, 0x6e, 0xca, 0x93, 0x5d, 0x96, 0xce,
0x28, 0xc5, 0xe7, 0xf9, 0x34, 0xd8, 0xd6, 0x21, 0x04, 0xf4, 0x69, 0xb0,
0x7a, 0x6b, 0x66, 0xa8, 0x5e, 0xa6, 0x58, 0x9f, 0x2c, 0xeb, 0x64, 0x36,
0xd1, 0xe6, 0xb1, 0xe3, 0xbc, 0x34, 0x94, 0x18, 0xb0, 0x97, 0xa0, 0x73,
0x5b, 0x9b, 0x63, 0x05, 0xa9, 0x63, 0x98, 0xd4, 0x0e, 0xb8, 0x92, 0xcd,
0x68, 0xa8, 0xdf, 0xa8, 0x9b, 0x75, 0x71, 0x02, 0xc4, 0xa0, 0xda, 0x2f,
0xf7, 0x67, 0x44, 0x6e, 0xda, 0x68, 0x08, 0x52, 0x11, 0x4c, 0xeb, 0xc4,
0x86, 0x2e, 0x30, 0x2d, 0x15, 0x23, 0xdb, 0xe6, 0x58, 0xcb, 0x18, 0xcd,
0x9c, 0x0d, 0x4d, 0xcb, 0x80, 0xe0, 0x26, 0x05, 0x9b, 0x40, 0x51, 0x74,
0xfc, 0xca, 0x7b, 0x89, 0x51, 0x76, 0xc0, 0x5b, 0xbf, 0x84, 0xe6, 0xad,
0x64, 0xfa, 0xa3, 0x71, 0x06, 0xb6, 0x10, 0x93, 0x29, 0x90, 0x8a, 0x11,
0x90, 0x39, 0x4a, 0xa8, 0x97, 0x7f, 0xdf, 0x00, 0x24, 0x71, 0x54, 0x96,
0xf3, 0x08, 0xfd, 0x63, 0xf1, 0xe7, 0xac, 0xc7, 0x20, 0x96, 0x8e, 0xcc,
0x4e, 0xef, 0x5d, 0x86, 0x26, 0x69, 0x1d, 0xa4, 0xa7, 0x32, 0xbf, 0xb2,
0x7b, 0xe2, 0x2c, 0x1c, 0x83, 0xd2, 0x30, 0x2b, 0x20, 0x25, 0x09, 0xbe,
0x42, 0xe0, 0xe0, 0xd1, 0x01, 0xb2, 0x90, 0xfa, 0xae, 0xfc, 0x53, 0x3e,
0xf5, 0xe3, 0x2f, 0xf9, 0x9f, 0x33, 0xe9, 0xf4, 0x77, 0x5f, 0x14, 0xf2,
0x68, 0x81, 0xc4, 0x94, 0x4d, 0x2b, 0xfd, 0xe3, 0xe6, 0xcf, 0x21, 0x4c,
0x5c, 0x41, 0x50, 0xf3, 0x5f, 0xa7, 0x7f, 0xca, 0x13, 0xd4, 0x95, 0x78,
0x20, 0x10, 0x8e, 0x0f, 0xb5, 0x11, 0xc1, 0xc6, 0xa3, 0x8b, 0x6c, 0x52,
0x8c, 0x60, 0x1d, 0x27, 0x45, 0x0c, 0x32, 0x0c, 0x64, 0x4b, 0xfd, 0x2d,
0xb7, 0x9b, 0x66, 0x6d, 0x92, 0x2f, 0xff, 0x30, 0xda, 0x0d, 0xcc, 0x2a,
0x5e, 0x35, 0x84, 0xe4, 0x7e, 0x89, 0x64, 0x09, 0xab, 0x62, 0x25, 0x47,
0x00, 0x43, 0xf4, 0xcf, 0xe3, 0xcd, 0x70, 0x3e, 0x4d, 0x70, 0xe8, 0x2f,
0x3e, 0x62, 0x5e, 0xf4, 0x61, 0xdc, 0xe9, 0x68, 0xcc, 0x30, 0xc8, 0xaf,
0x31, 0x1f, 0xcb, 0xb2, 0xfb, 0x98, 0xe1, 0xc0, 0x0d, 0xc1, 0xdf, 0x80,
0xb5, 0x54, 0x04, 0xd7, 0x80, 0x69, 0x63, 0x05, 0x9e, 0xfb, 0xed, 0x37,
0x8f, 0x59, 0xc7, 0xf8, 0xaa, 0xa0, 0x84, 0x1e, 0x32, 0x84, 0x48, 0xc6,
0x66, 0xc4, 0xdf, 0x38, 0x15, 0x6e, 0x09, 0xae, 0xfb, 0xc3, 0xdf, 0x4f,
0xcb, 0x38, 0xca, 0x6c, 0xa6, 0x9d, 0xe6, 0xd6, 0xc9, 0x41, 0x04, 0x82,
0x83, 0x3e, 0x44, 0x1e, 0x76, 0xd0, 0x15, 0xb7, 0xc4, 0xb3, 0x17, 0xa4,
0x87, 0xb1, 0x51, 0x1b, 0xcf, 0x40, 0xf8, 0x40, 0xcc, 0x49, 0x02, 0x9b,
0x0b, 0x4d, 0x5b, 0xb6, 0x14, 0x94, 0xe4, 0x47, 0x2f, 0x9a, 0x8d, 0x02,
0x70, 0x20, 0xb2, 0xf9, 0x03, 0x5b, 0x02, 0x79, 0x13, 0x51, 0xaf, 0x8e,
0x23, 0x6d, 0xd2, 0xb4, 0xb9, 0x88, 0x80, 0x09, 0x4f, 0xb9, 0x47, 0xda,
0x5c, 0xc5, 0xdf, 0xc4, 0x48, 0xa8, 0x2a, 0x56, 0x35, 0xb6, 0x21, 0x31,
0x9c, 0x1c, 0x49, 0x56, 0x6d, 0xa4, 0xf3, 0xa6, 0x21, 0xb2, 0x6e, 0xcd,
0xf0, 0xdf, 0xd9, 0xb5, 0x87, 0x96, 0x31, 0xf3, 0xad, 0x6a, 0x5f, 0x96,
0xb0, 0x71, 0x4e, 0x35, 0xba, 0x06, 0x17, 0x3c, 0xed, 0x3d, 0x1e, 0x5a,
0xc7, 0x0b, 0xfe, 0x3c, 0xcb, 0x15, 0x63, 0xed, 0xe1, 0xed, 0x43, 0xdf,
0xf8, 0xb1, 0xfb, 0x34, 0x0c, 0x4a, 0x32, 0xca, 0x91, 0xb0, 0xfe, 0x25,
0xca, 0x81, 0x3c, 0x1d, 0x73, 0x20, 0xe6, 0x21, 0xbf, 0x91, 0x21, 0x72,
0x6e, 0xf0, 0x1c, 0x21, 0x76, 0xc8, 0x4f, 0x85, 0x05, 0x3b, 0x7b, 0xb0,
0x59, 0x2c, 0x7e, 0xb9, 0xcf, 0xc1, 0x6f, 0x96, 0x76, 0xa2, 0x05, 0x76,
0x9e, 0x56, 0x98, 0x59, 0xda, 0xbe, 0x93, 0xd2, 0xa6, 0xa9, 0x6c, 0x9e,
0x2b, 0x7c, 0xbb, 0x91, 0x40, 0x45, 0x60, 0xfa, 0x4a, 0x43, 0x53, 0x20,
0x4d, 0x81, 0x8f, 0x00, 0xa4, 0x70, 0x5a, 0xdd, 0xd5, 0x94, 0xc7, 0x02,
0xf1, 0xce, 0xfc, 0x32, 0xeb, 0x9b, 0x29, 0x81, 0x99, 0x09, 0x29, 0x3e,
0x93, 0xc1, 0xe8, 0xe9, 0x90, 0x33, 0x17, 0x08, 0x13, 0x4b, 0xc8, 0x2a,
0x72, 0x80, 0x2c, 0xa6, 0xe3, 0x23, 0x4c, 0x49, 0x84, 0x49, 0xcb, 0x66,
0x8d, 0xe6, 0x90, 0x97, 0x0c, 0x37, 0x22, 0x69, 0x9e, 0xe5, 0x9a, 0x23,
0xe6, 0x28, 0x5d, 0x95, 0xde, 0xc4, 0x1b, 0xa1, 0x90, 0x0e, 0x4e, 0x45,
0x8c, 0xb3, 0xb0, 0xa3, 0x27, 0xe0, 0xfe, 0x95, 0xe2, 0x01, 0xde, 0xd5,
0xf8, 0xb6, 0xa6, 0x29, 0x8a, 0xa0, 0x9b, 0xe8, 0xa0, 0x40, 0x7e, 0xf2,
0xfb, 0x11, 0x78, 0x09, 0xc2, 0x2e, 0xf8, 0x24, 0x53, 0x45, 0x38, 0x2f,
0xe4, 0x72, 0xef, 0x10, 0x18, 0x6a, 0xd2, 0x93, 0x87, 0x8a, 0x59, 0x7d,
0xaa, 0xd9, 0x8e, 0x26, 0xb5, 0xe1, 0x39, 0x56, 0xb2, 0x91, 0x76, 0xe6,
0x52, 0x1c, 0x3f, 0xf8, 0xf1, 0x0d, 0x34, 0x85, 0xf3, 0x04, 0x4c, 0x5b,
0x4a, 0x68, 0x8d, 0xe6, 0xfc, 0x76, 0x7b, 0x05, 0xaf, 0xee, 0xcc, 0xc9,
0x3a, 0xdd, 0x12, 0xd1, 0x31, 0x94, 0x48, 0x10, 0x8c, 0x96, 0x46, 0x75,
0xc0, 0x05, 0x5d, 0x52, 0xda, 0xfa, 0x8f, 0xc4, 0x4b, 0xd8, 0x01, 0x64,
0x2c, 0x21, 0x61, 0xb4, 0xd2, 0x2c, 0x61, 0xb1, 0x0e, 0x05, 0x3f, 0x68,
0x52, 0x64, 0x37, 0x60, 0x12, 0x79, 0x11, 0x0b, 0x03, 0x10, 0xde, 0x20,
0x8d, 0xdb, 0x4a, 0x13, 0xfa, 0x5e, 0xd5, 0x06, 0xa1, 0x7f, 0x2c, 0xfd,
0x9c, 0x0e, 0x12, 0x25, 0x11, 0x70, 0x13, 0x59, 0x04, 0x96, 0x39, 0x81,
0x7f, 0x56, 0xff, 0xb3, 0xf9, 0x3f, 0xe9, 0xa0, 0xa9, 0x2f, 0xe0, 0x6f,
0xe9, 0x2f, 0x1c, 0x32, 0x78, 0x56, 0xda, 0xff, 0xbf, 0xbb, 0xdf, 0xad,
0xbb, 0x83, 0xfe, 0x98, 0xa4, 0x7f, 0xdf, 0xe6, 0x90, 0x29, 0x09, 0x3f,
0x10, 0x29, 0x8b, 0xb4, 0x20, 0x92, 0x73, 0x75, 0x2c, 0x28, 0x8c, 0x94,
0xcc, 0x80, 0xec, 0xac, 0x77, 0x5d, 0x59, 0x62, 0x03, 0xde, 0xdc, 0xb6,
0x2b, 0x84, 0xdb, 0x0d, 0x94, 0x40, 0xb4, 0x37, 0x81, 0x48, 0xf7, 0x9c,
0x66, 0xd5, 0x29, 0x14, 0x0d, 0x74, 0xa3, 0x3a, 0x93, 0x41, 0x86, 0xa3,
0xf2, 0x03, 0x6e, 0x33, 0xed, 0xc3, 0xb6, 0x83, 0x2e, 0x86, 0x11, 0x24,
0x46, 0x46, 0x62, 0x14, 0x82, 0x1b, 0x76, 0xc7, 0x36, 0x96, 0x0e, 0x12,
0x75, 0xfb, 0xfb, 0x6f, 0xb3, 0xbd, 0x97, 0x70, 0xc6, 0x06, 0x29, 0x38,
0x75, 0xfc, 0x26, 0x6b, 0x63, 0x34, 0xfc, 0x50, 0xac, 0x30, 0xca, 0xde,
0x8e, 0x20, 0xd8, 0xb6, 0x9c, 0x49, 0x3e, 0x84, 0x95, 0x2c, 0x9b, 0x46,
0x47, 0x36, 0x25, 0xc5, 0x76, 0x24, 0xfe, 0x21, 0x8a, 0x5d, 0x12, 0x82,
0x12, 0xe1, 0xfe, 0x43, 0x01, 0x28, 0x89, 0xf2, 0x70, 0xda, 0x1a, 0xe4,
0x62, 0xbd, 0x10, 0xec, 0x25, 0x8a, 0x16, 0x39, 0x71, 0xc1, 0xf2, 0xc3,
0x31, 0x82, 0x30, 0x52, 0xa2, 0x0c, 0x5b, 0x44, 0xfa, 0xf3, 0x9f, 0xe8,
0xe2, 0x89, 0x1f, 0xa1, 0xda, 0x3a, 0xc1, 0x47, 0x01, 0x5f, 0xa3, 0x2e,
0xb6, 0xc0, 0x7b, 0x0f, 0x8d, 0x79, 0xd6, 0x8b, 0xff, 0x48, 0x75, 0x05,
0xad, 0x17, 0x2f, 0x88, 0xdf, 0x3c, 0x27, 0xda, 0x44, 0xfc, 0x60, 0x76,
0x69, 0xa4, 0x9f, 0x62, 0x75, 0xb6, 0xca, 0x43, 0x88, 0x89, 0xe7, 0x46,
0x6f, 0x9e, 0xe0, 0x9f, 0xe5, 0xac, 0xfe, 0x9f, 0x05, 0xfe, 0x24, 0xc5,
0xc6, 0xcd, 0x02, 0xe6, 0x44, 0x9b, 0xd7, 0xdc, 0xb6, 0x52, 0x88, 0xce,
0x03, 0x59, 0x58, 0xc8, 0x93, 0x4d, 0xd8, 0x8f, 0xe1, 0x3d, 0x95, 0x47,
0x0a, 0xbf, 0x4e, 0x52, 0x8c, 0xa0, 0xe2, 0xe3, 0x5c, 0xb0, 0xa2, 0xee,
0x6b, 0xb0, 0x6d, 0x10, 0x90, 0xc2, 0xad, 0xf9, 0x2e, 0xb6, 0xa6, 0xec,
0xd6, 0xd8, 0x0f, 0xac, 0x3d, 0x17, 0x28, 0xa6, 0xc9, 0x33, 0x38, 0xb0,
0x12, 0x6e, 0xd3, 0xad, 0xfa, 0x2e, 0xb6, 0x6a, 0x75, 0xab, 0x18, 0x2a,
0xd4, 0xac, 0x42, 0x1b, 0x44, 0x79, 0x30, 0x18, 0x00, 0x1d, 0x40, 0x4e,
0x37, 0x1e, 0x1a, 0x1f, 0xc5, 0xf1, 0x00, 0xdf, 0x50, 0xe0, 0xb0, 0x40,
0xae, 0xea, 0xfd, 0xc9, 0x45, 0x9f, 0xad, 0xc4, 0x20, 0x84, 0x12, 0x65,
0x1b, 0x24, 0x5f, 0xb5, 0x02, 0x9c, 0x89, 0x81, 0xbf, 0x80, 0xa9, 0x0d,
0x7d, 0xb1, 0x02, 0x9e, 0x0a, 0x02, 0x7f, 0xbb, 0xd0, 0x3e, 0xd3, 0x67,
0x36, 0xe5, 0x0f, 0x3d, 0x5c, 0x2a, 0xee, 0x7a, 0x28, 0x10, 0xf1, 0xba,
0xd9, 0xb2, 0x04, 0x18, 0xbe, 0xae, 0xf4, 0xb9, 0x04, 0x17, 0x2f, 0x6c,
0x9b, 0x24, 0xe1, 0xc7, 0x1d, 0x7a, 0x65, 0xd2, 0x46, 0x23, 0x13, 0x59,
0xd7, 0xb8, 0x22, 0x04, 0x4e, 0xf3, 0x81, 0x51, 0xf0, 0xc7, 0xa4, 0x26,
0x4e, 0x4f, 0x9a, 0x3a, 0xd5, 0xe0, 0x66, 0x09, 0x1c, 0x76, 0x8e, 0xf6,
0x22, 0xae, 0xae, 0x5c, 0xdb, 0x39, 0x20, 0x1d, 0x80, 0x33, 0xfc, 0x6e,
0xd9, 0xb7, 0x5c, 0x8a, 0xf6, 0x0a, 0x65, 0x3c, 0xed, 0xad, 0xbd, 0x01,
0x0c, 0xe8, 0x03, 0x5f, 0x11, 0x46, 0x20, 0xfd, 0xc2, 0x38, 0x87, 0x89,
0xfe, 0x2f, 0x9d, 0x63, 0x83, 0xaa, 0x77, 0x3f, 0x2f, 0xeb, 0x7a, 0x2c,
0x37, 0xf1, 0x7f, 0x86, 0x04, 0xba, 0x44, 0xcb, 0x92, 0x5d, 0x9f, 0x2c,
0x87, 0xef, 0xd3, 0x45, 0x44, 0xb0, 0x00, 0xb6, 0xd6, 0x54, 0x02, 0xf0,
0xf4, 0xe8, 0x53, 0x2a, 0x45, 0xc8, 0x73, 0x74, 0x8f, 0x25, 0xfd, 0x1d,
0xcf, 0x97, 0x89, 0xbd, 0x65, 0xe0, 0x57, 0x86, 0x6c, 0x79, 0x81, 0xc9,
0x9f, 0x69, 0x73, 0x64, 0xd4, 0xe0, 0x1e, 0x45, 0x2a, 0x64, 0x55, 0xf4,
0x14, 0xed, 0x92, 0xb6, 0xf1, 0x64, 0xe3, 0x6f, 0x9d, 0xa2, 0xe4, 0xb1,
0xa6, 0x6a, 0xf4, 0xe8, 0x30, 0xdb, 0xd3, 0xf2, 0xb5, 0x14, 0x66, 0xd8,
0x67, 0xe8, 0x84, 0x46, 0x18, 0x26, 0xd1, 0x04, 0xe6, 0x8f, 0xa1, 0x99,
0x2e, 0xd2, 0x2b, 0xc3, 0x5c, 0x06, 0x48, 0x1b, 0x5d, 0x11, 0x6a, 0x3a,
0xc0, 0x4b, 0x43, 0x41, 0x1b, 0x2a, 0xb1, 0xc1, 0x38, 0x42, 0x32, 0x03,
0x05, 0x15, 0xcf, 0x96, 0x8a, 0x8a, 0xf2, 0x78, 0x6b, 0x00, 0x54, 0x7c,
0x44, 0xcf, 0xa2, 0x39, 0x6a, 0x75, 0x01, 0x4c, 0x18, 0x34, 0xb0, 0x37,
0xad, 0x0b, 0x63, 0x72, 0x4a, 0x38, 0x08, 0x11, 0x35, 0x7d, 0x32, 0xb6,
0xb3, 0x24, 0x31, 0x15, 0x9e, 0x90, 0x83, 0x7b, 0xec, 0x04, 0x7e, 0x2d,
0xb3, 0xaf, 0x1a, 0x02, 0x6c, 0x26, 0xfb, 0x0c, 0xdf, 0xbe, 0x5e, 0xf4,
0x76, 0xe3, 0xc7, 0x38, 0x24, 0xb7, 0xb6, 0xd6, 0x69, 0x41, 0x8e, 0xe2,
0x38, 0xc7, 0x01, 0xc9, 0x2f, 0xb8, 0x15, 0xcb, 0x87, 0x61, 0xde, 0x61,
0x64, 0xb9, 0x9b, 0xb8, 0xce, 0x65, 0xae, 0xcf, 0x30, 0x21, 0x67, 0x2b,
0x97, 0xe7, 0xbe, 0xfa, 0xca, 0xd5, 0x09, 0x6b, 0xd7, 0xfe, 0x8d, 0xf9,
0xb3, 0x9f, 0xf9, 0xe5, 0xe3, 0x88, 0x20, 0xae, 0x3f, 0xaa, 0x49, 0x7d,
0xe4, 0xb0, 0xc6, 0x47, 0xc9, 0x0e, 0x1d, 0x3d, 0xfc, 0x15, 0xe3, 0x9e,
0xb4, 0x95, 0xe4, 0xf4, 0x01, 0x51, 0x2b, 0x85, 0x16, 0xed, 0x7d, 0x92,
0xbf, 0x21, 0x23, 0x4a, 0xda, 0x5e, 0x73, 0xd4, 0x63, 0xa9, 0x93, 0xfa,
0xb6, 0xcf, 0x56, 0x88, 0xe8, 0x54, 0xbb, 0xd9, 0xe5, 0xbf, 0x25, 0x33,
0x4c, 0x38, 0x88, 0x77, 0xa8, 0x2b, 0xf9, 0x26, 0x1b, 0x49, 0x6b, 0xe8,
0xf0, 0x9f, 0xe0, 0x39, 0x6d, 0x99, 0xb3, 0x84, 0xfb, 0xa0, 0xef, 0x7c,
0xbd, 0xeb, 0x84, 0xc3, 0xe5, 0x67, 0xb0, 0x3c, 0x4c, 0xd1, 0x5c, 0xbf,
0xb3, 0xc0, 0xb1, 0xd0, 0xd4, 0x7c, 0x7b, 0xbe, 0x8b, 0x12, 0x4d, 0x90,
0xf3, 0x52, 0xc0, 0x65, 0x90, 0x46, 0x6d, 0x63, 0x09, 0x9e, 0x5d, 0x4a,
0x91, 0xfd, 0x53, 0x00, 0x2a, 0xee, 0xc3, 0xd7, 0x01, 0x20, 0xc0, 0x77,
0x26, 0x13, 0x91, 0xd8, 0x26, 0x64, 0x6c, 0x6a, 0x3f, 0xca, 0x3f, 0xef,
0x47, 0x43, 0xd4, 0x95, 0xf0, 0xea, 0x13, 0x97, 0x33, 0x37, 0x7d, 0x68,
0x1f, 0x54, 0x0f, 0x8d, 0x02, 0x86, 0x0d, 0x2d, 0x44, 0x06, 0x5b, 0x84,
0x06, 0xf6, 0x4d, 0xec, 0x11, 0x87, 0x5d, 0x49, 0xed, 0xd4, 0xa6, 0x1c,
0x9a, 0xcf, 0x02, 0xb4, 0xc3, 0x04, 0x57, 0xec, 0x2d, 0x52, 0xc2, 0x91,
0x36, 0xb3, 0xda, 0x42, 0x82, 0x59, 0xc3, 0x8f, 0x6b, 0x1d, 0x9c, 0xc2,
0x28, 0xe4, 0xf0, 0xd3, 0x2b, 0x4f, 0x1a, 0x99, 0x73, 0xd9, 0x02, 0x05,
0x00, 0x5c, 0x84, 0x3f, 0x02, 0xb7, 0x0f, 0xc7, 0xeb, 0xe1, 0x6c, 0x73,
0x39, 0xaa, 0x8a, 0x1c, 0x46, 0x5a, 0x52, 0xa5, 0xc4, 0xd5, 0xdd, 0x99,
0xf1, 0x35, 0x9a, 0x1a, 0x57, 0x27, 0xc6, 0x36, 0x15, 0x8b, 0xa1, 0xeb,
0xb1, 0x55, 0x66, 0x2c, 0x0f, 0x8b, 0x30, 0xe3, 0xee, 0xb0, 0x27, 0x3e,
0x39, 0xe1, 0xb1, 0x62, 0x1b, 0x87, 0x7a, 0x94, 0x04, 0xbe, 0x82, 0x85,
0xa9, 0xff, 0x5c, 0x53, 0x80, 0x5b, 0xdb, 0xb1, 0x3d, 0xa7, 0xc7, 0x56,
0x8d, 0xe5, 0x51, 0x5c, 0x95, 0x2c, 0x6a, 0x7f, 0xad, 0xae, 0xad, 0x89,
0x6c, 0x7a, 0x4f, 0x8b, 0x7b, 0x66, 0x1a, 0x47, 0xe5, 0xfe, 0x5d, 0xb8,
0xe0, 0x7e, 0xd6, 0x46, 0x61, 0x83, 0x6c, 0x9e, 0x85, 0x0e, 0xb4, 0x51,
0x6a, 0x50, 0xcd, 0x5a, 0x0f, 0x1e, 0xca, 0xf2, 0x4d, 0xca, 0x76, 0xa1,
0x77, 0x62, 0x2e, 0xd2, 0x89, 0x39, 0x3c, 0x2d, 0x3b, 0xd0, 0x59, 0x12,
0xb0, 0x26, 0xd8, 0x21, 0xa7, 0xcc, 0x90, 0xaf, 0xd0, 0xa9, 0xb8, 0xb0,
0x38, 0x98, 0xe2, 0xfb, 0x6e, 0x60, 0xff, 0x09, 0x41, 0x4a, 0xfc, 0xe6,
0x75, 0xf8, 0xec, 0x5e, 0xcc, 0x19, 0x35, 0x9c, 0x4c, 0xad, 0x0d, 0x59,
0x3f, 0x87, 0x6d, 0xc7, 0xb5, 0x04, 0x5a, 0xfb, 0xaa, 0x6b, 0x10, 0xf1,
0x17, 0x21, 0xc2, 0x90, 0xdc, 0xbb, 0x5d, 0x8d, 0x08, 0xdb, 0xc1, 0xeb,
0x8c, 0x38, 0xd6, 0x94, 0xdf, 0xc9, 0xa0, 0x13, 0x9b, 0x75, 0xb4, 0x50,
0xef, 0x67, 0xe2, 0xef, 0x65, 0xe8, 0x7f, 0x9a, 0xb9, 0x27, 0x33, 0x7a,
0xc7, 0xf4, 0x03, 0x05, 0xc9, 0x9c, 0x66, 0xdc, 0x3c, 0xe4, 0xee, 0x23,
0x38, 0xe7, 0xab, 0xff, 0x9c, 0x2b, 0x30, 0x64, 0x3c, 0xba, 0x6d, 0xbc,
0xd7, 0xd1, 0x7b, 0x76, 0xf7, 0x85, 0xd1, 0x5d, 0x7a, 0xd0, 0xfe, 0xa8,
0x7e, 0x56, 0xef, 0xd7, 0xdf, 0x76, 0xd4, 0x3e, 0x42, 0x83, 0x60, 0x44,
0xb5, 0xa1, 0x13, 0xf3, 0xff, 0xc9, 0x0e, 0xa7, 0x50, 0x10, 0xc1, 0x3e,
0x0c, 0x92, 0xbf, 0x82, 0x31, 0xb0, 0xda, 0x1f, 0x1d, 0x52, 0x7f, 0x14,
0xb3, 0x36, 0x39, 0xed, 0x75, 0x7e, 0xc0, 0x06, 0x0f, 0x4b, 0xfe, 0x48,
0xd7, 0xb3, 0xd6, 0xad, 0xaa, 0xb0, 0x6e, 0x98, 0x4d, 0xfb, 0x5b, 0x5d,
0xc3, 0xbc, 0xbc, 0x68, 0x6b, 0x98, 0x1a, 0xe9, 0x91, 0x24, 0xc8, 0xc4,
0x2c, 0x9a, 0x75, 0x7a, 0xfd, 0x02, 0x47, 0xfa, 0xdf, 0xc1, 0xf5, 0x97,
0x43, 0x9e, 0x1c, 0xd4, 0xa5, 0x79, 0xb5, 0x25, 0x36, 0xa2, 0xce, 0x14,
0xb6, 0x0c, 0x70, 0x3b, 0x07, 0xf8, 0x30, 0x2c, 0xbb, 0x73, 0x42, 0xea,
0x49, 0xec, 0x13, 0xa9, 0xc9, 0x90, 0x00, 0x66, 0x7f, 0xf5, 0xd9, 0x74,
0xf2, 0x52, 0x3c, 0xe7, 0x1a, 0x32, 0x1d, 0x0b, 0x59, 0xf2, 0x4a, 0xbd,
0x2c, 0x90, 0x80, 0x42, 0xf8, 0x7a, 0xd2, 0xd9, 0xb0, 0x0e, 0x1b, 0xef,
0x19, 0x00, 0x36, 0xe0, 0xda, 0x7f, 0x83, 0x0e, 0xa1, 0x90, 0x1f, 0x70,
0xc7, 0x28, 0xa1, 0x49, 0x2e, 0xda, 0x2a, 0x82, 0xac, 0xf2, 0xef, 0x74,
0xeb, 0xe3, 0x5d, 0xa3, 0x56, 0xb2, 0x80, 0x09, 0xf2, 0xc9, 0x0d, 0x41,
0x4f, 0xf7, 0xfb, 0xb1, 0x8b, 0x17, 0x07, 0x83, 0x2e, 0x65, 0x56, 0x20,
0xdc, 0x99, 0x1e, 0xf8, 0x3b, 0xe1, 0x51, 0xa0, 0x57, 0xc5, 0x57, 0x60,
0x89, 0x1e, 0x24, 0xf1, 0x57, 0x58, 0xad, 0xac, 0x80, 0x07, 0x88, 0x75,
0x31, 0xe2, 0x97, 0x39, 0xe6, 0x92, 0x3a, 0x7d, 0xa2, 0xbf, 0x6e, 0x5d,
0xa7, 0xa9, 0x6b, 0xae, 0xaa, 0xa8, 0x30, 0xb8, 0x97, 0x13, 0x7a, 0x15,
0x7b, 0x20, 0x10, 0xcc, 0xb0, 0x27, 0x0e, 0x1b, 0x10, 0xbd, 0x55, 0xec,
0x4f, 0xd1, 0xa6, 0x59, 0x29, 0x8c, 0x31, 0x72, 0x07, 0x2f, 0x4f, 0x6e,
0xd5, 0xc4, 0x50, 0x20, 0x2d, 0x05, 0x29, 0xf8, 0x6c, 0x8d, 0x41, 0xc4,
0x0e, 0x9c, 0x74, 0x12, 0x3e, 0xc9, 0xa8, 0x0c, 0x35, 0x43, 0x8a, 0x9d,
0x5b, 0xee, 0x53, 0x18, 0xd9, 0xf1, 0x7c, 0xe2, 0xaf, 0xe5, 0x7c, 0x7a,
0x6f, 0xcc, 0x43, 0xae, 0xdb, 0x55, 0xa1, 0x4b, 0x8b, 0x09, 0xeb, 0xd8,
0x57, 0xda, 0x8f, 0x64, 0x8f, 0xf2, 0xb0, 0x3c, 0xee, 0x90, 0x77, 0xdd,
0x37, 0x76, 0x87, 0xfb, 0xbe, 0x4a, 0xb6, 0x75, 0x03, 0x75, 0xf0, 0x2a,
0x92, 0x3c, 0xfe, 0xe1, 0x5c, 0x37, 0x09, 0xc8, 0x55, 0x28, 0xe8, 0x70,
0x37, 0xef, 0x3f, 0x70, 0x71, 0xd9, 0x3b, 0x25, 0x2e, 0x11, 0xc7, 0x71,
0x86, 0x59, 0x0e, 0x5f, 0x1d, 0x24, 0xfe, 0xf9, 0x4f, 0x0a, 0xbb, 0xfe,
0x92, 0x8b, 0x8f, 0x18, 0xa5, 0xaa, 0x68, 0xc3, 0xd4, 0x8f, 0xb8, 0x00,
0x6e, 0x3e, 0x7e, 0x24, 0x12, 0x95, 0xa9, 0x3d, 0xbd, 0xa4, 0x93, 0xc5,
0x67, 0xef, 0x75, 0x11, 0xb2, 0x50, 0x80, 0xc1, 0x19, 0x1b, 0x8c, 0xbc,
0x9b, 0x2d, 0xad, 0xbe, 0xe4, 0x95, 0xe4, 0x82, 0xd1, 0xab, 0xee, 0x29,
0x39, 0x97, 0x8f, 0x92, 0xc5, 0x7e, 0x94, 0x10, 0xe8, 0x8e, 0xbe, 0x05,
0x23, 0xb5, 0xda, 0x8e, 0xe9, 0x79, 0x88, 0x10, 0x22, 0x1f, 0x5c, 0xb9,
0xd9, 0x10, 0x24, 0x28, 0xed, 0xc1, 0xe8, 0xa6, 0x21, 0xee, 0xda, 0x83,
0x82, 0x44, 0x43, 0x13, 0x74, 0x69, 0xb0, 0x33, 0xd0, 0xaf, 0x1a, 0x07,
0x09, 0x46, 0x42, 0xa8, 0xfb, 0x09, 0x81, 0xe5, 0x91, 0x21, 0xe5, 0xcb,
0x1b, 0x0e, 0x26, 0x0c, 0x08, 0x99, 0xbb, 0x0c, 0x3a, 0xdc, 0xcf, 0x0e,
0x9d, 0xc8, 0xc4, 0xee, 0x1a, 0xdc, 0xf5, 0x3d, 0x60, 0x8a, 0xe8, 0x0e,
0xab, 0xbb, 0xad, 0x49, 0xa0, 0x6d, 0x70, 0x9b, 0x85, 0x29, 0x3c, 0x31,
0xf7, 0xed, 0xa5, 0xed, 0xf6, 0x4c, 0x1f, 0x26, 0x0d, 0x06, 0x8b, 0xe7,
0x0f, 0x0c, 0x4c, 0xbe, 0x23, 0xa0, 0xbf, 0x20, 0x76, 0xd3, 0x23, 0x67,
0x7e, 0x64, 0x32, 0x8b, 0x9d, 0xd0, 0x77, 0x4c, 0x3d, 0xb9, 0xb0, 0x71,
0x1c, 0x5d, 0x9a, 0xa8, 0xa7, 0x8d, 0xac, 0x3e, 0xbc, 0xe1, 0x27, 0x45,
0x34, 0xb1, 0x1a, 0x05, 0x60, 0x7b, 0x90, 0xb1, 0x4f, 0x95, 0xa2, 0x19,
0x3f, 0x86, 0xf3, 0x21, 0x0a, 0xfc, 0x6f, 0x55, 0x44, 0xfc, 0x52, 0xde,
0x33, 0x98, 0xc3, 0x1c, 0xca, 0x61, 0xe8, 0x1e, 0x6c, 0xe3, 0x9c, 0xc3,
0xb2, 0xdf, 0x6a, 0x93, 0x4b, 0x71, 0x29, 0x67, 0xe7, 0x26, 0x68, 0x89,
0xda, 0x74, 0x0a, 0xf7, 0x42, 0xcc, 0x3c, 0x2c, 0x78, 0x6a, 0xf4, 0x39,
0x15, 0x30, 0x29, 0xec, 0x87, 0xca, 0xdc, 0x06, 0x7e, 0x25, 0x07, 0x83,
0xd8, 0xc8, 0xfa, 0x21, 0x86, 0x10, 0x29, 0xb4, 0x10, 0xbc, 0x3e, 0xee,
0xe3, 0x5c, 0x56, 0x01, 0x94, 0xbe, 0xa6, 0x63, 0x23, 0x8b, 0x5f, 0x9d,
0x26, 0xc2, 0x6f, 0x86, 0x06, 0x45, 0x2f, 0x01, 0x4c, 0x1c, 0xea, 0x96,
0xdd, 0xb5, 0x1e, 0xbb, 0x28, 0x1a, 0xca, 0x6a, 0xf8, 0x67, 0x82, 0xac,
0xa3, 0x41, 0x7b, 0xa0, 0xc1, 0xfe, 0x34, 0x4f, 0x66, 0x85, 0x90, 0xc5,
0x05, 0x1b, 0xc4, 0x86, 0xde, 0x51, 0xf1, 0x2b, 0x9c, 0x89, 0x46, 0x3c,
0xd6, 0xf7, 0x26, 0xe5, 0xe0, 0xd7, 0x93, 0xac, 0xa3, 0x9c, 0xdb, 0xb0,
0x72, 0x6e, 0x5f, 0xad, 0x9c, 0x08, 0x7b, 0xc2, 0x3f, 0x2e, 0x81, 0xa7,
0xb6, 0xa0, 0x42, 0xd6, 0xdc, 0x80, 0x02, 0xcc, 0x21, 0xb1, 0x82, 0xbf,
0x4b, 0x45, 0x06, 0x5a, 0x4f, 0x45, 0xf4, 0x35, 0x2f, 0x61, 0x45, 0xd1,
0x8a, 0x3f, 0x5b, 0x5d, 0x06, 0x7a, 0x5f, 0x75, 0x31, 0x6f, 0xea, 0xc4,
0xbc, 0xd1, 0xc7, 0x75, 0x3c, 0x29, 0xf7, 0xe8, 0x65, 0xa5, 0x1d, 0x9c,
0xdb, 0x95, 0xfb, 0xaf, 0x0c, 0xb5, 0x93, 0xc7, 0xbb, 0xef, 0xe2, 0x7e,
0xe3, 0xe5, 0x7f, 0x09, 0xae, 0xe2, 0x59, 0x1b, 0xee, 0x3a, 0x3e, 0xb4,
0x8a, 0xd7, 0xd4, 0x2a, 0x1c, 0x63, 0x3b, 0xc3, 0x67, 0xa4, 0x03, 0x57,
0xca, 0xf1, 0xff, 0x26, 0x08, 0xf5, 0xf1, 0x25, 0xfc, 0x8e, 0x22, 0x0b,
0x57, 0x80, 0x79, 0xc1, 0x81, 0x6c, 0xd0, 0xb6, 0x48, 0x36, 0xbf, 0xf3,
0x13, 0x03, 0xe1, 0xe4, 0xa3, 0xae, 0x00, 0xef, 0xa9, 0xc2, 0x8f, 0xdf,
0x7d, 0xf5, 0x73, 0x06, 0x16, 0xe2, 0x87, 0xf0, 0x95, 0x3e, 0x84, 0x87,
0xaf, 0x7e, 0xfe, 0x3a, 0x5d, 0x18, 0xcb, 0x59, 0xb7, 0x53, 0xa6, 0x59,
0x78, 0x75, 0x60, 0x96, 0xbe, 0xa3, 0x82, 0xfb, 0x48, 0xda, 0xfb, 0x11,
0x4a, 0x7e, 0x06, 0xda, 0xa4, 0x70, 0xdf, 0xee, 0xf5, 0x70, 0x54, 0xef,
0xcb, 0x3e, 0x38, 0xd1, 0x4a, 0x96, 0xd0, 0x20, 0xaf, 0x87, 0x60, 0x8f,
0x58, 0x77, 0xec, 0x91, 0x4d, 0x4c, 0xe1, 0xbb, 0xef, 0xbe, 0x7d, 0xda,
0x14, 0x8f, 0x8b, 0x78, 0xdb, 0x2b, 0x7a, 0xe0, 0xa3, 0xde, 0xbe, 0xc6,
0xcf, 0xd8, 0x13, 0x20, 0x60, 0xbc, 0x30, 0x9a, 0xad, 0xbc, 0x83, 0x02,
0x5d, 0xa9, 0xfb, 0x5f, 0xf1, 0x46, 0x2f, 0x67, 0xe3, 0xee, 0x34, 0xcb,
0x90, 0x5d, 0x93, 0xd4, 0x3b, 0x13, 0xc2, 0x19, 0x6d, 0x26, 0x8d, 0x14,
0x48, 0x20, 0x61, 0x7f, 0x50, 0x10, 0xee, 0x84, 0x05, 0xa4, 0x87, 0x86,
0x66, 0x01, 0x9b, 0xc4, 0x66, 0x7e, 0x33, 0xbf, 0x87, 0x9f, 0xf2, 0x90,
0x09, 0xf0, 0xfe, 0xb3, 0x03, 0x9e, 0x5c, 0x00, 0x1c, 0x31, 0xc0, 0x49,
0x35, 0xeb, 0x90, 0x9f, 0x59, 0xa3, 0xdc, 0x2e, 0xff, 0xad, 0xa7, 0x6d,
0xcc, 0x88, 0xf3, 0x0f, 0x1c, 0x1c, 0xe0, 0x13, 0x8c, 0x9c, 0x46, 0xef,
0xbd, 0xf3, 0x5e, 0x4b, 0xd8, 0xe7, 0x6d, 0x3e, 0xe1, 0x4c, 0x23, 0x27,
0x43, 0xad, 0x2d, 0x28, 0xa6, 0x06, 0x65, 0xc1, 0x6a, 0x2c, 0x7c, 0x74,
0x15, 0xeb, 0x9b, 0xe8, 0x4a, 0x3b, 0x5c, 0x75, 0xae, 0xa5, 0xdb, 0x17,
0xcd, 0xc9, 0xbb, 0xb4, 0x03, 0x38, 0x32, 0xb9, 0xb8, 0x8f, 0xd1, 0xfc,
0x57, 0xf9, 0x19, 0xee, 0x86, 0x0f, 0x77, 0x03, 0x70, 0x29, 0x02, 0x93,
0x1a, 0xcb, 0x0a, 0x8f, 0x07, 0x05, 0xf6, 0x6f, 0x3f, 0xfc, 0x01, 0x35,
0x65, 0x9f, 0x7f, 0x0d, 0x62, 0x00, 0x00
};
File diff suppressed because it is too large Load Diff
+269
View File
@@ -0,0 +1,269 @@
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
#if defined(ARDUINOJSON_VERSION)
#if !(ARDUINOJSON_VERSION_MAJOR == 6 and ARDUINOJSON_VERSION_MINOR >= 8)
#error "Install ArduinoJson v6.8.x or higher"
#endif
#endif
char * listStateJSONfull() {
const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(20) + 250;
DynamicJsonDocument jsonBuffer(bufferSize);
JsonObject root = jsonBuffer.to<JsonObject>();
root["segment"] = segment;
root["start"] = seg_start;
root["stop"] = seg_stop;
root["mode"] = (uint8_t) mode;
//getSegmentParams(segment);
root["ws2812fx_mode"] = ws2812fx_mode;
root["ws2812fx_mode_name"] = strip->getModeName(ws2812fx_mode);
root["speed"] = ws2812fx_speed;
root["brightness"] = brightness;
JsonArray color = root.createNestedArray("color");
color.add(main_color.white);
color.add(main_color.red);
color.add(main_color.green);
color.add(main_color.blue);
color.add(back_color.white);
color.add(back_color.red);
color.add(back_color.green);
color.add(back_color.blue);
color.add(xtra_color.white);
color.add(xtra_color.red);
color.add(xtra_color.green);
color.add(xtra_color.blue);
root["hostname"] = HOSTNAME;
#if defined(ENABLE_MQTT)
root["mqtt_host"] = mqtt_host;
root["mqtt_port"] = mqtt_port;
root["mqtt_user"] = mqtt_user;
root["mqtt_pass"] = mqtt_pass;
#endif
root["ws_seg"] = num_segments;
root["ws_cnt"] = WS2812FXStripSettings.stripSize;
root["ws_rgbo"] = WS2812FXStripSettings.RGBOrder;
root["ws_pin"] = WS2812FXStripSettings.pin;
root["ws_fxopt"] = WS2812FXStripSettings.fxoptions;
root["transEffect"] = transEffect;
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
return buffer;
}
char * listStateJSON() {
const size_t bufferSize = JSON_OBJECT_SIZE(3) + 25;
DynamicJsonDocument jsonBuffer(bufferSize);
JsonObject root = jsonBuffer.to<JsonObject>();
root["segment"] = segment;
root["mode"] = (uint8_t) mode;
root["brightness"] = brightness;
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
return buffer;
}
char * listSegmentStateJSON(uint8_t seg) {
const size_t bufferSize = JSON_ARRAY_SIZE(12) + JSON_OBJECT_SIZE(7) + 100;
DynamicJsonDocument jsonBuffer(bufferSize);
JsonObject root = jsonBuffer.to<JsonObject>();
root["segment"] = seg;
if (seg == segment) {
root["start"] = seg_start;
root["stop"] = seg_stop;
} else {
root["start"] = strip->getSegment(seg)->start;
root["stop"] = strip->getSegment(seg)->stop;
}
//getSegmentParams(seg);
root["ws2812fx_mode"] = strip->getMode(seg);
root["ws2812fx_mode_name"] = strip->getModeName(strip->getMode(seg));
root["speed"] = ws2812fx_speed;
JsonArray color = root.createNestedArray("color");
color.add((strip->getColors(seg)[0] >> 24) & 0xFF);
color.add((strip->getColors(seg)[0] >> 16) & 0xFF);
color.add((strip->getColors(seg)[0] >> 8) & 0xFF);
color.add((strip->getColors(seg)[0]) & 0xFF);
color.add((strip->getColors(seg)[1] >> 24) & 0xFF);
color.add((strip->getColors(seg)[1] >> 16) & 0xFF);
color.add((strip->getColors(seg)[1] >> 8) & 0xFF);
color.add((strip->getColors(seg)[1]) & 0xFF);
color.add((strip->getColors(seg)[2] >> 24) & 0xFF);
color.add((strip->getColors(seg)[2] >> 16) & 0xFF);
color.add((strip->getColors(seg)[2] >> 8) & 0xFF);
color.add((strip->getColors(seg)[2]) & 0xFF);
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
return buffer;
}
void getStateJSON() {
char * buffer = listStateJSONfull();
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send ( 200, "application/json", buffer);
free (buffer);
}
char * listConfigJSON() {
#if defined(ENABLE_MQTT)
const size_t bufferSize = JSON_OBJECT_SIZE(11) + 150;
#else
const size_t bufferSize = JSON_OBJECT_SIZE(7) + 100;
#endif
DynamicJsonDocument jsonBuffer(bufferSize);
JsonObject root = jsonBuffer.to<JsonObject>();
root["hostname"] = HOSTNAME;
#if defined(ENABLE_MQTT)
root["mqtt_host"] = mqtt_host;
root["mqtt_port"] = mqtt_port;
root["mqtt_user"] = mqtt_user;
root["mqtt_pass"] = mqtt_pass;
#endif
root["ws_seg"] = num_segments;
root["ws_cnt"] = WS2812FXStripSettings.stripSize;
root["ws_rgbo"] = WS2812FXStripSettings.RGBOrder;
root["ws_pin"] = WS2812FXStripSettings.pin;
root["ws_fxopt"] = WS2812FXStripSettings.fxoptions;
root["transEffect"] = transEffect;
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
return buffer;
}
void getConfigJSON() {
char * buffer = listConfigJSON();
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send ( 200, "application/json", buffer);
free (buffer);
}
char * listModesJSON() {
const size_t bufferSize = JSON_ARRAY_SIZE(strip->getModeCount() + 1) + (strip->getModeCount() + 1)*JSON_OBJECT_SIZE(2) + 2000;
DynamicJsonDocument jsonBuffer(bufferSize);
JsonArray root = jsonBuffer.to<JsonArray>();
JsonObject objectoff = root.createNestedObject();
objectoff["mode"] = "off";
objectoff["name"] = "OFF";
for (uint8_t i = 0; i < strip->getModeCount(); i++) {
JsonObject object = root.createNestedObject();
object["mode"] = i;
object["name"] = strip->getModeName(i);
}
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
return buffer;
}
void getModesJSON() {
char * buffer = listModesJSON();
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send ( 200, "application/json", buffer);
free (buffer);
}
char * listESPStateJSON() {
const size_t bufferSize = JSON_OBJECT_SIZE(31) + 1500;
DynamicJsonDocument jsonBuffer(bufferSize);
JsonObject root = jsonBuffer.to<JsonObject>();
root["HOSTNAME"] = HOSTNAME;
root["version"] = SKETCH_VERSION;
root["heap"] = ESP.getFreeHeap();
root["sketch_size"] = ESP.getSketchSize();
root["free_sketch_space"] = ESP.getFreeSketchSpace();
root["flash_chip_size"] = ESP.getFlashChipSize();
root["flash_chip_real_size"] = ESP.getFlashChipRealSize();
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
root["sdk_version"] = ESP.getSdkVersion();
root["core_version"] = ESP.getCoreVersion();
root["cpu_freq"] = ESP.getCpuFreqMHz();
root["chip_id"] = ESP.getFlashChipId();
#if defined(USE_WS2812FX_DMA)
#if USE_WS2812FX_DMA == 0
root["animation_lib"] = "WS2812FX_DMA";
#endif
#if USE_WS2812FX_DMA == 1
root["animation_lib"] = "WS2812FX_UART1";
#endif
#if USE_WS2812FX_DMA == 2
root["animation_lib"] = "WS2812FX_UART2";
#endif
#else
root["animation_lib"] = "WS2812FX";
#endif
root["ws2812_pin"] = WS2812FXStripSettings.pin;
root["led_count"] = WS2812FXStripSettings.stripSize;
root["rgb_order"] = WS2812FXStripSettings.RGBOrder;
if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) {
root["rgbw_mode"] = "ON";
} else {
root["rgbw_mode"] = "OFF";
}
#if defined(ENABLE_BUTTON)
root["button_mode"] = "ON";
root["button_pin"] = ENABLE_BUTTON;
#else
root["button_mode"] = "OFF";
#endif
#if defined(ENABLE_BUTTON_GY33)
root["button_gy33"] = "ON";
root["gy33_pin"] = ENABLE_BUTTON_GY33;
#else
root["button_gy33"] = "OFF";
#endif
#if defined(ENABLE_REMOTE)
root["ir_remote"] = "ON";
root["tsop_ir_pin"] = ENABLE_REMOTE;
#else
root["ir_remote"] = "OFF";
#endif
#if defined(ENABLE_MQTT)
#if ENABLE_MQTT == 0
root["mqtt"] = "MQTT";
#endif
#if ENABLE_MQTT == 1
root["mqtt"] = "AMQTT";
#endif
#else
root["mqtt"] = "OFF";
#endif
#if defined(ENABLE_HOMEASSISTANT)
root["home_assistant"] = "ON";
#else
root["home_assistant"] = "OFF";
#endif
#if defined(ENABLE_OTA)
#if ENABLE_OTA == 0
root["ota"] = "ARDUINO";
#endif
#if ENABLE_OTA == 1
root["ota"] = "HTTP";
#endif
#else
root["ota"] = "OFF";
#endif
#if defined(ENABLE_STATE_SAVE)
root["state_save"] = "SPIFFS";
#else
root["state_save"] = "OFF";
#endif
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
return buffer;
}
void getESPStateJSON() {
char * buffer = listESPStateJSON();
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "application/json", buffer);
free (buffer);
}
@@ -1,3 +1,7 @@
// Prototypes
uint16_t convertSpeed(uint8_t mcl_speed);
uint32_t trans(uint32_t newcolor, uint32_t oldcolor, uint8_t level);
// End Prototypes
/*
Example of adding the example: https://github.com/kitesurfer1404/WS2812FX/blob/master/examples/ws2812fx_custom_FastLED/ws2812fx_custom_FastLED.ino
@@ -68,7 +72,7 @@ void hsb2rgbAN1(uint16_t index, uint8_t sat, uint8_t bright, uint16_t led) {
void updateLed (uint16_t led, uint8_t brightness) {
ledstates[led] = brightness;
for (uint16_t i=0; i<WS2812FXStripSettings.stripSize; i++) {
for (uint16_t i=seg_start; i<=seg_stop; i++) {
uint16_t index = (i%3 == 0) ? 400 : random(0,767);
hsb2rgbAN1(index, 200, ledstates[i], i);
}
@@ -200,12 +204,12 @@ void Fire2012() {
// Array of temperature readings at each simulation cell
// Step 1. Cool down every cell a little
for( uint16_t i = 0; i < WS2812FXStripSettings.stripSize; i++) {
for( uint16_t i = seg_start; i <= seg_stop; i++) {
ledstates[i] = qsub8( ledstates[i], random8(0, ((COOLING * 10) / WS2812FXStripSettings.stripSize) + 2));
}
// Step 2. Heat from each cell drifts 'up' and diffuses a little
for( uint16_t k= WS2812FXStripSettings.stripSize - 1; k >= 2; k--) {
for( uint16_t k= seg_stop-seg_start - 1; k >= 2; k--) {
ledstates[k] = (ledstates[k - 1] + ledstates[k - 2] + ledstates[k - 2]) / 3;
}
@@ -216,11 +220,11 @@ void Fire2012() {
}
// Step 4. Map from heat cells to LED colors
for( uint16_t j = 0; j < WS2812FXStripSettings.stripSize; j++) {
for( uint16_t j = seg_start; j <= seg_stop; j++) {
CRGB color = HeatColor( ledstates[j]);
uint16_t pixelnumber;
if( gReverseDirection ) {
pixelnumber = (WS2812FXStripSettings.stripSize - 1) - j;
pixelnumber = seg_stop - j;
} else {
pixelnumber = j;
}
@@ -229,15 +233,15 @@ void Fire2012() {
}
void Gradient() {
for( uint16_t j = 0; j < WS2812FXStripSettings.stripSize; j++) {
for( uint16_t j = seg_start; j <= seg_stop; j++) {
uint16_t pixelnumber;
uint32_t color;
if( gReverseDirection ) {
pixelnumber = (WS2812FXStripSettings.stripSize - 1) - j;
pixelnumber = seg_stop - j;
} else {
pixelnumber = j;
}
color = trans(strip->getColors(segment)[1], strip->getColors(segment)[0], (j*255)/(WS2812FXStripSettings.stripSize - 1));
color = trans(strip->getColors(segment)[1], strip->getColors(segment)[0], (j*255)/(seg_stop - seg_start));
strip->setPixelColor(pixelnumber, ((color >> 16) & 0xFF), ((color >> 8) & 0xFF), ((color >> 0) & 0xFF), ((color >> 24) & 0xFF));
}
}
File diff suppressed because it is too large Load Diff
+375 -328
View File
@@ -1,359 +1,406 @@
// ***************************************************************************
// Setup: Webserver handler
// ***************************************************************************
//list directory
server.on("/list", HTTP_GET, handleFileList);
//create file
server.on("/edit", HTTP_PUT, handleFileCreate);
//delete file
server.on("/edit", HTTP_DELETE, handleFileDelete);
//first callback is called after the request has ended with all parsed arguments
//second callback handles file uploads at that location
server.on("/edit", HTTP_POST, []() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "");
}, handleFileUpload);
// ***************************************************************************
// Setup: Webserver handler
// ***************************************************************************
//list directory
server.on("/list", HTTP_GET, handleFileList);
//create file
server.on("/edit", HTTP_PUT, handleFileCreate);
//delete file
server.on("/edit", HTTP_DELETE, handleFileDelete);
//first callback is called after the request has ended with all parsed arguments
//second callback handles file uploads at that location
server.on("/edit", HTTP_POST, []() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "");
}, handleFileUpload);
// ***************************************************************************
// Setup: SPIFFS Webserver handler
// ***************************************************************************
server.on("/", HTTP_GET, [&](){
#if defined(USE_HTML_MIN_GZ)
server.sendHeader("Content-Encoding", "gzip", true);
server.send_P(200, PSTR("text/html"), index_htm_gz, index_htm_gz_len);
#else
if (!handleFileRead(server.uri()))
handleNotFound();
#endif
});
server.on("/edit", HTTP_GET, [&](){
#if defined(USE_HTML_MIN_GZ)
server.sendHeader("Content-Encoding", "gzip", true);
server.send_P(200, PSTR("text/html"), edit_htm_gz, edit_htm_gz_len);
#else
if (!handleFileRead("/edit.htm"))
handleNotFound();
#endif
});
//called when the url is not defined here
//use it to load content from SPIFFS
server.onNotFound([]() {
server.on("/", HTTP_GET, [&](){
#if defined(USE_HTML_MIN_GZ)
server.sendHeader("Content-Encoding", "gzip", true);
server.send_P(200, PSTR("text/html"), index_htm_gz, index_htm_gz_len);
#else
if (!handleFileRead(server.uri()))
handleNotFound();
});
#endif
});
server.on("/upload", handleMinimalUpload);
server.on("/edit", HTTP_GET, [&](){
#if defined(USE_HTML_MIN_GZ)
server.sendHeader("Content-Encoding", "gzip", true);
server.send_P(200, PSTR("text/html"), edit_htm_gz, edit_htm_gz_len);
#else
if (!handleFileRead("/edit.htm"))
handleNotFound();
#endif
});
server.on("/esp_status", HTTP_GET, []() { //get heap status, analog input value and all GPIO statuses in one json call
const size_t bufferSize = JSON_OBJECT_SIZE(31) + 1500;
DynamicJsonDocument jsonBuffer(bufferSize);
JsonObject root = jsonBuffer.to<JsonObject>();
root["HOSTNAME"] = HOSTNAME;
root["version"] = SKETCH_VERSION;
root["heap"] = ESP.getFreeHeap();
root["sketch_size"] = ESP.getSketchSize();
root["free_sketch_space"] = ESP.getFreeSketchSpace();
root["flash_chip_size"] = ESP.getFlashChipSize();
root["flash_chip_real_size"] = ESP.getFlashChipRealSize();
root["flash_chip_speed"] = ESP.getFlashChipSpeed();
root["sdk_version"] = ESP.getSdkVersion();
root["core_version"] = ESP.getCoreVersion();
root["cpu_freq"] = ESP.getCpuFreqMHz();
root["chip_id"] = ESP.getFlashChipId();
#if defined(USE_WS2812FX_DMA)
#if USE_WS2812FX_DMA == 0
root["animation_lib"] = "WS2812FX_DMA";
#endif
#if USE_WS2812FX_DMA == 1
root["animation_lib"] = "WS2812FX_UART1";
#endif
#if USE_WS2812FX_DMA == 2
root["animation_lib"] = "WS2812FX_UART2";
#endif
#else
root["animation_lib"] = "WS2812FX";
#endif
root["ws2812_pin"] = WS2812FXStripSettings.pin;
root["led_count"] = WS2812FXStripSettings.stripSize;
root["rgb_order"] = WS2812FXStripSettings.RGBOrder;
if (strstr(WS2812FXStripSettings.RGBOrder, "W") != NULL) {
root["rgbw_mode"] = "ON";
} else {
root["rgbw_mode"] = "OFF";
}
#if defined(ENABLE_BUTTON)
root["button_mode"] = "ON";
root["button_pin"] = ENABLE_BUTTON;
#else
root["button_mode"] = "OFF";
#endif
#if defined(ENABLE_BUTTON_GY33)
root["button_gy33"] = "ON";
root["gy33_pin"] = ENABLE_BUTTON_GY33;
#else
root["button_gy33"] = "OFF";
#endif
#if defined(ENABLE_REMOTE)
root["ir_remote"] = "ON";
root["tsop_ir_pin"] = ENABLE_REMOTE;
#else
root["ir_remote"] = "OFF";
#endif
#if defined(ENABLE_MQTT)
#if ENABLE_MQTT == 0
root["mqtt"] = "MQTT";
#endif
#if ENABLE_MQTT == 1
root["mqtt"] = "AMQTT";
#endif
#else
root["mqtt"] = "OFF";
#endif
#if defined(ENABLE_HOMEASSISTANT)
root["home_assistant"] = "ON";
#else
root["home_assistant"] = "OFF";
#endif
#if defined(ENABLE_OTA)
#if ENABLE_OTA == 0
root["ota"] = "ARDUINO";
#endif
#if ENABLE_OTA == 1
root["ota"] = "HTTP";
#endif
#else
root["ota"] = "OFF";
#endif
#if defined(ENABLE_STATE_SAVE)
root["state_save"] = "SPIFFS";
#else
root["state_save"] = "OFF";
#endif
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "application/json", buffer);
free (buffer);
});
server.on("/restart", []() {
DBG_OUTPUT_PORT.printf("/restart\r\n");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "restarting..." );
ESP.restart();
});
server.on("/reset_wlan", []() {
DBG_OUTPUT_PORT.printf("/reset_wlan\r\n");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "Resetting WLAN and restarting..." );
WiFiManager wifiManager;
wifiManager.resetSettings();
ESP.restart();
});
server.on("/start_config_ap", []() {
DBG_OUTPUT_PORT.printf("/start_config_ap\r\n");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "Starting config AP ..." );
WiFiManager wifiManager;
wifiManager.startConfigPortal(HOSTNAME);
});
server.on("/format_spiffs", []() {
DBG_OUTPUT_PORT.printf("/format_spiffs\r\n");
server.send(200, "text/plain", "Formatting SPIFFS ..." );
SPIFFS.format();
});
server.on("/get_brightness", []() {
char str_brightness[4];
snprintf(str_brightness, sizeof(str_brightness), "%i", (int) (brightness / 2.55));
str_brightness[sizeof(str_brightness) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", str_brightness );
DBG_OUTPUT_PORT.printf("/get_brightness: %i\r\n", (int) (brightness / 2.55));
});
server.on("/get_speed", []() {
char str_speed[4];
snprintf(str_speed, sizeof(str_speed), "%i", ws2812fx_speed);
str_speed[sizeof(str_speed) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", str_speed );
DBG_OUTPUT_PORT.printf("/get_speed: %i\r\n", ws2812fx_speed);
});
server.on("/get_switch", []() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", (mode == OFF) ? "0" : "1" );
DBG_OUTPUT_PORT.printf("/get_switch: %s\r\n", (mode == OFF) ? "0" : "1");
});
server.on("/get_color", []() {
char rgbcolor[10];
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", main_color.white, main_color.red, main_color.green, main_color.blue);
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", rgbcolor );
DBG_OUTPUT_PORT.print("/get_color: ");
DBG_OUTPUT_PORT.println(rgbcolor);
});
server.on("/get_color2", []() {
char rgbcolor[10];
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", back_color.white, back_color.red, back_color.green, back_color.blue);
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", rgbcolor );
DBG_OUTPUT_PORT.print("/get_color2: ");
DBG_OUTPUT_PORT.println(rgbcolor);
});
server.on("/get_color3", []() {
char rgbcolor[10];
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", xtra_color.white, xtra_color.red, xtra_color.green, xtra_color.blue);
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", rgbcolor );
DBG_OUTPUT_PORT.print("/get_color3: ");
DBG_OUTPUT_PORT.println(rgbcolor);
});
server.on("/get_modes", []() {
getModesJSON();
});
server.on("/status", []() {
getStatusJSON();
});
server.on("/config", []() {
/*
// This will be used later when web-interface is ready and HTTP_GET will not be allowed to update the Strip Settings
if(server.args() == 0 and server.method() != HTTP_POST)
{
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "Only HTTP POST method is allowed and check the number of arguments!");
return;
}
*/
bool updateStrip = false;
bool updateConf = false;
if(server.hasArg("ws_seg")){
uint8_t wsseg = server.arg("ws_seg").toInt();
num_segments = constrain(wsseg, 1, MAX_NUM_SEGMENTS - 1);
updateStrip = true;
}
if(server.hasArg("ws_cnt")){
uint16_t pixelCt = server.arg("ws_cnt").toInt();
if (pixelCt > 0) {
WS2812FXStripSettings.stripSize = constrain(pixelCt, 1, MAXLEDS);
updateStrip = true;
}
}
if(server.hasArg("ws_rgbo")){
char tmp_rgbOrder[5];
snprintf(tmp_rgbOrder, sizeof(tmp_rgbOrder), "%s", server.arg("ws_rgbo").c_str());
tmp_rgbOrder[sizeof(tmp_rgbOrder) - 1] = 0x00;
checkRGBOrder(tmp_rgbOrder);
updateStrip = true;
//called when the url is not defined here
//use it to load content from SPIFFS
server.onNotFound([]() {
if (!handleFileRead(server.uri()))
handleNotFound();
});
server.on("/upload", handleMinimalUpload);
server.on("/esp_status", HTTP_GET, []() { //get heap status, analog input value and all GPIO statuses in one json call
getESPStateJSON();
});
server.on("/restart", []() {
DBG_OUTPUT_PORT.printf("/restart\r\n");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "restarting..." );
ESP.restart();
});
server.on("/reset_wlan", []() {
DBG_OUTPUT_PORT.printf("/reset_wlan\r\n");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "Resetting WLAN and restarting..." );
WiFiManager wifiManager;
wifiManager.resetSettings();
ESP.restart();
});
server.on("/start_config_ap", []() {
DBG_OUTPUT_PORT.printf("/start_config_ap\r\n");
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "Starting config AP ..." );
WiFiManager wifiManager;
wifiManager.startConfigPortal(HOSTNAME);
});
server.on("/format_spiffs", []() {
DBG_OUTPUT_PORT.printf("/format_spiffs\r\n");
server.send(200, "text/plain", "Formatting SPIFFS ..." );
SPIFFS.format();
});
server.on("/get_brightness", []() {
char str_brightness[4];
snprintf(str_brightness, sizeof(str_brightness), "%i", (int) (brightness / 2.55));
str_brightness[sizeof(str_brightness) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", str_brightness );
DBG_OUTPUT_PORT.printf("/get_brightness: %i\r\n", (int) (brightness / 2.55));
});
server.on("/get_speed", []() {
char str_speed[4];
snprintf(str_speed, sizeof(str_speed), "%i", ws2812fx_speed);
str_speed[sizeof(str_speed) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", str_speed );
DBG_OUTPUT_PORT.printf("/get_speed: %i\r\n", ws2812fx_speed);
});
server.on("/get_switch", []() {
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", (mode == OFF) ? "0" : "1" );
DBG_OUTPUT_PORT.printf("/get_switch: %s\r\n", (mode == OFF) ? "0" : "1");
});
server.on("/get_color", []() {
char rgbcolor[10];
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", main_color.white, main_color.red, main_color.green, main_color.blue);
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", rgbcolor );
DBG_OUTPUT_PORT.print("/get_color: ");
DBG_OUTPUT_PORT.println(rgbcolor);
});
server.on("/get_color2", []() {
char rgbcolor[10];
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", back_color.white, back_color.red, back_color.green, back_color.blue);
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", rgbcolor );
DBG_OUTPUT_PORT.print("/get_color2: ");
DBG_OUTPUT_PORT.println(rgbcolor);
});
server.on("/get_color3", []() {
char rgbcolor[10];
snprintf(rgbcolor, sizeof(rgbcolor), "%02X%02X%02X%02X", xtra_color.white, xtra_color.red, xtra_color.green, xtra_color.blue);
rgbcolor[sizeof(rgbcolor) - 1] = 0x00;
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", rgbcolor );
DBG_OUTPUT_PORT.print("/get_color3: ");
DBG_OUTPUT_PORT.println(rgbcolor);
});
server.on("/get_modes", []() {
getModesJSON();
});
server.on("/status", []() {
getStateJSON();
});
server.on("/config", []() {
/*
// This will be used later when web-interface is ready and HTTP_GET will not be allowed to update the Strip Settings
if(server.args() == 0 and server.method() != HTTP_POST)
{
server.sendHeader("Access-Control-Allow-Origin", "*");
server.send(200, "text/plain", "Only HTTP POST method is allowed and check the number of arguments!");
return;
}
*/
// ToDo do not save if no change
bool _updateStrip = false;
bool _updateConfig = false;
if(server.hasArg("ws_seg")){
uint8_t wsseg = server.arg("ws_seg").toInt();
num_segments = constrain(wsseg, 1, MAX_NUM_SEGMENTS - 1);
_updateStrip = true;
}
if(server.hasArg("ws_cnt")){
uint16_t pixelCt = server.arg("ws_cnt").toInt();
if (pixelCt > 0) {
WS2812FXStripSettings.stripSize = constrain(pixelCt, 1, MAXLEDS);
_updateStrip = true;
}
}
if(server.hasArg("ws_rgbo")){
char tmp_rgbOrder[5];
snprintf(tmp_rgbOrder, sizeof(tmp_rgbOrder), "%s", server.arg("ws_rgbo").c_str());
tmp_rgbOrder[sizeof(tmp_rgbOrder) - 1] = 0x00;
checkRGBOrder(tmp_rgbOrder);
_updateStrip = true;
}
#if !defined(USE_WS2812FX_DMA)
if(server.hasArg("ws_pin")){
if (checkPin(server.arg("ws_pin").toInt())) {
updateStrip = true;
DBG_OUTPUT_PORT.print("Pin was set to: ");
DBG_OUTPUT_PORT.println(WS2812FXStripSettings.pin);
} else {
DBG_OUTPUT_PORT.println("invalid input!");
}
if(server.hasArg("ws_pin")){
if (checkPin(server.arg("ws_pin").toInt())) {
_updateStrip = true;
DBG_OUTPUT_PORT.print("Pin was set to: ");
DBG_OUTPUT_PORT.println(WS2812FXStripSettings.pin);
} else {
DBG_OUTPUT_PORT.println("invalid input!");
}
}
#endif
if(server.hasArg("ws_fxopt")){
WS2812FXStripSettings.fxoptions = ((constrain(server.arg("ws_fxopt").toInt(), 0, 255)>>1)<<1);
updateStrip = true;
}
if(server.hasArg("ws_fxopt")){
WS2812FXStripSettings.fxoptions = ((constrain(server.arg("ws_fxopt").toInt(), 0, 255)>>1)<<1);
_updateStrip = true;
}
if(updateStrip) {
mode = INIT_STRIP;
}
if(_updateStrip) {
initStrip();
}
if(server.hasArg("hostname")){
snprintf(HOSTNAME, sizeof(HOSTNAME), "%s", server.arg("hostname").c_str());
HOSTNAME[sizeof(HOSTNAME) - 1] = 0x00;
updateConf = true;
}
if(server.hasArg("hostname")){
snprintf(HOSTNAME, sizeof(HOSTNAME), "%s", server.arg("hostname").c_str());
HOSTNAME[sizeof(HOSTNAME) - 1] = 0x00;
_updateConfig = true;
}
#if defined(ENABLE_MQTT)
if(server.hasArg("mqtt_host")){
snprintf(mqtt_host, sizeof(mqtt_host), "%s", server.arg("mqtt_host").c_str());
mqtt_host[sizeof(mqtt_host) - 1] = 0x00;
updateConf = true;
}
if(server.hasArg("mqtt_port")){
if ((server.arg("mqtt_port").toInt() >= 0) && (server.arg("mqtt_port").toInt() <=65535)) {
mqtt_port = server.arg("mqttport").toInt();
updateConf = true;
}
}
if(server.hasArg("mqtt_user")){
snprintf(mqtt_user, sizeof(mqtt_user), "%s", server.arg("mqtt_user").c_str());
mqtt_user[sizeof(mqtt_user) - 1] = 0x00;
updateConf = true;
}
if(server.hasArg("mqtt_pass")){
snprintf(mqtt_pass, sizeof(mqtt_pass), "%s", server.arg("mqtt_pass").c_str());
mqtt_pass[sizeof(mqtt_pass) - 1] = 0x00;
updateConf = true;
}
if (updateConf) {
initMqtt();
if(server.hasArg("mqtt_host")){
snprintf(mqtt_host, sizeof(mqtt_host), "%s", server.arg("mqtt_host").c_str());
mqtt_host[sizeof(mqtt_host) - 1] = 0x00;
_updateConfig = true;
}
if(server.hasArg("mqtt_port")){
if ((server.arg("mqtt_port").toInt() >= 0) && (server.arg("mqtt_port").toInt() <=65535)) {
mqtt_port = server.arg("mqttport").toInt();
_updateConfig = true;
}
}
if(server.hasArg("mqtt_user")){
snprintf(mqtt_user, sizeof(mqtt_user), "%s", server.arg("mqtt_user").c_str());
mqtt_user[sizeof(mqtt_user) - 1] = 0x00;
_updateConfig = true;
}
if(server.hasArg("mqtt_pass")){
snprintf(mqtt_pass, sizeof(mqtt_pass), "%s", server.arg("mqtt_pass").c_str());
mqtt_pass[sizeof(mqtt_pass) - 1] = 0x00;
_updateConfig = true;
}
if (_updateConfig) {
initMqtt();
}
#endif
if(server.hasArg("trans_effect")){
transEffect = server.arg("trans_effect").toInt();
updateConf = true;
}
if(server.hasArg("trans_effect")){
transEffect = server.arg("trans_effect").toInt();
_updateConfig = true;
}
#if defined(ENABLE_STATE_SAVE)
if (updateStrip || updateConf) {
if(!settings_save_conf.active()) settings_save_conf.once(3, tickerSaveConfig);
}
if (_updateStrip || _updateConfig) {
if(!save_conf.active()) save_conf.once(3, tickerSaveConfig);
}
#endif
updateStrip = false;
updateConf = false;
getConfigJSON();
});
_updateStrip = false;
_updateConfig = false;
getConfigJSON();
});
server.on("/off", []() {
server.on("/off", []() {
if (prevmode != OFF) {
mode = OFF;
getStatusJSON();
});
getStateJSON();
#if defined(ENABLE_STATE_SAVE)
if(!save_state.active()) save_state.once(3, tickerSaveState);
#endif
}
});
server.on("/on", []() {
server.on("/on", []() {
if (prevmode == OFF) {
mode = SET;
getStatusJSON();
});
getStateJSON();
#if defined(ENABLE_STATE_SAVE)
if(!save_state.active()) save_state.once(3, tickerSaveState);
#endif
}
});
server.on("/set", []() {
prevmode = HOLD;
ws2812fx_mode = FX_MODE_STATIC;
server.on("/set", []() {
prevmode = HOLD;
ws2812fx_mode = FX_MODE_STATIC;
boolean _updateState = false;
boolean _updateSegState = false;
// Segment
if ((server.arg("seg") != "") && (server.arg("seg").toInt() >= 0) && (server.arg("seg").toInt() <= MAX_NUM_SEGMENTS)) {
segment = server.arg("seg").toInt();
if (prevsegment != segment) {
prevsegment = segment;
getSegmentParams(segment);
memcpy(hex_colors_trans, hex_colors, sizeof(hex_colors_trans));
mode = SET;
_updateState = true;
}
}
//color wrgb
if (server.arg("rgb") != "") {
uint32_t rgb = (uint32_t) strtoul(server.arg("rgb").c_str(), NULL, 16);
main_color.white = ((rgb >> 24) & 0xFF);
main_color.red = ((rgb >> 16) & 0xFF);
main_color.green = ((rgb >> 8) & 0xFF);
main_color.blue = ((rgb >> 0) & 0xFF);
} else {
if ((server.arg("r") != "") && (server.arg("r").toInt() >= 0) && (server.arg("r").toInt() <= 255)) {
main_color.red = server.arg("r").toInt();
}
if ((server.arg("g") != "") && (server.arg("g").toInt() >= 0) && (server.arg("g").toInt() <= 255)) {
main_color.green = server.arg("g").toInt();
}
if ((server.arg("b") != "") && (server.arg("b").toInt() >= 0) && (server.arg("b").toInt() <= 255)) {
main_color.blue = server.arg("b").toInt();
}
if ((server.arg("w") != "") && (server.arg("w").toInt() >= 0) && (server.arg("w").toInt() <= 255)){
main_color.white = server.arg("w").toInt();
}
}
if (server.arg("rgb2") != "") {
uint32_t rgb2 = (uint32_t) strtoul(server.arg("rgb2").c_str(), NULL, 16);
back_color.white = ((rgb2 >> 24) & 0xFF);
back_color.red = ((rgb2 >> 16) & 0xFF);
back_color.green = ((rgb2 >> 8) & 0xFF);
back_color.blue = ((rgb2 >> 0) & 0xFF);
} else {
if ((server.arg("r2") != "") && (server.arg("r2").toInt() >= 0) && (server.arg("r2").toInt() <= 255)) {
back_color.red = server.arg("r2").toInt();
}
if ((server.arg("g2") != "") && (server.arg("g2").toInt() >= 0) && (server.arg("g2").toInt() <= 255)) {
back_color.green = server.arg("g2").toInt();
}
if ((server.arg("b2") != "") && (server.arg("b2").toInt() >= 0) && (server.arg("b2").toInt() <= 255)) {
back_color.blue = server.arg("b2").toInt();
}
if ((server.arg("w2") != "") && (server.arg("w2").toInt() >= 0) && (server.arg("w2").toInt() <= 255)){
back_color.white = server.arg("w2").toInt();
}
}
if (server.arg("rgb3") != "") {
uint32_t rgb3 = (uint32_t) strtoul(server.arg("rgb3").c_str(), NULL, 16);
xtra_color.white = ((rgb3 >> 24) & 0xFF);
xtra_color.red = ((rgb3 >> 16) & 0xFF);
xtra_color.green = ((rgb3 >> 8) & 0xFF);
xtra_color.blue = ((rgb3 >> 0) & 0xFF);
} else {
if ((server.arg("r3") != "") && (server.arg("r3").toInt() >= 0) && (server.arg("r3").toInt() <= 255)) {
xtra_color.red = server.arg("r3").toInt();
}
if ((server.arg("g3") != "") && (server.arg("g3").toInt() >= 0) && (server.arg("g3").toInt() <= 255)) {
xtra_color.green = server.arg("g3").toInt();
}
if ((server.arg("b3") != "") && (server.arg("b3").toInt() >= 0) && (server.arg("b3").toInt() <= 255)) {
xtra_color.blue = server.arg("b3").toInt();
}
if ((server.arg("w3") != "") && (server.arg("w3").toInt() >= 0) && (server.arg("w3").toInt() <= 255)){
xtra_color.white = server.arg("w3").toInt();
}
}
main_color.red = constrain(main_color.red, 0, 255);
main_color.green = constrain(main_color.green, 0, 255);
main_color.blue = constrain(main_color.blue, 0, 255);
main_color.white = constrain(main_color.white, 0, 255);
back_color.red = constrain(back_color.red, 0, 255);
back_color.green = constrain(back_color.green, 0, 255);
back_color.blue = constrain(back_color.blue, 0, 255);
back_color.white = constrain(back_color.white, 0, 255);
xtra_color.red = constrain(xtra_color.red, 0, 255);
xtra_color.green = constrain(xtra_color.green, 0, 255);
xtra_color.blue = constrain(xtra_color.blue, 0, 255);
xtra_color.white = constrain(xtra_color.white, 0, 255);
// Speed
if ((server.arg("s") != "") && (server.arg("s").toInt() >= 0) && (server.arg("s").toInt() <= 255)) {
ws2812fx_speed = constrain(server.arg("s").toInt(), 0, 255);
mode = SET;
getArgs();
getStatusJSON();
});
_updateSegState = true;
}
//Mode
if ((server.arg("m") != "") && (server.arg("m").toInt() >= 0) && (server.arg("m").toInt() <= strip->getModeCount())) {
ws2812fx_mode = constrain(server.arg("m").toInt(), 0, strip->getModeCount() - 1);
if (ws2812fx_mode != strip->getMode(segment)) {
mode = SET;
_updateSegState = true;
}
}
// Brightness
if ((server.arg("c") != "") && (server.arg("c").toInt() >= 0) && (server.arg("c").toInt() <= 100)) {
brightness = constrain((int) server.arg("c").toInt() * 2.55, 0, 255);
} else if ((server.arg("p") != "") && (server.arg("p").toInt() >= 0) && (server.arg("p").toInt() <= 255)) {
brightness = constrain(server.arg("p").toInt(), 0, 255);
}
if (strip->getBrightness() != brightness) {
mode = SET;
_updateState = true;
}
DBG_OUTPUT_PORT.printf("Get Args: %s\r\n", listStateJSONfull());
getStateJSON();
#if defined(ENABLE_STATE_SAVE)
if (_updateState) {
DBG_OUTPUT_PORT.println("Saving stripstate.json!");
if(!save_state.active()) save_state.once(3, tickerSaveState);
}
if (_updateSegState) {
DBG_OUTPUT_PORT.println("Saving stripstate_segment.json!");
if(!save_seg_state.active()) save_seg_state.once(3, tickerSaveSegmentState);
}
#endif
_updateState = false;
_updateSegState = false;
});
-33
View File
@@ -1,33 +0,0 @@
char * listStatusJSON2() {
const size_t bufferSize = 10*JSON_ARRAY_SIZE(12) + 10*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(12) + 600;
DynamicJsonDocument jsonBuffer(bufferSize);
JsonObject root = jsonBuffer.to<JsonObject>();
root["mode"] = (uint8_t) mode;
root["brightness"] = brightness;
for(uint8_t i=0; i<10; i++) {
char int2char[3];
itoa(i, int2char, 10);
JsonObject segments = root.createNestedObject(int2char);
segments["ws2812fx_mode"] = strip->getMode(i);
segments["ws2812fx_mode_name"] = strip->getModeName(strip->getMode(i));
segments["speed"] = ws2812fx_speed;
JsonArray color = segments.createNestedArray("color");
color.add(main_color.white);
color.add(main_color.red);
color.add(main_color.green);
color.add(main_color.blue);
color.add(back_color.white);
color.add(back_color.red);
color.add(back_color.green);
color.add(back_color.blue);
color.add(xtra_color.white);
color.add(xtra_color.red);
color.add(xtra_color.green);
color.add(xtra_color.blue);
}
uint16_t msg_len = measureJson(root) + 1;
char * buffer = (char *) malloc(msg_len);
serializeJson(root, buffer, msg_len);
jsonBuffer.clear();
return buffer;
}
+1 -1
View File
@@ -1 +1 @@
#define SKETCH_VERSION "3.0.0.BETA1"
#define SKETCH_VERSION "3.1.0.ALPHA2"
+6
View File
@@ -195,4 +195,10 @@
* removal of saving to EEPROM
* first integration of multi segments
*
* * 3 October 2019
* Version Bump to 3.1.0.ALPHA2
* further code changes
* further integration of multi segments
* integration of multi segments to GUI
*
*/