mirror of
https://github.com/wled/WLED.git
synced 2025-04-24 06:47:18 +00:00
Merge branch '0_15' into temporary-AP
This commit is contained in:
commit
07495f6621
5
.github/workflows/wled-ci.yml
vendored
5
.github/workflows/wled-ci.yml
vendored
@ -39,6 +39,11 @@ jobs:
|
||||
environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
cache: 'npm'
|
||||
- run: npm install
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,7 +2,6 @@
|
||||
.clang-format
|
||||
.direnv
|
||||
.DS_Store
|
||||
.gitignore
|
||||
.idea
|
||||
.pio
|
||||
.pioenvs
|
||||
@ -22,3 +21,4 @@ wled-update.sh
|
||||
/wled00/my_config.h
|
||||
/wled00/Release
|
||||
/wled00/wled00.ino.cpp
|
||||
/wled00/html_*.h
|
31
CHANGELOG.md
31
CHANGELOG.md
@ -1,19 +1,42 @@
|
||||
## WLED changelog
|
||||
|
||||
#### Build 2309120 till build 2311120
|
||||
#### Build 2309120 till build 2201060
|
||||
- WLED version 0.15.0-a0
|
||||
- Global JSON buffer guarding (#3648 by @willmmiles, resolves #3641, #3312, #3367, #3637, #3646, #3447)
|
||||
- Effect: Fireworks 1D (fix for matrix trailing strip)
|
||||
- BREAKING: Reduced number of segments (12) on ESP8266 due to less available RAM
|
||||
- Increased available effect data buffer (increases more if board has PSRAM)
|
||||
- Custom palette editor mobile UI enhancement (by @imeszaros)
|
||||
- Per port Auto Brightness Limiter (ABL)
|
||||
- Use PSRAM for JSON buffer (double size, larger ledmaps, up to 2k)
|
||||
- Reduced heap fragmentation by allocating ledmap array only once and not deallocating effect buffer
|
||||
- HTTP retries on failed UI load
|
||||
- UI Search: scroll to top (#3587 by @WoodyLetsCode)
|
||||
- Return to inline iro.js and rangetouch.js (#3597 by @WoodyLetsCode)
|
||||
- Better caching (#3591 by @WoodyLetsCode)
|
||||
- Do not send 404 for missing `skin.css` (#3590 by @WoodyLetsCode)
|
||||
- Simplified UI rework (#3511 by @WoodyLetsCode)
|
||||
- Domoticz device ID for PIR and Temperature usermods
|
||||
- Bugfix for UCS8904 `hasWhite()`
|
||||
- Better search in UI (#3540 by @WoodyLetsCode)
|
||||
- Seeding FastLED PRNG (#3552 by @TripleWhy)
|
||||
- WIZ Smart Button support (#3547 by @micw)
|
||||
- New button type (button switch, fix for #3537)
|
||||
- Pixel Magic Tool update (#3483 by @ajotanc)
|
||||
- Effect: 2D Matrix fix for gaps
|
||||
- Bugfix #3526, #3533, #3561
|
||||
- Spookier Halloween Eyes (#3501)
|
||||
- Compile time options for Multi Relay usermod (#3498)
|
||||
- Fix for Dissolve (#3502)
|
||||
- Effect: Fix for Dissolve (#3502)
|
||||
- Better reverse proxy support (nested paths)
|
||||
- Implement global JSON API boolean toggle (i.e. instead of "var":true or "var":false -> "var":"t").
|
||||
- Sort presets by ID
|
||||
- Fix #3496
|
||||
- Fix for #3641, #3312, #3367, #3637, #3646, #3447, #3632, #3496, #2922, #3593, #3514, #3522, #3578 (partial), #3606 (@WoodyLetsCode)
|
||||
- Improved random bg image and added random bg image options (@WoodyLetsCode, #3481)
|
||||
- Audio palettes (Audioreactive usermod, credit @netmindz)
|
||||
- Better UI tooltips (@ajotnac, #3464)
|
||||
- Better effect filters (filter dropdown)
|
||||
- Fix udp sync (fix for #3487)
|
||||
- UDP sync fix (for #3487)
|
||||
- Power button override (solves #3431)
|
||||
- Additional HTTP request throttling (ESP8266)
|
||||
- Additional UI/UX improvements
|
||||
|
3
pio-scripts/build_ui.py
Normal file
3
pio-scripts/build_ui.py
Normal file
@ -0,0 +1,3 @@
|
||||
Import('env')
|
||||
|
||||
env.Execute("npm run build")
|
@ -137,6 +137,7 @@ build_flags =
|
||||
; -D USERMOD_SENSORSTOMQTT
|
||||
#For ADS1115 sensor uncomment following
|
||||
; -D USERMOD_ADS1115
|
||||
; -D USERMOD_ANIMARTRIX
|
||||
|
||||
build_unflags =
|
||||
|
||||
@ -155,6 +156,7 @@ extra_scripts =
|
||||
post:pio-scripts/output_bins.py
|
||||
post:pio-scripts/strip-floats.py
|
||||
pre:pio-scripts/user_config_copy.py
|
||||
pre:pio-scripts/build_ui.py
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# COMMON SETTINGS:
|
||||
@ -198,6 +200,11 @@ lib_deps =
|
||||
#For ADS1115 sensor uncomment following
|
||||
; adafruit/Adafruit BusIO @ 1.13.2
|
||||
; adafruit/Adafruit ADS1X15 @ 2.4.0
|
||||
#For MPU6050 IMU uncomment follwoing
|
||||
; electroniccats/MPU6050 @1.0.1
|
||||
# For -D USERMOD_ANIMARTRIX
|
||||
# CC BY-NC 3.0 licensed effects by Stefan Petrick, include this usermod only if you accept the terms!
|
||||
; https://github.com/netmindz/animartrix.git#18bf17389e57c69f11bc8d04ebe1d215422c7fb7
|
||||
|
||||
extra_scripts = ${scripts_defaults.extra_scripts}
|
||||
|
||||
|
@ -16,12 +16,15 @@
|
||||
*/
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require('path');
|
||||
const inliner = require("inliner");
|
||||
const zlib = require("zlib");
|
||||
const CleanCSS = require("clean-css");
|
||||
const MinifyHTML = require("html-minifier-terser").minify;
|
||||
const packageJson = require("../package.json");
|
||||
|
||||
const output = ["wled00/html_ui.h", "wled00/html_pixart.h", "wled00/html_cpal.h", "wled00/html_pxmagic.h", "wled00/html_settings.h", "wled00/html_other.h"]
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -182,7 +185,7 @@ ${result}
|
||||
const result = hexdump(buf);
|
||||
const chunk = `
|
||||
// Autogenerated from ${srcDir}/${s.file}, do not edit!!
|
||||
const uint16_t ${s.name}_length = ${result.length};
|
||||
const uint16_t ${s.name}_length = ${buf.length};
|
||||
const uint8_t ${s.name}[] PROGMEM = {
|
||||
${result}
|
||||
};
|
||||
@ -204,12 +207,13 @@ function writeChunks(srcDir, specs, resultFile) {
|
||||
*/
|
||||
`;
|
||||
specs.forEach((s) => {
|
||||
const file = srcDir + "/" + s.file;
|
||||
try {
|
||||
console.info("Reading " + srcDir + "/" + s.file + " as " + s.name);
|
||||
console.info("Reading " + file + " as " + s.name);
|
||||
src += specToChunk(srcDir, s);
|
||||
} catch (e) {
|
||||
console.warn(
|
||||
"Failed " + s.name + " from " + srcDir + "/" + s.file,
|
||||
"Failed " + s.name + " from " + file,
|
||||
e.message.length > 60 ? e.message.substring(0, 60) : e.message
|
||||
);
|
||||
}
|
||||
@ -218,37 +222,57 @@ function writeChunks(srcDir, specs, resultFile) {
|
||||
fs.writeFileSync(resultFile, src);
|
||||
}
|
||||
|
||||
// Check if a file is newer than a given time
|
||||
function isFileNewerThan(filePath, time) {
|
||||
try {
|
||||
const stats = fs.statSync(filePath);
|
||||
return stats.mtimeMs > time;
|
||||
} catch (e) {
|
||||
console.error(`Failed to get stats for file ${filePath}:`, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if any file in a folder (or its subfolders) is newer than a given time
|
||||
function isAnyFileInFolderNewerThan(folderPath, time) {
|
||||
const files = fs.readdirSync(folderPath, { withFileTypes: true });
|
||||
for (const file of files) {
|
||||
const filePath = path.join(folderPath, file.name);
|
||||
if (isFileNewerThan(filePath, time)) {
|
||||
return true;
|
||||
}
|
||||
if (file.isDirectory() && isAnyFileInFolderNewerThan(filePath, time)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isAlreadyBuilt(folderPath) {
|
||||
let lastBuildTime = Infinity;
|
||||
|
||||
for (const file of output) {
|
||||
try {
|
||||
lastBuildTime = Math.min(lastBuildTime, fs.statSync(file).mtimeMs);
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return !isAnyFileInFolderNewerThan(folderPath, lastBuildTime);
|
||||
}
|
||||
|
||||
if (isAlreadyBuilt("wled00/data") && process.argv[2] !== '--force' && process.argv[2] !== '-f') {
|
||||
console.info("Web UI is already built");
|
||||
return;
|
||||
}
|
||||
|
||||
writeHtmlGzipped("wled00/data/index.htm", "wled00/html_ui.h", 'index');
|
||||
writeHtmlGzipped("wled00/data/simple.htm", "wled00/html_simple.h", 'simple');
|
||||
writeHtmlGzipped("wled00/data/pixart/pixart.htm", "wled00/html_pixart.h", 'pixart');
|
||||
writeHtmlGzipped("wled00/data/cpal/cpal.htm", "wled00/html_cpal.h", 'cpal');
|
||||
writeHtmlGzipped("wled00/data/pxmagic/pxmagic.htm", "wled00/html_pxmagic.h", 'pxmagic');
|
||||
/*
|
||||
writeChunks(
|
||||
"wled00/data",
|
||||
[
|
||||
{
|
||||
file: "simple.css",
|
||||
name: "PAGE_simpleCss",
|
||||
method: "gzip",
|
||||
filter: "css-minify",
|
||||
},
|
||||
{
|
||||
file: "simple.js",
|
||||
name: "PAGE_simpleJs",
|
||||
method: "gzip",
|
||||
filter: "js-minify",
|
||||
},
|
||||
{
|
||||
file: "simple.htm",
|
||||
name: "PAGE_simple",
|
||||
method: "gzip",
|
||||
filter: "html-minify-ui",
|
||||
}
|
||||
],
|
||||
"wled00/html_simplex.h"
|
||||
);
|
||||
*/
|
||||
|
||||
writeChunks(
|
||||
"wled00/data",
|
||||
[
|
||||
@ -406,16 +430,6 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()=====";
|
||||
file: "favicon.ico",
|
||||
name: "favicon",
|
||||
method: "binary",
|
||||
},
|
||||
{
|
||||
file: "iro.js",
|
||||
name: "iroJs",
|
||||
method: "gzip"
|
||||
},
|
||||
{
|
||||
file: "rangetouch.js",
|
||||
name: "rangetouchJs",
|
||||
method: "gzip"
|
||||
}
|
||||
],
|
||||
"wled00/html_other.h"
|
||||
|
@ -87,7 +87,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* readFromConfig() is called prior to setup()
|
||||
* You can use it to initialize variables, sensors or similar.
|
||||
*/
|
||||
void setup() {
|
||||
void setup() override {
|
||||
// do your set-up here
|
||||
//Serial.println("Hello from my usermod!");
|
||||
initDone = true;
|
||||
@ -98,7 +98,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
* Use it to initialize network interfaces
|
||||
*/
|
||||
void connected() {
|
||||
void connected() override {
|
||||
//Serial.println("Connected to WiFi!");
|
||||
}
|
||||
|
||||
@ -113,7 +113,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
|
||||
* Instead, use a timer check as shown here.
|
||||
*/
|
||||
void loop() {
|
||||
void loop() override {
|
||||
// if usermod is disabled or called during strip updating just exit
|
||||
// NOTE: on very long strips strip.isUpdating() may always return true so update accordingly
|
||||
if (!enabled || strip.isUpdating()) return;
|
||||
@ -131,7 +131,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
*/
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
void addToJsonInfo(JsonObject& root) override
|
||||
{
|
||||
// if "u" object does not exist yet wee need to create it
|
||||
JsonObject user = root["u"];
|
||||
@ -156,7 +156,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void addToJsonState(JsonObject& root)
|
||||
void addToJsonState(JsonObject& root) override
|
||||
{
|
||||
if (!initDone || !enabled) return; // prevent crash on boot applyPreset()
|
||||
|
||||
@ -171,7 +171,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject& root)
|
||||
void readFromJsonState(JsonObject& root) override
|
||||
{
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
|
||||
@ -220,7 +220,7 @@ class MyExampleUsermod : public Usermod {
|
||||
*
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root)
|
||||
void addToConfig(JsonObject& root) override
|
||||
{
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
@ -253,7 +253,7 @@ class MyExampleUsermod : public Usermod {
|
||||
*
|
||||
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root)
|
||||
bool readFromConfig(JsonObject& root) override
|
||||
{
|
||||
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
|
||||
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
|
||||
@ -285,7 +285,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* it may add additional metadata for certain entry fields (adding drop down is possible)
|
||||
* be careful not to add too much as oappend() buffer is limited to 3k
|
||||
*/
|
||||
void appendConfigData()
|
||||
void appendConfigData() override
|
||||
{
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":great")); oappend(SET_F("',1,'<i>(this is a great config value)</i>');"));
|
||||
oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":testString")); oappend(SET_F("',1,'enter any string you want');"));
|
||||
@ -300,7 +300,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* Use this to blank out some LEDs or set them to a different color regardless of the set effect mode.
|
||||
* Commonly used for custom clocks (Cronixie, 7 segment)
|
||||
*/
|
||||
void handleOverlayDraw()
|
||||
void handleOverlayDraw() override
|
||||
{
|
||||
//strip.setPixelColor(0, RGBW32(0,0,0,0)) // set the first pixel to black
|
||||
}
|
||||
@ -311,7 +311,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* will prevent button working in a default way.
|
||||
* Replicating button.cpp
|
||||
*/
|
||||
bool handleButton(uint8_t b) {
|
||||
bool handleButton(uint8_t b) override {
|
||||
yield();
|
||||
// ignore certain button types as they may have other consequences
|
||||
if (!enabled
|
||||
@ -334,7 +334,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* handling of MQTT message
|
||||
* topic only contains stripped topic (part after /wled/MAC)
|
||||
*/
|
||||
bool onMqttMessage(char* topic, char* payload) {
|
||||
bool onMqttMessage(char* topic, char* payload) override {
|
||||
// check if we received a command
|
||||
//if (strlen(topic) == 8 && strncmp_P(topic, PSTR("/command"), 8) == 0) {
|
||||
// String action = payload;
|
||||
@ -355,7 +355,7 @@ class MyExampleUsermod : public Usermod {
|
||||
/**
|
||||
* onMqttConnect() is called when MQTT connection is established
|
||||
*/
|
||||
void onMqttConnect(bool sessionPresent) {
|
||||
void onMqttConnect(bool sessionPresent) override {
|
||||
// do any MQTT related initialisation here
|
||||
//publishMqtt("I am alive!");
|
||||
}
|
||||
@ -366,7 +366,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* onStateChanged() is used to detect WLED state change
|
||||
* @mode parameter is CALL_MODE_... parameter used for notifications
|
||||
*/
|
||||
void onStateChange(uint8_t mode) {
|
||||
void onStateChange(uint8_t mode) override {
|
||||
// do something if WLED state changed (color, brightness, effect, preset, etc)
|
||||
}
|
||||
|
||||
@ -375,7 +375,7 @@ class MyExampleUsermod : public Usermod {
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId()
|
||||
uint16_t getId() override
|
||||
{
|
||||
return USERMOD_ID_EXAMPLE;
|
||||
}
|
||||
|
@ -50,8 +50,7 @@ private:
|
||||
|
||||
volatile unsigned long offTimerStart = 0; // off timer start time
|
||||
volatile bool PIRtriggered = false; // did PIR trigger?
|
||||
byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // notification mode for stateUpdated(): CALL_MODE_NO_NOTIFY or CALL_MODE_DIRECT_CHANGE
|
||||
byte sensorPinState = LOW; // current PIR sensor pin state
|
||||
bool sensorPinState = LOW; // current PIR sensor pin state
|
||||
bool initDone = false; // status of initialization
|
||||
unsigned long lastLoop = 0;
|
||||
|
||||
@ -82,7 +81,6 @@ private:
|
||||
static const char _mqttOnly[];
|
||||
static const char _offOnly[];
|
||||
static const char _haDiscovery[];
|
||||
static const char _notify[];
|
||||
static const char _override[];
|
||||
static const char _domoticzIDX[];
|
||||
|
||||
@ -96,7 +94,7 @@ private:
|
||||
* switch strip on/off
|
||||
*/
|
||||
void switchStrip(bool switchOn);
|
||||
void publishMqtt(const char* state);
|
||||
void publishMqtt(bool switchOn);
|
||||
|
||||
// Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
|
||||
void publishHomeAssistantAutodiscovery();
|
||||
@ -119,7 +117,7 @@ public:
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
* You can use it to initialize variables, sensors or similar.
|
||||
*/
|
||||
void setup();
|
||||
void setup() override;
|
||||
|
||||
/**
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
@ -130,24 +128,24 @@ public:
|
||||
/**
|
||||
* onMqttConnect() is called when MQTT connection is established
|
||||
*/
|
||||
void onMqttConnect(bool sessionPresent);
|
||||
void onMqttConnect(bool sessionPresent) override;
|
||||
|
||||
/**
|
||||
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||
*/
|
||||
void loop();
|
||||
void loop() override;
|
||||
|
||||
/**
|
||||
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||
*
|
||||
* Add PIR sensor state and switch off timer duration to jsoninfo
|
||||
*/
|
||||
void addToJsonInfo(JsonObject &root);
|
||||
void addToJsonInfo(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* onStateChanged() is used to detect WLED state change
|
||||
*/
|
||||
void onStateChange(uint8_t mode);
|
||||
void onStateChange(uint8_t mode) override;
|
||||
|
||||
/**
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
@ -159,17 +157,17 @@ public:
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject &root);
|
||||
void readFromJsonState(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* provide the changeable values
|
||||
*/
|
||||
void addToConfig(JsonObject &root);
|
||||
void addToConfig(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* provide UI information and allow extending UI options
|
||||
*/
|
||||
void appendConfigData();
|
||||
void appendConfigData() override;
|
||||
|
||||
/**
|
||||
* restore the changeable values
|
||||
@ -177,13 +175,13 @@ public:
|
||||
*
|
||||
* The function should return true if configuration was successfully loaded or false if there was no configuration.
|
||||
*/
|
||||
bool readFromConfig(JsonObject &root);
|
||||
bool readFromConfig(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId() { return USERMOD_ID_PIRSWITCH; }
|
||||
uint16_t getId() override { return USERMOD_ID_PIRSWITCH; }
|
||||
};
|
||||
|
||||
// strings to reduce flash memory usage (used more than twice)
|
||||
@ -196,7 +194,6 @@ const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only";
|
||||
const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only";
|
||||
const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only";
|
||||
const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery";
|
||||
const char PIRsensorSwitch::_notify[] PROGMEM = "notifications";
|
||||
const char PIRsensorSwitch::_override[] PROGMEM = "override";
|
||||
const char PIRsensorSwitch::_domoticzIDX[] PROGMEM = "domoticz-idx";
|
||||
|
||||
@ -238,24 +235,24 @@ void PIRsensorSwitch::switchStrip(bool switchOn)
|
||||
prevPlaylist = 0;
|
||||
prevPreset = 255;
|
||||
}
|
||||
applyPreset(m_onPreset, NotifyUpdateMode);
|
||||
applyPreset(m_onPreset, CALL_MODE_BUTTON_PRESET);
|
||||
return;
|
||||
}
|
||||
// preset not assigned
|
||||
if (bri == 0) {
|
||||
bri = briLast;
|
||||
stateUpdated(NotifyUpdateMode);
|
||||
stateUpdated(CALL_MODE_BUTTON);
|
||||
}
|
||||
} else {
|
||||
if (m_offPreset) {
|
||||
applyPreset(m_offPreset, NotifyUpdateMode);
|
||||
applyPreset(m_offPreset, CALL_MODE_BUTTON_PRESET);
|
||||
return;
|
||||
} else if (prevPlaylist) {
|
||||
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, NotifyUpdateMode);
|
||||
if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, CALL_MODE_BUTTON_PRESET);
|
||||
prevPlaylist = 0;
|
||||
return;
|
||||
} else if (prevPreset) {
|
||||
if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, NotifyUpdateMode); }
|
||||
if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, CALL_MODE_BUTTON_PRESET); }
|
||||
else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); }
|
||||
prevPreset = 0;
|
||||
return;
|
||||
@ -264,28 +261,27 @@ void PIRsensorSwitch::switchStrip(bool switchOn)
|
||||
if (bri != 0) {
|
||||
briLast = bri;
|
||||
bri = 0;
|
||||
stateUpdated(NotifyUpdateMode);
|
||||
stateUpdated(CALL_MODE_BUTTON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PIRsensorSwitch::publishMqtt(const char* state)
|
||||
void PIRsensorSwitch::publishMqtt(bool switchOn)
|
||||
{
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||
if (WLED_MQTT_CONNECTED) {
|
||||
char buf[128];
|
||||
sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40
|
||||
mqtt->publish(buf, 0, false, state);
|
||||
mqtt->publish(buf, 0, false, switchOn?"on":"off");
|
||||
// Domoticz formatted message
|
||||
if (idx > 0) {
|
||||
StaticJsonDocument <128> msg;
|
||||
msg[F("idx")] = idx;
|
||||
msg[F("RSSI")] = WiFi.RSSI();
|
||||
msg[F("command")] = F("switchlight");
|
||||
strcpy(buf, state); buf[0] = toupper(buf[0]);
|
||||
msg[F("switchcmd")] = (const char *)buf;
|
||||
serializeJson(msg, buf, 127);
|
||||
msg[F("switchcmd")] = switchOn ? F("On") : F("Off");
|
||||
serializeJson(msg, buf, 128);
|
||||
mqtt->publish("domoticz/in", 0, false, buf);
|
||||
}
|
||||
}
|
||||
@ -336,13 +332,11 @@ bool PIRsensorSwitch::updatePIRsensorState()
|
||||
if (sensorPinState == HIGH) {
|
||||
offTimerStart = 0;
|
||||
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true);
|
||||
else if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND);
|
||||
publishMqtt("on");
|
||||
} else {
|
||||
// start switch off timer
|
||||
offTimerStart = millis();
|
||||
if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND);
|
||||
}
|
||||
publishMqtt(sensorPinState == HIGH);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -352,11 +346,7 @@ bool PIRsensorSwitch::handleOffTimer()
|
||||
{
|
||||
if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) {
|
||||
offTimerStart = 0;
|
||||
if (enabled == true) {
|
||||
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false);
|
||||
else if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND);
|
||||
publishMqtt("off");
|
||||
}
|
||||
if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -497,14 +487,12 @@ void PIRsensorSwitch::addToConfig(JsonObject &root)
|
||||
top[FPSTR(_override)] = m_override;
|
||||
top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery;
|
||||
top[FPSTR(_domoticzIDX)] = idx;
|
||||
top[FPSTR(_notify)] = (NotifyUpdateMode != CALL_MODE_NO_NOTIFY);
|
||||
DEBUG_PRINTLN(F("PIR config saved."));
|
||||
}
|
||||
|
||||
void PIRsensorSwitch::appendConfigData()
|
||||
{
|
||||
oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('PIRsensorSwitch:notifications',1,'Periodic WS updates');")); // 0 is field type, 1 is actual field
|
||||
oappend(SET_F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
@ -538,8 +526,6 @@ bool PIRsensorSwitch::readFromConfig(JsonObject &root)
|
||||
HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery;
|
||||
idx = top[FPSTR(_domoticzIDX)] | idx;
|
||||
|
||||
NotifyUpdateMode = top[FPSTR(_notify)] ? CALL_MODE_DIRECT_CHANGE : CALL_MODE_NO_NOTIFY;
|
||||
|
||||
if (!initDone) {
|
||||
// reading config prior to setup()
|
||||
DEBUG_PRINTLN(F(" config loaded."));
|
||||
|
@ -188,7 +188,7 @@ class PWMFanUsermod : public Usermod {
|
||||
|
||||
// gets called once at boot. Do all initialization that doesn't depend on
|
||||
// network here
|
||||
void setup() {
|
||||
void setup() override {
|
||||
#ifdef USERMOD_DALLASTEMPERATURE
|
||||
// This Usermod requires Temperature usermod
|
||||
tempUM = (UsermodTemperature*) usermods.lookup(USERMOD_ID_TEMPERATURE);
|
||||
@ -203,12 +203,12 @@ class PWMFanUsermod : public Usermod {
|
||||
|
||||
// gets called every time WiFi is (re-)connected. Initialize own network
|
||||
// interfaces here
|
||||
void connected() {}
|
||||
void connected() override {}
|
||||
|
||||
/*
|
||||
* Da loop.
|
||||
*/
|
||||
void loop() {
|
||||
void loop() override {
|
||||
if (!enabled || strip.isUpdating()) return;
|
||||
|
||||
unsigned long now = millis();
|
||||
@ -223,7 +223,7 @@ class PWMFanUsermod : public Usermod {
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
*/
|
||||
void addToJsonInfo(JsonObject& root) {
|
||||
void addToJsonInfo(JsonObject& root) override {
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
@ -272,7 +272,7 @@ class PWMFanUsermod : public Usermod {
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject& root) {
|
||||
void readFromJsonState(JsonObject& root) override {
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
JsonObject usermod = root[FPSTR(_name)];
|
||||
if (!usermod.isNull()) {
|
||||
@ -305,7 +305,7 @@ class PWMFanUsermod : public Usermod {
|
||||
*
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root) {
|
||||
void addToConfig(JsonObject& root) override {
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
top[FPSTR(_pwmPin)] = pwmPin;
|
||||
@ -328,7 +328,7 @@ class PWMFanUsermod : public Usermod {
|
||||
*
|
||||
* The function should return true if configuration was successfully loaded or false if there was no configuration.
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root) {
|
||||
bool readFromConfig(JsonObject& root) override {
|
||||
int8_t newTachoPin = tachoPin;
|
||||
int8_t newPwmPin = pwmPin;
|
||||
|
||||
@ -380,7 +380,7 @@ class PWMFanUsermod : public Usermod {
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId() {
|
||||
uint16_t getId() override {
|
||||
return USERMOD_ID_PWM_FAN;
|
||||
}
|
||||
};
|
||||
|
@ -132,7 +132,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
* You can use it to initialize variables, sensors or similar.
|
||||
*/
|
||||
void setup()
|
||||
void setup() override
|
||||
{
|
||||
PinManagerPinType spiPins[] = { { spi_mosi, true }, { spi_miso, false}, { spi_sclk, true } };
|
||||
if (!pinManager.allocateMultiplePins(spiPins, 3, PinOwner::HW_SPI)) { enabled = false; return; }
|
||||
@ -162,7 +162,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
* Use it to initialize network interfaces
|
||||
*/
|
||||
void connected() {
|
||||
void connected() override {
|
||||
//Serial.println("Connected to WiFi!");
|
||||
}
|
||||
|
||||
@ -176,7 +176,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
|
||||
* Instead, use a timer check as shown here.
|
||||
*/
|
||||
void loop() {
|
||||
void loop() override {
|
||||
char buff[LINE_BUFFER_SIZE];
|
||||
|
||||
// Check if we time interval for redrawing passes.
|
||||
@ -307,7 +307,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
// Print estimated milliamp usage (must specify the LED type in LED prefs for this to be a reasonable estimate).
|
||||
tft.print("Current: ");
|
||||
tft.setTextColor(TFT_ORANGE);
|
||||
tft.print(strip.currentMilliamps);
|
||||
tft.print(BusManager::currentMilliamps());
|
||||
tft.print("mA");
|
||||
}
|
||||
|
||||
@ -316,7 +316,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
*/
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
void addToJsonInfo(JsonObject& root) override
|
||||
{
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
@ -330,7 +330,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void addToJsonState(JsonObject& root)
|
||||
void addToJsonState(JsonObject& root) override
|
||||
{
|
||||
//root["user0"] = userVar0;
|
||||
}
|
||||
@ -340,7 +340,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject& root)
|
||||
void readFromJsonState(JsonObject& root) override
|
||||
{
|
||||
//userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value
|
||||
//if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!"));
|
||||
@ -361,7 +361,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
*
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root)
|
||||
void addToConfig(JsonObject& root) override
|
||||
{
|
||||
JsonObject top = root.createNestedObject("ST7789");
|
||||
JsonArray pins = top.createNestedArray("pin");
|
||||
@ -373,7 +373,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
}
|
||||
|
||||
|
||||
void appendConfigData() {
|
||||
void appendConfigData() override {
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',0,'','SPI CS');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',1,'','SPI DC');"));
|
||||
oappend(SET_F("addInfo('ST7789:pin[]',2,'','SPI RST');"));
|
||||
@ -388,7 +388,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root)
|
||||
bool readFromConfig(JsonObject& root) override
|
||||
{
|
||||
//JsonObject top = root["top"];
|
||||
//userVar0 = top["great"] | 42; //The value right of the pipe "|" is the default value in case your setting was not present in cfg.json (e.g. first boot)
|
||||
@ -400,7 +400,7 @@ class St7789DisplayUsermod : public Usermod {
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId()
|
||||
uint16_t getId() override
|
||||
{
|
||||
return USERMOD_ID_ST7789_DISPLAY;
|
||||
}
|
||||
|
@ -76,26 +76,26 @@ class UsermodTemperature : public Usermod {
|
||||
inline float getTemperatureF() { return temperature * 1.8f + 32.0f; }
|
||||
float getTemperature();
|
||||
const char *getTemperatureUnit();
|
||||
uint16_t getId() { return USERMOD_ID_TEMPERATURE; }
|
||||
uint16_t getId() override { return USERMOD_ID_TEMPERATURE; }
|
||||
|
||||
void setup();
|
||||
void loop();
|
||||
//void connected();
|
||||
void setup() override;
|
||||
void loop() override;
|
||||
//void connected() override;
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
void onMqttConnect(bool sessionPresent);
|
||||
void onMqttConnect(bool sessionPresent) override;
|
||||
#endif
|
||||
//void onUpdateBegin(bool init);
|
||||
//void onUpdateBegin(bool init) override;
|
||||
|
||||
//bool handleButton(uint8_t b);
|
||||
//void handleOverlayDraw();
|
||||
//bool handleButton(uint8_t b) override;
|
||||
//void handleOverlayDraw() override;
|
||||
|
||||
void addToJsonInfo(JsonObject& root);
|
||||
//void addToJsonState(JsonObject &root);
|
||||
//void readFromJsonState(JsonObject &root);
|
||||
void addToConfig(JsonObject &root);
|
||||
bool readFromConfig(JsonObject &root);
|
||||
void addToJsonInfo(JsonObject& root) override;
|
||||
//void addToJsonState(JsonObject &root) override;
|
||||
//void readFromJsonState(JsonObject &root) override;
|
||||
void addToConfig(JsonObject &root) override;
|
||||
bool readFromConfig(JsonObject &root) override;
|
||||
|
||||
void appendConfigData();
|
||||
void appendConfigData() override;
|
||||
};
|
||||
|
||||
//Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013
|
||||
@ -283,7 +283,6 @@ void UsermodTemperature::loop() {
|
||||
msg[F("nvalue")] = 0;
|
||||
msg[F("svalue")] = String(getTemperatureC());
|
||||
serializeJson(msg, subuf, 127);
|
||||
DEBUG_PRINTLN(subuf);
|
||||
mqtt->publish("domoticz/in", 0, false, subuf);
|
||||
}
|
||||
} else {
|
||||
|
@ -1094,7 +1094,7 @@ class AudioReactive : public Usermod {
|
||||
* You can use it to initialize variables, sensors or similar.
|
||||
* It is called *AFTER* readFromConfig()
|
||||
*/
|
||||
void setup()
|
||||
void setup() override
|
||||
{
|
||||
disableSoundProcessing = true; // just to be sure
|
||||
if (!initDone) {
|
||||
@ -1217,7 +1217,7 @@ class AudioReactive : public Usermod {
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
* Use it to initialize network interfaces
|
||||
*/
|
||||
void connected()
|
||||
void connected() override
|
||||
{
|
||||
if (udpSyncConnected) { // clean-up: if open, close old UDP sync connection
|
||||
udpSyncConnected = false;
|
||||
@ -1244,7 +1244,7 @@ class AudioReactive : public Usermod {
|
||||
* 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds.
|
||||
* Instead, use a timer check as shown here.
|
||||
*/
|
||||
void loop()
|
||||
void loop() override
|
||||
{
|
||||
static unsigned long lastUMRun = millis();
|
||||
|
||||
@ -1375,7 +1375,7 @@ class AudioReactive : public Usermod {
|
||||
}
|
||||
|
||||
|
||||
bool getUMData(um_data_t **data)
|
||||
bool getUMData(um_data_t **data) override
|
||||
{
|
||||
if (!data || !enabled) return false; // no pointer provided by caller or not enabled -> exit
|
||||
*data = um_data;
|
||||
@ -1383,7 +1383,7 @@ class AudioReactive : public Usermod {
|
||||
}
|
||||
|
||||
|
||||
void onUpdateBegin(bool init)
|
||||
void onUpdateBegin(bool init) override
|
||||
{
|
||||
#ifdef WLED_DEBUG
|
||||
fftTime = sampleTime = 0;
|
||||
@ -1438,7 +1438,7 @@ class AudioReactive : public Usermod {
|
||||
* handleButton() can be used to override default button behaviour. Returning true
|
||||
* will prevent button working in a default way.
|
||||
*/
|
||||
bool handleButton(uint8_t b) {
|
||||
bool handleButton(uint8_t b) override {
|
||||
yield();
|
||||
// crude way of determining if audio input is analog
|
||||
// better would be for AudioSource to implement getType()
|
||||
@ -1461,7 +1461,7 @@ class AudioReactive : public Usermod {
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
*/
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
void addToJsonInfo(JsonObject& root) override
|
||||
{
|
||||
char myStringBuffer[16]; // buffer for snprintf()
|
||||
JsonObject user = root["u"];
|
||||
@ -1600,7 +1600,7 @@ class AudioReactive : public Usermod {
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void addToJsonState(JsonObject& root)
|
||||
void addToJsonState(JsonObject& root) override
|
||||
{
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
JsonObject usermod = root[FPSTR(_name)];
|
||||
@ -1615,7 +1615,7 @@ class AudioReactive : public Usermod {
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject& root)
|
||||
void readFromJsonState(JsonObject& root) override
|
||||
{
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
bool prevEnabled = enabled;
|
||||
@ -1640,7 +1640,7 @@ class AudioReactive : public Usermod {
|
||||
}
|
||||
}
|
||||
|
||||
void onStateChange(uint8_t callMode) {
|
||||
void onStateChange(uint8_t callMode) override {
|
||||
if (initDone && enabled && addPalettes && palettes==0 && strip.customPalettes.size()<10) {
|
||||
// if palettes were removed during JSON call re-add them
|
||||
createAudioPalettes();
|
||||
@ -1682,7 +1682,7 @@ class AudioReactive : public Usermod {
|
||||
*
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root)
|
||||
void addToConfig(JsonObject& root) override
|
||||
{
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||
top[FPSTR(_enabled)] = enabled;
|
||||
@ -1735,7 +1735,7 @@ class AudioReactive : public Usermod {
|
||||
*
|
||||
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root)
|
||||
bool readFromConfig(JsonObject& root) override
|
||||
{
|
||||
JsonObject top = root[FPSTR(_name)];
|
||||
bool configComplete = !top.isNull();
|
||||
@ -1786,7 +1786,7 @@ class AudioReactive : public Usermod {
|
||||
}
|
||||
|
||||
|
||||
void appendConfigData()
|
||||
void appendConfigData() override
|
||||
{
|
||||
oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');"));
|
||||
#if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
@ -1841,7 +1841,7 @@ class AudioReactive : public Usermod {
|
||||
* Use this to blank out some LEDs or set them to a different color regardless of the set effect mode.
|
||||
* Commonly used for custom clocks (Cronixie, 7 segment)
|
||||
*/
|
||||
//void handleOverlayDraw()
|
||||
//void handleOverlayDraw() override
|
||||
//{
|
||||
//strip.setPixelColor(0, RGBW32(0,0,0,0)) // set the first pixel to black
|
||||
//}
|
||||
@ -1851,7 +1851,7 @@ class AudioReactive : public Usermod {
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId()
|
||||
uint16_t getId() override
|
||||
{
|
||||
return USERMOD_ID_AUDIOREACTIVE;
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ class BobLightUsermod : public Usermod {
|
||||
|
||||
public:
|
||||
|
||||
void setup() {
|
||||
void setup() override {
|
||||
uint16_t totalLights = bottom + left + top + right;
|
||||
if ( totalLights > strip.getLengthTotal() ) {
|
||||
DEBUG_PRINTLN(F("BobLight: Too many lights."));
|
||||
@ -202,14 +202,14 @@ class BobLightUsermod : public Usermod {
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
void connected() {
|
||||
void connected() override {
|
||||
// we can only start server when WiFi is connected
|
||||
if (!bob) bob = new WiFiServer(bobPort, 1);
|
||||
bob->begin();
|
||||
bob->setNoDelay(true);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
void loop() override {
|
||||
if (!enabled || strip.isUpdating()) return;
|
||||
if (millis() - lastTime > 10) {
|
||||
lastTime = millis();
|
||||
@ -225,7 +225,7 @@ class BobLightUsermod : public Usermod {
|
||||
* topic only contains stripped topic (part after /wled/MAC)
|
||||
* topic should look like: /swipe with amessage of [up|down]
|
||||
*/
|
||||
bool onMqttMessage(char* topic, char* payload) {
|
||||
bool onMqttMessage(char* topic, char* payload) override {
|
||||
//if (strlen(topic) == 6 && strncmp_P(topic, PSTR("/subtopic"), 6) == 0) {
|
||||
// String action = payload;
|
||||
// if (action == "on") {
|
||||
@ -242,7 +242,7 @@ class BobLightUsermod : public Usermod {
|
||||
/**
|
||||
* subscribe to MQTT topic for controlling usermod
|
||||
*/
|
||||
void onMqttConnect(bool sessionPresent) {
|
||||
void onMqttConnect(bool sessionPresent) override {
|
||||
//char subuf[64];
|
||||
//if (mqttDeviceTopic[0] != 0) {
|
||||
// strcpy(subuf, mqttDeviceTopic);
|
||||
@ -252,7 +252,7 @@ class BobLightUsermod : public Usermod {
|
||||
}
|
||||
#endif
|
||||
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
void addToJsonInfo(JsonObject& root) override
|
||||
{
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
@ -273,7 +273,7 @@ class BobLightUsermod : public Usermod {
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void addToJsonState(JsonObject& root)
|
||||
void addToJsonState(JsonObject& root) override
|
||||
{
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ class BobLightUsermod : public Usermod {
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject& root) {
|
||||
void readFromJsonState(JsonObject& root) override {
|
||||
if (!initDone) return; // prevent crash on boot applyPreset()
|
||||
bool en = enabled;
|
||||
JsonObject um = root[FPSTR(_name)];
|
||||
@ -304,7 +304,7 @@ class BobLightUsermod : public Usermod {
|
||||
}
|
||||
}
|
||||
|
||||
void appendConfigData() {
|
||||
void appendConfigData() override {
|
||||
//oappend(SET_F("dd=addDropdown('usermod','selectfield');"));
|
||||
//oappend(SET_F("addOption(dd,'1st value',0);"));
|
||||
//oappend(SET_F("addOption(dd,'2nd value',1);"));
|
||||
@ -315,7 +315,7 @@ class BobLightUsermod : public Usermod {
|
||||
oappend(SET_F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
void addToConfig(JsonObject& root) {
|
||||
void addToConfig(JsonObject& root) override {
|
||||
JsonObject umData = root.createNestedObject(FPSTR(_name));
|
||||
umData[FPSTR(_enabled)] = enabled;
|
||||
umData[F("port")] = bobPort;
|
||||
@ -326,7 +326,7 @@ class BobLightUsermod : public Usermod {
|
||||
umData[F("pct")] = pct;
|
||||
}
|
||||
|
||||
bool readFromConfig(JsonObject& root) {
|
||||
bool readFromConfig(JsonObject& root) override {
|
||||
JsonObject umData = root[FPSTR(_name)];
|
||||
bool configComplete = !umData.isNull();
|
||||
|
||||
@ -355,11 +355,11 @@ class BobLightUsermod : public Usermod {
|
||||
* Use this to blank out some LEDs or set them to a different color regardless of the set effect mode.
|
||||
* Commonly used for custom clocks (Cronixie, 7 segment)
|
||||
*/
|
||||
void handleOverlayDraw() {
|
||||
void handleOverlayDraw() override {
|
||||
//strip.setPixelColor(0, RGBW32(0,0,0,0)) // set the first pixel to black
|
||||
}
|
||||
|
||||
uint16_t getId() { return USERMOD_ID_BOBLIGHT; }
|
||||
uint16_t getId() override { return USERMOD_ID_BOBLIGHT; }
|
||||
|
||||
};
|
||||
|
||||
@ -445,7 +445,7 @@ void BobLightUsermod::pollBob() {
|
||||
//strip.setPixelColor(light_id, RGBW32(red, green, blue, 0));
|
||||
setRealtimePixel(light_id, red, green, blue, 0);
|
||||
} // currently no support for interpolation or speed, we just ignore this
|
||||
} else if (input.startsWith(F("sync"))) {
|
||||
} else if (input.startsWith("sync")) {
|
||||
BobSync();
|
||||
} else {
|
||||
// Client sent gibberish
|
||||
|
@ -20,14 +20,11 @@ react to the globes orientation. See the blog post on building it <https://www.r
|
||||
|
||||
I2Cdev and MPU6050 must be installed.
|
||||
|
||||
To install them, add I2Cdevlib-MPU6050@fbde122cc5 to lib_deps in the platformio.ini file.
|
||||
|
||||
You also need to change lib_compat_mode from strict to soft in platformio.ini (This ignores that I2Cdevlib-MPU6050 doesn't list platform compatibility)
|
||||
To install them, add electroniccats/MPU6050@1.0.1 to lib_deps in the platformio.ini file.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
lib_compat_mode = soft
|
||||
lib_deps =
|
||||
FastLED@3.3.2
|
||||
NeoPixelBus@2.5.7
|
||||
@ -36,7 +33,7 @@ lib_deps =
|
||||
AsyncTCP@1.0.3
|
||||
Esp Async WebServer@1.2.0
|
||||
IRremoteESP8266@2.7.3
|
||||
jrowberg/I2Cdevlib-MPU6050@^1.0.0
|
||||
electroniccats/MPU6050@1.0.1
|
||||
```
|
||||
|
||||
## Wiring
|
||||
|
219
usermods/mpu6050_imu/usermod_gyro_surge.h
Normal file
219
usermods/mpu6050_imu/usermod_gyro_surge.h
Normal file
@ -0,0 +1,219 @@
|
||||
#pragma once
|
||||
|
||||
/* This usermod uses gyro data to provide a "surge" effect on movement
|
||||
|
||||
Requires lib_deps = bolderflight/Bolder Flight Systems Eigen@^3.0.0
|
||||
|
||||
*/
|
||||
|
||||
#include "wled.h"
|
||||
|
||||
// Eigen include block
|
||||
#ifdef A0
|
||||
namespace { constexpr size_t A0_temp {A0}; }
|
||||
#undef A0
|
||||
static constexpr size_t A0 {A0_temp};
|
||||
#endif
|
||||
|
||||
#ifdef A1
|
||||
namespace { constexpr size_t A1_temp {A1}; }
|
||||
#undef A1
|
||||
static constexpr size_t A1 {A1_temp};
|
||||
#endif
|
||||
|
||||
#ifdef B0
|
||||
namespace { constexpr size_t B0_temp {B0}; }
|
||||
#undef B0
|
||||
static constexpr size_t B0 {B0_temp};
|
||||
#endif
|
||||
|
||||
#ifdef B1
|
||||
namespace { constexpr size_t B1_temp {B1}; }
|
||||
#undef B1
|
||||
static constexpr size_t B1 {B1_temp};
|
||||
#endif
|
||||
|
||||
#ifdef D0
|
||||
namespace { constexpr size_t D0_temp {D0}; }
|
||||
#undef D0
|
||||
static constexpr size_t D0 {D0_temp};
|
||||
#endif
|
||||
|
||||
#ifdef D1
|
||||
namespace { constexpr size_t D1_temp {D1}; }
|
||||
#undef D1
|
||||
static constexpr size_t D1 {D1_temp};
|
||||
#endif
|
||||
|
||||
#ifdef D2
|
||||
namespace { constexpr size_t D2_temp {D2}; }
|
||||
#undef D2
|
||||
static constexpr size_t D2 {D2_temp};
|
||||
#endif
|
||||
|
||||
#ifdef D3
|
||||
namespace { constexpr size_t D3_temp {D3}; }
|
||||
#undef D3
|
||||
static constexpr size_t D3 {D3_temp};
|
||||
#endif
|
||||
|
||||
#include "eigen.h"
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
constexpr auto ESTIMATED_G = 9.801; // m/s^2
|
||||
constexpr auto ESTIMATED_G_COUNTS = 8350.;
|
||||
constexpr auto ESTIMATED_ANGULAR_RATE = (M_PI * 2000) / (INT16_MAX * 180); // radians per second
|
||||
|
||||
// Horribly lame digital filter code
|
||||
// Currently implements a static IIR filter.
|
||||
template<typename T, unsigned C>
|
||||
class xir_filter {
|
||||
typedef Eigen::Array<T, C, 1> array_t;
|
||||
const array_t a_coeff, b_coeff;
|
||||
const T gain;
|
||||
array_t x, y;
|
||||
|
||||
public:
|
||||
xir_filter(T gain_, array_t a, array_t b) : a_coeff(std::move(a)), b_coeff(std::move(b)), gain(gain_), x(array_t::Zero()), y(array_t::Zero()) {};
|
||||
|
||||
T operator()(T input) {
|
||||
x.head(C-1) = x.tail(C-1); // shift by one
|
||||
x(C-1) = input / gain;
|
||||
y.head(C-1) = y.tail(C-1); // shift by one
|
||||
y(C-1) = (x * b_coeff).sum();
|
||||
y(C-1) -= (y.head(C-1) * a_coeff.head(C-1)).sum();
|
||||
return y(C-1);
|
||||
}
|
||||
|
||||
T last() { return y(C-1); };
|
||||
};
|
||||
|
||||
|
||||
|
||||
class GyroSurge : public Usermod {
|
||||
private:
|
||||
static const char _name[];
|
||||
bool enabled = true;
|
||||
|
||||
// Params
|
||||
uint8_t max = 0;
|
||||
float sensitivity = 0;
|
||||
|
||||
// State
|
||||
uint32_t last_sample;
|
||||
// 100hz input
|
||||
// butterworth low pass filter at 20hz
|
||||
xir_filter<float, 3> filter = { 1., { -0.36952738, 0.19581571, 1.}, {0.20657208, 0.41314417, 0.20657208} };
|
||||
// { 1., { 0., 0., 1.}, { 0., 0., 1. } }; // no filter
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
*/
|
||||
void setup() {};
|
||||
|
||||
|
||||
/*
|
||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root)
|
||||
{
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||
|
||||
//save these vars persistently whenever settings are saved
|
||||
top["max"] = max;
|
||||
top["sensitivity"] = sensitivity;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||
* This is called by WLED when settings are loaded (currently this only happens immediately after boot, or after saving on the Usermod Settings page)
|
||||
*
|
||||
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
|
||||
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||
*
|
||||
* Return true in case the config values returned from Usermod Settings were complete, or false if you'd like WLED to save your defaults to disk (so any missing values are editable in Usermod Settings)
|
||||
*
|
||||
* getJsonValue() returns false if the value is missing, or copies the value into the variable provided and returns true if the value is present
|
||||
* The configComplete variable is true only if the "exampleUsermod" object and all values are present. If any values are missing, WLED will know to call addToConfig() to save them
|
||||
*
|
||||
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root)
|
||||
{
|
||||
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
|
||||
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
|
||||
|
||||
JsonObject top = root[FPSTR(_name)];
|
||||
|
||||
bool configComplete = !top.isNull();
|
||||
|
||||
configComplete &= getJsonValue(top["max"], max, 0);
|
||||
configComplete &= getJsonValue(top["sensitivity"], sensitivity, 10);
|
||||
|
||||
return configComplete;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// get IMU data
|
||||
um_data_t *um_data;
|
||||
if (!usermods.getUMData(&um_data, USERMOD_ID_IMU)) {
|
||||
// Apply max
|
||||
strip.getSegment(0).fadeToBlackBy(max);
|
||||
return;
|
||||
}
|
||||
uint32_t sample_count = *(uint32_t*)(um_data->u_data[8]);
|
||||
|
||||
if (sample_count != last_sample) {
|
||||
last_sample = sample_count;
|
||||
// Calculate based on new data
|
||||
// We use the raw gyro data (angular rate)
|
||||
auto gyros = (int16_t*)um_data->u_data[4]; // 16384 == 2000 deg/s
|
||||
|
||||
// Compute the overall rotation rate
|
||||
// For my application (a plasma sword) we ignore X axis rotations (eg. around the long axis)
|
||||
auto gyro_q = Eigen::AngleAxis<float> {
|
||||
//Eigen::AngleAxis<float>(ESTIMATED_ANGULAR_RATE * gyros[0], Eigen::Vector3f::UnitX()) *
|
||||
Eigen::AngleAxis<float>(ESTIMATED_ANGULAR_RATE * gyros[1], Eigen::Vector3f::UnitY()) *
|
||||
Eigen::AngleAxis<float>(ESTIMATED_ANGULAR_RATE * gyros[2], Eigen::Vector3f::UnitZ()) };
|
||||
|
||||
// Filter the results
|
||||
filter(std::min(sensitivity * gyro_q.angle(), 1.0f)); // radians per second
|
||||
/*
|
||||
Serial.printf("[%lu] Gy: %d, %d, %d -- ", millis(), (int)gyros[0], (int)gyros[1], (int)gyros[2]);
|
||||
Serial.print(gyro_q.angle());
|
||||
Serial.print(", ");
|
||||
Serial.print(sensitivity * gyro_q.angle());
|
||||
Serial.print(" --> ");
|
||||
Serial.println(filter.last());
|
||||
*/
|
||||
}
|
||||
}; // noop
|
||||
|
||||
/*
|
||||
* handleOverlayDraw() is called just before every show() (LED strip update frame) after effects have set the colors.
|
||||
* Use this to blank out some LEDs or set them to a different color regardless of the set effect mode.
|
||||
* Commonly used for custom clocks (Cronixie, 7 segment)
|
||||
*/
|
||||
void handleOverlayDraw()
|
||||
{
|
||||
|
||||
// TODO: some kind of timing analysis for filtering ...
|
||||
|
||||
// Calculate brightness boost
|
||||
auto r_float = std::max(std::min(filter.last(), 1.0f), 0.f);
|
||||
auto result = (uint8_t) (r_float * max);
|
||||
//Serial.printf("[%lu] %d -- ", millis(), result);
|
||||
//Serial.println(r_float);
|
||||
// TODO - multiple segment handling??
|
||||
strip.getSegment(0).fadeToBlackBy(max - result);
|
||||
}
|
||||
};
|
||||
|
||||
const char GyroSurge::_name[] PROGMEM = "GyroSurge";
|
@ -20,11 +20,11 @@
|
||||
XCL not connected
|
||||
AD0 not connected
|
||||
INT D8 (GPIO15) Interrupt pin
|
||||
|
||||
|
||||
Using usermod:
|
||||
1. Copy the usermod into the sketch folder (same folder as wled00.ino)
|
||||
2. Register the usermod by adding #include "usermod_filename.h" in the top and registerUsermod(new MyUsermodClass()) in the bottom of usermods_list.cpp
|
||||
3. I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h file
|
||||
3. I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h file
|
||||
for both classes must be in the include path of your project. To install the
|
||||
libraries add I2Cdevlib-MPU6050@fbde122cc5 to lib_deps in the platformio.ini file.
|
||||
4. You also need to change lib_compat_mode from strict to soft in platformio.ini (This ignores that I2Cdevlib-MPU6050 doesn't list platform compatibility)
|
||||
@ -33,6 +33,9 @@
|
||||
|
||||
#include "I2Cdev.h"
|
||||
|
||||
#undef DEBUG_PRINT
|
||||
#undef DEBUG_PRINTLN
|
||||
#undef DEBUG_PRINTF
|
||||
#include "MPU6050_6Axis_MotionApps20.h"
|
||||
//#include "MPU6050.h" // not necessary if using MotionApps include file
|
||||
|
||||
@ -42,6 +45,23 @@
|
||||
#include "Wire.h"
|
||||
#endif
|
||||
|
||||
// Restore debug macros
|
||||
// MPU6050 unfortunately uses the same macro names as WLED :(
|
||||
#undef DEBUG_PRINT
|
||||
#undef DEBUG_PRINTLN
|
||||
#undef DEBUG_PRINTF
|
||||
#ifdef WLED_DEBUG
|
||||
#define DEBUG_PRINT(x) DEBUGOUT.print(x)
|
||||
#define DEBUG_PRINTLN(x) DEBUGOUT.println(x)
|
||||
#define DEBUG_PRINTF(x...) DEBUGOUT.printf(x)
|
||||
#else
|
||||
#define DEBUG_PRINT(x)
|
||||
#define DEBUG_PRINTLN(x)
|
||||
#define DEBUG_PRINTF(x...)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ================================================================
|
||||
// === INTERRUPT DETECTION ROUTINE ===
|
||||
// ================================================================
|
||||
@ -52,21 +72,31 @@ void IRAM_ATTR dmpDataReady() {
|
||||
}
|
||||
|
||||
|
||||
|
||||
class MPU6050Driver : public Usermod {
|
||||
private:
|
||||
MPU6050 mpu;
|
||||
bool enabled = true;
|
||||
|
||||
// configuration state
|
||||
// default values are set in readFromConfig
|
||||
// By making this a struct, we enable easy backup and comparison in the readFromConfig class
|
||||
struct config_t {
|
||||
bool enabled;
|
||||
int8_t interruptPin;
|
||||
int16_t gyro_offset[3];
|
||||
int16_t accel_offset[3];
|
||||
};
|
||||
config_t config;
|
||||
|
||||
// MPU control/status vars
|
||||
bool irqBound = false; // set true if we have bound the IRQ pin
|
||||
bool dmpReady = false; // set true if DMP init was successful
|
||||
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
|
||||
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
|
||||
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
|
||||
uint16_t fifoCount; // count of all bytes currently in FIFO
|
||||
uint8_t fifoBuffer[64]; // FIFO storage buffer
|
||||
|
||||
//NOTE: some of these can be removed to save memory, processing time
|
||||
// if the measurement isn't needed
|
||||
// TODO: some of these can be removed to save memory, processing time if the measurement isn't needed
|
||||
Quaternion qat; // [w, x, y, z] quaternion container
|
||||
float euler[3]; // [psi, theta, phi] Euler angle container
|
||||
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container
|
||||
@ -75,17 +105,67 @@ class MPU6050Driver : public Usermod {
|
||||
VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements
|
||||
VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements
|
||||
VectorFloat gravity; // [x, y, z] gravity vector
|
||||
uint32 sample_count;
|
||||
|
||||
static const int INTERRUPT_PIN = 15; // use pin 15 on ESP8266
|
||||
// Usermod output
|
||||
um_data_t um_data;
|
||||
|
||||
// config element names as progmem strs
|
||||
static const char _name[];
|
||||
static const char _enabled[];
|
||||
static const char _interrupt_pin[];
|
||||
static const char _x_acc_bias[];
|
||||
static const char _y_acc_bias[];
|
||||
static const char _z_acc_bias[];
|
||||
static const char _x_gyro_bias[];
|
||||
static const char _y_gyro_bias[];
|
||||
static const char _z_gyro_bias[];
|
||||
|
||||
public:
|
||||
//Functions called by WLED
|
||||
|
||||
inline bool initDone() { return um_data.u_size != 0; }; // recycle this instead of storing an extra variable
|
||||
|
||||
//Functions called by WLED
|
||||
/*
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
*/
|
||||
void setup() {
|
||||
if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; }
|
||||
dmpReady = false; // Start clean
|
||||
|
||||
// one time init
|
||||
if (!initDone()) {
|
||||
um_data.u_size = 9;
|
||||
um_data.u_type = new um_types_t[um_data.u_size];
|
||||
um_data.u_data = new void*[um_data.u_size];
|
||||
um_data.u_data[0] = &qat;
|
||||
um_data.u_type[0] = UMT_FLOAT_ARR;
|
||||
um_data.u_data[1] = &euler;
|
||||
um_data.u_type[1] = UMT_FLOAT_ARR;
|
||||
um_data.u_data[2] = &ypr;
|
||||
um_data.u_type[2] = UMT_FLOAT_ARR;
|
||||
um_data.u_data[3] = &aa;
|
||||
um_data.u_type[3] = UMT_INT16_ARR;
|
||||
um_data.u_data[4] = &gy;
|
||||
um_data.u_type[4] = UMT_INT16_ARR;
|
||||
um_data.u_data[5] = &aaReal;
|
||||
um_data.u_type[5] = UMT_INT16_ARR;
|
||||
um_data.u_data[6] = &aaWorld;
|
||||
um_data.u_type[6] = UMT_INT16_ARR;
|
||||
um_data.u_data[7] = &gravity;
|
||||
um_data.u_type[7] = UMT_FLOAT_ARR;
|
||||
um_data.u_data[8] = &sample_count;
|
||||
um_data.u_type[8] = UMT_UINT32;
|
||||
}
|
||||
|
||||
if (!config.enabled) return;
|
||||
if (i2c_scl<0 || i2c_sda<0) { DEBUG_PRINTLN(F("MPU6050: I2C is no good.")); return; }
|
||||
// Check the interrupt pin
|
||||
if (config.interruptPin >= 0) {
|
||||
irqBound = pinManager.allocatePin(config.interruptPin, false, PinOwner::UM_IMU);
|
||||
if (!irqBound) { DEBUG_PRINTLN(F("MPU6050: IRQ pin already in use.")); return; }
|
||||
pinMode(config.interruptPin, INPUT);
|
||||
};
|
||||
|
||||
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
|
||||
Wire.setClock(400000U); // 400kHz I2C clock. Comment this line if having compilation difficulties
|
||||
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
|
||||
@ -95,7 +175,6 @@ class MPU6050Driver : public Usermod {
|
||||
// initialize device
|
||||
DEBUG_PRINTLN(F("Initializing I2C devices..."));
|
||||
mpu.initialize();
|
||||
pinMode(INTERRUPT_PIN, INPUT);
|
||||
|
||||
// verify connection
|
||||
DEBUG_PRINTLN(F("Testing device connections..."));
|
||||
@ -105,11 +184,16 @@ class MPU6050Driver : public Usermod {
|
||||
DEBUG_PRINTLN(F("Initializing DMP..."));
|
||||
devStatus = mpu.dmpInitialize();
|
||||
|
||||
// supply your own gyro offsets here, scaled for min sensitivity
|
||||
mpu.setXGyroOffset(220);
|
||||
mpu.setYGyroOffset(76);
|
||||
mpu.setZGyroOffset(-85);
|
||||
mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
|
||||
// set offsets (from config)
|
||||
mpu.setXGyroOffset(config.gyro_offset[0]);
|
||||
mpu.setYGyroOffset(config.gyro_offset[1]);
|
||||
mpu.setZGyroOffset(config.gyro_offset[2]);
|
||||
mpu.setXAccelOffset(config.accel_offset[0]);
|
||||
mpu.setYAccelOffset(config.accel_offset[1]);
|
||||
mpu.setZAccelOffset(config.accel_offset[2]);
|
||||
|
||||
// set sample rate
|
||||
mpu.setRate(16); // ~100Hz
|
||||
|
||||
// make sure it worked (returns 0 if so)
|
||||
if (devStatus == 0) {
|
||||
@ -117,17 +201,19 @@ class MPU6050Driver : public Usermod {
|
||||
DEBUG_PRINTLN(F("Enabling DMP..."));
|
||||
mpu.setDMPEnabled(true);
|
||||
|
||||
// enable Arduino interrupt detection
|
||||
DEBUG_PRINTLN(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
|
||||
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
|
||||
mpuIntStatus = mpu.getIntStatus();
|
||||
|
||||
// set our DMP Ready flag so the main loop() function knows it's okay to use it
|
||||
DEBUG_PRINTLN(F("DMP ready! Waiting for first interrupt..."));
|
||||
dmpReady = true;
|
||||
mpuInterrupt = true;
|
||||
if (irqBound) {
|
||||
// enable Arduino interrupt detection
|
||||
DEBUG_PRINTLN(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
|
||||
attachInterrupt(digitalPinToInterrupt(config.interruptPin), dmpDataReady, RISING);
|
||||
}
|
||||
|
||||
// get expected DMP packet size for later comparison
|
||||
packetSize = mpu.dmpGetFIFOPacketSize();
|
||||
|
||||
// set our DMP Ready flag so the main loop() function knows it's okay to use it
|
||||
DEBUG_PRINTLN(F("DMP ready!"));
|
||||
dmpReady = true;
|
||||
} else {
|
||||
// ERROR!
|
||||
// 1 = initial memory load failed
|
||||
@ -137,6 +223,9 @@ class MPU6050Driver : public Usermod {
|
||||
DEBUG_PRINT(devStatus);
|
||||
DEBUG_PRINTLN(")");
|
||||
}
|
||||
|
||||
fifoCount = 0;
|
||||
sample_count = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -153,28 +242,31 @@ class MPU6050Driver : public Usermod {
|
||||
*/
|
||||
void loop() {
|
||||
// if programming failed, don't try to do anything
|
||||
if (!enabled || !dmpReady || strip.isUpdating()) return;
|
||||
if (!config.enabled || !dmpReady || strip.isUpdating()) return;
|
||||
|
||||
// wait for MPU interrupt or extra packet(s) available
|
||||
// mpuInterrupt is fixed on if interrupt pin is disabled
|
||||
if (!mpuInterrupt && fifoCount < packetSize) return;
|
||||
|
||||
// reset interrupt flag and get INT_STATUS byte
|
||||
mpuInterrupt = false;
|
||||
mpuIntStatus = mpu.getIntStatus();
|
||||
|
||||
// get current FIFO count
|
||||
auto mpuIntStatus = mpu.getIntStatus();
|
||||
// Update current FIFO count
|
||||
fifoCount = mpu.getFIFOCount();
|
||||
|
||||
// check for overflow (this should never happen unless our code is too inefficient)
|
||||
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
|
||||
// reset so we can continue cleanly
|
||||
mpu.resetFIFO();
|
||||
DEBUG_PRINTLN(F("FIFO overflow!"));
|
||||
DEBUG_PRINTLN(F("MPU6050: FIFO overflow!"));
|
||||
|
||||
// otherwise, check for DMP data ready interrupt (this should happen frequently)
|
||||
} else if (mpuIntStatus & 0x02) {
|
||||
// wait for correct available data length, should be a VERY short wait
|
||||
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
|
||||
// otherwise, check for data ready
|
||||
} else if (fifoCount >= packetSize) {
|
||||
// clear local interrupt pending status, if not polling
|
||||
mpuInterrupt = !irqBound;
|
||||
|
||||
// DEBUG_PRINT(F("MPU6050: Processing packet: "));
|
||||
// DEBUG_PRINT(fifoCount);
|
||||
// DEBUG_PRINTLN(F(" bytes in FIFO"));
|
||||
|
||||
// read a packet from FIFO
|
||||
mpu.getFIFOBytes(fifoBuffer, packetSize);
|
||||
@ -183,7 +275,6 @@ class MPU6050Driver : public Usermod {
|
||||
// (this lets us immediately read more without waiting for an interrupt)
|
||||
fifoCount -= packetSize;
|
||||
|
||||
|
||||
//NOTE: some of these can be removed to save memory, processing time
|
||||
// if the measurement isn't needed
|
||||
mpu.dmpGetQuaternion(&qat, fifoBuffer);
|
||||
@ -194,87 +285,141 @@ class MPU6050Driver : public Usermod {
|
||||
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
|
||||
mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &qat);
|
||||
mpu.dmpGetYawPitchRoll(ypr, &qat, &gravity);
|
||||
++sample_count;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
{
|
||||
int reading = 20;
|
||||
//this code adds "u":{"Light":[20," lux"]} to the info object
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
JsonObject imu_meas = user.createNestedObject("IMU");
|
||||
JsonArray quat_json = imu_meas.createNestedArray("Quat");
|
||||
// Unfortunately the web UI doesn't know how to print sub-objects: you just see '[object Object]'
|
||||
// For now, we just put everything in the root userdata object.
|
||||
//auto imu_meas = user.createNestedObject("IMU");
|
||||
auto& imu_meas = user;
|
||||
|
||||
// If an element is an array, the UI expects two elements in the form [value, unit]
|
||||
// Since our /value/ is an array, wrap it, eg. [[a, b, c]]
|
||||
JsonArray quat_json = imu_meas.createNestedArray("Quat").createNestedArray();
|
||||
quat_json.add(qat.w);
|
||||
quat_json.add(qat.x);
|
||||
quat_json.add(qat.y);
|
||||
quat_json.add(qat.z);
|
||||
JsonArray euler_json = imu_meas.createNestedArray("Euler");
|
||||
JsonArray euler_json = imu_meas.createNestedArray("Euler").createNestedArray();
|
||||
euler_json.add(euler[0]);
|
||||
euler_json.add(euler[1]);
|
||||
euler_json.add(euler[2]);
|
||||
JsonArray accel_json = imu_meas.createNestedArray("Accel");
|
||||
JsonArray accel_json = imu_meas.createNestedArray("Accel").createNestedArray();
|
||||
accel_json.add(aa.x);
|
||||
accel_json.add(aa.y);
|
||||
accel_json.add(aa.z);
|
||||
JsonArray gyro_json = imu_meas.createNestedArray("Gyro");
|
||||
JsonArray gyro_json = imu_meas.createNestedArray("Gyro").createNestedArray();
|
||||
gyro_json.add(gy.x);
|
||||
gyro_json.add(gy.y);
|
||||
gyro_json.add(gy.z);
|
||||
JsonArray world_json = imu_meas.createNestedArray("WorldAccel");
|
||||
JsonArray world_json = imu_meas.createNestedArray("WorldAccel").createNestedArray();
|
||||
world_json.add(aaWorld.x);
|
||||
world_json.add(aaWorld.y);
|
||||
world_json.add(aaWorld.z);
|
||||
JsonArray real_json = imu_meas.createNestedArray("RealAccel");
|
||||
JsonArray real_json = imu_meas.createNestedArray("RealAccel").createNestedArray();
|
||||
real_json.add(aaReal.x);
|
||||
real_json.add(aaReal.y);
|
||||
real_json.add(aaReal.z);
|
||||
JsonArray grav_json = imu_meas.createNestedArray("Gravity");
|
||||
JsonArray grav_json = imu_meas.createNestedArray("Gravity").createNestedArray();
|
||||
grav_json.add(gravity.x);
|
||||
grav_json.add(gravity.y);
|
||||
grav_json.add(gravity.z);
|
||||
JsonArray orient_json = imu_meas.createNestedArray("Orientation");
|
||||
JsonArray orient_json = imu_meas.createNestedArray("Orientation").createNestedArray();
|
||||
orient_json.add(ypr[0]);
|
||||
orient_json.add(ypr[1]);
|
||||
orient_json.add(ypr[2]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void addToJsonState(JsonObject& root)
|
||||
//{
|
||||
//root["user0"] = userVar0;
|
||||
//}
|
||||
|
||||
|
||||
/*
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void readFromJsonState(JsonObject& root)
|
||||
//{
|
||||
//if (root["bri"] == 255) DEBUG_PRINTLN(F("Don't burn down your garage!"));
|
||||
//}
|
||||
|
||||
|
||||
/*
|
||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||
* It will be called by WLED when settings are actually saved (for example, LED settings are saved)
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
// void addToConfig(JsonObject& root)
|
||||
// {
|
||||
// JsonObject top = root.createNestedObject("MPU6050_IMU");
|
||||
// JsonArray pins = top.createNestedArray("pin");
|
||||
// pins.add(HW_PIN_SCL);
|
||||
// pins.add(HW_PIN_SDA);
|
||||
// }
|
||||
void addToConfig(JsonObject& root)
|
||||
{
|
||||
JsonObject top = root.createNestedObject(FPSTR(_name));
|
||||
|
||||
//save these vars persistently whenever settings are saved
|
||||
top[FPSTR(_enabled)] = config.enabled;
|
||||
top[FPSTR(_interrupt_pin)] = config.interruptPin;
|
||||
top[FPSTR(_x_acc_bias)] = config.accel_offset[0];
|
||||
top[FPSTR(_y_acc_bias)] = config.accel_offset[1];
|
||||
top[FPSTR(_z_acc_bias)] = config.accel_offset[2];
|
||||
top[FPSTR(_x_gyro_bias)] = config.gyro_offset[0];
|
||||
top[FPSTR(_y_gyro_bias)] = config.gyro_offset[1];
|
||||
top[FPSTR(_z_gyro_bias)] = config.gyro_offset[2];
|
||||
}
|
||||
|
||||
/*
|
||||
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||
* This is called by WLED when settings are loaded (currently this only happens immediately after boot, or after saving on the Usermod Settings page)
|
||||
*
|
||||
* readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes),
|
||||
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||
*
|
||||
* Return true in case the config values returned from Usermod Settings were complete, or false if you'd like WLED to save your defaults to disk (so any missing values are editable in Usermod Settings)
|
||||
*
|
||||
* getJsonValue() returns false if the value is missing, or copies the value into the variable provided and returns true if the value is present
|
||||
* The configComplete variable is true only if the "exampleUsermod" object and all values are present. If any values are missing, WLED will know to call addToConfig() to save them
|
||||
*
|
||||
* This function is guaranteed to be called on boot, but could also be called every time settings are updated
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root)
|
||||
{
|
||||
// default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor
|
||||
// setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed)
|
||||
auto old_cfg = config;
|
||||
|
||||
JsonObject top = root[FPSTR(_name)];
|
||||
|
||||
bool configComplete = top.isNull();
|
||||
// Ensure default configuration is loaded
|
||||
configComplete &= getJsonValue(top[FPSTR(_enabled)], config.enabled, true);
|
||||
configComplete &= getJsonValue(top[FPSTR(_interrupt_pin)], config.interruptPin, -1);
|
||||
configComplete &= getJsonValue(top[FPSTR(_x_acc_bias)], config.accel_offset[0], 0);
|
||||
configComplete &= getJsonValue(top[FPSTR(_y_acc_bias)], config.accel_offset[1], 0);
|
||||
configComplete &= getJsonValue(top[FPSTR(_z_acc_bias)], config.accel_offset[2], 0);
|
||||
configComplete &= getJsonValue(top[FPSTR(_x_gyro_bias)], config.gyro_offset[0], 0);
|
||||
configComplete &= getJsonValue(top[FPSTR(_y_gyro_bias)], config.gyro_offset[1], 0);
|
||||
configComplete &= getJsonValue(top[FPSTR(_z_gyro_bias)], config.gyro_offset[2], 0);
|
||||
|
||||
DEBUG_PRINT(FPSTR(_name));
|
||||
if (top.isNull()) {
|
||||
DEBUG_PRINTLN(F(": No config found. (Using defaults.)"));
|
||||
} else if (!initDone()) {
|
||||
DEBUG_PRINTLN(F(": config loaded."));
|
||||
} else if (memcmp(&config, &old_cfg, sizeof(config)) == 0) {
|
||||
DEBUG_PRINTLN(F(": config unchanged."));
|
||||
} else {
|
||||
DEBUG_PRINTLN(F(": config updated."));
|
||||
// Previously loaded and config changed
|
||||
if (irqBound && ((old_cfg.interruptPin != config.interruptPin) || !config.enabled)) {
|
||||
detachInterrupt(old_cfg.interruptPin);
|
||||
pinManager.deallocatePin(old_cfg.interruptPin, PinOwner::UM_IMU);
|
||||
irqBound = false;
|
||||
}
|
||||
|
||||
// Just re-init
|
||||
setup();
|
||||
}
|
||||
|
||||
return configComplete;
|
||||
}
|
||||
|
||||
bool getUMData(um_data_t **data)
|
||||
{
|
||||
if (!data || !config.enabled || !dmpReady) return false; // no pointer provided by caller or not enabled -> exit
|
||||
*data = &um_data;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
@ -285,3 +430,14 @@ class MPU6050Driver : public Usermod {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
const char MPU6050Driver::_name[] PROGMEM = "MPU6050_IMU";
|
||||
const char MPU6050Driver::_enabled[] PROGMEM = "enabled";
|
||||
const char MPU6050Driver::_interrupt_pin[] PROGMEM = "interrupt_pin";
|
||||
const char MPU6050Driver::_x_acc_bias[] PROGMEM = "x_acc_bias";
|
||||
const char MPU6050Driver::_y_acc_bias[] PROGMEM = "y_acc_bias";
|
||||
const char MPU6050Driver::_z_acc_bias[] PROGMEM = "z_acc_bias";
|
||||
const char MPU6050Driver::_x_gyro_bias[] PROGMEM = "x_gyro_bias";
|
||||
const char MPU6050Driver::_y_gyro_bias[] PROGMEM = "y_gyro_bias";
|
||||
const char MPU6050Driver::_z_gyro_bias[] PROGMEM = "z_gyro_bias";
|
||||
|
@ -143,7 +143,7 @@ class MultiRelay : public Usermod {
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
inline uint16_t getId() { return USERMOD_ID_MULTI_RELAY; }
|
||||
inline uint16_t getId() override { return USERMOD_ID_MULTI_RELAY; }
|
||||
|
||||
/**
|
||||
* switch relay on/off
|
||||
@ -161,22 +161,22 @@ class MultiRelay : public Usermod {
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
* You can use it to initialize variables, sensors or similar.
|
||||
*/
|
||||
void setup();
|
||||
void setup() override;
|
||||
|
||||
/**
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
* Use it to initialize network interfaces
|
||||
*/
|
||||
inline void connected() { InitHtmlAPIHandle(); }
|
||||
inline void connected() override { InitHtmlAPIHandle(); }
|
||||
|
||||
/**
|
||||
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||
*/
|
||||
void loop();
|
||||
void loop() override;
|
||||
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
bool onMqttMessage(char* topic, char* payload);
|
||||
void onMqttConnect(bool sessionPresent);
|
||||
bool onMqttMessage(char* topic, char* payload) override;
|
||||
void onMqttConnect(bool sessionPresent) override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -184,31 +184,31 @@ class MultiRelay : public Usermod {
|
||||
* will prevent button working in a default way.
|
||||
* Replicating button.cpp
|
||||
*/
|
||||
bool handleButton(uint8_t b);
|
||||
bool handleButton(uint8_t b) override;
|
||||
|
||||
/**
|
||||
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||
*/
|
||||
void addToJsonInfo(JsonObject &root);
|
||||
void addToJsonInfo(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void addToJsonState(JsonObject &root);
|
||||
void addToJsonState(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
void readFromJsonState(JsonObject &root);
|
||||
void readFromJsonState(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* provide the changeable values
|
||||
*/
|
||||
void addToConfig(JsonObject &root);
|
||||
void addToConfig(JsonObject &root) override;
|
||||
|
||||
void appendConfigData();
|
||||
void appendConfigData() override;
|
||||
|
||||
/**
|
||||
* restore the changeable values
|
||||
@ -216,7 +216,7 @@ class MultiRelay : public Usermod {
|
||||
*
|
||||
* The function should return true if configuration was successfully loaded or false if there was no configuration.
|
||||
*/
|
||||
bool readFromConfig(JsonObject &root);
|
||||
bool readFromConfig(JsonObject &root) override;
|
||||
};
|
||||
|
||||
|
||||
@ -534,10 +534,10 @@ void MultiRelay::setup() {
|
||||
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||
*/
|
||||
void MultiRelay::loop() {
|
||||
yield();
|
||||
if (!enabled || strip.isUpdating()) return;
|
||||
|
||||
static unsigned long lastUpdate = 0;
|
||||
yield();
|
||||
if (!enabled || (strip.isUpdating() && millis() - lastUpdate < 100)) return;
|
||||
|
||||
if (millis() - lastUpdate < 100) return; // update only 10 times/s
|
||||
lastUpdate = millis();
|
||||
|
||||
|
@ -84,11 +84,11 @@ class QuinLEDAnPentaUsermod : public Usermod
|
||||
void getCurrentUsedLedPins()
|
||||
{
|
||||
for (int8_t lp = 0; lp <= 4; lp++) currentLedPins[lp] = 0;
|
||||
byte numBusses = busses.getNumBusses();
|
||||
byte numBusses = BusManager::getNumBusses();
|
||||
byte numUsedPins = 0;
|
||||
|
||||
for (int8_t b = 0; b < numBusses; b++) {
|
||||
Bus* curBus = busses.getBus(b);
|
||||
Bus* curBus = BusManager::getBus(b);
|
||||
if (curBus != nullptr) {
|
||||
uint8_t pins[5] = {0, 0, 0, 0, 0};
|
||||
currentBussesNumPins[b] = curBus->getPins(pins);
|
||||
@ -104,11 +104,11 @@ class QuinLEDAnPentaUsermod : public Usermod
|
||||
|
||||
void getCurrentLedcValues()
|
||||
{
|
||||
byte numBusses = busses.getNumBusses();
|
||||
byte numBusses = BusManager::getNumBusses();
|
||||
byte numLedc = 0;
|
||||
|
||||
for (int8_t b = 0; b < numBusses; b++) {
|
||||
Bus* curBus = busses.getBus(b);
|
||||
Bus* curBus = BusManager::getBus(b);
|
||||
if (curBus != nullptr) {
|
||||
uint32_t curPixColor = curBus->getPixelColor(0);
|
||||
uint8_t _data[5] = {255, 255, 255, 255, 255};
|
||||
|
14
usermods/usermod_v2_animartrix/readme.md
Normal file
14
usermods/usermod_v2_animartrix/readme.md
Normal file
@ -0,0 +1,14 @@
|
||||
# ANIMartRIX
|
||||
|
||||
Addes the effects from ANIMartRIX to WLED
|
||||
|
||||
CC BY-NC 3.0 licensed effects by Stefan Petrick, include this usermod only if you accept the terms!
|
||||
|
||||
## Installation
|
||||
|
||||
Please uncomment the two references to ANIMartRIX in your platform.ini
|
||||
|
||||
lib_dep to a version of https://github.com/netmindz/animartrix.git
|
||||
and the build_flags -D USERMOD_ANIMARTRIX
|
||||
|
||||
|
456
usermods/usermod_v2_animartrix/usermod_v2_animartrix.h
Normal file
456
usermods/usermod_v2_animartrix/usermod_v2_animartrix.h
Normal file
@ -0,0 +1,456 @@
|
||||
#pragma once
|
||||
|
||||
#include "wled.h"
|
||||
#include <ANIMartRIX.h>
|
||||
|
||||
#warning WLED usermod: CC BY-NC 3.0 licensed effects by Stefan Petrick, include this usermod only if you accept the terms!
|
||||
//========================================================================================================================
|
||||
|
||||
|
||||
static const char _data_FX_mode_Module_Experiment10[] PROGMEM = "Z💡Module_Experiment10@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment9[] PROGMEM = "Z💡Module_Experiment9@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment8[] PROGMEM = "Z💡Module_Experiment8@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment7[] PROGMEM = "Z💡Module_Experiment7@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment6[] PROGMEM = "Z💡Module_Experiment6@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment5[] PROGMEM = "Z💡Module_Experiment5@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment4[] PROGMEM = "Z💡Module_Experiment4@Speed;;1;2";
|
||||
static const char _data_FX_mode_Zoom2[] PROGMEM = "Z💡Zoom2@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment3[] PROGMEM = "Z💡Module_Experiment3@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment2[] PROGMEM = "Z💡Module_Experiment2@Speed;;1;2";
|
||||
static const char _data_FX_mode_Module_Experiment1[] PROGMEM = "Z💡Module_Experiment1@Speed;;1;2";
|
||||
static const char _data_FX_mode_Parametric_Water[] PROGMEM = "Z💡Parametric_Water@Speed;;1;2";
|
||||
static const char _data_FX_mode_Water[] PROGMEM = "Z💡Water@Speed;;1;2";
|
||||
static const char _data_FX_mode_Complex_Kaleido_6[] PROGMEM = "Z💡Complex_Kaleido_6@Speed;;1;2";
|
||||
static const char _data_FX_mode_Complex_Kaleido_5[] PROGMEM = "Z💡Complex_Kaleido_5@Speed;;1;2";
|
||||
static const char _data_FX_mode_Complex_Kaleido_4[] PROGMEM = "Z💡Complex_Kaleido_4@Speed;;1;2";
|
||||
static const char _data_FX_mode_Complex_Kaleido_3[] PROGMEM = "Z💡Complex_Kaleido_3@Speed;;1;2";
|
||||
static const char _data_FX_mode_Complex_Kaleido_2[] PROGMEM = "Z💡Complex_Kaleido_2@Speed;;1;2";
|
||||
static const char _data_FX_mode_Complex_Kaleido[] PROGMEM = "Z💡Complex_Kaleido@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM10[] PROGMEM = "Z💡SM10@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM9[] PROGMEM = "Z💡SM9@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM8[] PROGMEM = "Z💡SM8@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM7[] PROGMEM = "Z💡SM7@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM6[] PROGMEM = "Z💡SM6@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM5[] PROGMEM = "Z💡SM5@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM4[] PROGMEM = "Z💡SM4@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM3[] PROGMEM = "Z💡SM3@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM2[] PROGMEM = "Z💡SM2@Speed;;1;2";
|
||||
static const char _data_FX_mode_SM1[] PROGMEM = "Z💡SM1@Speed;;1;2";
|
||||
static const char _data_FX_mode_Big_Caleido[] PROGMEM = "Z💡Big_Caleido@Speed;;1;2";
|
||||
static const char _data_FX_mode_RGB_Blobs5[] PROGMEM = "Z💡RGB_Blobs5@Speed;;1;2";
|
||||
static const char _data_FX_mode_RGB_Blobs4[] PROGMEM = "Z💡RGB_Blobs4@Speed;;1;2";
|
||||
static const char _data_FX_mode_RGB_Blobs3[] PROGMEM = "Z💡RGB_Blobs3@Speed;;1;2";
|
||||
static const char _data_FX_mode_RGB_Blobs2[] PROGMEM = "Z💡RGB_Blobs2@Speed;;1;2";
|
||||
static const char _data_FX_mode_RGB_Blobs[] PROGMEM = "Z💡RGB_Blobs@Speed;;1;2";
|
||||
static const char _data_FX_mode_Polar_Waves[] PROGMEM = "Z💡Polar_Waves@Speed;;1;2";
|
||||
static const char _data_FX_mode_Slow_Fade[] PROGMEM = "Z💡Slow_Fade@Speed;;1;2";
|
||||
static const char _data_FX_mode_Zoom[] PROGMEM = "Z💡Zoom@Speed;;1;2";
|
||||
static const char _data_FX_mode_Hot_Blob[] PROGMEM = "Z💡Hot_Blob@Speed;;1;2";
|
||||
static const char _data_FX_mode_Spiralus2[] PROGMEM = "Z💡Spiralus2@Speed;;1;2";
|
||||
static const char _data_FX_mode_Spiralus[] PROGMEM = "Z💡Spiralus@Speed;;1;2";
|
||||
static const char _data_FX_mode_Yves[] PROGMEM = "Z💡Yves@Speed;;1;2";
|
||||
static const char _data_FX_mode_Scaledemo1[] PROGMEM = "Z💡Scaledemo1@Speed;;1;2";
|
||||
static const char _data_FX_mode_Lava1[] PROGMEM = "Z💡Lava1@Speed;;1;2";
|
||||
static const char _data_FX_mode_Caleido3[] PROGMEM = "Z💡Caleido3@Speed;;1;2";
|
||||
static const char _data_FX_mode_Caleido2[] PROGMEM = "Z💡Caleido2@Speed;;1;2";
|
||||
static const char _data_FX_mode_Caleido1[] PROGMEM = "Z💡Caleido1@Speed;;1;2";
|
||||
static const char _data_FX_mode_Distance_Experiment[] PROGMEM = "Z💡Distance_Experiment@Speed;;1;2";
|
||||
static const char _data_FX_mode_Center_Field[] PROGMEM = "Z💡Center_Field@Speed;;1;2";
|
||||
static const char _data_FX_mode_Waves[] PROGMEM = "Z💡Waves@Speed;;1;2";
|
||||
static const char _data_FX_mode_Chasing_Spirals[] PROGMEM = "Z💡Chasing_Spirals@Speed;;1;2";
|
||||
static const char _data_FX_mode_Rotating_Blob[] PROGMEM = "Z💡Rotating_Blob@Speed;;1;2";
|
||||
|
||||
|
||||
class ANIMartRIXMod:public ANIMartRIX {
|
||||
public:
|
||||
void initEffect() {
|
||||
if (SEGENV.call == 0) {
|
||||
init(SEGMENT.virtualWidth(), SEGMENT.virtualHeight(), false);
|
||||
}
|
||||
float speedFactor = 1.0;
|
||||
if (SEGMENT.speed < 128) {
|
||||
speedFactor = (float) map(SEGMENT.speed, 0, 127, 1, 10) / 10.0f;
|
||||
}
|
||||
else{
|
||||
speedFactor = map(SEGMENT.speed, 128, 255, 10, 100) / 10;
|
||||
}
|
||||
setSpeedFactor(speedFactor);
|
||||
}
|
||||
void setPixelColor(int x, int y, rgb pixel) {
|
||||
SEGMENT.setPixelColorXY(x, y, CRGB(pixel.red, pixel.green, pixel.blue));
|
||||
}
|
||||
void setPixelColor(int index, rgb pixel) {
|
||||
SEGMENT.setPixelColor(index, CRGB(pixel.red, pixel.green, pixel.blue));
|
||||
}
|
||||
|
||||
// Add any extra custom effects not part of the ANIMartRIX libary here
|
||||
};
|
||||
ANIMartRIXMod anim;
|
||||
|
||||
uint16_t mode_Module_Experiment10() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment10();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment9() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment9();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment8() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment8();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment7() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment7();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment6() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment6();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment5() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment5();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment4() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment4();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Zoom2() {
|
||||
anim.initEffect();
|
||||
anim.Zoom2();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment3() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment3();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment2() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment2();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Module_Experiment1() {
|
||||
anim.initEffect();
|
||||
anim.Module_Experiment1();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Parametric_Water() {
|
||||
anim.initEffect();
|
||||
anim.Parametric_Water();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Water() {
|
||||
anim.initEffect();
|
||||
anim.Water();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Complex_Kaleido_6() {
|
||||
anim.initEffect();
|
||||
anim.Complex_Kaleido_6();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Complex_Kaleido_5() {
|
||||
anim.initEffect();
|
||||
anim.Complex_Kaleido_5();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Complex_Kaleido_4() {
|
||||
anim.initEffect();
|
||||
anim.Complex_Kaleido_4();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Complex_Kaleido_3() {
|
||||
anim.initEffect();
|
||||
anim.Complex_Kaleido_3();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Complex_Kaleido_2() {
|
||||
anim.initEffect();
|
||||
anim.Complex_Kaleido_2();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Complex_Kaleido() {
|
||||
anim.initEffect();
|
||||
anim.Complex_Kaleido();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM10() {
|
||||
anim.initEffect();
|
||||
anim.SM10();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM9() {
|
||||
anim.initEffect();
|
||||
anim.SM9();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM8() {
|
||||
anim.initEffect();
|
||||
anim.SM8();
|
||||
return FRAMETIME;
|
||||
}
|
||||
// uint16_t mode_SM7() {
|
||||
// anim.initEffect();
|
||||
// anim.SM7();
|
||||
//
|
||||
// return FRAMETIME;
|
||||
// }
|
||||
uint16_t mode_SM6() {
|
||||
anim.initEffect();
|
||||
anim.SM6();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM5() {
|
||||
anim.initEffect();
|
||||
anim.SM5();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM4() {
|
||||
anim.initEffect();
|
||||
anim.SM4();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM3() {
|
||||
anim.initEffect();
|
||||
anim.SM3();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM2() {
|
||||
anim.initEffect();
|
||||
anim.SM2();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_SM1() {
|
||||
anim.initEffect();
|
||||
anim.SM1();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Big_Caleido() {
|
||||
anim.initEffect();
|
||||
anim.Big_Caleido();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_RGB_Blobs5() {
|
||||
anim.initEffect();
|
||||
anim.RGB_Blobs5();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_RGB_Blobs4() {
|
||||
anim.initEffect();
|
||||
anim.RGB_Blobs4();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_RGB_Blobs3() {
|
||||
anim.initEffect();
|
||||
anim.RGB_Blobs3();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_RGB_Blobs2() {
|
||||
anim.initEffect();
|
||||
anim.RGB_Blobs2();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_RGB_Blobs() {
|
||||
anim.initEffect();
|
||||
anim.RGB_Blobs();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Polar_Waves() {
|
||||
anim.initEffect();
|
||||
anim.Polar_Waves();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Slow_Fade() {
|
||||
anim.initEffect();
|
||||
anim.Slow_Fade();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Zoom() {
|
||||
anim.initEffect();
|
||||
anim.Zoom();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Hot_Blob() {
|
||||
anim.initEffect();
|
||||
anim.Hot_Blob();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Spiralus2() {
|
||||
anim.initEffect();
|
||||
anim.Spiralus2();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Spiralus() {
|
||||
anim.initEffect();
|
||||
anim.Spiralus();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Yves() {
|
||||
anim.initEffect();
|
||||
anim.Yves();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Scaledemo1() {
|
||||
anim.initEffect();
|
||||
anim.Scaledemo1();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Lava1() {
|
||||
anim.initEffect();
|
||||
anim.Lava1();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Caleido3() {
|
||||
anim.initEffect();
|
||||
anim.Caleido3();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Caleido2() {
|
||||
anim.initEffect();
|
||||
anim.Caleido2();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Caleido1() {
|
||||
anim.initEffect();
|
||||
anim.Caleido1();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Distance_Experiment() {
|
||||
anim.initEffect();
|
||||
anim.Distance_Experiment();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Center_Field() {
|
||||
anim.initEffect();
|
||||
anim.Center_Field();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Waves() {
|
||||
anim.initEffect();
|
||||
anim.Waves();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Chasing_Spirals() {
|
||||
anim.initEffect();
|
||||
anim.Chasing_Spirals();
|
||||
return FRAMETIME;
|
||||
}
|
||||
uint16_t mode_Rotating_Blob() {
|
||||
anim.initEffect();
|
||||
anim.Rotating_Blob();
|
||||
return FRAMETIME;
|
||||
}
|
||||
|
||||
|
||||
class AnimartrixUsermod : public Usermod {
|
||||
protected:
|
||||
bool enabled = false; //WLEDMM
|
||||
const char *_name; //WLEDMM
|
||||
bool initDone = false; //WLEDMM
|
||||
unsigned long lastTime = 0; //WLEDMM
|
||||
|
||||
public:
|
||||
|
||||
AnimartrixUsermod(const char *name, bool enabled) {
|
||||
this->_name = name;
|
||||
this->enabled = enabled;
|
||||
} //WLEDMM
|
||||
|
||||
|
||||
void setup() {
|
||||
|
||||
strip.addEffect(255, &mode_Module_Experiment10, _data_FX_mode_Module_Experiment10);
|
||||
strip.addEffect(255, &mode_Module_Experiment9, _data_FX_mode_Module_Experiment9);
|
||||
strip.addEffect(255, &mode_Module_Experiment8, _data_FX_mode_Module_Experiment8);
|
||||
strip.addEffect(255, &mode_Module_Experiment7, _data_FX_mode_Module_Experiment7);
|
||||
strip.addEffect(255, &mode_Module_Experiment6, _data_FX_mode_Module_Experiment6);
|
||||
strip.addEffect(255, &mode_Module_Experiment5, _data_FX_mode_Module_Experiment5);
|
||||
strip.addEffect(255, &mode_Module_Experiment4, _data_FX_mode_Module_Experiment4);
|
||||
strip.addEffect(255, &mode_Zoom2, _data_FX_mode_Zoom2);
|
||||
strip.addEffect(255, &mode_Module_Experiment3, _data_FX_mode_Module_Experiment3);
|
||||
strip.addEffect(255, &mode_Module_Experiment2, _data_FX_mode_Module_Experiment2);
|
||||
strip.addEffect(255, &mode_Module_Experiment1, _data_FX_mode_Module_Experiment1);
|
||||
strip.addEffect(255, &mode_Parametric_Water, _data_FX_mode_Parametric_Water);
|
||||
strip.addEffect(255, &mode_Water, _data_FX_mode_Water);
|
||||
strip.addEffect(255, &mode_Complex_Kaleido_6, _data_FX_mode_Complex_Kaleido_6);
|
||||
strip.addEffect(255, &mode_Complex_Kaleido_5, _data_FX_mode_Complex_Kaleido_5);
|
||||
strip.addEffect(255, &mode_Complex_Kaleido_4, _data_FX_mode_Complex_Kaleido_4);
|
||||
strip.addEffect(255, &mode_Complex_Kaleido_3, _data_FX_mode_Complex_Kaleido_3);
|
||||
strip.addEffect(255, &mode_Complex_Kaleido_2, _data_FX_mode_Complex_Kaleido_2);
|
||||
strip.addEffect(255, &mode_Complex_Kaleido, _data_FX_mode_Complex_Kaleido);
|
||||
strip.addEffect(255, &mode_SM10, _data_FX_mode_SM10);
|
||||
strip.addEffect(255, &mode_SM9, _data_FX_mode_SM9);
|
||||
strip.addEffect(255, &mode_SM8, _data_FX_mode_SM8);
|
||||
// strip.addEffect(255, &mode_SM7, _data_FX_mode_SM7);
|
||||
strip.addEffect(255, &mode_SM6, _data_FX_mode_SM6);
|
||||
strip.addEffect(255, &mode_SM5, _data_FX_mode_SM5);
|
||||
strip.addEffect(255, &mode_SM4, _data_FX_mode_SM4);
|
||||
strip.addEffect(255, &mode_SM3, _data_FX_mode_SM3);
|
||||
strip.addEffect(255, &mode_SM2, _data_FX_mode_SM2);
|
||||
strip.addEffect(255, &mode_SM1, _data_FX_mode_SM1);
|
||||
strip.addEffect(255, &mode_Big_Caleido, _data_FX_mode_Big_Caleido);
|
||||
strip.addEffect(255, &mode_RGB_Blobs5, _data_FX_mode_RGB_Blobs5);
|
||||
strip.addEffect(255, &mode_RGB_Blobs4, _data_FX_mode_RGB_Blobs4);
|
||||
strip.addEffect(255, &mode_RGB_Blobs3, _data_FX_mode_RGB_Blobs3);
|
||||
strip.addEffect(255, &mode_RGB_Blobs2, _data_FX_mode_RGB_Blobs2);
|
||||
strip.addEffect(255, &mode_RGB_Blobs, _data_FX_mode_RGB_Blobs);
|
||||
strip.addEffect(255, &mode_Polar_Waves, _data_FX_mode_Polar_Waves);
|
||||
strip.addEffect(255, &mode_Slow_Fade, _data_FX_mode_Slow_Fade);
|
||||
strip.addEffect(255, &mode_Zoom, _data_FX_mode_Zoom);
|
||||
strip.addEffect(255, &mode_Hot_Blob, _data_FX_mode_Hot_Blob);
|
||||
strip.addEffect(255, &mode_Spiralus2, _data_FX_mode_Spiralus2);
|
||||
strip.addEffect(255, &mode_Spiralus, _data_FX_mode_Spiralus);
|
||||
strip.addEffect(255, &mode_Yves, _data_FX_mode_Yves);
|
||||
strip.addEffect(255, &mode_Scaledemo1, _data_FX_mode_Scaledemo1);
|
||||
strip.addEffect(255, &mode_Lava1, _data_FX_mode_Lava1);
|
||||
strip.addEffect(255, &mode_Caleido3, _data_FX_mode_Caleido3);
|
||||
strip.addEffect(255, &mode_Caleido2, _data_FX_mode_Caleido2);
|
||||
strip.addEffect(255, &mode_Caleido1, _data_FX_mode_Caleido1);
|
||||
strip.addEffect(255, &mode_Distance_Experiment, _data_FX_mode_Distance_Experiment);
|
||||
strip.addEffect(255, &mode_Center_Field, _data_FX_mode_Center_Field);
|
||||
strip.addEffect(255, &mode_Waves, _data_FX_mode_Waves);
|
||||
strip.addEffect(255, &mode_Chasing_Spirals, _data_FX_mode_Chasing_Spirals);
|
||||
strip.addEffect(255, &mode_Rotating_Blob, _data_FX_mode_Rotating_Blob);
|
||||
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (!enabled || strip.isUpdating()) return;
|
||||
|
||||
// do your magic here
|
||||
if (millis() - lastTime > 1000) {
|
||||
//USER_PRINTLN("I'm alive!");
|
||||
lastTime = millis();
|
||||
}
|
||||
}
|
||||
|
||||
void addToJsonInfo(JsonObject& root)
|
||||
{
|
||||
char myStringBuffer[16]; // buffer for snprintf()
|
||||
JsonObject user = root["u"];
|
||||
if (user.isNull()) user = root.createNestedObject("u");
|
||||
|
||||
JsonArray infoArr = user.createNestedArray(FPSTR(_name));
|
||||
|
||||
String uiDomString = F("Animartrix requires the Creative Commons Attribution License CC BY-NC 3.0");
|
||||
infoArr.add(uiDomString);
|
||||
}
|
||||
|
||||
uint16_t getId()
|
||||
{
|
||||
return USERMOD_ID_ANIMARTRIX;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -211,16 +211,16 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
|
||||
// gets called once at boot. Do all initialization that doesn't depend on
|
||||
// network here
|
||||
void setup();
|
||||
void setup() override;
|
||||
|
||||
// gets called every time WiFi is (re-)connected. Initialize own network
|
||||
// interfaces here
|
||||
void connected();
|
||||
void connected() override;
|
||||
|
||||
/**
|
||||
* Da loop.
|
||||
*/
|
||||
void loop();
|
||||
void loop() override;
|
||||
|
||||
//function to update lastredraw
|
||||
inline void updateRedrawTime() { lastRedraw = millis(); }
|
||||
@ -287,28 +287,28 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
*/
|
||||
bool handleButton(uint8_t b);
|
||||
|
||||
void onUpdateBegin(bool init);
|
||||
void onUpdateBegin(bool init) override;
|
||||
|
||||
/*
|
||||
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||
* Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI.
|
||||
* Below it is shown how this could be used for e.g. a light sensor
|
||||
*/
|
||||
//void addToJsonInfo(JsonObject& root);
|
||||
//void addToJsonInfo(JsonObject& root) override;
|
||||
|
||||
/*
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void addToJsonState(JsonObject& root);
|
||||
//void addToJsonState(JsonObject& root) override;
|
||||
|
||||
/*
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void readFromJsonState(JsonObject& root);
|
||||
//void readFromJsonState(JsonObject& root) override;
|
||||
|
||||
void appendConfigData();
|
||||
void appendConfigData() override;
|
||||
|
||||
/*
|
||||
* addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object.
|
||||
@ -324,7 +324,7 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
*
|
||||
* I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings!
|
||||
*/
|
||||
void addToConfig(JsonObject& root);
|
||||
void addToConfig(JsonObject& root) override;
|
||||
|
||||
/*
|
||||
* readFromConfig() can be used to read back the custom settings you added with addToConfig().
|
||||
@ -334,13 +334,13 @@ class FourLineDisplayUsermod : public Usermod {
|
||||
* but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup.
|
||||
* If you don't know what that is, don't fret. It most likely doesn't affect your use case :)
|
||||
*/
|
||||
bool readFromConfig(JsonObject& root);
|
||||
bool readFromConfig(JsonObject& root) override;
|
||||
|
||||
/*
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId() {
|
||||
uint16_t getId() override {
|
||||
return USERMOD_ID_FOUR_LINE_DISP;
|
||||
}
|
||||
};
|
||||
|
@ -285,7 +285,7 @@ class RotaryEncoderUIUsermod : public Usermod {
|
||||
* getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!).
|
||||
* This could be used in the future for the system to determine whether your usermod is installed.
|
||||
*/
|
||||
uint16_t getId() { return USERMOD_ID_ROTARY_ENC_UI; }
|
||||
uint16_t getId() override { return USERMOD_ID_ROTARY_ENC_UI; }
|
||||
/**
|
||||
* Enable/Disable the usermod
|
||||
*/
|
||||
@ -300,7 +300,7 @@ class RotaryEncoderUIUsermod : public Usermod {
|
||||
* setup() is called once at boot. WiFi is not yet connected at this point.
|
||||
* You can use it to initialize variables, sensors or similar.
|
||||
*/
|
||||
void setup();
|
||||
void setup() override;
|
||||
|
||||
/**
|
||||
* connected() is called every time the WiFi is (re)connected
|
||||
@ -311,11 +311,11 @@ class RotaryEncoderUIUsermod : public Usermod {
|
||||
/**
|
||||
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||
*/
|
||||
void loop();
|
||||
void loop() override;
|
||||
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
//bool onMqttMessage(char* topic, char* payload);
|
||||
//void onMqttConnect(bool sessionPresent);
|
||||
//bool onMqttMessage(char* topic, char* payload) override;
|
||||
//void onMqttConnect(bool sessionPresent) override;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -323,31 +323,31 @@ class RotaryEncoderUIUsermod : public Usermod {
|
||||
* will prevent button working in a default way.
|
||||
* Replicating button.cpp
|
||||
*/
|
||||
//bool handleButton(uint8_t b);
|
||||
//bool handleButton(uint8_t b) override;
|
||||
|
||||
/**
|
||||
* addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API.
|
||||
*/
|
||||
//void addToJsonInfo(JsonObject &root);
|
||||
//void addToJsonInfo(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void addToJsonState(JsonObject &root);
|
||||
//void addToJsonState(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object).
|
||||
* Values in the state object may be modified by connected clients
|
||||
*/
|
||||
//void readFromJsonState(JsonObject &root);
|
||||
//void readFromJsonState(JsonObject &root) override;
|
||||
|
||||
/**
|
||||
* provide the changeable values
|
||||
*/
|
||||
void addToConfig(JsonObject &root);
|
||||
void addToConfig(JsonObject &root) override;
|
||||
|
||||
void appendConfigData();
|
||||
void appendConfigData() override;
|
||||
|
||||
/**
|
||||
* restore the changeable values
|
||||
@ -355,7 +355,7 @@ class RotaryEncoderUIUsermod : public Usermod {
|
||||
*
|
||||
* The function should return true if configuration was successfully loaded or false if there was no configuration.
|
||||
*/
|
||||
bool readFromConfig(JsonObject &root);
|
||||
bool readFromConfig(JsonObject &root) override;
|
||||
|
||||
// custom methods
|
||||
void displayNetworkInfo();
|
||||
|
@ -67,8 +67,8 @@ class WireguardUsermod : public Usermod {
|
||||
JsonObject top = root.createNestedObject(F("WireGuard"));
|
||||
top[F("host")] = endpoint_address;
|
||||
top[F("port")] = endpoint_port;
|
||||
top[F("ip")] = local_ip.toString();
|
||||
top[F("psk")] = preshared_key;
|
||||
top["ip"] = local_ip.toString();
|
||||
top["psk"] = preshared_key;
|
||||
top[F("pem")] = private_key;
|
||||
top[F("pub")] = public_key;
|
||||
top[F("tz")] = posix_tz;
|
||||
@ -77,11 +77,11 @@ class WireguardUsermod : public Usermod {
|
||||
bool readFromConfig(JsonObject& root) {
|
||||
JsonObject top = root[F("WireGuard")];
|
||||
|
||||
if (top["host"].isNull() || top["port"].isNull() || top["ip"].isNull() || top["pem"].isNull() || top["pub"].isNull() || top["tz"].isNull()) {
|
||||
if (top[F("host")].isNull() || top[F("port")].isNull() || top["ip"].isNull() || top[F("pem")].isNull() || top[F("pub")].isNull() || top[F("tz")].isNull()) {
|
||||
is_enabled = false;
|
||||
return false;
|
||||
} else {
|
||||
const char* host = top["host"];
|
||||
const char* host = top[F("host")];
|
||||
strncpy(endpoint_address, host, 100);
|
||||
|
||||
const char* ip_s = top["ip"];
|
||||
@ -89,16 +89,16 @@ class WireguardUsermod : public Usermod {
|
||||
sscanf(ip_s, "%u.%u.%u.%u", &ip[0], &ip[1], &ip[2], &ip[3]);
|
||||
local_ip = IPAddress(ip[0], ip[1], ip[2], ip[3]);
|
||||
|
||||
const char* pem = top["pem"];
|
||||
const char* pem = top[F("pem")];
|
||||
strncpy(private_key, pem, 45);
|
||||
|
||||
const char* pub = top["pub"];
|
||||
const char* pub = top[F("pub")];
|
||||
strncpy(public_key, pub, 45);
|
||||
|
||||
const char* tz = top["tz"];
|
||||
const char* tz = top[F("tz")];
|
||||
strncpy(posix_tz, tz, 150);
|
||||
|
||||
endpoint_port = top["port"];
|
||||
endpoint_port = top[F("port")];
|
||||
|
||||
if (!top["psk"].isNull()) {
|
||||
const char* psk = top["psk"];
|
||||
|
@ -325,8 +325,8 @@ public:
|
||||
void addToConfig(JsonObject& root)
|
||||
{
|
||||
JsonObject modName = root.createNestedObject("id");
|
||||
modName["mdns"] = "wled-word-clock";
|
||||
modName["name"] = "WLED WORD CLOCK";
|
||||
modName[F("mdns")] = "wled-word-clock";
|
||||
modName[F("name")] = "WLED WORD CLOCK";
|
||||
}
|
||||
|
||||
uint16_t getId()
|
||||
|
@ -3444,8 +3444,8 @@ static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chanc
|
||||
uint16_t mode_exploding_fireworks(void)
|
||||
{
|
||||
if (SEGLEN == 1) return mode_static();
|
||||
const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1;
|
||||
const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength();
|
||||
const uint16_t cols = SEGMENT.is2D() ? SEGMENT.virtualWidth() : 1;
|
||||
const uint16_t rows = SEGMENT.is2D() ? SEGMENT.virtualHeight() : SEGMENT.virtualLength();
|
||||
|
||||
//allocate segment data
|
||||
uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640
|
||||
@ -3476,11 +3476,11 @@ uint16_t mode_exploding_fireworks(void)
|
||||
if (SEGENV.aux0 < 2) { //FLARE
|
||||
if (SEGENV.aux0 == 0) { //init flare
|
||||
flare->pos = 0;
|
||||
flare->posX = strip.isMatrix ? random16(2,cols-3) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D
|
||||
flare->posX = SEGMENT.is2D() ? random16(2,cols-3) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D
|
||||
uint16_t peakHeight = 75 + random8(180); //0-255
|
||||
peakHeight = (peakHeight * (rows -1)) >> 8;
|
||||
flare->vel = sqrtf(-2.0f * gravity * peakHeight);
|
||||
flare->velX = strip.isMatrix ? (random8(9)-4)/32.f : 0; // no X velocity on 1D
|
||||
flare->velX = SEGMENT.is2D() ? (random8(9)-4)/64.0f : 0; // no X velocity on 1D
|
||||
flare->col = 255; //brightness
|
||||
SEGENV.aux0 = 1;
|
||||
}
|
||||
@ -3488,12 +3488,14 @@ uint16_t mode_exploding_fireworks(void)
|
||||
// launch
|
||||
if (flare->vel > 12 * gravity) {
|
||||
// flare
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col);
|
||||
else SEGMENT.setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col);
|
||||
if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col);
|
||||
else SEGMENT.setPixelColor((flare->posX > 0.0f) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col);
|
||||
flare->pos += flare->vel;
|
||||
flare->posX += flare->velX;
|
||||
flare->pos = constrain(flare->pos, 0, rows-1);
|
||||
flare->posX = constrain(flare->posX, 0, cols-strip.isMatrix);
|
||||
if (SEGMENT.is2D()) {
|
||||
flare->posX += flare->velX;
|
||||
flare->posX = constrain(flare->posX, 0, cols-1);
|
||||
}
|
||||
flare->vel += gravity;
|
||||
flare->col -= 2;
|
||||
} else {
|
||||
@ -3516,12 +3518,12 @@ uint16_t mode_exploding_fireworks(void)
|
||||
sparks[i].posX = flare->posX;
|
||||
sparks[i].vel = (float(random16(20001)) / 10000.0f) - 0.9f; // from -0.9 to 1.1
|
||||
sparks[i].vel *= rows<32 ? 0.5f : 1; // reduce velocity for smaller strips
|
||||
sparks[i].velX = strip.isMatrix ? (float(random16(10001)) / 10000.0f) - 0.5f : 0; // from -0.5 to 0.5
|
||||
sparks[i].velX = SEGMENT.is2D() ? (float(random16(20001)) / 10000.0f) - 1.0f : 0; // from -1 to 1
|
||||
sparks[i].col = 345;//abs(sparks[i].vel * 750.0); // set colors before scaling velocity to keep them bright
|
||||
//sparks[i].col = constrain(sparks[i].col, 0, 345);
|
||||
sparks[i].colIndex = random8();
|
||||
sparks[i].vel *= flare->pos/rows; // proportional to height
|
||||
sparks[i].velX *= strip.isMatrix ? flare->posX/cols : 0; // proportional to width
|
||||
sparks[i].velX *= SEGMENT.is2D() ? flare->posX/cols : 0; // proportional to width
|
||||
sparks[i].vel *= -gravity *50;
|
||||
}
|
||||
//sparks[1].col = 345; // this will be our known spark
|
||||
@ -3534,11 +3536,11 @@ uint16_t mode_exploding_fireworks(void)
|
||||
sparks[i].pos += sparks[i].vel;
|
||||
sparks[i].posX += sparks[i].velX;
|
||||
sparks[i].vel += *dying_gravity;
|
||||
sparks[i].velX += strip.isMatrix ? *dying_gravity : 0;
|
||||
sparks[i].velX += SEGMENT.is2D() ? *dying_gravity : 0;
|
||||
if (sparks[i].col > 3) sparks[i].col -= 4;
|
||||
|
||||
if (sparks[i].pos > 0 && sparks[i].pos < rows) {
|
||||
if (strip.isMatrix && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue;
|
||||
if (SEGMENT.is2D() && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue;
|
||||
uint16_t prog = sparks[i].col;
|
||||
uint32_t spColor = (SEGMENT.palette) ? SEGMENT.color_wheel(sparks[i].colIndex) : SEGCOLOR(0);
|
||||
CRGB c = CRGB::Black; //HeatColor(sparks[i].col);
|
||||
@ -3550,7 +3552,7 @@ uint16_t mode_exploding_fireworks(void)
|
||||
c.g = qsub8(c.g, cooling);
|
||||
c.b = qsub8(c.b, cooling * 2);
|
||||
}
|
||||
if (strip.isMatrix) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue);
|
||||
if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue);
|
||||
else SEGMENT.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue);
|
||||
}
|
||||
}
|
||||
@ -5292,7 +5294,6 @@ uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams.
|
||||
if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed
|
||||
|
||||
if (SEGENV.call == 0) {
|
||||
memset(SEGMENT.data, 0, dataSize); // no falling spawns
|
||||
SEGMENT.fill(BLACK);
|
||||
SEGENV.step = 0;
|
||||
}
|
||||
|
159
wled00/FX.h
159
wled00/FX.h
@ -62,10 +62,10 @@
|
||||
//#define FRAMETIME _frametime
|
||||
#define FRAMETIME strip.getFrameTime()
|
||||
|
||||
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
||||
/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of
|
||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||
#ifdef ESP8266
|
||||
#define MAX_NUM_SEGMENTS 16
|
||||
#define MAX_NUM_SEGMENTS 12
|
||||
/* How much data bytes all segments combined may allocate */
|
||||
#define MAX_SEGMENT_DATA 5120
|
||||
#else
|
||||
@ -73,9 +73,13 @@
|
||||
#define MAX_NUM_SEGMENTS 32
|
||||
#endif
|
||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||
#define MAX_SEGMENT_DATA 24576
|
||||
#if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1024 // 32k by default
|
||||
#else
|
||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*768 // 24k by default
|
||||
#endif
|
||||
#else
|
||||
#define MAX_SEGMENT_DATA 32767
|
||||
#define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1280 // 40k by default
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -278,7 +282,7 @@
|
||||
#define FX_MODE_RIPPLEPEAK 148
|
||||
#define FX_MODE_2DFIRENOISE 149
|
||||
#define FX_MODE_2DSQUAREDSWIRL 150
|
||||
#define FX_MODE_2DFIRE2012 151
|
||||
// #define FX_MODE_2DFIRE2012 151
|
||||
#define FX_MODE_2DDNA 152
|
||||
#define FX_MODE_2DMATRIX 153
|
||||
#define FX_MODE_2DMETABALLS 154
|
||||
@ -288,7 +292,7 @@
|
||||
#define FX_MODE_GRAVFREQ 158
|
||||
#define FX_MODE_DJLIGHT 159
|
||||
#define FX_MODE_2DFUNKYPLANK 160
|
||||
#define FX_MODE_2DCENTERBARS 161
|
||||
//#define FX_MODE_2DCENTERBARS 161
|
||||
#define FX_MODE_2DPULSER 162
|
||||
#define FX_MODE_BLURZ 163
|
||||
#define FX_MODE_2DDRIFT 164
|
||||
@ -531,7 +535,7 @@ typedef struct Segment {
|
||||
#endif
|
||||
static void handleRandomPalette();
|
||||
|
||||
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1, uint8_t segId = 255);
|
||||
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1);
|
||||
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
|
||||
void setCCT(uint16_t k);
|
||||
void setOpacity(uint8_t o);
|
||||
@ -543,9 +547,9 @@ typedef struct Segment {
|
||||
|
||||
// runtime data functions
|
||||
inline uint16_t dataSize(void) const { return _dataLen; }
|
||||
bool allocateData(size_t len);
|
||||
void deallocateData(void);
|
||||
void resetIfRequired(void);
|
||||
bool allocateData(size_t len); // allocates effect data buffer in heap and clears it
|
||||
void deallocateData(void); // deallocates (frees) effect data buffer from heap
|
||||
void resetIfRequired(void); // sets all SEGENV variables to 0 and clears data buffer
|
||||
/**
|
||||
* Flags that before the next effect is calculated,
|
||||
* the internal segment state should be reset.
|
||||
@ -555,17 +559,17 @@ typedef struct Segment {
|
||||
inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true)
|
||||
|
||||
// transition functions
|
||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||
void stopTransition(void);
|
||||
void startTransition(uint16_t dur); // transition has to start before actual segment values change
|
||||
void stopTransition(void); // ends transition mode by destroying transition structure
|
||||
void handleTransition(void);
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
void swapSegenv(tmpsegd_t &tmpSegD);
|
||||
void restoreSegenv(tmpsegd_t &tmpSegD);
|
||||
void swapSegenv(tmpsegd_t &tmpSegD); // copies segment data into specifed buffer, if buffer is not a transition buffer, segment data is overwritten from transition buffer
|
||||
void restoreSegenv(tmpsegd_t &tmpSegD); // restores segment data from buffer, if buffer is not transition buffer, changed values are copied to transition buffer
|
||||
#endif
|
||||
uint16_t progress(void); //transition progression between 0-65535
|
||||
uint8_t currentBri(bool useCct = false);
|
||||
uint8_t currentMode(void);
|
||||
uint32_t currentColor(uint8_t slot);
|
||||
uint16_t progress(void); // transition progression between 0-65535
|
||||
uint8_t currentBri(bool useCct = false); // current segment brightness/CCT (blended while in transition)
|
||||
uint8_t currentMode(void); // currently active effect/mode (while in transition)
|
||||
uint32_t currentColor(uint8_t slot); // currently active segment color (blended while in transition)
|
||||
CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
|
||||
CRGBPalette16 ¤tPalette(CRGBPalette16 &tgt, uint8_t paletteID);
|
||||
|
||||
@ -594,9 +598,9 @@ typedef struct Segment {
|
||||
uint32_t color_wheel(uint8_t pos);
|
||||
|
||||
// 2D matrix
|
||||
uint16_t virtualWidth(void) const;
|
||||
uint16_t virtualHeight(void) const;
|
||||
uint16_t nrOfVStrips(void) const;
|
||||
uint16_t virtualWidth(void) const; // segment width in virtual pixels (accounts for groupping and spacing)
|
||||
uint16_t virtualHeight(void) const; // segment height in virtual pixels (accounts for groupping and spacing)
|
||||
uint16_t nrOfVStrips(void) const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D)
|
||||
#ifndef WLED_DISABLE_2D
|
||||
uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment
|
||||
void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color
|
||||
@ -682,10 +686,7 @@ class WS2812FX { // 96 bytes
|
||||
WS2812FX() :
|
||||
paletteFade(0),
|
||||
paletteBlend(0),
|
||||
milliampsPerLed(55),
|
||||
cctBlending(0),
|
||||
ablMilliampsMax(ABL_MILLIAMPS_DEFAULT),
|
||||
currentMilliamps(0),
|
||||
now(millis()),
|
||||
timebase(0),
|
||||
isMatrix(false),
|
||||
@ -697,6 +698,7 @@ class WS2812FX { // 96 bytes
|
||||
_colors_t{0,0,0},
|
||||
_virtualSegmentLength(0),
|
||||
// true private variables
|
||||
_suspend(false),
|
||||
_length(DEFAULT_LED_COUNT),
|
||||
_brightness(DEFAULT_BRIGHTNESS),
|
||||
_transitionDur(750),
|
||||
@ -745,38 +747,39 @@ class WS2812FX { // 96 bytes
|
||||
|
||||
void
|
||||
#ifdef WLED_DEBUG
|
||||
printSize(),
|
||||
printSize(), // prints memory usage for strip components
|
||||
#endif
|
||||
finalizeInit(),
|
||||
service(void),
|
||||
setMode(uint8_t segid, uint8_t m),
|
||||
setColor(uint8_t slot, uint32_t c),
|
||||
setCCT(uint16_t k),
|
||||
setBrightness(uint8_t b, bool direct = false),
|
||||
setRange(uint16_t i, uint16_t i2, uint32_t col),
|
||||
purgeSegments(bool force = false),
|
||||
finalizeInit(), // initialises strip components
|
||||
service(void), // executes effect functions when due and calls strip.show()
|
||||
setMode(uint8_t segid, uint8_t m), // sets effect/mode for given segment (high level API)
|
||||
setColor(uint8_t slot, uint32_t c), // sets color (in slot) for given segment (high level API)
|
||||
setCCT(uint16_t k), // sets global CCT (either in relative 0-255 value or in K)
|
||||
setBrightness(uint8_t b, bool direct = false), // sets strip brightness
|
||||
setRange(uint16_t i, uint16_t i2, uint32_t col), // used for clock overlay
|
||||
purgeSegments(void), // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint)
|
||||
setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 1, uint8_t spacing = 0, uint16_t offset = UINT16_MAX, uint16_t startY=0, uint16_t stopY=1),
|
||||
setMainSegmentId(uint8_t n),
|
||||
resetSegments(),
|
||||
makeAutoSegments(bool forceReset = false),
|
||||
fixInvalidSegments(),
|
||||
setPixelColor(int n, uint32_t c),
|
||||
show(void),
|
||||
resetSegments(), // marks all segments for reset
|
||||
makeAutoSegments(bool forceReset = false), // will create segments based on configured outputs
|
||||
fixInvalidSegments(), // fixes incorrect segment configuration
|
||||
setPixelColor(unsigned n, uint32_t c), // paints absolute strip pixel with index n and color c
|
||||
show(void), // initiates LED output
|
||||
setTargetFps(uint8_t fps),
|
||||
addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name), // add effect to the list; defined in FX.cpp
|
||||
setupEffectData(void); // add default effects to the list; defined in FX.cpp
|
||||
setupEffectData(void); // add default effects to the list; defined in FX.cpp
|
||||
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
|
||||
inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); }
|
||||
inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); }
|
||||
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
|
||||
inline void fill(uint32_t c) { for (int i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline)
|
||||
// outsmart the compiler :) by correctly overloading
|
||||
inline void setPixelColor(int n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(int n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); }
|
||||
inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments.
|
||||
inline void setShowCallback(show_callback cb) { _callback = cb; }
|
||||
inline void setTransition(uint16_t t) { _transitionDur = t; }
|
||||
inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColor(unsigned n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); }
|
||||
inline void fill(uint32_t c) { for (unsigned i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline)
|
||||
inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments.
|
||||
inline void setShowCallback(show_callback cb) { _callback = cb; }
|
||||
inline void setTransition(uint16_t t) { _transitionDur = t; } // sets transition time (in ms)
|
||||
inline void appendSegment(const Segment &seg = Segment()) { if (_segments.size() < getMaxSegments()) _segments.push_back(seg); }
|
||||
inline void suspend(void) { _suspend = true; } // will suspend (and canacel) strip.service() execution
|
||||
inline void resume(void) { _suspend = false; } // will resume strip.service() execution
|
||||
|
||||
bool
|
||||
paletteFade,
|
||||
@ -787,48 +790,47 @@ class WS2812FX { // 96 bytes
|
||||
isUpdating(void),
|
||||
deserializeMap(uint8_t n=0);
|
||||
|
||||
inline bool isServicing(void) { return _isServicing; }
|
||||
inline bool hasWhiteChannel(void) {return _hasWhiteChannel;}
|
||||
inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;}
|
||||
inline bool isServicing(void) { return _isServicing; } // returns true if strip.service() is executing
|
||||
inline bool hasWhiteChannel(void) { return _hasWhiteChannel; } // returns true if strip contains separate white chanel
|
||||
inline bool isOffRefreshRequired(void) { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset)
|
||||
inline bool isSuspended(void) { return _suspend; } // returns true if strip.service() execution is suspended
|
||||
inline bool needsUpdate(void) { return _triggered; } // returns true if strip received a trigger() request
|
||||
|
||||
uint8_t
|
||||
paletteBlend,
|
||||
milliampsPerLed,
|
||||
cctBlending,
|
||||
getActiveSegmentsNum(void),
|
||||
getFirstSelectedSegId(void),
|
||||
getLastActiveSegmentId(void),
|
||||
getActiveSegsLightCapabilities(bool selectedOnly = false),
|
||||
setPixelSegment(uint8_t n);
|
||||
getActiveSegsLightCapabilities(bool selectedOnly = false);
|
||||
|
||||
inline uint8_t getBrightness(void) { return _brightness; }
|
||||
inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
||||
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments
|
||||
inline uint8_t getCurrSegmentId(void) { return _segment_index; }
|
||||
inline uint8_t getMainSegmentId(void) { return _mainSegment; }
|
||||
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count
|
||||
inline uint8_t getTargetFps() { return _targetFps; }
|
||||
inline uint8_t getModeCount() { return _modeCount; }
|
||||
inline uint8_t getBrightness(void) { return _brightness; } // returns current strip brightness
|
||||
inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value)
|
||||
inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments
|
||||
inline uint8_t getCurrSegmentId(void) { return _segment_index; } // returns current segment index (only valid while strip.isServicing())
|
||||
inline uint8_t getMainSegmentId(void) { return _mainSegment; } // returns main segment index
|
||||
inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count
|
||||
inline uint8_t getTargetFps() { return _targetFps; } // returns rough FPS value for las 2s interval
|
||||
inline uint8_t getModeCount() { return _modeCount; } // returns number of registered modes/effects
|
||||
|
||||
uint16_t
|
||||
ablMilliampsMax,
|
||||
currentMilliamps,
|
||||
getLengthPhysical(void),
|
||||
getLengthTotal(void), // will include virtual/nonexistent pixels in matrix
|
||||
getFps();
|
||||
getFps(),
|
||||
getMappedPixelIndex(uint16_t index);
|
||||
|
||||
inline uint16_t getFrameTime(void) { return _frametime; }
|
||||
inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; }
|
||||
inline uint16_t getLength(void) { return _length; } // 2D matrix may have less pixels than W*H
|
||||
inline uint16_t getTransition(void) { return _transitionDur; }
|
||||
inline uint16_t getFrameTime(void) { return _frametime; } // returns amount of time a frame should take (in ms)
|
||||
inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant)
|
||||
inline uint16_t getLength(void) { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H)
|
||||
inline uint16_t getTransition(void) { return _transitionDur; } // returns currently set transition time (in ms)
|
||||
|
||||
uint32_t
|
||||
now,
|
||||
timebase,
|
||||
getPixelColor(uint16_t);
|
||||
|
||||
inline uint32_t getLastShow(void) { return _lastShow; }
|
||||
inline uint32_t segColor(uint8_t i) { return _colors_t[i]; }
|
||||
inline uint32_t getLastShow(void) { return _lastShow; } // returns millis() timestamp of last strip.show() call
|
||||
inline uint32_t segColor(uint8_t i) { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition
|
||||
|
||||
const char *
|
||||
getModeData(uint8_t id = 0) { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); }
|
||||
@ -837,9 +839,9 @@ class WS2812FX { // 96 bytes
|
||||
getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data
|
||||
|
||||
Segment& getSegment(uint8_t id);
|
||||
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; }
|
||||
inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; }
|
||||
inline Segment* getSegments(void) { return &(_segments[0]); }
|
||||
inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected"
|
||||
inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; } // returns reference to main segment
|
||||
inline Segment* getSegments(void) { return &(_segments[0]); } // returns pointer to segment vector structure (warning: use carefully)
|
||||
|
||||
// 2D support (panels)
|
||||
bool
|
||||
@ -875,10 +877,10 @@ class WS2812FX { // 96 bytes
|
||||
std::vector<Panel> panel;
|
||||
#endif
|
||||
|
||||
void setUpMatrix();
|
||||
void setUpMatrix(); // sets up automatic matrix ledmap from panel configuration
|
||||
|
||||
// outsmart the compiler :) by correctly overloading
|
||||
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(y * Segment::maxWidth + x, c); }
|
||||
inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor((unsigned)(y * Segment::maxWidth + x), c); }
|
||||
inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); }
|
||||
inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); }
|
||||
|
||||
@ -899,6 +901,8 @@ class WS2812FX { // 96 bytes
|
||||
friend class Segment;
|
||||
|
||||
private:
|
||||
volatile bool _suspend;
|
||||
|
||||
uint16_t _length;
|
||||
uint8_t _brightness;
|
||||
uint16_t _transitionDur;
|
||||
@ -932,9 +936,10 @@ class WS2812FX { // 96 bytes
|
||||
uint16_t _qStart, _qStop, _qStartY, _qStopY;
|
||||
uint8_t _qGrouping, _qSpacing;
|
||||
uint16_t _qOffset;
|
||||
|
||||
/*
|
||||
void
|
||||
setUpSegmentFromQueuedChanges(void);
|
||||
*/
|
||||
};
|
||||
|
||||
extern const char JSON_mode_names[];
|
||||
|
@ -36,14 +36,9 @@
|
||||
// so matrix should disable regular ledmap processing
|
||||
void WS2812FX::setUpMatrix() {
|
||||
#ifndef WLED_DISABLE_2D
|
||||
// erase old ledmap, just in case.
|
||||
if (customMappingTable != nullptr) delete[] customMappingTable;
|
||||
customMappingTable = nullptr;
|
||||
customMappingSize = 0;
|
||||
|
||||
// isMatrix is set in cfg.cpp or set.cpp
|
||||
if (isMatrix) {
|
||||
// calculate width dynamically because it will have gaps
|
||||
// calculate width dynamically because it may have gaps
|
||||
Segment::maxWidth = 1;
|
||||
Segment::maxHeight = 1;
|
||||
for (size_t i = 0; i < panel.size(); i++) {
|
||||
@ -68,15 +63,17 @@ void WS2812FX::setUpMatrix() {
|
||||
return;
|
||||
}
|
||||
|
||||
customMappingTable = new uint16_t[Segment::maxWidth * Segment::maxHeight];
|
||||
customMappingSize = 0; // prevent use of mapping if anything goes wrong
|
||||
|
||||
if (customMappingTable == nullptr) customMappingTable = new uint16_t[getLengthTotal()];
|
||||
|
||||
if (customMappingTable != nullptr) {
|
||||
customMappingSize = Segment::maxWidth * Segment::maxHeight;
|
||||
customMappingSize = getLengthTotal();
|
||||
|
||||
// fill with empty in case we don't fill the entire matrix
|
||||
for (size_t i = 0; i< customMappingSize; i++) {
|
||||
customMappingTable[i] = (uint16_t)-1;
|
||||
}
|
||||
unsigned matrixSize = Segment::maxWidth * Segment::maxHeight;
|
||||
for (unsigned i = 0; i<matrixSize; i++) customMappingTable[i] = 0xFFFFU;
|
||||
for (unsigned i = matrixSize; i<getLengthTotal(); i++) customMappingTable[i] = i; // trailing LEDs for ledmap (after matrix) if it exist
|
||||
|
||||
// we will try to load a "gap" array (a JSON file)
|
||||
// the array has to have the same amount of values as mapping array (or larger)
|
||||
@ -94,14 +91,14 @@ void WS2812FX::setUpMatrix() {
|
||||
DEBUG_PRINT(F("Reading LED gap from "));
|
||||
DEBUG_PRINTLN(fileName);
|
||||
// read the array into global JSON buffer
|
||||
if (readObjectFromFile(fileName, nullptr, &doc)) {
|
||||
if (readObjectFromFile(fileName, nullptr, pDoc)) {
|
||||
// the array is similar to ledmap, except it has only 3 values:
|
||||
// -1 ... missing pixel (do not increase pixel count)
|
||||
// 0 ... inactive pixel (it does count, but should be mapped out (-1))
|
||||
// 1 ... active pixel (it will count and will be mapped)
|
||||
JsonArray map = doc.as<JsonArray>();
|
||||
JsonArray map = pDoc->as<JsonArray>();
|
||||
gapSize = map.size();
|
||||
if (!map.isNull() && gapSize >= customMappingSize) { // not an empty map
|
||||
if (!map.isNull() && gapSize >= matrixSize) { // not an empty map
|
||||
gapTable = new int8_t[gapSize];
|
||||
if (gapTable) for (size_t i = 0; i < gapSize; i++) {
|
||||
gapTable[i] = constrain(map[i], -1, 1);
|
||||
|
@ -143,27 +143,28 @@ Segment& Segment::operator= (Segment &&orig) noexcept {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// allocates effect data buffer on heap and initialises (erases) it
|
||||
bool IRAM_ATTR Segment::allocateData(size_t len) {
|
||||
if (len == 0) return false; // nothing to do
|
||||
if (data && _dataLen >= len) { // already allocated enough (reduce fragmentation)
|
||||
if (call == 0) memset(data, 0, len); // erase buffer if called during effect initialisation
|
||||
return true;
|
||||
}
|
||||
//DEBUG_PRINTF("-- Allocating data (%d): %p\n", len, this);
|
||||
deallocateData();
|
||||
if (len == 0) return false; // nothing to do
|
||||
deallocateData(); // if the old buffer was smaller release it first
|
||||
if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) {
|
||||
// not enough memory
|
||||
DEBUG_PRINT(F("!!! Effect RAM depleted: "));
|
||||
DEBUG_PRINTF("%d/%d !!!\n", len, Segment::getUsedSegmentData());
|
||||
errorFlag = ERR_NORAM;
|
||||
return false;
|
||||
}
|
||||
// do not use SPI RAM on ESP32 since it is slow
|
||||
data = (byte*) malloc(len);
|
||||
data = (byte*)calloc(len, sizeof(byte));
|
||||
if (!data) { DEBUG_PRINTLN(F("!!! Allocation failed. !!!")); return false; } // allocation failed
|
||||
Segment::addUsedSegmentData(len);
|
||||
//DEBUG_PRINTF("--- Allocated data (%p): %d/%d -> %p\n", this, len, Segment::getUsedSegmentData(), data);
|
||||
_dataLen = len;
|
||||
memset(data, 0, len);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -194,7 +195,7 @@ void IRAM_ATTR Segment::deallocateData() {
|
||||
void Segment::resetIfRequired() {
|
||||
if (!reset) return;
|
||||
//DEBUG_PRINTF("-- Segment reset: %p\n", this);
|
||||
deallocateData();
|
||||
if (data && _dataLen > 0) memset(data, 0, _dataLen); // prevent heap fragmentation (just erase buffer instead of deallocateData())
|
||||
next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0;
|
||||
reset = false;
|
||||
}
|
||||
@ -424,7 +425,7 @@ uint8_t IRAM_ATTR Segment::currentBri(bool useCct) {
|
||||
uint32_t prog = progress();
|
||||
if (prog < 0xFFFFU) {
|
||||
uint32_t curBri = (useCct ? cct : (on ? opacity : 0)) * prog;
|
||||
curBri += (useCct ? _t->_cctT : (on ? _t->_briT : 0)) * (0xFFFFU - prog);
|
||||
curBri += (useCct ? _t->_cctT : _t->_briT) * (0xFFFFU - prog);
|
||||
return curBri / 0xFFFFU;
|
||||
}
|
||||
return (useCct ? cct : (on ? opacity : 0));
|
||||
@ -439,6 +440,7 @@ uint8_t IRAM_ATTR Segment::currentMode() {
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR Segment::currentColor(uint8_t slot) {
|
||||
if (slot >= NUM_COLORS) slot = 0;
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
return isInTransition() ? color_blend(_t->_segT._colorT[slot], colors[slot], progress(), true) : colors[slot];
|
||||
#else
|
||||
@ -468,7 +470,7 @@ void Segment::handleRandomPalette() {
|
||||
}
|
||||
|
||||
// segId is given when called from network callback, changes are queued if that segment is currently in its effect function
|
||||
void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y, uint8_t segId) {
|
||||
void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) {
|
||||
// return if neither bounds nor grouping have changed
|
||||
bool boundsUnchanged = (start == i1 && stop == i2);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
@ -561,35 +563,36 @@ void Segment::setOption(uint8_t n, bool val) {
|
||||
}
|
||||
|
||||
void Segment::setMode(uint8_t fx, bool loadDefaults) {
|
||||
// skip reserved
|
||||
while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++;
|
||||
if (fx >= strip.getModeCount()) fx = 0; // set solid mode
|
||||
// if we have a valid mode & is not reserved
|
||||
if (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4)) {
|
||||
if (fx != mode) {
|
||||
if (fx != mode) {
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
if (modeBlending) startTransition(strip.getTransition()); // set effect transitions
|
||||
if (modeBlending) startTransition(strip.getTransition()); // set effect transitions
|
||||
#endif
|
||||
mode = fx;
|
||||
// load default values from effect string
|
||||
if (loadDefaults) {
|
||||
int16_t sOpt;
|
||||
sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED;
|
||||
sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY;
|
||||
sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1;
|
||||
sOpt = extractModeDefaults(fx, "c2"); custom2 = (sOpt >= 0) ? sOpt : DEFAULT_C2;
|
||||
sOpt = extractModeDefaults(fx, "c3"); custom3 = (sOpt >= 0) ? sOpt : DEFAULT_C3;
|
||||
sOpt = extractModeDefaults(fx, "o1"); check1 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||
sOpt = extractModeDefaults(fx, "o2"); check2 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||
sOpt = extractModeDefaults(fx, "o3"); check3 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||
sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7); else map1D2D = M12_Pixels; // reset mapping if not defined (2D FX may not work)
|
||||
sOpt = extractModeDefaults(fx, "si"); if (sOpt >= 0) soundSim = constrain(sOpt, 0, 3);
|
||||
sOpt = extractModeDefaults(fx, "rev"); if (sOpt >= 0) reverse = (bool)sOpt;
|
||||
sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business
|
||||
sOpt = extractModeDefaults(fx, "rY"); if (sOpt >= 0) reverse_y = (bool)sOpt;
|
||||
sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business
|
||||
sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); //else setPalette(0);
|
||||
}
|
||||
markForReset();
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
mode = fx;
|
||||
// load default values from effect string
|
||||
if (loadDefaults) {
|
||||
int16_t sOpt;
|
||||
sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED;
|
||||
sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY;
|
||||
sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1;
|
||||
sOpt = extractModeDefaults(fx, "c2"); custom2 = (sOpt >= 0) ? sOpt : DEFAULT_C2;
|
||||
sOpt = extractModeDefaults(fx, "c3"); custom3 = (sOpt >= 0) ? sOpt : DEFAULT_C3;
|
||||
sOpt = extractModeDefaults(fx, "o1"); check1 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||
sOpt = extractModeDefaults(fx, "o2"); check2 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||
sOpt = extractModeDefaults(fx, "o3"); check3 = (sOpt >= 0) ? (bool)sOpt : false;
|
||||
sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7); else map1D2D = M12_Pixels; // reset mapping if not defined (2D FX may not work)
|
||||
sOpt = extractModeDefaults(fx, "si"); if (sOpt >= 0) soundSim = constrain(sOpt, 0, 3);
|
||||
sOpt = extractModeDefaults(fx, "rev"); if (sOpt >= 0) reverse = (bool)sOpt;
|
||||
sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business
|
||||
sOpt = extractModeDefaults(fx, "rY"); if (sOpt >= 0) reverse_y = (bool)sOpt;
|
||||
sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business
|
||||
sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); //else setPalette(0);
|
||||
}
|
||||
markForReset();
|
||||
stateChanged = true; // send UDP/WS broadcast
|
||||
}
|
||||
}
|
||||
|
||||
@ -751,10 +754,10 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col)
|
||||
uint32_t tmpCol = col;
|
||||
// set all the pixels in the group
|
||||
for (int j = 0; j < grouping; j++) {
|
||||
uint16_t indexSet = i + ((reverse) ? -j : j);
|
||||
unsigned indexSet = i + ((reverse) ? -j : j);
|
||||
if (indexSet >= start && indexSet < stop) {
|
||||
if (mirror) { //set the corresponding mirrored pixel
|
||||
uint16_t indexMir = stop - indexSet + start - 1;
|
||||
unsigned indexMir = stop - indexSet + start - 1;
|
||||
indexMir += offset; // offset/phase
|
||||
if (indexMir >= stop) indexMir -= len; // wrap
|
||||
#ifndef WLED_DISABLE_MODE_BLEND
|
||||
@ -884,8 +887,7 @@ void Segment::refreshLightCapabilities() {
|
||||
if (start < Segment::maxWidth * Segment::maxHeight) {
|
||||
// we are withing 2D matrix (includes 1D segments)
|
||||
for (int y = startY; y < stopY; y++) for (int x = start; x < stop; x++) {
|
||||
uint16_t index = x + Segment::maxWidth * y;
|
||||
if (index < strip.customMappingSize) index = strip.customMappingTable[index]; // convert logical address to physical
|
||||
uint16_t index = strip.getMappedPixelIndex(x + Segment::maxWidth * y); // convert logical address to physical
|
||||
if (index < 0xFFFFU) {
|
||||
if (segStartIdx > index) segStartIdx = index;
|
||||
if (segStopIdx < index) segStopIdx = index;
|
||||
@ -898,8 +900,8 @@ void Segment::refreshLightCapabilities() {
|
||||
segStopIdx = stop;
|
||||
}
|
||||
|
||||
for (unsigned b = 0; b < busses.getNumBusses(); b++) {
|
||||
Bus *bus = busses.getBus(b);
|
||||
for (unsigned b = 0; b < BusManager::getNumBusses(); b++) {
|
||||
Bus *bus = BusManager::getBus(b);
|
||||
if (bus == nullptr || bus->getLength()==0) break;
|
||||
if (!bus->isOk()) continue;
|
||||
if (bus->getStart() >= segStopIdx) continue;
|
||||
@ -1024,7 +1026,7 @@ void Segment::blur(uint8_t blur_amount) {
|
||||
* Inspired by the Adafruit examples.
|
||||
*/
|
||||
uint32_t Segment::color_wheel(uint8_t pos) {
|
||||
if (palette) return color_from_palette(pos, false, true, 0);
|
||||
if (palette) return color_from_palette(pos, false, true, 0); // perhaps "strip.paletteBlend < 2" should be better instead of "true"
|
||||
uint8_t w = W(currentColor(0));
|
||||
pos = 255 - pos;
|
||||
if (pos < 85) {
|
||||
@ -1055,6 +1057,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
|
||||
|
||||
uint8_t paletteIndex = i;
|
||||
if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1);
|
||||
// paletteBlend: 0 - wrap when moving, 1 - always wrap, 2 - never wrap, 3 - none (undefined)
|
||||
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
|
||||
CRGBPalette16 curPal;
|
||||
curPal = currentPalette(curPal, palette);
|
||||
@ -1084,7 +1087,7 @@ void WS2812FX::finalizeInit(void) {
|
||||
_hasWhiteChannel = _isOffRefreshRequired = false;
|
||||
|
||||
//if busses failed to load, add default (fresh install, FS issue, ...)
|
||||
if (busses.getNumBusses() == 0) {
|
||||
if (BusManager::getNumBusses() == 0) {
|
||||
DEBUG_PRINTLN(F("No busses, init default"));
|
||||
const uint8_t defDataPins[] = {DATA_PINS};
|
||||
const uint16_t defCounts[] = {PIXEL_COUNTS};
|
||||
@ -1097,13 +1100,13 @@ void WS2812FX::finalizeInit(void) {
|
||||
uint16_t count = defCounts[(i < defNumCounts) ? i : defNumCounts -1];
|
||||
prevLen += count;
|
||||
BusConfig defCfg = BusConfig(DEFAULT_LED_TYPE, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY);
|
||||
if (busses.add(defCfg) == -1) break;
|
||||
if (BusManager::add(defCfg) == -1) break;
|
||||
}
|
||||
}
|
||||
|
||||
_length = 0;
|
||||
for (int i=0; i<busses.getNumBusses(); i++) {
|
||||
Bus *bus = busses.getBus(i);
|
||||
for (int i=0; i<BusManager::getNumBusses(); i++) {
|
||||
Bus *bus = BusManager::getBus(i);
|
||||
if (bus == nullptr) continue;
|
||||
if (bus->getStart() + bus->getLength() > MAX_LEDS) break;
|
||||
//RGBW mode is enabled if at least one of the strips is RGBW
|
||||
@ -1121,29 +1124,28 @@ void WS2812FX::finalizeInit(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (isMatrix) setUpMatrix();
|
||||
else {
|
||||
Segment::maxWidth = _length;
|
||||
Segment::maxHeight = 1;
|
||||
}
|
||||
Segment::maxWidth = _length;
|
||||
Segment::maxHeight = 1;
|
||||
|
||||
//segments are created in makeAutoSegments();
|
||||
DEBUG_PRINTLN(F("Loading custom palettes"));
|
||||
loadCustomPalettes(); // (re)load all custom palettes
|
||||
DEBUG_PRINTLN(F("Loading custom ledmaps"));
|
||||
deserializeMap(); // (re)load default ledmap
|
||||
deserializeMap(); // (re)load default ledmap (will also setUpMatrix() if ledmap does not exist)
|
||||
}
|
||||
|
||||
void WS2812FX::service() {
|
||||
unsigned long nowUp = millis(); // Be aware, millis() rolls over every 49 days
|
||||
now = nowUp + timebase;
|
||||
if (nowUp - _lastShow < MIN_SHOW_DELAY) return;
|
||||
if (nowUp - _lastShow < MIN_SHOW_DELAY || _suspend) return;
|
||||
bool doShow = false;
|
||||
|
||||
_isServicing = true;
|
||||
_segment_index = 0;
|
||||
Segment::handleRandomPalette(); // move it into for loop when each segment has individual random palette
|
||||
for (segment &seg : _segments) {
|
||||
if (_suspend) return; // immediately stop processing segments if suspend requested during service()
|
||||
|
||||
// process transition (mode changes in the middle of transition)
|
||||
seg.handleTransition();
|
||||
// reset the segment runtime data if needed
|
||||
@ -1163,7 +1165,7 @@ void WS2812FX::service() {
|
||||
_colors_t[1] = gamma32(seg.currentColor(1));
|
||||
_colors_t[2] = gamma32(seg.currentColor(2));
|
||||
seg.currentPalette(_currentPalette, seg.palette); // we need to pass reference
|
||||
if (!cctFromRgb || correctWB) busses.setSegmentCCT(seg.currentBri(true), correctWB);
|
||||
if (!cctFromRgb || correctWB) BusManager::setSegmentCCT(seg.currentBri(true), correctWB);
|
||||
// Effect blending
|
||||
// When two effects are being blended, each may have different segment data, this
|
||||
// data needs to be saved first and then restored before running previous mode.
|
||||
@ -1190,11 +1192,11 @@ void WS2812FX::service() {
|
||||
|
||||
seg.next_time = nowUp + delay;
|
||||
}
|
||||
if (_segment_index == _queuedChangesSegId) setUpSegmentFromQueuedChanges();
|
||||
// if (_segment_index == _queuedChangesSegId) setUpSegmentFromQueuedChanges();
|
||||
_segment_index++;
|
||||
}
|
||||
_virtualSegmentLength = 0;
|
||||
busses.setSegmentCCT(-1);
|
||||
BusManager::setSegmentCCT(-1);
|
||||
_isServicing = false;
|
||||
_triggered = false;
|
||||
|
||||
@ -1210,16 +1212,16 @@ void WS2812FX::service() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void IRAM_ATTR WS2812FX::setPixelColor(int i, uint32_t col) {
|
||||
if (i < customMappingSize) i = customMappingTable[i];
|
||||
void IRAM_ATTR WS2812FX::setPixelColor(unsigned i, uint32_t col) {
|
||||
i = getMappedPixelIndex(i);
|
||||
if (i >= _length) return;
|
||||
busses.setPixelColor(i, col);
|
||||
BusManager::setPixelColor(i, col);
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR WS2812FX::getPixelColor(uint16_t i) {
|
||||
if (i < customMappingSize) i = customMappingTable[i];
|
||||
i = getMappedPixelIndex(i);
|
||||
if (i >= _length) return 0;
|
||||
return busses.getPixelColor(i);
|
||||
return BusManager::getPixelColor(i);
|
||||
}
|
||||
|
||||
void WS2812FX::show(void) {
|
||||
@ -1230,7 +1232,7 @@ void WS2812FX::show(void) {
|
||||
// some buses send asynchronously and this method will return before
|
||||
// all of the data has been sent.
|
||||
// See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods
|
||||
busses.show();
|
||||
BusManager::show();
|
||||
|
||||
unsigned long showNow = millis();
|
||||
size_t diff = showNow - _lastShow;
|
||||
@ -1245,7 +1247,7 @@ void WS2812FX::show(void) {
|
||||
* On some hardware (ESP32), strip updates are done asynchronously.
|
||||
*/
|
||||
bool WS2812FX::isUpdating() {
|
||||
return !busses.canAllShow();
|
||||
return !BusManager::canAllShow();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1304,7 +1306,7 @@ void WS2812FX::setBrightness(uint8_t b, bool direct) {
|
||||
}
|
||||
// setting brightness with NeoPixelBusLg has no effect on already painted pixels,
|
||||
// so we need to force an update to existing buffer
|
||||
busses.setBrightness(b);
|
||||
BusManager::setBrightness(b);
|
||||
if (!direct) {
|
||||
unsigned long t = millis();
|
||||
if (_segments[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) trigger(); //apply brightness change immediately if no refresh soon
|
||||
@ -1360,8 +1362,8 @@ uint16_t WS2812FX::getLengthTotal(void) {
|
||||
|
||||
uint16_t WS2812FX::getLengthPhysical(void) {
|
||||
uint16_t len = 0;
|
||||
for (size_t b = 0; b < busses.getNumBusses(); b++) {
|
||||
Bus *bus = busses.getBus(b);
|
||||
for (size_t b = 0; b < BusManager::getNumBusses(); b++) {
|
||||
Bus *bus = BusManager::getBus(b);
|
||||
if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses
|
||||
len += bus->getLength();
|
||||
}
|
||||
@ -1372,8 +1374,8 @@ uint16_t WS2812FX::getLengthPhysical(void) {
|
||||
//returns if there is an RGBW bus (supports RGB and White, not only white)
|
||||
//not influenced by auto-white mode, also true if white slider does not affect output white channel
|
||||
bool WS2812FX::hasRGBWBus(void) {
|
||||
for (size_t b = 0; b < busses.getNumBusses(); b++) {
|
||||
Bus *bus = busses.getBus(b);
|
||||
for (size_t b = 0; b < BusManager::getNumBusses(); b++) {
|
||||
Bus *bus = BusManager::getBus(b);
|
||||
if (bus == nullptr || bus->getLength()==0) break;
|
||||
if (bus->hasRGB() && bus->hasWhite()) return true;
|
||||
}
|
||||
@ -1382,8 +1384,8 @@ bool WS2812FX::hasRGBWBus(void) {
|
||||
|
||||
bool WS2812FX::hasCCTBus(void) {
|
||||
if (cctFromRgb && !correctWB) return false;
|
||||
for (size_t b = 0; b < busses.getNumBusses(); b++) {
|
||||
Bus *bus = busses.getBus(b);
|
||||
for (size_t b = 0; b < BusManager::getNumBusses(); b++) {
|
||||
Bus *bus = BusManager::getBus(b);
|
||||
if (bus == nullptr || bus->getLength()==0) break;
|
||||
switch (bus->getType()) {
|
||||
case TYPE_ANALOG_5CH:
|
||||
@ -1394,18 +1396,18 @@ bool WS2812FX::hasCCTBus(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void WS2812FX::purgeSegments(bool force) {
|
||||
void WS2812FX::purgeSegments() {
|
||||
// remove all inactive segments (from the back)
|
||||
int deleted = 0;
|
||||
if (_segments.size() <= 1) return;
|
||||
for (size_t i = _segments.size()-1; i > 0; i--)
|
||||
if (_segments[i].stop == 0 || force) {
|
||||
if (_segments[i].stop == 0) {
|
||||
deleted++;
|
||||
_segments.erase(_segments.begin() + i);
|
||||
}
|
||||
if (deleted) {
|
||||
_segments.shrink_to_fit();
|
||||
/*if (_mainSegment >= _segments.size())*/ setMainSegmentId(0);
|
||||
setMainSegmentId(0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1420,7 +1422,7 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group
|
||||
appendSegment(Segment(0, strip.getLengthTotal()));
|
||||
segId = getSegmentsNum()-1; // segments are added at the end of list
|
||||
}
|
||||
|
||||
/*
|
||||
if (_queuedChangesSegId == segId) _queuedChangesSegId = 255; // cancel queued change if already queued for this segment
|
||||
|
||||
if (segId < getMaxSegments() && segId == getCurrSegmentId() && isServicing()) { // queue change to prevent concurrent access
|
||||
@ -1432,17 +1434,19 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group
|
||||
DEBUG_PRINT(F("Segment queued: ")); DEBUG_PRINTLN(segId);
|
||||
return; // queued changes are applied immediately after effect function returns
|
||||
}
|
||||
|
||||
*/
|
||||
suspend();
|
||||
_segments[segId].setUp(i1, i2, grouping, spacing, offset, startY, stopY);
|
||||
resume();
|
||||
if (segId > 0 && segId == getSegmentsNum()-1 && i2 <= i1) _segments.pop_back(); // if last segment was deleted remove it from vector
|
||||
}
|
||||
|
||||
/*
|
||||
void WS2812FX::setUpSegmentFromQueuedChanges() {
|
||||
if (_queuedChangesSegId >= getSegmentsNum()) return;
|
||||
getSegment(_queuedChangesSegId).setUp(_qStart, _qStop, _qGrouping, _qSpacing, _qOffset, _qStartY, _qStopY);
|
||||
_segments[_queuedChangesSegId].setUp(_qStart, _qStop, _qGrouping, _qSpacing, _qOffset, _qStartY, _qStopY);
|
||||
_queuedChangesSegId = 255;
|
||||
}
|
||||
|
||||
*/
|
||||
void WS2812FX::resetSegments() {
|
||||
_segments.clear(); // destructs all Segment as part of clearing
|
||||
#ifndef WLED_DISABLE_2D
|
||||
@ -1469,8 +1473,8 @@ void WS2812FX::makeAutoSegments(bool forceReset) {
|
||||
}
|
||||
#endif
|
||||
|
||||
for (size_t i = s; i < busses.getNumBusses(); i++) {
|
||||
Bus* b = busses.getBus(i);
|
||||
for (size_t i = s; i < BusManager::getNumBusses(); i++) {
|
||||
Bus* b = BusManager::getBus(i);
|
||||
|
||||
segStarts[s] = b->getStart();
|
||||
segStops[s] = segStarts[s] + b->getLength();
|
||||
@ -1559,8 +1563,8 @@ void WS2812FX::fixInvalidSegments() {
|
||||
bool WS2812FX::checkSegmentAlignment() {
|
||||
bool aligned = false;
|
||||
for (segment &seg : _segments) {
|
||||
for (unsigned b = 0; b<busses.getNumBusses(); b++) {
|
||||
Bus *bus = busses.getBus(b);
|
||||
for (unsigned b = 0; b<BusManager::getNumBusses(); b++) {
|
||||
Bus *bus = BusManager::getBus(b);
|
||||
if (seg.start == bus->getStart() && seg.stop == bus->getStart() + bus->getLength()) aligned = true;
|
||||
}
|
||||
if (seg.start == 0 && seg.stop == _length) aligned = true;
|
||||
@ -1569,18 +1573,7 @@ bool WS2812FX::checkSegmentAlignment() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//After this function is called, setPixelColor() will use that segment (offsets, grouping, ... will apply)
|
||||
//Note: If called in an interrupt (e.g. JSON API), original segment must be restored,
|
||||
//otherwise it can lead to a crash on ESP32 because _segment_index is modified while in use by the main thread
|
||||
uint8_t WS2812FX::setPixelSegment(uint8_t n) {
|
||||
uint8_t prevSegId = _segment_index;
|
||||
if (n < _segments.size()) {
|
||||
_segment_index = n;
|
||||
_virtualSegmentLength = _segments[_segment_index].virtualLength();
|
||||
}
|
||||
return prevSegId;
|
||||
}
|
||||
|
||||
// used by analog clock overlay
|
||||
void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) {
|
||||
if (i2 < i) std::swap(i,i2);
|
||||
for (unsigned x = i; x <= i2; x++) setPixelColor(x, col);
|
||||
@ -1658,46 +1651,44 @@ bool WS2812FX::deserializeMap(uint8_t n) {
|
||||
strcat_P(fileName, PSTR(".json"));
|
||||
bool isFile = WLED_FS.exists(fileName);
|
||||
|
||||
if (!isFile) {
|
||||
// erase custom mapping if selecting nonexistent ledmap.json (n==0)
|
||||
if (!isMatrix && !n && customMappingTable != nullptr) {
|
||||
customMappingSize = 0;
|
||||
delete[] customMappingTable;
|
||||
customMappingTable = nullptr;
|
||||
}
|
||||
customMappingSize = 0; // prevent use of mapping if anything goes wrong
|
||||
|
||||
if (!isFile && n==0 && isMatrix) {
|
||||
setUpMatrix();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!requestJSONBufferLock(7)) return false;
|
||||
if (!isFile || !requestJSONBufferLock(7)) return false; // this will trigger setUpMatrix() when called from wled.cpp
|
||||
|
||||
if (!readObjectFromFile(fileName, nullptr, &doc)) {
|
||||
if (!readObjectFromFile(fileName, nullptr, pDoc)) {
|
||||
DEBUG_PRINT(F("ERROR Invalid ledmap in ")); DEBUG_PRINTLN(fileName);
|
||||
releaseJSONBufferLock();
|
||||
return false; //if file does not exist just exit
|
||||
return false; // if file does not load properly then exit
|
||||
}
|
||||
|
||||
DEBUG_PRINT(F("Reading LED map from "));
|
||||
DEBUG_PRINTLN(fileName);
|
||||
DEBUG_PRINT(F("Reading LED map from ")); DEBUG_PRINTLN(fileName);
|
||||
|
||||
// erase old custom ledmap
|
||||
if (customMappingTable != nullptr) {
|
||||
customMappingSize = 0;
|
||||
delete[] customMappingTable;
|
||||
customMappingTable = nullptr;
|
||||
}
|
||||
if (customMappingTable == nullptr) customMappingTable = new uint16_t[getLengthTotal()];
|
||||
|
||||
JsonArray map = doc[F("map")];
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
JsonArray map = root[F("map")];
|
||||
if (!map.isNull() && map.size()) { // not an empty map
|
||||
customMappingSize = map.size();
|
||||
customMappingTable = new uint16_t[customMappingSize];
|
||||
for (unsigned i=0; i<customMappingSize; i++) {
|
||||
customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]);
|
||||
}
|
||||
customMappingSize = min((unsigned)map.size(), (unsigned)getLengthTotal());
|
||||
for (unsigned i=0; i<customMappingSize; i++) customMappingTable[i] = (uint16_t) (map[i]<0 ? 0xFFFFU : map[i]);
|
||||
}
|
||||
|
||||
releaseJSONBufferLock();
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t IRAM_ATTR WS2812FX::getMappedPixelIndex(uint16_t index) {
|
||||
// convert logical address to physical
|
||||
if (index < customMappingSize
|
||||
&& (realtimeMode == REALTIME_MODE_INACTIVE || realtimeRespectLedMaps)) index = customMappingTable[index];
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
WS2812FX* WS2812FX::instance = nullptr;
|
||||
|
||||
|
99
wled00/bus_manager.cpp
Normal file → Executable file
99
wled00/bus_manager.cpp
Normal file → Executable file
@ -53,7 +53,8 @@ void ColorOrderMap::add(uint16_t start, uint16_t len, uint8_t colorOrder) {
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
if (colorOrder > COL_ORDER_MAX) {
|
||||
// upper nibble contains W swap information
|
||||
if ((colorOrder & 0x0F) > COL_ORDER_MAX) {
|
||||
return;
|
||||
}
|
||||
_mappings[_count].start = start;
|
||||
@ -63,12 +64,13 @@ void ColorOrderMap::add(uint16_t start, uint16_t len, uint8_t colorOrder) {
|
||||
}
|
||||
|
||||
uint8_t IRAM_ATTR ColorOrderMap::getPixelColorOrder(uint16_t pix, uint8_t defaultColorOrder) const {
|
||||
if (_count == 0) return defaultColorOrder;
|
||||
// upper nibble containd W swap information
|
||||
uint8_t swapW = defaultColorOrder >> 4;
|
||||
for (unsigned i = 0; i < _count; i++) {
|
||||
if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) {
|
||||
return _mappings[i].colorOrder | (swapW << 4);
|
||||
if (_count > 0) {
|
||||
// upper nibble contains W swap information
|
||||
// when ColorOrderMap's upper nibble contains value >0 then swap information is used from it, otherwise global swap is used
|
||||
for (unsigned i = 0; i < _count; i++) {
|
||||
if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) {
|
||||
return _mappings[i].colorOrder | ((_mappings[i].colorOrder >> 4) ? 0 : (defaultColorOrder & 0xF0));
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultColorOrder;
|
||||
@ -125,7 +127,7 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com)
|
||||
if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus
|
||||
_busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr, _frequencykHz);
|
||||
_valid = (_busPtr != nullptr);
|
||||
DEBUG_PRINTF("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n", _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], _pins[1], _iType);
|
||||
DEBUG_PRINTF("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u). mA=%d/%d\n", _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], _pins[1], _iType, _milliAmpsPerLed, _milliAmpsMax);
|
||||
}
|
||||
|
||||
//fine tune power estimation constants for your setup
|
||||
@ -150,7 +152,7 @@ uint8_t BusDigital::estimateCurrentAndLimitBri() {
|
||||
bool useWackyWS2815PowerModel = false;
|
||||
byte actualMilliampsPerLed = _milliAmpsPerLed;
|
||||
|
||||
if (_milliAmpsMax < MA_FOR_ESP || actualMilliampsPerLed == 0) { //0 mA per LED and too low numbers turn off calculation
|
||||
if (_milliAmpsMax < MA_FOR_ESP/BusManager::getNumBusses() || actualMilliampsPerLed == 0) { //0 mA per LED and too low numbers turn off calculation
|
||||
return _bri;
|
||||
}
|
||||
|
||||
@ -159,7 +161,12 @@ uint8_t BusDigital::estimateCurrentAndLimitBri() {
|
||||
actualMilliampsPerLed = 12; // from testing an actual strip
|
||||
}
|
||||
|
||||
size_t powerBudget = (_milliAmpsMax - MA_FOR_ESP); //100mA for ESP power
|
||||
size_t powerBudget = (_milliAmpsMax - MA_FOR_ESP/BusManager::getNumBusses()); //80/120mA for ESP power
|
||||
if (powerBudget > getLength()) { //each LED uses about 1mA in standby, exclude that from power budget
|
||||
powerBudget -= getLength();
|
||||
} else {
|
||||
powerBudget = 0;
|
||||
}
|
||||
|
||||
uint32_t busPowerSum = 0;
|
||||
for (unsigned i = 0; i < getLength(); i++) { //sum up the usage of each LED
|
||||
@ -178,29 +185,26 @@ uint8_t BusDigital::estimateCurrentAndLimitBri() {
|
||||
busPowerSum >>= 2; //same as /= 4
|
||||
}
|
||||
|
||||
if (powerBudget > getLength()) { //each LED uses about 1mA in standby, exclude that from power budget
|
||||
powerBudget -= getLength();
|
||||
} else {
|
||||
powerBudget = 0;
|
||||
}
|
||||
|
||||
// powerSum has all the values of channels summed (max would be getLength()*765 as white is excluded) so convert to milliAmps
|
||||
busPowerSum = (busPowerSum * actualMilliampsPerLed) / 765;
|
||||
_milliAmpsTotal = busPowerSum * _bri / 255;
|
||||
|
||||
uint8_t newBri = _bri;
|
||||
if (busPowerSum * _bri / 255 > powerBudget) { //scale brightness down to stay in current limit
|
||||
float scale = (float)(powerBudget * 255) / (float)(busPowerSum * _bri);
|
||||
uint16_t scaleI = scale * 255;
|
||||
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
|
||||
if (scale >= 1.0f) return _bri;
|
||||
_milliAmpsTotal = ceilf((float)_milliAmpsTotal * scale);
|
||||
uint8_t scaleB = min((int)(scale * 255), 255);
|
||||
newBri = unsigned(_bri * scaleB) / 256 + 1;
|
||||
}
|
||||
return newBri;
|
||||
}
|
||||
|
||||
void BusDigital::show() {
|
||||
_milliAmpsTotal = 0;
|
||||
if (!_valid) return;
|
||||
|
||||
uint8_t newBri = estimateCurrentAndLimitBri();
|
||||
uint8_t newBri = estimateCurrentAndLimitBri(); // will fill _milliAmpsTotal
|
||||
if (newBri < _bri) PolyBus::setBrightness(_busPtr, _iType, newBri); // limit brightness to stay within current limits
|
||||
|
||||
if (_data) { // use _buffering this causes ~20% FPS drop
|
||||
@ -258,23 +262,8 @@ void BusDigital::setBrightness(uint8_t b) {
|
||||
if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) reinit();
|
||||
}
|
||||
#endif
|
||||
uint8_t prevBri = _bri;
|
||||
Bus::setBrightness(b);
|
||||
PolyBus::setBrightness(_busPtr, _iType, b);
|
||||
/*
|
||||
if (_data) return; // use _buffering this causes ~20% FPS drop
|
||||
|
||||
// must update/repaint every LED in the NeoPixelBus buffer to the new brightness
|
||||
// the only case where repainting is unnecessary is when all pixels are set after the brightness change but before the next show
|
||||
// (which we can't rely on)
|
||||
uint16_t hwLen = _len;
|
||||
if (_type == TYPE_WS2812_1CH_X3) hwLen = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus
|
||||
for (unsigned i = 0; i < hwLen; i++) {
|
||||
// use 0 as color order, actual order does not matter here as we just update the channel values as-is
|
||||
uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, i, 0), prevBri);
|
||||
PolyBus::setPixelColor(_busPtr, _iType, i, c, 0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
//If LEDs are skipped, it is possible to use the first as a status LED.
|
||||
@ -617,29 +606,34 @@ void BusNetwork::cleanup() {
|
||||
|
||||
//utility to get the approx. memory usage of a given BusConfig
|
||||
uint32_t BusManager::memUsage(BusConfig &bc) {
|
||||
uint8_t type = bc.type;
|
||||
if (bc.type == TYPE_ONOFF || IS_PWM(bc.type)) return 5;
|
||||
|
||||
uint16_t len = bc.count + bc.skipAmount;
|
||||
if (type > 15 && type < 32) { // digital types
|
||||
if (type == TYPE_UCS8903 || type == TYPE_UCS8904) len *= 2; // 16-bit LEDs
|
||||
uint16_t channels = 3;
|
||||
uint16_t multiplier = 1;
|
||||
if (IS_DIGITAL(bc.type)) { // digital types
|
||||
if (IS_16BIT(bc.type)) len *= 2; // 16-bit LEDs
|
||||
#ifdef ESP8266
|
||||
if (bc.type > 28) channels = 4; //RGBW
|
||||
if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem
|
||||
if (type > 28) return len*20; //RGBW
|
||||
return len*15;
|
||||
multiplier = 5;
|
||||
}
|
||||
if (type > 28) return len*4; //RGBW
|
||||
return len*3;
|
||||
#else //ESP32 RMT uses double buffer?
|
||||
if (type > 28) return len*8; //RGBW
|
||||
return len*6;
|
||||
#else //ESP32 RMT uses double buffer, I2S uses 5x buffer
|
||||
if (bc.type > 28) channels = 4; //RGBW
|
||||
multiplier = 2;
|
||||
#endif
|
||||
}
|
||||
if (type > 31 && type < 48) return 5;
|
||||
return len*3; //RGB
|
||||
if (IS_VIRTUAL(bc.type)) {
|
||||
switch (bc.type) {
|
||||
case TYPE_NET_DDP_RGBW: channels = 4; break;
|
||||
}
|
||||
}
|
||||
return len * channels * multiplier; //RGB
|
||||
}
|
||||
|
||||
int BusManager::add(BusConfig &bc) {
|
||||
if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1;
|
||||
if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) {
|
||||
if (IS_VIRTUAL(bc.type)) {
|
||||
busses[numBusses] = new BusNetwork(bc);
|
||||
} else if (IS_DIGITAL(bc.type)) {
|
||||
busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap);
|
||||
@ -661,9 +655,12 @@ void BusManager::removeAll() {
|
||||
}
|
||||
|
||||
void BusManager::show() {
|
||||
_milliAmpsUsed = 0;
|
||||
for (unsigned i = 0; i < numBusses; i++) {
|
||||
busses[i]->show();
|
||||
_milliAmpsUsed += busses[i]->getUsedCurrent();
|
||||
}
|
||||
if (_milliAmpsUsed) _milliAmpsUsed += MA_FOR_ESP;
|
||||
}
|
||||
|
||||
void BusManager::setStatusPixel(uint32_t c) {
|
||||
@ -729,3 +726,11 @@ uint16_t BusManager::getTotalLength() {
|
||||
int16_t Bus::_cct = -1;
|
||||
uint8_t Bus::_cctBlend = 0;
|
||||
uint8_t Bus::_gAWM = 255;
|
||||
|
||||
uint16_t BusDigital::_milliAmpsTotal = 0;
|
||||
|
||||
uint8_t BusManager::numBusses = 0;
|
||||
Bus* BusManager::busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||
ColorOrderMap BusManager::colorOrderMap = {};
|
||||
uint16_t BusManager::_milliAmpsUsed = 0;
|
||||
uint16_t BusManager::_milliAmpsMax = ABL_MILLIAMPS_DEFAULT;
|
@ -129,14 +129,14 @@ class Bus {
|
||||
virtual void setPixelColor(uint16_t pix, uint32_t c) = 0;
|
||||
virtual uint32_t getPixelColor(uint16_t pix) { return 0; }
|
||||
virtual void setBrightness(uint8_t b) { _bri = b; };
|
||||
virtual void cleanup() = 0;
|
||||
virtual uint8_t getPins(uint8_t* pinArray) { return 0; }
|
||||
virtual uint16_t getLength() { return _len; }
|
||||
virtual void setColorOrder() {}
|
||||
virtual void setColorOrder(uint8_t co) {}
|
||||
virtual uint8_t getColorOrder() { return COL_ORDER_RGB; }
|
||||
virtual uint8_t skippedLeds() { return 0; }
|
||||
virtual uint16_t getFrequency() { return 0U; }
|
||||
virtual uint16_t getLEDCurrent() { return 0; }
|
||||
virtual uint16_t getUsedCurrent() { return 0; }
|
||||
virtual uint16_t getMaxCurrent() { return 0; }
|
||||
inline void setReversed(bool reversed) { _reversed = reversed; }
|
||||
inline uint16_t getStart() { return _start; }
|
||||
@ -206,20 +206,21 @@ class BusDigital : public Bus {
|
||||
BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com);
|
||||
~BusDigital() { cleanup(); }
|
||||
|
||||
void show();
|
||||
bool canShow();
|
||||
void setBrightness(uint8_t b);
|
||||
void setStatusPixel(uint32_t c);
|
||||
void setPixelColor(uint16_t pix, uint32_t c);
|
||||
void setColorOrder(uint8_t colorOrder);
|
||||
uint32_t getPixelColor(uint16_t pix);
|
||||
uint8_t getColorOrder() { return _colorOrder; }
|
||||
uint8_t getPins(uint8_t* pinArray);
|
||||
uint8_t skippedLeds() { return _skip; }
|
||||
uint16_t getFrequency() { return _frequencykHz; }
|
||||
void show() override;
|
||||
bool canShow() override;
|
||||
void setBrightness(uint8_t b) override;
|
||||
void setStatusPixel(uint32_t c) override;
|
||||
void setPixelColor(uint16_t pix, uint32_t c) override;
|
||||
void setColorOrder(uint8_t colorOrder) override;
|
||||
uint32_t getPixelColor(uint16_t pix) override;
|
||||
uint8_t getColorOrder() override { return _colorOrder; }
|
||||
uint8_t getPins(uint8_t* pinArray) override;
|
||||
uint8_t skippedLeds() override { return _skip; }
|
||||
uint16_t getFrequency() override { return _frequencykHz; }
|
||||
uint8_t estimateCurrentAndLimitBri();
|
||||
uint16_t getLEDCurrent() { return _milliAmpsPerLed; }
|
||||
uint16_t getMaxCurrent() { return _milliAmpsMax; }
|
||||
uint16_t getLEDCurrent() override { return _milliAmpsPerLed; }
|
||||
uint16_t getUsedCurrent() override { return _milliAmpsTotal; }
|
||||
uint16_t getMaxCurrent() override { return _milliAmpsMax; }
|
||||
void reinit();
|
||||
void cleanup();
|
||||
|
||||
@ -233,7 +234,8 @@ class BusDigital : public Bus {
|
||||
uint16_t _milliAmpsMax;
|
||||
void * _busPtr;
|
||||
const ColorOrderMap &_colorOrderMap;
|
||||
//bool _buffering; // temporary until we figure out why comparison "_data" causes severe FPS drop
|
||||
|
||||
static uint16_t _milliAmpsTotal; // is overwitten/recalculated on each show()
|
||||
|
||||
inline uint32_t restoreColorLossy(uint32_t c, uint8_t restoreBri) {
|
||||
if (restoreBri < 255) {
|
||||
@ -253,11 +255,11 @@ class BusPwm : public Bus {
|
||||
BusPwm(BusConfig &bc);
|
||||
~BusPwm() { cleanup(); }
|
||||
|
||||
void setPixelColor(uint16_t pix, uint32_t c);
|
||||
uint32_t getPixelColor(uint16_t pix); //does no index check
|
||||
uint8_t getPins(uint8_t* pinArray);
|
||||
uint16_t getFrequency() { return _frequency; }
|
||||
void show();
|
||||
void setPixelColor(uint16_t pix, uint32_t c) override;
|
||||
uint32_t getPixelColor(uint16_t pix) override; //does no index check
|
||||
uint8_t getPins(uint8_t* pinArray) override;
|
||||
uint16_t getFrequency() override { return _frequency; }
|
||||
void show() override;
|
||||
void cleanup() { deallocatePins(); }
|
||||
|
||||
private:
|
||||
@ -277,10 +279,10 @@ class BusOnOff : public Bus {
|
||||
BusOnOff(BusConfig &bc);
|
||||
~BusOnOff() { cleanup(); }
|
||||
|
||||
void setPixelColor(uint16_t pix, uint32_t c);
|
||||
uint32_t getPixelColor(uint16_t pix);
|
||||
uint8_t getPins(uint8_t* pinArray);
|
||||
void show();
|
||||
void setPixelColor(uint16_t pix, uint32_t c) override;
|
||||
uint32_t getPixelColor(uint16_t pix) override;
|
||||
uint8_t getPins(uint8_t* pinArray) override;
|
||||
void show() override;
|
||||
void cleanup() { pinManager.deallocatePin(_pin, PinOwner::BusOnOff); }
|
||||
|
||||
private:
|
||||
@ -294,13 +296,13 @@ class BusNetwork : public Bus {
|
||||
BusNetwork(BusConfig &bc);
|
||||
~BusNetwork() { cleanup(); }
|
||||
|
||||
bool hasRGB() { return true; }
|
||||
bool hasWhite() { return _rgbw; }
|
||||
bool canShow() { return !_broadcastLock; } // this should be a return value from UDP routine if it is still sending data out
|
||||
void setPixelColor(uint16_t pix, uint32_t c);
|
||||
uint32_t getPixelColor(uint16_t pix);
|
||||
uint8_t getPins(uint8_t* pinArray);
|
||||
void show();
|
||||
bool hasRGB() override { return true; }
|
||||
bool hasWhite() override { return _rgbw; }
|
||||
bool canShow() override { return !_broadcastLock; } // this should be a return value from UDP routine if it is still sending data out
|
||||
void setPixelColor(uint16_t pix, uint32_t c) override;
|
||||
uint32_t getPixelColor(uint16_t pix) override;
|
||||
uint8_t getPins(uint8_t* pinArray) override;
|
||||
void show() override;
|
||||
void cleanup();
|
||||
|
||||
private:
|
||||
@ -314,39 +316,44 @@ class BusNetwork : public Bus {
|
||||
|
||||
class BusManager {
|
||||
public:
|
||||
BusManager() : numBusses(0) {};
|
||||
BusManager() {};
|
||||
|
||||
//utility to get the approx. memory usage of a given BusConfig
|
||||
static uint32_t memUsage(BusConfig &bc);
|
||||
static uint16_t currentMilliamps(void) { return _milliAmpsUsed; }
|
||||
static uint16_t ablMilliampsMax(void) { return _milliAmpsMax; }
|
||||
|
||||
int add(BusConfig &bc);
|
||||
static int add(BusConfig &bc);
|
||||
|
||||
//do not call this method from system context (network callback)
|
||||
void removeAll();
|
||||
static void removeAll();
|
||||
|
||||
void show();
|
||||
bool canAllShow();
|
||||
void setStatusPixel(uint32_t c);
|
||||
void setPixelColor(uint16_t pix, uint32_t c);
|
||||
void setBrightness(uint8_t b);
|
||||
void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
||||
uint32_t getPixelColor(uint16_t pix);
|
||||
static void show();
|
||||
static bool canAllShow();
|
||||
static void setStatusPixel(uint32_t c);
|
||||
static void setPixelColor(uint16_t pix, uint32_t c);
|
||||
static void setBrightness(uint8_t b);
|
||||
static void setSegmentCCT(int16_t cct, bool allowWBCorrection = false);
|
||||
static void setMilliampsMax(uint16_t max) { _milliAmpsMax = max;}
|
||||
static uint32_t getPixelColor(uint16_t pix);
|
||||
|
||||
Bus* getBus(uint8_t busNr);
|
||||
static Bus* getBus(uint8_t busNr);
|
||||
|
||||
//semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit())
|
||||
uint16_t getTotalLength();
|
||||
inline uint8_t getNumBusses() const { return numBusses; }
|
||||
static uint16_t getTotalLength();
|
||||
static uint8_t getNumBusses() { return numBusses; }
|
||||
|
||||
inline void updateColorOrderMap(const ColorOrderMap &com) { memcpy(&colorOrderMap, &com, sizeof(ColorOrderMap)); }
|
||||
inline const ColorOrderMap& getColorOrderMap() const { return colorOrderMap; }
|
||||
static void updateColorOrderMap(const ColorOrderMap &com) { memcpy(&colorOrderMap, &com, sizeof(ColorOrderMap)); }
|
||||
static const ColorOrderMap& getColorOrderMap() { return colorOrderMap; }
|
||||
|
||||
private:
|
||||
uint8_t numBusses;
|
||||
Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||
ColorOrderMap colorOrderMap;
|
||||
static uint8_t numBusses;
|
||||
static Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES];
|
||||
static ColorOrderMap colorOrderMap;
|
||||
static uint16_t _milliAmpsUsed;
|
||||
static uint16_t _milliAmpsMax;
|
||||
|
||||
inline uint8_t getNumVirtualBusses() {
|
||||
static uint8_t getNumVirtualBusses() {
|
||||
int j = 0;
|
||||
for (int i=0; i<numBusses; i++) if (busses[i]->getType() >= TYPE_NET_DDP_RGB && busses[i]->getType() < 96) j++;
|
||||
return j;
|
||||
|
@ -347,10 +347,10 @@ void handleButton()
|
||||
void esp32RMTInvertIdle()
|
||||
{
|
||||
bool idle_out;
|
||||
for (uint8_t u = 0; u < busses.getNumBusses(); u++)
|
||||
for (uint8_t u = 0; u < BusManager::getNumBusses(); u++)
|
||||
{
|
||||
if (u > 7) return; // only 8 RMT channels, TODO: ESP32 variants have less RMT channels
|
||||
Bus *bus = busses.getBus(u);
|
||||
Bus *bus = BusManager::getBus(u);
|
||||
if (!bus || bus->getLength()==0 || !IS_DIGITAL(bus->getType()) || IS_2PIN(bus->getType())) continue;
|
||||
//assumes that bus number to rmt channel mapping stays 1:1
|
||||
rmt_channel_t ch = static_cast<rmt_channel_t>(u);
|
||||
|
107
wled00/cfg.cpp
Normal file → Executable file
107
wled00/cfg.cpp
Normal file → Executable file
@ -31,9 +31,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
getStringFromJson(cmDNS, id[F("mdns")], 33);
|
||||
getStringFromJson(serverDescription, id[F("name")], 33);
|
||||
getStringFromJson(alexaInvocationName, id[F("inv")], 33);
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
CJSON(simplifiedUI, id[F("sui")]);
|
||||
#endif
|
||||
|
||||
JsonObject nw = doc["nw"];
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
@ -81,7 +79,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
|
||||
noWifiSleep = doc[F("wifi")][F("sleep")] | !noWifiSleep; // inverted
|
||||
noWifiSleep = !noWifiSleep;
|
||||
//int wifi_phy = doc[F("wifi")][F("phy")]; //force phy mode n?
|
||||
force802_3g = doc[F("wifi")][F("phy")] | force802_3g; //force phy mode g?
|
||||
|
||||
JsonObject hw = doc[F("hw")];
|
||||
|
||||
@ -89,8 +87,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
JsonObject hw_led = hw["led"];
|
||||
|
||||
uint16_t total = hw_led[F("total")] | strip.getLengthTotal();
|
||||
CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]);
|
||||
CJSON(strip.milliampsPerLed, hw_led[F("ledma")]); // no longer used
|
||||
uint16_t ablMilliampsMax = hw_led[F("maxpwr")] | BusManager::ablMilliampsMax();
|
||||
BusManager::setMilliampsMax(ablMilliampsMax);
|
||||
Bus::setGlobalAWMode(hw_led[F("rgbwm")] | AW_GLOBAL_DISABLED);
|
||||
CJSON(correctWB, hw_led["cct"]);
|
||||
CJSON(cctFromRgb, hw_led[F("cr")]);
|
||||
@ -140,7 +138,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
|
||||
if (fromFS || !ins.isNull()) {
|
||||
uint8_t s = 0; // bus iterator
|
||||
if (fromFS) busses.removeAll(); // can't safely manipulate busses directly in network callback
|
||||
if (fromFS) BusManager::removeAll(); // can't safely manipulate busses directly in network callback
|
||||
uint32_t mem = 0, globalBufMem = 0;
|
||||
uint16_t maxlen = 0;
|
||||
bool busesChanged = false;
|
||||
@ -166,8 +164,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
bool refresh = elm["ref"] | false;
|
||||
uint16_t freqkHz = elm[F("freq")] | 0; // will be in kHz for DotStar and Hz for PWM (not yet implemented fully)
|
||||
uint8_t AWmode = elm[F("rgbwm")] | RGBW_MODE_MANUAL_ONLY;
|
||||
uint8_t maPerLed = elm[F("ledma")] | strip.milliampsPerLed; // replace with 55 when removing strip.milliampsPerLed
|
||||
uint16_t maMax = elm[F("maxpwr")] | (strip.ablMilliampsMax * length) / total; // rough (incorrect?) per strip ABL calculation when no config exists
|
||||
uint8_t maPerLed = elm[F("ledma")] | 55;
|
||||
uint16_t maMax = elm[F("maxpwr")] | (ablMilliampsMax * length) / total; // rough (incorrect?) per strip ABL calculation when no config exists
|
||||
// To disable brightness limiter we either set output max current to 0 or single LED current to 0 (we choose output max current)
|
||||
if ((ledType > TYPE_TM1814 && ledType < TYPE_WS2801) || ledType >= TYPE_NET_DDP_RGB) { // analog and virtual
|
||||
maPerLed = 0;
|
||||
@ -181,7 +179,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
maxlen = start + length;
|
||||
globalBufMem = maxlen * 4;
|
||||
}
|
||||
if (mem + globalBufMem <= MAX_LED_MEMORY) if (busses.add(bc) == -1) break; // finalization will be done in WLED::beginStrip()
|
||||
if (mem + globalBufMem <= MAX_LED_MEMORY) if (BusManager::add(bc) == -1) break; // finalization will be done in WLED::beginStrip()
|
||||
} else {
|
||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||
busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax);
|
||||
@ -192,7 +190,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
doInitBusses = busesChanged;
|
||||
// finalization done in beginStrip()
|
||||
}
|
||||
if (hw_led["rev"]) busses.getBus(0)->setReversed(true); //set 0.11 global reversed setting for first bus
|
||||
if (hw_led["rev"]) BusManager::getBus(0)->setReversed(true); //set 0.11 global reversed setting for first bus
|
||||
|
||||
// read color order map configuration
|
||||
JsonArray hw_com = hw[F("com")];
|
||||
@ -207,7 +205,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
com.add(start, len, colorOrder);
|
||||
s++;
|
||||
}
|
||||
busses.updateColorOrderMap(com);
|
||||
BusManager::updateColorOrderMap(com);
|
||||
}
|
||||
|
||||
// read multiple button configuration
|
||||
@ -419,7 +417,6 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
CJSON(notifyButton, if_sync_send["btn"]);
|
||||
CJSON(notifyAlexa, if_sync_send["va"]);
|
||||
CJSON(notifyHue, if_sync_send["hue"]);
|
||||
// CJSON(notifyMacro, if_sync_send["macro"]);
|
||||
CJSON(syncGroups, if_sync_send["grp"]);
|
||||
if (if_sync_send[F("twice")]) udpNumRetries = 1; // import setting from 0.13 and earlier
|
||||
CJSON(udpNumRetries, if_sync_send["ret"]);
|
||||
@ -431,6 +428,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
JsonObject if_live = interfaces["live"];
|
||||
CJSON(receiveDirect, if_live["en"]); // UDP/Hyperion realtime
|
||||
CJSON(useMainSegmentOnly, if_live[F("mso")]);
|
||||
CJSON(realtimeRespectLedMaps, if_live[F("rlm")]);
|
||||
CJSON(e131Port, if_live["port"]); // 5568
|
||||
if (e131Port == DDP_DEFAULT_PORT) e131Port = E131_DEFAULT_PORT; // prevent double DDP port allocation
|
||||
CJSON(e131Multicast, if_live[F("mc")]);
|
||||
@ -611,7 +609,7 @@ void deserializeConfigFromFS() {
|
||||
|
||||
DEBUG_PRINTLN(F("Reading settings from /cfg.json..."));
|
||||
|
||||
success = readObjectFromFile("/cfg.json", nullptr, &doc);
|
||||
success = readObjectFromFile("/cfg.json", nullptr, pDoc);
|
||||
if (!success) { // if file does not exist, optionally try reading from EEPROM and then save defaults to FS
|
||||
releaseJSONBufferLock();
|
||||
#ifdef WLED_ADD_EEPROM_SUPPORT
|
||||
@ -632,7 +630,8 @@ void deserializeConfigFromFS() {
|
||||
|
||||
// NOTE: This routine deserializes *and* applies the configuration
|
||||
// Therefore, must also initialize ethernet from this function
|
||||
bool needsSave = deserializeConfig(doc.as<JsonObject>(), true);
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
bool needsSave = deserializeConfig(root, true);
|
||||
releaseJSONBufferLock();
|
||||
|
||||
if (needsSave) serializeConfig(); // usermods required new parameters
|
||||
@ -645,21 +644,21 @@ void serializeConfig() {
|
||||
|
||||
if (!requestJSONBufferLock(2)) return;
|
||||
|
||||
JsonArray rev = doc.createNestedArray("rev");
|
||||
JsonObject root = pDoc->to<JsonObject>();
|
||||
|
||||
JsonArray rev = root.createNestedArray("rev");
|
||||
rev.add(1); //major settings revision
|
||||
rev.add(0); //minor settings revision
|
||||
|
||||
doc[F("vid")] = VERSION;
|
||||
root[F("vid")] = VERSION;
|
||||
|
||||
JsonObject id = doc.createNestedObject("id");
|
||||
JsonObject id = root.createNestedObject("id");
|
||||
id[F("mdns")] = cmDNS;
|
||||
id[F("name")] = serverDescription;
|
||||
id[F("inv")] = alexaInvocationName;
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
id[F("sui")] = simplifiedUI;
|
||||
#endif
|
||||
|
||||
JsonObject nw = doc.createNestedObject("nw");
|
||||
JsonObject nw = root.createNestedObject("nw");
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
nw[F("espnow")] = enableESPNow;
|
||||
nw[F("linked_remote")] = linked_remote;
|
||||
@ -681,7 +680,7 @@ void serializeConfig() {
|
||||
nw_ins_0_sn.add(staticSubnet[i]);
|
||||
}
|
||||
|
||||
JsonObject ap = doc.createNestedObject("ap");
|
||||
JsonObject ap = root.createNestedObject("ap");
|
||||
ap[F("ssid")] = apSSID;
|
||||
ap[F("pskl")] = strlen(apPass);
|
||||
ap[F("chan")] = apChannel;
|
||||
@ -694,12 +693,12 @@ void serializeConfig() {
|
||||
ap_ip.add(2);
|
||||
ap_ip.add(1);
|
||||
|
||||
JsonObject wifi = doc.createNestedObject("wifi");
|
||||
JsonObject wifi = root.createNestedObject("wifi");
|
||||
wifi[F("sleep")] = !noWifiSleep;
|
||||
//wifi[F("phy")] = 1;
|
||||
wifi[F("phy")] = force802_3g;
|
||||
|
||||
#ifdef WLED_USE_ETHERNET
|
||||
JsonObject ethernet = doc.createNestedObject("eth");
|
||||
JsonObject ethernet = root.createNestedObject("eth");
|
||||
ethernet["type"] = ethernetType;
|
||||
if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) {
|
||||
JsonArray pins = ethernet.createNestedArray("pin");
|
||||
@ -722,12 +721,12 @@ void serializeConfig() {
|
||||
}
|
||||
#endif
|
||||
|
||||
JsonObject hw = doc.createNestedObject("hw");
|
||||
JsonObject hw = root.createNestedObject("hw");
|
||||
|
||||
JsonObject hw_led = hw.createNestedObject("led");
|
||||
hw_led[F("total")] = strip.getLengthTotal(); //provided for compatibility on downgrade and per-output ABL
|
||||
hw_led[F("maxpwr")] = strip.ablMilliampsMax;
|
||||
hw_led[F("ledma")] = strip.milliampsPerLed; // no longer used
|
||||
hw_led[F("maxpwr")] = BusManager::ablMilliampsMax();
|
||||
hw_led[F("ledma")] = 0; // no longer used
|
||||
hw_led["cct"] = correctWB;
|
||||
hw_led[F("cr")] = cctFromRgb;
|
||||
hw_led[F("cb")] = strip.cctBlending;
|
||||
@ -757,8 +756,8 @@ void serializeConfig() {
|
||||
|
||||
JsonArray hw_led_ins = hw_led.createNestedArray("ins");
|
||||
|
||||
for (uint8_t s = 0; s < busses.getNumBusses(); s++) {
|
||||
Bus *bus = busses.getBus(s);
|
||||
for (uint8_t s = 0; s < BusManager::getNumBusses(); s++) {
|
||||
Bus *bus = BusManager::getBus(s);
|
||||
if (!bus || bus->getLength()==0) break;
|
||||
JsonObject ins = hw_led_ins.createNestedObject();
|
||||
ins["start"] = bus->getStart();
|
||||
@ -779,7 +778,7 @@ void serializeConfig() {
|
||||
}
|
||||
|
||||
JsonArray hw_com = hw.createNestedArray(F("com"));
|
||||
const ColorOrderMap& com = busses.getColorOrderMap();
|
||||
const ColorOrderMap& com = BusManager::getColorOrderMap();
|
||||
for (uint8_t s = 0; s < com.count(); s++) {
|
||||
const ColorOrderMapEntry *entry = com.get(s);
|
||||
if (!entry) break;
|
||||
@ -834,7 +833,7 @@ void serializeConfig() {
|
||||
//JsonObject hw_status = hw.createNestedObject("status");
|
||||
//hw_status["pin"] = -1;
|
||||
|
||||
JsonObject light = doc.createNestedObject(F("light"));
|
||||
JsonObject light = root.createNestedObject(F("light"));
|
||||
light[F("scale-bri")] = briMultiplier;
|
||||
light[F("pal-mode")] = strip.paletteBlend;
|
||||
light[F("aseg")] = autoSegments;
|
||||
@ -857,12 +856,12 @@ void serializeConfig() {
|
||||
light_nl[F("tbri")] = nightlightTargetBri;
|
||||
light_nl["macro"] = macroNl;
|
||||
|
||||
JsonObject def = doc.createNestedObject("def");
|
||||
JsonObject def = root.createNestedObject("def");
|
||||
def["ps"] = bootPreset;
|
||||
def["on"] = turnOnAtBoot;
|
||||
def["bri"] = briS;
|
||||
|
||||
JsonObject interfaces = doc.createNestedObject("if");
|
||||
JsonObject interfaces = root.createNestedObject("if");
|
||||
|
||||
JsonObject if_sync = interfaces.createNestedObject("sync");
|
||||
if_sync[F("port0")] = udpPort;
|
||||
@ -886,7 +885,6 @@ void serializeConfig() {
|
||||
if_sync_send["btn"] = notifyButton;
|
||||
if_sync_send["va"] = notifyAlexa;
|
||||
if_sync_send["hue"] = notifyHue;
|
||||
// if_sync_send["macro"] = notifyMacro;
|
||||
if_sync_send["grp"] = syncGroups;
|
||||
if_sync_send["ret"] = udpNumRetries;
|
||||
|
||||
@ -897,6 +895,7 @@ void serializeConfig() {
|
||||
JsonObject if_live = interfaces.createNestedObject("live");
|
||||
if_live["en"] = receiveDirect; // UDP/Hyperion realtime
|
||||
if_live[F("mso")] = useMainSegmentOnly;
|
||||
if_live[F("rlm")] = realtimeRespectLedMaps;
|
||||
if_live["port"] = e131Port;
|
||||
if_live[F("mc")] = e131Multicast;
|
||||
|
||||
@ -965,7 +964,7 @@ void serializeConfig() {
|
||||
if_ntp[F("ln")] = longitude;
|
||||
if_ntp[F("lt")] = latitude;
|
||||
|
||||
JsonObject ol = doc.createNestedObject("ol");
|
||||
JsonObject ol = root.createNestedObject("ol");
|
||||
ol[F("clock")] = overlayCurrent;
|
||||
ol[F("cntdwn")] = countdownMode;
|
||||
|
||||
@ -975,7 +974,7 @@ void serializeConfig() {
|
||||
ol[F("o5m")] = analogClock5MinuteMarks;
|
||||
ol[F("osec")] = analogClockSecondsTrail;
|
||||
|
||||
JsonObject timers = doc.createNestedObject(F("timers"));
|
||||
JsonObject timers = root.createNestedObject(F("timers"));
|
||||
|
||||
JsonObject cntdwn = timers.createNestedObject(F("cntdwn"));
|
||||
JsonArray goal = cntdwn.createNestedArray(F("goal"));
|
||||
@ -1003,14 +1002,14 @@ void serializeConfig() {
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject ota = doc.createNestedObject("ota");
|
||||
JsonObject ota = root.createNestedObject("ota");
|
||||
ota[F("lock")] = otaLock;
|
||||
ota[F("lock-wifi")] = wifiLock;
|
||||
ota[F("pskl")] = strlen(otaPass);
|
||||
ota[F("aota")] = aOtaEnabled;
|
||||
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
JsonObject dmx = doc.createNestedObject("dmx");
|
||||
JsonObject dmx = root.createNestedObject("dmx");
|
||||
dmx[F("chan")] = DMXChannels;
|
||||
dmx[F("gap")] = DMXGap;
|
||||
dmx["start"] = DMXStart;
|
||||
@ -1024,11 +1023,11 @@ void serializeConfig() {
|
||||
dmx[F("e131proxy")] = e131ProxyUniverse;
|
||||
#endif
|
||||
|
||||
JsonObject usermods_settings = doc.createNestedObject("um");
|
||||
JsonObject usermods_settings = root.createNestedObject("um");
|
||||
usermods.addToConfig(usermods_settings);
|
||||
|
||||
File f = WLED_FS.open("/cfg.json", "w");
|
||||
if (f) serializeJson(doc, f);
|
||||
if (f) serializeJson(root, f);
|
||||
f.close();
|
||||
releaseJSONBufferLock();
|
||||
|
||||
@ -1041,19 +1040,21 @@ bool deserializeConfigSec() {
|
||||
|
||||
if (!requestJSONBufferLock(3)) return false;
|
||||
|
||||
bool success = readObjectFromFile("/wsec.json", nullptr, &doc);
|
||||
bool success = readObjectFromFile("/wsec.json", nullptr, pDoc);
|
||||
if (!success) {
|
||||
releaseJSONBufferLock();
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonObject nw_ins_0 = doc["nw"]["ins"][0];
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
|
||||
JsonObject nw_ins_0 = root["nw"]["ins"][0];
|
||||
getStringFromJson(clientPass, nw_ins_0["psk"], 65);
|
||||
|
||||
JsonObject ap = doc["ap"];
|
||||
JsonObject ap = root["ap"];
|
||||
getStringFromJson(apPass, ap["psk"] , 65);
|
||||
|
||||
[[maybe_unused]] JsonObject interfaces = doc["if"];
|
||||
[[maybe_unused]] JsonObject interfaces = root["if"];
|
||||
|
||||
#ifdef WLED_ENABLE_MQTT
|
||||
JsonObject if_mqtt = interfaces["mqtt"];
|
||||
@ -1064,10 +1065,10 @@ bool deserializeConfigSec() {
|
||||
getStringFromJson(hueApiKey, interfaces["hue"][F("key")], 47);
|
||||
#endif
|
||||
|
||||
getStringFromJson(settingsPIN, doc["pin"], 5);
|
||||
getStringFromJson(settingsPIN, root["pin"], 5);
|
||||
correctPIN = !strlen(settingsPIN);
|
||||
|
||||
JsonObject ota = doc["ota"];
|
||||
JsonObject ota = root["ota"];
|
||||
getStringFromJson(otaPass, ota[F("pwd")], 33);
|
||||
CJSON(otaLock, ota[F("lock")]);
|
||||
CJSON(wifiLock, ota[F("lock-wifi")]);
|
||||
@ -1082,17 +1083,19 @@ void serializeConfigSec() {
|
||||
|
||||
if (!requestJSONBufferLock(4)) return;
|
||||
|
||||
JsonObject nw = doc.createNestedObject("nw");
|
||||
JsonObject root = pDoc->to<JsonObject>();
|
||||
|
||||
JsonObject nw = root.createNestedObject("nw");
|
||||
|
||||
JsonArray nw_ins = nw.createNestedArray("ins");
|
||||
|
||||
JsonObject nw_ins_0 = nw_ins.createNestedObject();
|
||||
nw_ins_0["psk"] = clientPass;
|
||||
|
||||
JsonObject ap = doc.createNestedObject("ap");
|
||||
JsonObject ap = root.createNestedObject("ap");
|
||||
ap["psk"] = apPass;
|
||||
|
||||
[[maybe_unused]] JsonObject interfaces = doc.createNestedObject("if");
|
||||
[[maybe_unused]] JsonObject interfaces = root.createNestedObject("if");
|
||||
#ifdef WLED_ENABLE_MQTT
|
||||
JsonObject if_mqtt = interfaces.createNestedObject("mqtt");
|
||||
if_mqtt["psk"] = mqttPass;
|
||||
@ -1102,16 +1105,16 @@ void serializeConfigSec() {
|
||||
if_hue[F("key")] = hueApiKey;
|
||||
#endif
|
||||
|
||||
doc["pin"] = settingsPIN;
|
||||
root["pin"] = settingsPIN;
|
||||
|
||||
JsonObject ota = doc.createNestedObject("ota");
|
||||
JsonObject ota = root.createNestedObject("ota");
|
||||
ota[F("pwd")] = otaPass;
|
||||
ota[F("lock")] = otaLock;
|
||||
ota[F("lock-wifi")] = wifiLock;
|
||||
ota[F("aota")] = aOtaEnabled;
|
||||
|
||||
File f = WLED_FS.open("/wsec.json", "w");
|
||||
if (f) serializeJson(doc, f);
|
||||
if (f) serializeJson(root, f);
|
||||
f.close();
|
||||
releaseJSONBufferLock();
|
||||
}
|
||||
|
@ -150,6 +150,7 @@
|
||||
#define USERMOD_ID_KLIPPER 40 //Usermod Klipper percentage
|
||||
#define USERMOD_ID_WIREGUARD 41 //Usermod "wireguard.h"
|
||||
#define USERMOD_ID_INTERNAL_TEMPERATURE 42 //Usermod "usermod_internal_temperature.h"
|
||||
#define USERMOD_ID_ANIMARTRIX 44 //Usermod "usermod_v2_animartrix.h"
|
||||
|
||||
//Access point behavior
|
||||
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot
|
||||
@ -225,7 +226,7 @@
|
||||
|
||||
#define TYPE_NONE 0 //light is not configured
|
||||
#define TYPE_RESERVED 1 //unused. Might indicate a "virtual" light
|
||||
//Digital types (data pin only) (16-31)
|
||||
//Digital types (data pin only) (16-39)
|
||||
#define TYPE_WS2812_1CH 18 //white-only chips (1 channel per IC) (unused)
|
||||
#define TYPE_WS2812_1CH_X3 19 //white-only chips (3 channels per IC)
|
||||
#define TYPE_WS2812_2CH_X3 20 //CCT chips (1st IC controls WW + CW of 1st zone and CW of 2nd zone, 2nd IC controls WW of 2nd zone and WW + CW of 3rd zone)
|
||||
@ -235,11 +236,11 @@
|
||||
#define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units
|
||||
#define TYPE_TM1829 25
|
||||
#define TYPE_UCS8903 26
|
||||
#define TYPE_UCS8904 29
|
||||
#define TYPE_UCS8904 29 //first RGBW digital type (hardcoded in busmanager.cpp, memUsage())
|
||||
#define TYPE_SK6812_RGBW 30
|
||||
#define TYPE_TM1814 31
|
||||
//"Analog" types (PWM) (32-47)
|
||||
#define TYPE_ONOFF 40 //binary output (relays etc.)
|
||||
//"Analog" types (40-47)
|
||||
#define TYPE_ONOFF 40 //binary output (relays etc.; NOT PWM)
|
||||
#define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel
|
||||
#define TYPE_ANALOG_2CH 42 //analog WW + CW
|
||||
#define TYPE_ANALOG_3CH 43 //analog RGB
|
||||
@ -257,10 +258,13 @@
|
||||
#define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus, unused)
|
||||
#define TYPE_NET_DDP_RGBW 88 //network DDP RGBW bus (master broadcast bus)
|
||||
|
||||
#define IS_DIGITAL(t) ((t) & 0x10) //digital are 16-31 and 48-63
|
||||
#define IS_PWM(t) ((t) > 40 && (t) < 46)
|
||||
#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only
|
||||
#define IS_2PIN(t) ((t) > 47)
|
||||
#define IS_TYPE_VALID(t) ((t) > 15 && (t) < 128)
|
||||
#define IS_DIGITAL(t) (((t) > 15 && (t) < 40) || ((t) > 47 && (t) < 64)) //digital are 16-39 and 48-63
|
||||
#define IS_2PIN(t) ((t) > 47 && (t) < 64)
|
||||
#define IS_16BIT(t) ((t) == TYPE_UCS8903 || (t) == TYPE_UCS8904)
|
||||
#define IS_PWM(t) ((t) > 40 && (t) < 46) //does not include on/Off type
|
||||
#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only
|
||||
#define IS_VIRTUAL(t) ((t) >= 80 && (t) < 96) //this was a poor choice a better would be 96-111
|
||||
|
||||
//Color orders
|
||||
#define COL_ORDER_GRB 0 //GRB(w),defaut
|
||||
@ -346,6 +350,7 @@
|
||||
#define ERR_CONCURRENCY 2 // Conurrency (client active)
|
||||
#define ERR_NOBUF 3 // JSON buffer was not released in time, request cannot be handled at this time
|
||||
#define ERR_NOT_IMPL 4 // Not implemented
|
||||
#define ERR_NORAM 8 // effect RAM depleted
|
||||
#define ERR_JSON 9 // JSON parsing failed (input too large?)
|
||||
#define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?)
|
||||
#define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached
|
||||
@ -450,7 +455,11 @@
|
||||
#ifdef ESP8266
|
||||
#define JSON_BUFFER_SIZE 10240
|
||||
#else
|
||||
#define JSON_BUFFER_SIZE 24576
|
||||
#if defined(ARDUINO_ARCH_ESP32S2)
|
||||
#define JSON_BUFFER_SIZE 24576
|
||||
#else
|
||||
#define JSON_BUFFER_SIZE 32767
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#define MIN_HEAP_SIZE (8k for AsyncWebServer)
|
||||
|
@ -1,6 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
||||
<meta http-equiv="Pragma" content="no-cache">
|
||||
<meta http-equiv="Expires" content="0">
|
||||
@ -45,6 +46,7 @@
|
||||
width: 7px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
touch-action: none;
|
||||
}
|
||||
.color-picker-marker {
|
||||
height: 7px;
|
||||
@ -94,9 +96,14 @@
|
||||
line-height: 1;
|
||||
}
|
||||
.wrap {
|
||||
width: 800px;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
.wrap {
|
||||
width: 800px;
|
||||
}
|
||||
}
|
||||
.palette {
|
||||
height: 20px;
|
||||
}
|
||||
@ -136,6 +143,9 @@
|
||||
.sendSpan, .editSpan{
|
||||
cursor: pointer;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.6rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@ -191,6 +201,7 @@
|
||||
var gradientLength = rect.width;
|
||||
var mOffs = Math.round((gradientLength / 256) / 2) - 5;
|
||||
var paletteArray = []; //Holds the palettes after load.
|
||||
var paletteName = []; // Holds the names of the palettes after load.
|
||||
var svgSave = '<svg style="width:25px;height:25px" viewBox="0 0 24 24"><path fill=#fff d="M22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2A10,10 0 0,1 22,12M7,12L12,17V14H16V10H12V7L7,12Z"/></svg>'
|
||||
var svgEdit = '<svg style="width:25px;height:25px" viewBox="0 0 24 24"><path fill=#fff d="M12,2C6.47,2 2,6.47 2,12C2,17.53 6.47,22 12,22C17.53,22 22,17.53 22,12C22,6.47 17.53,2 12,2M15.1,7.07C15.24,7.07 15.38,7.12 15.5,7.23L16.77,8.5C17,8.72 17,9.07 16.77,9.28L15.77,10.28L13.72,8.23L14.72,7.23C14.82,7.12 14.96,7.07 15.1,7.07M13.13,8.81L15.19,10.87L9.13,16.93H7.07V14.87L13.13,8.81Z"/></svg>'
|
||||
|
||||
@ -349,24 +360,31 @@
|
||||
var gradientLength = maxX - minX + 1;
|
||||
|
||||
elmnt.onmousedown = dragMouseDown;
|
||||
elmnt.ontouchstart = dragMouseDown;
|
||||
|
||||
function dragMouseDown(e) {
|
||||
removeTrashcan(event)
|
||||
e = e || window.event;
|
||||
e.preventDefault();
|
||||
var isTouch = e.type.startsWith('touch');
|
||||
if (!isTouch) e.preventDefault();
|
||||
// get the mouse cursor position at startup:
|
||||
mousePos = e.clientX;
|
||||
mousePos = isTouch ? e.touches[0].clientX : e.clientX;
|
||||
d.onmouseup = closeDragElement;
|
||||
d.ontouchcancel = closeDragElement;
|
||||
d.ontouchend = closeDragElement;
|
||||
// call a function whenever the cursor moves:
|
||||
d.onmousemove = elementDrag;
|
||||
d.ontouchmove = elementDrag;
|
||||
}
|
||||
|
||||
function elementDrag(e) {
|
||||
e = e || window.event;
|
||||
e.preventDefault();
|
||||
var isTouch = e.type.startsWith('touch');
|
||||
if (!isTouch) e.preventDefault();
|
||||
// calculate the new cursor position:
|
||||
posNew = mousePos - e.clientX;
|
||||
mousePos = e.clientX;
|
||||
var clientX = isTouch ? e.touches[0].clientX : e.clientX;
|
||||
posNew = mousePos - clientX;
|
||||
mousePos = clientX;
|
||||
mousePosInGradient = mousePos - (minX + 1)
|
||||
|
||||
truePos = Math.round((mousePosInGradient/gradientLength)*256);
|
||||
@ -393,7 +411,10 @@
|
||||
function closeDragElement() {
|
||||
/* stop moving when mouse button is released:*/
|
||||
d.onmouseup = null;
|
||||
d.ontouchcancel = null;
|
||||
d.ontouchend = null;
|
||||
d.onmousemove = null;
|
||||
d.ontouchmove = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -500,8 +521,10 @@
|
||||
if (hst.length > 0 ) {
|
||||
try {
|
||||
var arr = [];
|
||||
const response = await fetch('http://'+hst+'/json/info');
|
||||
const json = await response.json();
|
||||
const responseInfo = await fetch('http://'+hst+'/json/info');
|
||||
const responsePalettes = await fetch('http://'+hst+'/json/palettes');
|
||||
const json = await responseInfo.json();
|
||||
paletteName = await responsePalettes.json();
|
||||
cpalc = json.cpalcount;
|
||||
fetchPalettes(cpalc-1);
|
||||
} catch (error) {
|
||||
@ -521,6 +544,7 @@
|
||||
const json = await response.json();
|
||||
paletteArray.push(json);
|
||||
} catch (error) {
|
||||
cpalc--; //remove audio/dynamically generated palettes
|
||||
console.error(`Error fetching JSON from ${url}: `, error);
|
||||
}
|
||||
}
|
||||
@ -540,6 +564,7 @@
|
||||
alert("The cache of palettes are missig from your browser. You should probably return to the main page and let it load properly for the palettes cache to regenerate before returning here.","Missing cached palettes!")
|
||||
} else {
|
||||
for (const key in wledPalx.p) {
|
||||
wledPalx.p[key].name = paletteName[key];
|
||||
if (key > 245) {
|
||||
delete wledPalx.p[key];
|
||||
continue;
|
||||
@ -571,8 +596,11 @@
|
||||
}
|
||||
|
||||
const pArray = Object.entries(wledPalx.p).map(([key, value]) => ({
|
||||
[key]: value.flat()
|
||||
[key]: value.flat(),
|
||||
name: value.name
|
||||
}));
|
||||
// Sort pArray by name
|
||||
pArray.sort((a, b) => a.name.localeCompare(b.name));
|
||||
|
||||
paletteArray.push( ...pArray);
|
||||
}
|
||||
@ -614,6 +642,9 @@
|
||||
editSpan.id = `editSpan${i}`;
|
||||
editSpan.onclick = function() {loadForEdit(i)};
|
||||
editSpan.setAttribute('title', `Copy slot ${i} palette to editor`);
|
||||
if (paletteArray[i].name) {
|
||||
editSpan.setAttribute('title', `Copy ${paletteArray[i].name} palette to editor`);
|
||||
}
|
||||
editSpan.innerHTML = svgEdit;
|
||||
editSpan.classList.add("editSpan")
|
||||
|
||||
|
@ -370,6 +370,16 @@ button {
|
||||
padding: 5px 0 0;
|
||||
}
|
||||
|
||||
/* Quick load magin for simplified UI */
|
||||
.simplified #pql {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* Button margin for simplified UI */
|
||||
.simplified #fx .btn, .simplified #palw .btn {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.smooth { transition: transform calc(var(--f, 1)*.5s) ease-out }
|
||||
|
||||
.tab-label {
|
||||
@ -413,6 +423,7 @@ button {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
max-width: 300px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#sliders .labels {
|
||||
@ -754,13 +765,17 @@ input[type=range]::-moz-range-thumb {
|
||||
}
|
||||
|
||||
#Colors .sliderwrap {
|
||||
margin: 4px 0 0;
|
||||
margin: 2px 0 0;
|
||||
}
|
||||
|
||||
/* Dynamically hide brightness slider label */
|
||||
/* Dynamically hide labels */
|
||||
.hd {
|
||||
display: var(--bhd);
|
||||
}
|
||||
/* Do not hide quick load label in simplified mode on small screen widths */
|
||||
.simplified #pql .hd {
|
||||
display: var(--bhd) !important;
|
||||
}
|
||||
|
||||
#briwrap {
|
||||
min-width: 300px;
|
||||
@ -770,7 +785,7 @@ input[type=range]::-moz-range-thumb {
|
||||
|
||||
#picker {
|
||||
margin-top: 8px !important;
|
||||
max-width: 260px;
|
||||
max-width: max-content;
|
||||
}
|
||||
|
||||
/* buttons */
|
||||
@ -1284,6 +1299,12 @@ TD .checkmark, TD .radiomark {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Simplify segments */
|
||||
.simplified #segcont .lstI {
|
||||
margin-top: 4px;
|
||||
min-height: unset;
|
||||
}
|
||||
|
||||
/* selected item/element */
|
||||
.selected { /* has to be after .lstI since !important is not ok */
|
||||
background: var(--c-4);
|
||||
@ -1324,6 +1345,19 @@ TD .checkmark, TD .radiomark {
|
||||
top: calc(var(--sti) + 42px);
|
||||
}
|
||||
|
||||
dialog::backdrop {
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
dialog {
|
||||
max-height: 70%;
|
||||
border: 0;
|
||||
border-radius: 10px;
|
||||
background: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.1)), var(--c-3);
|
||||
box-shadow: 4px 4px 10px 4px var(--c-1);
|
||||
color: var(--c-f);
|
||||
}
|
||||
|
||||
#fxlist .lstI.sticky,
|
||||
#pallist .lstI.sticky {
|
||||
top: var(--sti);
|
||||
@ -1532,9 +1566,6 @@ TD .checkmark, TD .radiomark {
|
||||
max-width: 280px;
|
||||
font-size: 18px;
|
||||
}
|
||||
#picker {
|
||||
width: 230px;
|
||||
}
|
||||
#putil .btn-s {
|
||||
width: 114px;
|
||||
}
|
||||
|
@ -7,52 +7,9 @@
|
||||
<meta content="yes" name="apple-mobile-web-app-capable">
|
||||
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
|
||||
<title>WLED</title>
|
||||
<script>
|
||||
function feedback(){}
|
||||
// instead of including [script src="iro.js"][/script] and [script src="rangetouch.js"][/script]
|
||||
// (which would be inlined by nodeJS inliner during minimization and compression) we need to load them dynamically
|
||||
// the following is needed to load iro.js and rangetouch.js as consecutive requests to allow ESP8266
|
||||
// to keep up with requests (if requests happent too fast some may not get processed)
|
||||
// it will also call onLoad() after last is loaded (it was removed from [body onload="onLoad()"]).
|
||||
var h = document.getElementsByTagName('head')[0];
|
||||
var l = document.createElement('script');
|
||||
l.type = 'application/javascript';
|
||||
l.src = 'iro.js';
|
||||
l.addEventListener('load', (e) => {
|
||||
// after iro is loaded initialize global variable
|
||||
cpick = new iro.ColorPicker("#picker", {
|
||||
width: 260,
|
||||
wheelLightness: false,
|
||||
wheelAngle: 270,
|
||||
wheelDirection: "clockwise",
|
||||
layout: [{
|
||||
component: iro.ui.Wheel,
|
||||
options: {}
|
||||
}]
|
||||
});
|
||||
cpick.on("input:end", () => {setColor(1);});
|
||||
cpick.on("color:change", () => {updatePSliders()});
|
||||
var l = document.createElement('script');
|
||||
l.type = 'application/javascript';
|
||||
l.src = 'rangetouch.js';
|
||||
l.addEventListener('load', (e) => {
|
||||
// after rangetouch is loaded initialize global variable
|
||||
ranges = RangeTouch.setup('input[type="range"]', {});
|
||||
let stateCheck = setInterval(() => {
|
||||
if (document.readyState === 'complete') {
|
||||
clearInterval(stateCheck);
|
||||
// document ready, start processing UI
|
||||
onLoad();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
setTimeout(()=>{h.appendChild(l)},100);
|
||||
});
|
||||
setTimeout(()=>{h.appendChild(l)},200);
|
||||
</script>
|
||||
<link rel="stylesheet" href="index.css">
|
||||
</head>
|
||||
<body>
|
||||
<body onload="onLoad()">
|
||||
|
||||
<div id="cv" class="overlay">Loading WLED UI...</div>
|
||||
<noscript><div class="overlay" style="opacity:1;">Sorry, WLED UI needs JavaScript!</div></noscript>
|
||||
@ -168,7 +125,7 @@
|
||||
<input id="hexc" tooltip="Hex RGB" type="text" class="noslide" onkeydown="hexEnter()" autocomplete="off" maxlength="8" />
|
||||
<button id="hexcnf" class="btn btn-xs" onclick="fromHex();"><i class="icons btn-icon"></i></button>
|
||||
</div>
|
||||
<div style="padding: 8px 0;">
|
||||
<div style="padding: 8px 0;" id="btns">
|
||||
<button class="btn btn-xs" tooltip="Pixel Magic Tool" type="button" id="pxmb" onclick="window.location.href=getURL('/pxmagic.htm')"><i class="icons btn-icon"></i></button>
|
||||
<button class="btn btn-xs" tooltip="Add custom palette" type="button" onclick="window.location.href=getURL('/cpal.htm')"><i class="icons btn-icon"></i></button>
|
||||
<button class="btn btn-xs" tooltip="Remove custom palette" type="button" id="rmPal" onclick="palettesData=null;localStorage.removeItem('wledPalx');requestJson({rmcpal:true});setTimeout(loadPalettes,250,loadPalettesData);"><i class="icons btn-icon"></i></button>
|
||||
@ -351,7 +308,7 @@
|
||||
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button>
|
||||
</div>
|
||||
<br>
|
||||
<span class="h">Made with <span id="heart">❤︎</span> by Aircoookie and the <a href="https://wled.discourse.group/" target="_blank">WLED community</a></span>
|
||||
<span class="h">Made with <span id="heart">❤︎</span> by <a href="https://github.com/Aircoookie/" target="_blank">Aircoookie</a> and the <a href="https://wled.discourse.group/" target="_blank">WLED community</a></span>
|
||||
</div>
|
||||
|
||||
<div id="nodes" class="modal">
|
||||
@ -378,6 +335,13 @@
|
||||
</div>
|
||||
|
||||
<i id="roverstar" class="icons huge" onclick="setLor(0)"></i><br>
|
||||
|
||||
<!--
|
||||
If you want to load iro.js and rangetouch.js as consecutive requests, you can do it like it was done in 0.14.0:
|
||||
https://github.com/Aircoookie/WLED/blob/v0.14.0/wled00/data/index.htm
|
||||
-->
|
||||
<script src="iro.js"></script>
|
||||
<script src="rangetouch.js"></script>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -12,8 +12,11 @@ var currentPreset = -1;
|
||||
var lastUpdate = 0;
|
||||
var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0;
|
||||
var pcMode = false, pcModeA = false, lastw = 0, wW;
|
||||
var simplifiedUI = false;
|
||||
var tr = 7;
|
||||
var d = document;
|
||||
const ranges = RangeTouch.setup('input[type="range"]', {});
|
||||
var retry = false;
|
||||
var palettesData;
|
||||
var fxdata = [];
|
||||
var pJson = {}, eJson = {}, lJson = {};
|
||||
@ -22,22 +25,34 @@ var pN = "", pI = 0, pNum = 0;
|
||||
var pmt = 1, pmtLS = 0, pmtLast = 0;
|
||||
var lastinfo = {};
|
||||
var isM = false, mw = 0, mh=0;
|
||||
var ws, cpick, ranges, wsRpt=0;
|
||||
var ws, wsRpt=0;
|
||||
var cfg = {
|
||||
theme:{base:"dark", bg:{url:"", rnd: false, rndGrayscale: false, rndBlur: false}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
|
||||
comp :{colors:{picker: true, rgb: false, quick: true, hex: false},
|
||||
labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:false,
|
||||
css:true, hdays:false, fxdef:true, on:0, off:0, idsort: false}
|
||||
};
|
||||
// [year, month (0 -> January, 11 -> December), day, duration in days, image url]
|
||||
var hol = [
|
||||
[0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas
|
||||
[0,2,17,1,"https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day
|
||||
[2025,3,20,2,"https://aircoookie.github.io/easter.png"],
|
||||
[2024,2,31,2,"https://aircoookie.github.io/easter.png"],
|
||||
[0,6,4,1,"https://images.alphacoders.com/516/516792.jpg"], // 4th of July
|
||||
[0,0,1,1,"https://images.alphacoders.com/119/1198800.jpg"] // new year
|
||||
[0, 11, 24, 4, "https://aircoookie.github.io/xmas.png"], // christmas
|
||||
[0, 2, 17, 1, "https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day
|
||||
[2025, 3, 20, 2, "https://aircoookie.github.io/easter.png"], // easter 2025
|
||||
[2024, 2, 31, 2, "https://aircoookie.github.io/easter.png"], // easter 2024
|
||||
[0, 6, 4, 1, "https://images.alphacoders.com/516/516792.jpg"], // 4th of July
|
||||
[0, 0, 1, 1, "https://images.alphacoders.com/119/1198800.jpg"] // new year
|
||||
];
|
||||
|
||||
var cpick = new iro.ColorPicker("#picker", {
|
||||
width: 260,
|
||||
wheelLightness: false,
|
||||
wheelAngle: 270,
|
||||
wheelDirection: "clockwise",
|
||||
layout: [{
|
||||
component: iro.ui.Wheel,
|
||||
options: {}
|
||||
}]
|
||||
});
|
||||
|
||||
function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson();}
|
||||
function sCol(na, col) {d.documentElement.style.setProperty(na, col);}
|
||||
function gId(c) {return d.getElementById(c);}
|
||||
@ -161,19 +176,19 @@ function cTheme(light) {
|
||||
}
|
||||
}
|
||||
|
||||
function loadBg(iUrl)
|
||||
{
|
||||
let bg = gId('bg');
|
||||
let img = d.createElement("img");
|
||||
function loadBg() {
|
||||
const { url: iUrl, rnd: iRnd } = cfg.theme.bg;
|
||||
const bg = gId('bg');
|
||||
const img = d.createElement("img");
|
||||
img.src = iUrl;
|
||||
if (iUrl == "" || iUrl==="https://picsum.photos/1920/1080") {
|
||||
var today = new Date();
|
||||
for (var h of (hol||[])) {
|
||||
var yr = h[0]==0 ? today.getFullYear() : h[0];
|
||||
var hs = new Date(yr,h[1],h[2]);
|
||||
var he = new Date(hs);
|
||||
he.setDate(he.getDate() + h[3]);
|
||||
if (today>=hs && today<=he) img.src = h[4];
|
||||
if (!iUrl || iRnd) {
|
||||
const today = new Date();
|
||||
for (const holiday of (hol || [])) {
|
||||
const year = holiday[0] == 0 ? today.getFullYear() : holiday[0];
|
||||
const holidayStart = new Date(year, holiday[1], holiday[2]);
|
||||
const holidayEnd = new Date(holidayStart);
|
||||
holidayEnd.setDate(holidayEnd.getDate() + holiday[3]);
|
||||
if (today >= holidayStart && today <= holidayEnd) img.src = holiday[4];
|
||||
}
|
||||
}
|
||||
img.addEventListener('load', (e) => {
|
||||
@ -181,7 +196,6 @@ function loadBg(iUrl)
|
||||
if (isNaN(a)) a = 0.6;
|
||||
bg.style.opacity = a;
|
||||
bg.style.backgroundImage = `url(${img.src})`;
|
||||
img = null;
|
||||
gId('namelabel').style.color = "var(--c-c)"; // improve namelabel legibility on background image
|
||||
});
|
||||
}
|
||||
@ -252,31 +266,37 @@ function onLoad()
|
||||
console.log("No array of holidays in holidays.json. Defaults loaded.");
|
||||
})
|
||||
.finally(()=>{
|
||||
loadBg(cfg.theme.bg.url);
|
||||
loadBg();
|
||||
});
|
||||
} else
|
||||
loadBg(cfg.theme.bg.url);
|
||||
loadBg();
|
||||
|
||||
selectSlot(0);
|
||||
updateTablinks(0);
|
||||
cpick.on("input:end", () => {setColor(1);});
|
||||
cpick.on("color:change", () => {updatePSliders()});
|
||||
pmtLS = localStorage.getItem('wledPmt');
|
||||
|
||||
// Load initial data
|
||||
// Once we figure out why ESP8266 sometimes corrupts JSON responses if they are made in quick succession
|
||||
// we can remove all setTimeout() throttling
|
||||
loadPalettes(()=>{
|
||||
// fill effect extra data array
|
||||
loadFXData(()=>{
|
||||
setTimeout(()=>{ // ESP8266 can't handle quick requests
|
||||
// load and populate effects
|
||||
loadFX(()=>{
|
||||
setTimeout(()=>{ // ESP8266 can't handle quick requests
|
||||
loadPalettesData(()=>{
|
||||
requestJson();// will load presets and create WS
|
||||
if (cfg.comp.css) setTimeout(()=>{loadSkinCSS('skinCss')},100);
|
||||
});
|
||||
},100);
|
||||
});
|
||||
},100);
|
||||
});
|
||||
setTimeout(()=>{ // ESP8266 can't handle quick requests
|
||||
// fill effect extra data array
|
||||
loadFXData(()=>{
|
||||
setTimeout(()=>{ // ESP8266 can't handle quick requests
|
||||
// load and populate effects
|
||||
loadFX(()=>{
|
||||
setTimeout(()=>{ // ESP8266 can't handle quick requests
|
||||
loadPalettesData(()=>{
|
||||
requestJson();// will load presets and create WS
|
||||
if (cfg.comp.css) setTimeout(()=>{loadSkinCSS('skinCss')},100);
|
||||
});
|
||||
},50);
|
||||
});
|
||||
},50);
|
||||
});
|
||||
},50);
|
||||
});
|
||||
resetUtil();
|
||||
|
||||
@ -309,7 +329,6 @@ function openTab(tabI, force = false)
|
||||
var timeout;
|
||||
function showToast(text, error = false)
|
||||
{
|
||||
if (error) gId('connind').style.backgroundColor = "var(--c-r)";
|
||||
var x = gId('toast');
|
||||
//if (error) text += '<i class="icons btn-icon" style="transform:rotate(45deg);position:absolute;top:10px;right:0px;" onclick="clearErrorToast(100);"></i>';
|
||||
x.innerHTML = text;
|
||||
@ -322,6 +341,7 @@ function showToast(text, error = false)
|
||||
|
||||
function showErrorToast()
|
||||
{
|
||||
gId('connind').style.backgroundColor = "var(--c-r)";
|
||||
showToast('Connection to light failed!', true);
|
||||
}
|
||||
|
||||
@ -500,8 +520,13 @@ function loadPalettes(callback = null)
|
||||
.then((json)=>{
|
||||
lJson = Object.entries(json);
|
||||
populatePalettes();
|
||||
retry = false;
|
||||
})
|
||||
.catch((e)=>{
|
||||
if (!retry) {
|
||||
retry = true;
|
||||
setTimeout(loadPalettes, 500); // retry
|
||||
}
|
||||
showToast(e, true);
|
||||
})
|
||||
.finally(()=>{
|
||||
@ -522,9 +547,13 @@ function loadFX(callback = null)
|
||||
.then((json)=>{
|
||||
eJson = Object.entries(json);
|
||||
populateEffects();
|
||||
retry = false;
|
||||
})
|
||||
.catch((e)=>{
|
||||
//setTimeout(loadFX, 250); // retry
|
||||
if (!retry) {
|
||||
retry = true;
|
||||
setTimeout(loadFX, 500); // retry
|
||||
}
|
||||
showToast(e, true);
|
||||
})
|
||||
.finally(()=>{
|
||||
@ -547,10 +576,14 @@ function loadFXData(callback = null)
|
||||
// add default value for Solid
|
||||
fxdata.shift()
|
||||
fxdata.unshift(";!;");
|
||||
retry = false;
|
||||
})
|
||||
.catch((e)=>{
|
||||
fxdata = [];
|
||||
//setTimeout(loadFXData, 250); // retry
|
||||
if (!retry) {
|
||||
retry = true;
|
||||
setTimeout(loadFXData, 500); // retry
|
||||
}
|
||||
showToast(e, true);
|
||||
})
|
||||
.finally(()=>{
|
||||
@ -624,11 +657,12 @@ function parseInfo(i) {
|
||||
if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)"; // Minecraft easter egg
|
||||
if (i.live) name = "(Live) " + name;
|
||||
if (loc) name = "(L) " + name;
|
||||
d.title = name;
|
||||
ledCount = i.leds.count;
|
||||
//syncTglRecv = i.str;
|
||||
maxSeg = i.leds.maxseg;
|
||||
pmt = i.fs.pmt;
|
||||
d.title = name;
|
||||
simplifiedUI = i.simplifiedui;
|
||||
ledCount = i.leds.count;
|
||||
//syncTglRecv = i.str;
|
||||
maxSeg = i.leds.maxseg;
|
||||
pmt = i.fs.pmt;
|
||||
gId('buttonNodes').style.display = lastinfo.ndc > 0 ? null:"none";
|
||||
// do we have a matrix set-up
|
||||
mw = i.leds.matrix ? i.leds.matrix.w : 0;
|
||||
@ -750,6 +784,7 @@ function populateSegments(s)
|
||||
let rvXck = `<label class="check revchkl">Reverse ${isM?'':'direction'}<input type="checkbox" id="seg${i}rev" onchange="setRev(${i})" ${inst.rev?"checked":""}><span class="checkmark"></span></label>`;
|
||||
let miXck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mi" onchange="setMi(${i})" ${inst.mi?"checked":""}><span class="checkmark"></span></label>`;
|
||||
let rvYck = "", miYck ="";
|
||||
let smpl = simplifiedUI ? 'hide' : '';
|
||||
if (isMSeg) {
|
||||
rvYck = `<label class="check revchkl">Reverse<input type="checkbox" id="seg${i}rY" onchange="setRevY(${i})" ${inst.rY?"checked":""}><span class="checkmark"></span></label>`;
|
||||
miYck = `<label class="check revchkl">Mirror<input type="checkbox" id="seg${i}mY" onchange="setMiY(${i})" ${inst.mY?"checked":""}><span class="checkmark"></span></label>`;
|
||||
@ -768,23 +803,23 @@ function populateSegments(s)
|
||||
`<option value="1" ${inst.si==1?' selected':''}>WeWillRockYou</option>`+
|
||||
`</select></div>`+
|
||||
`</div>`;
|
||||
cn += `<div class="seg lstI ${i==s.mainseg ? 'selected' : ''} ${exp ? "expanded":""}" id="seg${i}" data-set="${inst.set}">`+
|
||||
`<label class="check schkl">`+
|
||||
cn += `<div class="seg lstI ${i==s.mainseg && !simplifiedUI ? 'selected' : ''} ${exp ? "expanded":""}" id="seg${i}" data-set="${inst.set}">`+
|
||||
`<label class="check schkl ${smpl}">`+
|
||||
`<input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}>`+
|
||||
`<span class="checkmark"></span>`+
|
||||
`</label>`+
|
||||
`<div class="segname" onclick="selSegEx(${i})">`+
|
||||
`<div class="segname ${smpl}" onclick="selSegEx(${i})">`+
|
||||
`<i class="icons e-icon frz" id="seg${i}frz" onclick="event.preventDefault();tglFreeze(${i});">&#x${inst.frz ? (li.live && li.liveseg==i?'e410':'e0e8') : 'e325'};</i>`+
|
||||
(inst.n ? inst.n : "Segment "+i) +
|
||||
`<div class="pop hide" onclick="event.preventDefault();event.stopPropagation();">`+
|
||||
`<i class="icons g-icon" style="color:${cG};" onclick="this.nextElementSibling.classList.toggle('hide');">ɸ${String.fromCharCode(inst.set+"A".charCodeAt(0))};</i>`+
|
||||
`<div class="pop-c hide"><span style="color:var(--c-f);" onclick="setGrp(${i},0);">➊</span><span style="color:var(--c-r);" onclick="setGrp(${i},1);">➋</span><span style="color:var(--c-g);" onclick="setGrp(${i},2);">➌</span><span style="color:var(--c-l);" onclick="setGrp(${i},3);">➍</span></div>`+
|
||||
`</div> `+
|
||||
`<i class="icons edit-icon flr" id="seg${i}nedit" onclick="tglSegn(${i})"></i>`+
|
||||
`<i class="icons edit-icon flr ${smpl}" id="seg${i}nedit" onclick="tglSegn(${i})"></i>`+
|
||||
`</div>`+
|
||||
`<i class="icons e-icon flr" id="sege${i}" onclick="expand(${i})"></i>`+
|
||||
`<i class="icons e-icon flr ${smpl}" id="sege${i}" onclick="expand(${i})"></i>`+
|
||||
(cfg.comp.segpwr ? segp : '') +
|
||||
`<div class="segin" id="seg${i}in">`+
|
||||
`<div class="segin ${smpl}" id="seg${i}in">`+
|
||||
`<input type="text" class="ptxt" id="seg${i}t" autocomplete="off" maxlength=${li.arch=="esp8266"?32:64} value="${inst.n?inst.n:""}" placeholder="Enter name..."/>`+
|
||||
`<table class="infot segt">`+
|
||||
`<tr>`+
|
||||
@ -834,6 +869,7 @@ function populateSegments(s)
|
||||
}
|
||||
|
||||
gId('segcont').innerHTML = cn;
|
||||
gId("segcont").classList.remove("hide");
|
||||
let noNewSegs = (lowestUnused >= maxSeg);
|
||||
resetUtil(noNewSegs);
|
||||
if (gId('selall')) gId('selall').checked = true;
|
||||
@ -847,6 +883,8 @@ function populateSegments(s)
|
||||
if (segCount < 2) {
|
||||
gId(`segd${lSeg}`).classList.add("hide");
|
||||
if (parseInt(gId("seg0bri").value)==255) gId(`segp0`).classList.add("hide");
|
||||
// hide segment controls if there is only one segment in simplified UI
|
||||
if (simplifiedUI) gId("segcont").classList.add("hide");
|
||||
}
|
||||
if (!isM && !noNewSegs && (cfg.comp.seglen?parseInt(gId(`seg${lSeg}s`).value):0)+parseInt(gId(`seg${lSeg}e`).value)<ledCount) gId(`segr${lSeg}`).classList.remove("hide");
|
||||
gId('segutil2').style.display = (segCount > 1) ? "block":"none"; // rsbtn parent
|
||||
@ -1258,6 +1296,12 @@ function updateSelectedPalette(s)
|
||||
var selectedPalette = parent.querySelector(`.lstI[data-id="${s}"]`);
|
||||
if (selectedPalette) parent.querySelector(`.lstI[data-id="${s}"]`).classList.add('selected');
|
||||
|
||||
// Display selected palette name on button in simplified UI
|
||||
let selectedName = selectedPalette.querySelector(".lstIname").innerText;
|
||||
if (simplifiedUI) {
|
||||
gId("palwbtn").innerText = "Palette: " + selectedName;
|
||||
}
|
||||
|
||||
// in case of special palettes (* Colors...), force show color selectors (if hidden by effect data)
|
||||
let cd = gId('csl').children; // color selectors
|
||||
if (s > 1 && s < 6) {
|
||||
@ -1299,8 +1343,15 @@ function updateSelectedFx()
|
||||
}
|
||||
}
|
||||
});
|
||||
// hide 2D mapping and/or sound simulation options
|
||||
var selectedName = selectedEffect.querySelector(".lstIname").innerText;
|
||||
|
||||
// Display selected effect name on button in simplified UI
|
||||
let selectedNameOnlyAscii = selectedName.replace(/[^\x00-\x7F]/g, "");
|
||||
if (simplifiedUI) {
|
||||
gId("fxbtn").innerText = "Effect: " + selectedNameOnlyAscii;
|
||||
}
|
||||
|
||||
// hide 2D mapping and/or sound simulation options
|
||||
var segs = gId("segcont").querySelectorAll(`div[data-map="map2D"]`);
|
||||
for (const seg of segs) if (selectedName.indexOf("\u25A6")<0) seg.classList.remove('hide'); else seg.classList.add('hide');
|
||||
var segs = gId("segcont").querySelectorAll(`div[data-snd="si"]`);
|
||||
@ -1441,25 +1492,31 @@ function readState(s,command=false)
|
||||
gId('checkO3').checked = !(!i.o3);
|
||||
|
||||
if (s.error && s.error != 0) {
|
||||
var errstr = "";
|
||||
switch (s.error) {
|
||||
case 10:
|
||||
errstr = "Could not mount filesystem!";
|
||||
break;
|
||||
case 11:
|
||||
errstr = "Not enough space to save preset!";
|
||||
break;
|
||||
case 12:
|
||||
errstr = "Preset not found.";
|
||||
break;
|
||||
case 13:
|
||||
errstr = "Missing ir.json.";
|
||||
break;
|
||||
case 19:
|
||||
errstr = "A filesystem error has occured.";
|
||||
break;
|
||||
var errstr = "";
|
||||
switch (s.error) {
|
||||
case 8:
|
||||
errstr = "Effect RAM depleted!";
|
||||
break;
|
||||
case 9:
|
||||
errstr = "JSON parsing error!";
|
||||
break;
|
||||
case 10:
|
||||
errstr = "Could not mount filesystem!";
|
||||
break;
|
||||
case 11:
|
||||
errstr = "Not enough space to save preset!";
|
||||
break;
|
||||
case 12:
|
||||
errstr = "Preset not found.";
|
||||
break;
|
||||
case 13:
|
||||
errstr = "Missing ir.json.";
|
||||
break;
|
||||
case 19:
|
||||
errstr = "A filesystem error has occured.";
|
||||
break;
|
||||
}
|
||||
showToast('Error ' + s.error + ": " + errstr, true);
|
||||
showToast('Error ' + s.error + ": " + errstr, true);
|
||||
}
|
||||
|
||||
selectedPal = i.pal;
|
||||
@ -1530,6 +1587,7 @@ function setEffectParameters(idx)
|
||||
|
||||
// set the bottom position of selected effect (sticky) as the top of sliders div
|
||||
function setSelectedEffectPosition() {
|
||||
if (simplifiedUI) return;
|
||||
let top = parseInt(getComputedStyle(gId("sliders")).height);
|
||||
top += 5;
|
||||
let sel = d.querySelector('#fxlist .selected');
|
||||
@ -1596,6 +1654,10 @@ function setEffectParameters(idx)
|
||||
// disable palette list
|
||||
text += ' not used';
|
||||
palw.style.display = "none";
|
||||
// Close palette dialog if not available
|
||||
if (gId("palw").lastElementChild.tagName == "DIALOG") {
|
||||
gId("palw").lastElementChild.close();
|
||||
}
|
||||
}
|
||||
pall.innerHTML = icon + text;
|
||||
// not all color selectors shown, hide palettes created from color selectors
|
||||
@ -1661,6 +1723,7 @@ function requestJson(command=null)
|
||||
parseInfo(i);
|
||||
populatePalettes(i);
|
||||
if (isInfo) populateInfo(i);
|
||||
if (simplifiedUI) simplifyUI();
|
||||
}
|
||||
var s = json.state ? json.state : json;
|
||||
readState(s);
|
||||
@ -1673,8 +1736,13 @@ function requestJson(command=null)
|
||||
});
|
||||
},25);
|
||||
reqsLegal = true;
|
||||
retry = false;
|
||||
})
|
||||
.catch((e)=>{
|
||||
if (!retry) {
|
||||
retry = true;
|
||||
setTimeout(requestJson,500);
|
||||
}
|
||||
showToast(e, true);
|
||||
});
|
||||
}
|
||||
@ -2093,7 +2161,7 @@ function selGrp(g)
|
||||
var sel = gId(`segcont`).querySelectorAll(`div[data-set="${g}"]`);
|
||||
var obj = {"seg":[]};
|
||||
for (let i=0; i<=lSeg; i++) if (gId(`seg${i}`)) obj.seg.push({"id":i,"sel":false});
|
||||
if (sel) for (let s of sel||[]) {
|
||||
for (let s of (sel||[])) {
|
||||
let i = parseInt(s.id.substring(3));
|
||||
obj.seg[i] = {"id":i,"sel":true};
|
||||
}
|
||||
@ -2259,6 +2327,12 @@ function setFX(ind = null)
|
||||
} else {
|
||||
d.querySelector(`#fxlist input[name="fx"][value="${ind}"]`).checked = true;
|
||||
}
|
||||
|
||||
// Close effect dialog in simplified UI
|
||||
if (simplifiedUI) {
|
||||
gId("fx").lastElementChild.close();
|
||||
}
|
||||
|
||||
var obj = {"seg": {"fx": parseInt(ind), "fxdef": cfg.comp.fxdef}}; // fxdef sets effect parameters to default values
|
||||
requestJson(obj);
|
||||
}
|
||||
@ -2271,6 +2345,11 @@ function setPalette(paletteId = null)
|
||||
d.querySelector(`#pallist input[name="palette"][value="${paletteId}"]`).checked = true;
|
||||
}
|
||||
|
||||
// Close palette dialog in simplified UI
|
||||
if (simplifiedUI) {
|
||||
gId("palw").lastElementChild.close();
|
||||
}
|
||||
|
||||
var obj = {"seg": {"pal": paletteId}};
|
||||
requestJson(obj);
|
||||
}
|
||||
@ -2722,8 +2801,10 @@ function search(field, listId = null) {
|
||||
field.nextElementSibling.style.display = (field.value !== '') ? 'block' : 'none';
|
||||
if (!listId) return;
|
||||
|
||||
const search = field.value !== '';
|
||||
|
||||
// clear filter if searching in fxlist
|
||||
if (listId === 'fxlist' && field.value !== '') {
|
||||
if (listId === 'fxlist' && search) {
|
||||
gId("filters").querySelectorAll("input[type=checkbox]").forEach((e) => { e.checked = false; });
|
||||
}
|
||||
|
||||
@ -2757,6 +2838,12 @@ function search(field, listId = null) {
|
||||
sortedListItems.forEach(item => {
|
||||
gId(listId).append(item);
|
||||
});
|
||||
|
||||
// scroll to first search result
|
||||
const firstVisibleItem = sortedListItems.find(item => item.style.display !== 'none' && !item.classList.contains('sticky') && !item.classList.contains('selected'));
|
||||
if (firstVisibleItem && search) {
|
||||
firstVisibleItem.scrollIntoView({ behavior: "instant", block: "center" });
|
||||
}
|
||||
}
|
||||
|
||||
function clean(clearButton) {
|
||||
@ -2903,7 +2990,7 @@ function hasIroClass(classList)
|
||||
//required by rangetouch.js
|
||||
function lock(e)
|
||||
{
|
||||
if (pcMode) return;
|
||||
if (pcMode || simplifiedUI) return;
|
||||
var l = e.target.classList;
|
||||
var pl = e.target.parentElement.classList;
|
||||
|
||||
@ -2917,7 +3004,7 @@ function lock(e)
|
||||
//required by rangetouch.js
|
||||
function move(e)
|
||||
{
|
||||
if(!locked || pcMode) return;
|
||||
if(!locked || pcMode || simplifiedUI) return;
|
||||
var clientX = unify(e).clientX;
|
||||
var dx = clientX - x0;
|
||||
var s = Math.sign(dx);
|
||||
@ -2963,7 +3050,7 @@ function togglePcMode(fromB = false)
|
||||
gId('buttonPcm').className = (pcMode) ? "active":"";
|
||||
gId('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto";
|
||||
sCol('--bh', gId('bot').clientHeight + "px");
|
||||
_C.style.width = (pcMode)?'100%':'400%';
|
||||
_C.style.width = (pcMode || simplifiedUI)?'100%':'400%';
|
||||
}
|
||||
|
||||
function mergeDeep(target, ...sources)
|
||||
@ -3018,6 +3105,98 @@ function tooltip()
|
||||
});
|
||||
};
|
||||
|
||||
// Transforms the default UI into the simple UI
|
||||
function simplifyUI() {
|
||||
// Create dropdown dialog
|
||||
function createDropdown(id, buttonText, dialogElements = null) {
|
||||
// Create dropdown dialog
|
||||
const dialog = document.createElement("dialog");
|
||||
// Move every dialogElement to the dropdown dialog or if none are given, move all children of the element with the given id
|
||||
if (dialogElements) {
|
||||
dialogElements.forEach((e) => {
|
||||
dialog.appendChild(e);
|
||||
});
|
||||
} else {
|
||||
while (gId(id).firstChild) {
|
||||
dialog.appendChild(gId(id).firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
// Create button for the dropdown
|
||||
const btn = document.createElement("button");
|
||||
btn.id = id + "btn";
|
||||
btn.classList.add("btn");
|
||||
btn.innerText = buttonText;
|
||||
function toggleDialog(e) {
|
||||
if (e.target != btn && e.target != dialog) return;
|
||||
if (dialog.open) {
|
||||
dialog.close();
|
||||
return;
|
||||
}
|
||||
// Prevent autofocus on dialog open
|
||||
dialog.inert = true;
|
||||
dialog.showModal();
|
||||
dialog.inert = false;
|
||||
clean(dialog.firstElementChild.children[1]);
|
||||
dialog.scrollTop = 0;
|
||||
};
|
||||
btn.addEventListener("click", toggleDialog);
|
||||
dialog.addEventListener("click", toggleDialog);
|
||||
|
||||
// Add the dialog and button to the element with the given id
|
||||
gId(id).append(btn);
|
||||
gId(id).append(dialog);
|
||||
}
|
||||
|
||||
// Check if the UI was already simplified
|
||||
if (gId("Colors").classList.contains("simplified")) return;
|
||||
|
||||
// Disable PC Mode as it does not exist in simple UI
|
||||
if (pcMode) togglePcMode(true);
|
||||
_C.style.width = '100%'
|
||||
_C.style.setProperty('--n', 1);
|
||||
|
||||
gId("Colors").classList.add("simplified");
|
||||
// Put effects below palett list
|
||||
gId("Colors").append(gId("fx"));
|
||||
gId("Colors").append(gId("sliders"));
|
||||
// Put segments before palette list
|
||||
gId("Colors").insertBefore(gId("segcont"), gId("pall"));
|
||||
// Put preset quick load before palette list and segemts
|
||||
gId("Colors").insertBefore(gId("pql"), gId("pall"));
|
||||
|
||||
// Create dropdown for palette list
|
||||
createDropdown("palw", "Change palette");
|
||||
createDropdown("fx", "Change effect", [gId("fxFind"), gId("fxlist")]);
|
||||
|
||||
// Hide pallete label
|
||||
gId("pall").style.display = "none";
|
||||
gId("Colors").insertBefore(document.createElement("br"), gId("pall"));
|
||||
// Hide effect label
|
||||
gId("modeLabel").style.display = "none";
|
||||
|
||||
// Hide buttons in top bar
|
||||
gId("buttonNl").style.display = "none";
|
||||
gId("buttonSync").style.display = "none";
|
||||
gId("buttonSr").style.display = "none";
|
||||
gId("buttonPcm").style.display = "none";
|
||||
|
||||
// Hide bottom bar
|
||||
gId("bot").style.display = "none";
|
||||
document.documentElement.style.setProperty('--bh', '0px');
|
||||
|
||||
// Hide other tabs
|
||||
gId("Effects").style.display = "none";
|
||||
gId("Segments").style.display = "none";
|
||||
gId("Presets").style.display = "none";
|
||||
|
||||
// Hide filter options
|
||||
gId("filters").style.display = "none";
|
||||
|
||||
// Hide buttons for pixel art and custom palettes (add / delete)
|
||||
gId("btns").style.display = "none";
|
||||
}
|
||||
|
||||
size();
|
||||
_C.style.setProperty('--n', N);
|
||||
|
||||
|
@ -6,23 +6,33 @@
|
||||
<meta name="theme-color" content="#222222">
|
||||
<title>WLED Live Preview</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#canv {
|
||||
background: black;
|
||||
filter: brightness(175%);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
#canv {
|
||||
background: black;
|
||||
filter: brightness(175%);
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
var d = document;
|
||||
var ws;
|
||||
var tmout = null;
|
||||
function update() // via HTTP (/json/live)
|
||||
{
|
||||
if (document.hidden) {
|
||||
var c;
|
||||
var ctx;
|
||||
function draw(start, skip, leds, fill) {
|
||||
c.width = d.documentElement.clientWidth;
|
||||
let w = (c.width * skip) / (leds.length - start);
|
||||
for (let i = start; i < leds.length; i += skip) {
|
||||
ctx.fillStyle = fill(leds,i);
|
||||
ctx.fillRect(Math.round((i - start) * w / skip), 0, Math.ceil(w), c.height);
|
||||
}
|
||||
}
|
||||
function update() { // via HTTP (/json/live)
|
||||
if (d.hidden) {
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 250);
|
||||
return;
|
||||
@ -36,27 +46,20 @@
|
||||
return res.json();
|
||||
})
|
||||
.then(json => {
|
||||
var str = "linear-gradient(90deg,";
|
||||
var len = json.leds.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
var leddata = json.leds[i];
|
||||
if (leddata.length > 6) leddata = leddata.substring(2);
|
||||
str += "#" + leddata;
|
||||
if (i < len -1) str += ","
|
||||
}
|
||||
str += ")";
|
||||
document.getElementById("canv").style.background = str;
|
||||
draw(0, 1, json.leds, (a,i) => "#" + ((a[i].length > 6) ? a[i].substring(2) : a[i]));
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 40);
|
||||
})
|
||||
.catch(function (error) {
|
||||
.catch((error)=>{
|
||||
//console.error("Peek HTTP error:",error);
|
||||
clearTimeout(tmout);
|
||||
tmout = setTimeout(update, 2500);
|
||||
})
|
||||
}
|
||||
function S() { // Startup function (onload)
|
||||
let wsOn = (window.location.href.indexOf("?ws") > 0);
|
||||
if (!wsOn) {update(); return;}
|
||||
c = d.getElementById('canv');
|
||||
ctx = c.getContext('2d');
|
||||
if (window.location.href.indexOf("?ws") == -1) {update(); return;}
|
||||
|
||||
// Initialize WebSocket connection
|
||||
try {
|
||||
@ -86,15 +89,8 @@
|
||||
if (toString.call(e.data) === '[object ArrayBuffer]') {
|
||||
let leds = new Uint8Array(event.data);
|
||||
if (leds[0] != 76) return; //'L'
|
||||
let str = "linear-gradient(90deg,";
|
||||
let len = leds.length;
|
||||
let start = leds[1]==2 ? 4 : 2; // 1 = 1D, 2 = 1D/2D (leds[2]=w, leds[3]=h)
|
||||
for (i = start; i < len; i+=3) {
|
||||
str += `rgb(${leds[i]},${leds[i+1]},${leds[i+2]})`;
|
||||
if (i < len -3) str += ","
|
||||
}
|
||||
str += ")";
|
||||
document.getElementById("canv").style.background = str;
|
||||
// leds[1] = 1: 1D; leds[1] = 2: 1D/2D (leds[2]=w, leds[3]=h)
|
||||
draw(leds[1]==2 ? 4 : 2, 3, leds, (a,i) => `rgb(${a[i]},${a[i+1]},${a[i+2]})`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Peek WS error:",err);
|
||||
@ -104,6 +100,6 @@
|
||||
</script>
|
||||
</head>
|
||||
<body onload="S()">
|
||||
<div id="canv"></div>
|
||||
<canvas id="canv"></canvas>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
@ -16,6 +16,13 @@
|
||||
function B(){window.open(getURL("/settings"),"_self");}
|
||||
function gId(n){return d.getElementById(n);}
|
||||
function off(n){d.getElementsByName(n)[0].value = -1;}
|
||||
// these functions correspond to C macros found in const.h
|
||||
function isPWM(t) { return t > 40 && t < 46; } // is PWM type
|
||||
function isAna(t) { return t == 40 || isPWM(t); } // is analog type
|
||||
function isDig(t) { return (t > 15 && t < 40) || isD2P(t); } // is digital type
|
||||
function isD2P(t) { return t > 47 && t < 64; } // is digital 2 pin type
|
||||
function is16b(t) { return t == 26 || t == 29 } // is digital 16 bit type
|
||||
function isVir(t) { return t >= 80 && t < 96; } // is virtual type
|
||||
// https://www.educative.io/edpresso/how-to-dynamically-load-a-js-file-in-javascript
|
||||
function loadJS(FILE_URL, async = true) {
|
||||
let scE = d.createElement("script");
|
||||
@ -26,8 +33,8 @@
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
GetV();
|
||||
setABL();
|
||||
checkSi();
|
||||
setABL();
|
||||
d.Sf.addEventListener("submit", trySubmit);
|
||||
if (d.um_p[0]==-1) d.um_p.shift();
|
||||
pinDropdowns();
|
||||
@ -107,44 +114,50 @@
|
||||
e.preventDefault();
|
||||
if (!pinsOK()) {e.stopPropagation();return false;} // Prevent form submission and contact with server
|
||||
if (bquot > 100) {var msg = "Too many LEDs for me to handle!"; if (maxM < 10000) msg += "\n\rConsider using an ESP32."; alert(msg);}
|
||||
if (!d.Sf.ABL.checked || d.Sf.PPL.checked) d.Sf.MA.value = 0; // submit 0 as ABL (PPL will handle it)
|
||||
if (d.Sf.checkValidity()) d.Sf.submit(); //https://stackoverflow.com/q/37323914
|
||||
}
|
||||
function enABL()
|
||||
{
|
||||
var en = d.Sf["ABL"].checked;
|
||||
d.Sf["MA"].min = en ? 250 : 0;
|
||||
var en = d.Sf.ABL.checked;
|
||||
gId('abl').style.display = (en) ? 'inline':'none';
|
||||
gId('psu2').style.display = (en) ? 'inline':'none';
|
||||
if (!en) d.Sf["PPL"].checked = false;
|
||||
if (!en) d.Sf.PPL.checked = false;
|
||||
enPPL();
|
||||
UI();
|
||||
}
|
||||
function enPPL()
|
||||
{
|
||||
const abl = d.Sf["ABL"].checked;
|
||||
const en = d.Sf["PPL"].checked;
|
||||
d.Sf["MA"].readonly = en;
|
||||
gId("ppldis").style.display = en ? 'inline' : 'none';
|
||||
const abl = d.Sf.ABL.checked;
|
||||
const ppl = d.Sf.PPL.checked;
|
||||
let sumMA = 0;
|
||||
d.Sf.MA.readonly = ppl;
|
||||
d.Sf.MA.min = abl && !ppl ? 250 : 0;
|
||||
gId("psuMA").style.display = ppl ? 'none' : 'inline';
|
||||
gId("ppldis").style.display = ppl ? 'inline' : 'none';
|
||||
// set PPL minimum value and clear actual PPL limit if ABL disabled
|
||||
d.Sf.querySelectorAll("#mLC input[name^=MA]").forEach((i,n)=>{
|
||||
gId("PSU"+n).style.display = en ? "inline" : "none";
|
||||
gId("PSU"+n).style.display = ppl ? "inline" : "none";
|
||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||
i.min = en && !((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 250 : 0;
|
||||
i.min = ppl && !(isVir(t) || isAna(t)) ? 250 : 0;
|
||||
if (!abl) i.value = 0;
|
||||
else if (ppl) sumMA += parseInt(i.value,10);
|
||||
});
|
||||
if (ppl) d.Sf.MA.value = sumMA; // populate UI ABL value if PPL used
|
||||
}
|
||||
function enLA(s,n)
|
||||
{
|
||||
const t = parseInt(d.Sf["LT"+n].value); // LED type SELECT
|
||||
gId('LAdis'+n).style.display = s.selectedIndex==5 ? "inline" : "none";
|
||||
d.Sf["LA"+n].value = s.value==="0" ? 55 : s.value;
|
||||
d.Sf["LA"+n].min = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 0 : 1;
|
||||
d.Sf["LA"+n].min = (isVir(t) || isAna(t)) ? 0 : 1;
|
||||
}
|
||||
function setABL()
|
||||
{
|
||||
d.Sf["ABL"].checked = false;
|
||||
d.Sf.ABL.checked = parseInt(d.Sf.MA.value) > 0;
|
||||
// check if ABL is enabled (max mA entered per output)
|
||||
d.Sf.querySelectorAll("#mLC input[name^=MA]").forEach((i,n)=>{
|
||||
if (parseInt(i.value) > 0) d.Sf["ABL"].checked = true;
|
||||
if (parseInt(i.value) > 0) d.Sf.ABL.checked = true;
|
||||
});
|
||||
// select appropriate LED current
|
||||
d.Sf.querySelectorAll("#mLC select[name^=LAsel]").forEach((sel,n)=>{
|
||||
@ -164,25 +177,25 @@
|
||||
}
|
||||
//returns mem usage
|
||||
function getMem(t, n) {
|
||||
if (isAna(t)) return 5; // analog
|
||||
let len = parseInt(d.getElementsByName("LC"+n)[0].value);
|
||||
len += parseInt(d.getElementsByName("SL"+n)[0].value); // skipped LEDs are allocated too
|
||||
let dbl = 0;
|
||||
if (d.Sf.LD.checked) dbl = len * 4; // double buffering
|
||||
if (t < 32) {
|
||||
if (t==26 || t==29) len *= 2; // 16 bit LEDs
|
||||
let ch = 3;
|
||||
let mul = 1;
|
||||
if (isDig(t)) {
|
||||
if (is16b(t)) len *= 2; // 16 bit LEDs
|
||||
if (t > 28 && t < 40) ch = 4; //RGBW
|
||||
if (maxM < 10000 && d.getElementsByName("L0"+n)[0].value == 3) { //8266 DMA uses 5x the mem
|
||||
if (t > 28) return len*20 + dbl; //RGBW
|
||||
return len*15 + dbl;
|
||||
} else if (maxM >= 10000) //ESP32 RMT uses double buffer?
|
||||
{
|
||||
if (t > 28) return len*8 + dbl; //RGBW
|
||||
return len*6 + dbl;
|
||||
mul = 5;
|
||||
}
|
||||
if (t > 28) return len*4 + dbl; //RGBW
|
||||
return len*3 + dbl;
|
||||
if (maxM >= 10000) { //ESP32 RMT uses double buffer?
|
||||
mul = 2;
|
||||
}
|
||||
if (d.Sf.LD.checked) dbl = len * ch; // double buffering
|
||||
}
|
||||
if (t > 31 && t < 48) return 5; // analog
|
||||
return len*3 + dbl;
|
||||
if (isVir(t) && t == 88) ch = 4;
|
||||
return len * ch * mul + dbl;
|
||||
}
|
||||
|
||||
function UI(change=false)
|
||||
@ -190,20 +203,17 @@
|
||||
let isRGBW = false, gRGBW = false, memu = 0;
|
||||
let sumMA = 0, busMA = 0;
|
||||
let sLC = 0, sPC = 0, sDI = 0, maxLC = 0;
|
||||
const ablEN = d.Sf["ABL"].checked;
|
||||
const pplEN = d.Sf["PPL"].checked;
|
||||
const ablEN = d.Sf.ABL.checked;
|
||||
const pplEN = d.Sf.PPL.checked;
|
||||
|
||||
// enable/disable LED fields
|
||||
d.Sf.querySelectorAll("#mLC select[name^=LT]").forEach((s)=>{
|
||||
// is the field a LED type?
|
||||
var n = s.name.substring(2);
|
||||
var t = parseInt(s.value);
|
||||
let isDig = ((t >= 16 && t < 32) || (t >= 50 && t < 64));
|
||||
let isVir = (t >= 80 && t < 96);
|
||||
let isPwm = (t >= 40 && t < 48);
|
||||
gId("p0d"+n).innerHTML = (t>=80 && t<96) ? "IP address:" : (t > 49) ? "Data GPIO:" : (t > 41) ? "GPIOs:" : "GPIO:";
|
||||
gId("p1d"+n).innerHTML = (t> 49 && t<64) ? "Clk GPIO:" : "";
|
||||
gId("abl"+n).style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none" : "inline";
|
||||
gId("p0d"+n).innerHTML = isVir(t) ? "IP address:" : isD2P(t) ? "Data GPIO:" : (t > 41) ? "GPIOs:" : "GPIO:";
|
||||
gId("p1d"+n).innerHTML = isD2P(t) ? "Clk GPIO:" : "";
|
||||
gId("abl"+n).style.display = (!ablEN || isVir(t) || isAna(t)) ? "none" : "inline";
|
||||
//var LK = d.getElementsByName("L1"+n)[0]; // clock pin
|
||||
|
||||
memu += getMem(t, n); // calc memory
|
||||
@ -212,7 +222,7 @@
|
||||
for (p=1; p<5; p++) {
|
||||
var LK = d.Sf["L"+p+n]; // secondary pins
|
||||
if (!LK) continue;
|
||||
if (((t>=80 && t<96) && p<4) || (t>49 && p==1) || (t>41 && t < 50 && (p+40 < t))) // TYPE_xxxx values from const.h
|
||||
if ((isVir(t) && p<4) || (isD2P(t) && p==1) || (isPWM(t) && (p+40 < t))) // TYPE_xxxx values from const.h
|
||||
{
|
||||
// display pin field
|
||||
LK.style.display = "inline";
|
||||
@ -226,25 +236,25 @@
|
||||
}
|
||||
if (change) {
|
||||
gId("rf"+n).checked = (gId("rf"+n).checked || t == 31); // LEDs require data in off state
|
||||
if (t > 31 && t < 48) d.Sf["LC"+n].value = 1; // for sanity change analog count just to 1 LED
|
||||
d.Sf["LA"+n].min = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 0 : 1;
|
||||
d.Sf["MA"+n].min = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? 0 : 250;
|
||||
if (isAna(t)) d.Sf["LC"+n].value = 1; // for sanity change analog count just to 1 LED
|
||||
d.Sf["LA"+n].min = (isVir(t) || isAna(t)) ? 0 : 1;
|
||||
d.Sf["MA"+n].min = (isVir(t) || isAna(t)) ? 0 : 250;
|
||||
}
|
||||
gId("rf"+n).onclick = (t == 31) ? (()=>{return false}) : (()=>{}); // prevent change for TM1814
|
||||
gRGBW |= isRGBW = ((t > 17 && t < 22) || (t > 28 && t < 32) || (t > 40 && t < 46 && t != 43) || t == 88); // RGBW checkbox, TYPE_xxxx values from const.h
|
||||
gId("co"+n).style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none":"inline"; // hide color order for PWM
|
||||
gId("dig"+n+"w").style.display = (t > 28 && t < 32) ? "inline":"none"; // show swap channels dropdown
|
||||
if (!(t > 28 && t < 32)) d.Sf["WO"+n].value = 0; // reset swapping
|
||||
gId("dig"+n+"c").style.display = (t >= 40 && t < 48) ? "none":"inline"; // hide count for analog
|
||||
gId("dig"+n+"r").style.display = (t >= 80 && t < 96) ? "none":"inline"; // hide reversed for virtual
|
||||
gId("dig"+n+"s").style.display = ((t >= 80 && t < 96) || (t >= 40 && t < 48)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
||||
gId("dig"+n+"f").style.display = ((t >= 16 && t < 32) || (t >= 50 && t < 64)) ? "inline":"none"; // hide refresh
|
||||
gId("dig"+n+"a").style.display = (isRGBW && t != 40) ? "inline":"none"; // auto calculate white
|
||||
gId("dig"+n+"l").style.display = (t > 48 && t < 64) ? "inline":"none"; // bus clock speed
|
||||
gId("rev"+n).innerHTML = (t >= 40 && t < 48) ? "Inverted output":"Reversed (rotated 180°)"; // change reverse text for analog
|
||||
gId("psd"+n).innerHTML = (t >= 40 && t < 48) ? "Index:":"Start:"; // change analog start description
|
||||
if (ablEN && pplEN && !((t >= 80 && t < 96) || (t >= 40 && t < 48))) {
|
||||
sumMA += parseInt(d.Sf["MA"+n].value);
|
||||
gId("co"+n).style.display = (isVir(t) || isAna(t)) ? "none":"inline"; // hide color order for PWM
|
||||
gId("dig"+n+"w").style.display = (isDig(t) && isRGBW) ? "inline":"none"; // show swap channels dropdown
|
||||
if (!(isDig(t) && isRGBW)) d.Sf["WO"+n].value = 0; // reset swapping
|
||||
gId("dig"+n+"c").style.display = (isAna(t)) ? "none":"inline"; // hide count for analog
|
||||
gId("dig"+n+"r").style.display = (isVir(t)) ? "none":"inline"; // hide reversed for virtual
|
||||
gId("dig"+n+"s").style.display = (isVir(t) || isAna(t)) ? "none":"inline"; // hide skip 1st for virtual & analog
|
||||
gId("dig"+n+"f").style.display = (isDig(t)) ? "inline":"none"; // hide refresh
|
||||
gId("dig"+n+"a").style.display = (isRGBW) ? "inline":"none"; // auto calculate white
|
||||
gId("dig"+n+"l").style.display = (isD2P(t) || isPWM(t)) ? "inline":"none"; // bus clock speed / PWM speed (relative) (not On/Off)
|
||||
gId("rev"+n).innerHTML = isAna(t) ? "Inverted output":"Reversed (rotated 180°)"; // change reverse text for analog
|
||||
//gId("psd"+n).innerHTML = isAna(t) ? "Index:":"Start:"; // change analog start description
|
||||
if (ablEN && pplEN && !(isVir(t) || isAna(t))) {
|
||||
sumMA += parseInt(d.Sf["MA"+n].value); // summarize PPL ABL limit (fields)
|
||||
}
|
||||
});
|
||||
// display global white channel overrides
|
||||
@ -268,12 +278,13 @@
|
||||
let s = parseInt(gId("ls"+n).value); //start value
|
||||
if (s+c > sLC) sLC = s+c; //update total count
|
||||
if (c > maxLC) maxLC = c; //max per output
|
||||
if (t < 80) sPC += c; //virtual out busses do not count towards physical LEDs
|
||||
if (!((t >= 80 && t < 96) || (t >= 40 && t < 48))) sDI += c;
|
||||
if (!((t >= 80 && t < 96) || (t >= 40 && t < 48))) {
|
||||
if (!isVir(t)) sPC += c; //virtual out busses do not count towards physical LEDs
|
||||
//if (!(isVir(t) || isPWM(t))) sDI += c;
|
||||
if (!(isVir(t) || isAna(t))) {
|
||||
sDI += c; // summarize digital LED count
|
||||
let maPL = parseInt(d.Sf["LA"+n].value);
|
||||
if (maPL == 255) maPL = 12;
|
||||
busMA += maPL*c;
|
||||
busMA += maPL*c; // summarize maximum bus current (calculated)
|
||||
}
|
||||
} // increase led count
|
||||
return;
|
||||
@ -284,7 +295,7 @@
|
||||
}
|
||||
// ignore IP address (stored in pins for virtual busses)
|
||||
if (nm=="L0" || nm=="L1" || nm=="L2" || nm=="L3") {
|
||||
if (t>=80) {
|
||||
if (isVir(t)) {
|
||||
LC.max = 255;
|
||||
LC.min = 0;
|
||||
LC.style.color="#fff";
|
||||
@ -306,7 +317,7 @@
|
||||
if (n2.substring(0,1)==="L") {
|
||||
let m = nList[j].name.substring(2);
|
||||
let t2 = parseInt(d.Sf["LT"+m].value, 10);
|
||||
if (t2 >= 80) continue;
|
||||
if (isVir(t2)) continue;
|
||||
}
|
||||
if (nList[j].value!="" && nList[j].value!="-1") p.push(parseInt(nList[j].value,10)); // add current pin
|
||||
}
|
||||
@ -316,14 +327,18 @@
|
||||
else LC.style.color = d.ro_gpio.some((e)=>e==parseInt(LC.value)) ? "orange" : "#fff";
|
||||
}
|
||||
});
|
||||
// distribute ABL current if not using PPL, otherwise sumMA contains summarized ABL limit
|
||||
d.Sf.querySelectorAll("#mLC input[name^=LC]").forEach((s,n)=>{
|
||||
let c = parseInt(s.value,10); //get LED count
|
||||
let t = parseInt(d.Sf["LT"+n].value);
|
||||
if (ablEN) {
|
||||
let v = Math.round(parseInt(d.Sf["MA"].value,10)*c/sDI);
|
||||
if (!pplEN && !((t >= 80 && t < 96) || (t >= 40 && t < 48))) d.Sf["MA"+n].value = v;
|
||||
} else d.Sf["MA"+n].value = 0;
|
||||
let t = parseInt(d.Sf["LT"+n].value); //get LED type
|
||||
if (!ablEN || isVir(t) || isAna(t)) {
|
||||
// virtual and analog LEDs have no limiter
|
||||
d.Sf["MA"+n].value = 0;
|
||||
return;
|
||||
}
|
||||
if (!pplEN) d.Sf["MA"+n].value = Math.round(parseInt(d.Sf.MA.value,10)*c/sDI);
|
||||
});
|
||||
if (pplEN) d.Sf.MA.value = sumMA; // update global ABL if using PPL
|
||||
// update total led count
|
||||
gId("lc").textContent = sLC;
|
||||
gId("pc").textContent = (sLC == sPC) ? "":"(" + sPC + " physical)";
|
||||
@ -336,7 +351,6 @@
|
||||
gId('ledwarning').style.color = (maxLC > Math.max(maxPB,800) || bquot > 100) ? 'red':'orange';
|
||||
gId('wreason').innerHTML = (bquot > 80) ? "80% of max. LED memory" +(bquot>100 ? ` (<b>ERROR: Using over ${maxM}B!</b>)` : "") : "800 LEDs per output";
|
||||
// calculate power
|
||||
if (pplEN) d.Sf.MA.value = sumMA;
|
||||
gId('ampwarning').style.display = (parseInt(d.Sf.MA.value,10) > 7200) ? 'inline':'none';
|
||||
var val = Math.ceil((100 + busMA)/500)/2;
|
||||
val = (val > 5) ? Math.ceil(val) : val;
|
||||
@ -409,7 +423,7 @@ mA/LED: <select name="LAsel${i}" onchange="enLA(this,${i});UI();">
|
||||
<option value="0">Custom</option>
|
||||
</select><br>
|
||||
<div id="LAdis${i}" style="display: none;">max. mA/LED: <input name="LA${i}" type="number" min="1" max="254" oninput="UI()"> mA<br></div>
|
||||
<div id="PSU${i}">PSU: <input name="MA${i}" type="number" class="xl" min="250" max="65000" oninput="UI()"> mA<br></div>
|
||||
<div id="PSU${i}">PSU: <input name="MA${i}" type="number" class="xl" min="250" max="65000" oninput="UI()" value="250"> mA<br></div>
|
||||
</div>
|
||||
<div id="co${i}" style="display:inline">Color Order:
|
||||
<select name="CO${i}">
|
||||
@ -445,7 +459,10 @@ mA/LED: <select name="LAsel${i}" onchange="enLA(this,${i});UI();">
|
||||
gId("+").style.display = (i<maxB+maxV-1) ? "inline":"none";
|
||||
gId("-").style.display = (i>0) ? "inline":"none";
|
||||
|
||||
if (!init) UI();
|
||||
if (!init) {
|
||||
enPPL();
|
||||
UI();
|
||||
}
|
||||
}
|
||||
|
||||
function addCOM(start=0,len=1,co=0) {
|
||||
@ -456,7 +473,7 @@ mA/LED: <select name="LAsel${i}" onchange="enLA(this,${i});UI();">
|
||||
<hr class="sml">
|
||||
${i+1}: Start: <input type="number" name="XS${i}" id="xs${i}" class="l starts" min="0" max="65535" value="${start}" oninput="UI();" required="">
|
||||
Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65535" value="${len}" required="" oninput="UI()">
|
||||
<div style="display:inline">Color Order:
|
||||
<div>Color Order:
|
||||
<select id="xo${i}" name="XO${i}">
|
||||
<option value="0">GRB</option>
|
||||
<option value="1">RGB</option>
|
||||
@ -465,9 +482,16 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
||||
<option value="4">BGR</option>
|
||||
<option value="5">GBR</option>
|
||||
</select>
|
||||
</div><br></div>`;
|
||||
Swap: <select id="xw${i}" name="XW${i}">
|
||||
<option value="0">Use global</option>
|
||||
<option value="1">W & B</option>
|
||||
<option value="2">W & G</option>
|
||||
<option value="3">W & R</option>
|
||||
</select>
|
||||
</div></div>`;
|
||||
gId("com_entries").insertAdjacentHTML("beforeend", b);
|
||||
gId("xo"+i).value = co;
|
||||
gId("xo"+i).value = co & 0x0F;
|
||||
gId("xw"+i).value = co >> 4;
|
||||
btnCOM(i+1);
|
||||
UI();
|
||||
}
|
||||
@ -750,7 +774,7 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
||||
<i>Automatically limits brightness to stay close to the limit.<br>
|
||||
Keep at <1A if poweing LEDs directly from the ESP 5V pin!<br>
|
||||
Analog (PWM) and virtual LEDs cannot use automatic brightness limiter.<br></i>
|
||||
Maximum PSU Current: <input name="MA" type="number" class="xl" min="250" max="65000" oninput="UI()" required> mA<br>
|
||||
<div id="psuMA">Maximum PSU Current: <input name="MA" type="number" class="xl" min="250" max="65000" oninput="UI()" required> mA<br></div>
|
||||
Use per-output limiter: <input type="checkbox" name="PPL" onchange="enPPL()"><br>
|
||||
<div id="ppldis" style="display:none;">
|
||||
<i>Make sure you enter correct values in each LED output.<br>
|
||||
|
6
wled00/data/settings_sync.htm
Normal file → Executable file
6
wled00/data/settings_sync.htm
Normal file → Executable file
@ -19,7 +19,7 @@
|
||||
scE.setAttribute("type", "text/javascript");
|
||||
scE.setAttribute("async", async);
|
||||
d.body.appendChild(scE);
|
||||
// success event
|
||||
// success event
|
||||
scE.addEventListener("load", () => {
|
||||
//console.log("File loaded");
|
||||
GetV();SetVal();
|
||||
@ -146,7 +146,6 @@ Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
||||
Send notifications on button press or IR: <input type="checkbox" name="SB"><br>
|
||||
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
||||
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
||||
<!-- Send Macro notifications: <input type="checkbox" name="SM"><br> -->
|
||||
UDP packet retransmissions: <input name="UR" type="number" min="0" max="30" class="d5" required><br><br>
|
||||
<i>Reboot required to apply changes. </i>
|
||||
<hr class="sml">
|
||||
@ -156,7 +155,8 @@ Make this instance discoverable: <input type="checkbox" name="NB">
|
||||
<hr class="sml">
|
||||
<h3>Realtime</h3>
|
||||
Receive UDP realtime: <input type="checkbox" name="RD"><br>
|
||||
Use main segment only: <input type="checkbox" name="MO"><br><br>
|
||||
Use main segment only: <input type="checkbox" name="MO"><br>
|
||||
Respect LED Maps: <input type="checkbox" name="RLM"><br><br>
|
||||
<i>Network DMX input</i><br>
|
||||
Type:
|
||||
<select name=DI onchange="SP(); adj();">
|
||||
|
@ -118,12 +118,13 @@
|
||||
function genForm(s) {
|
||||
var str = "";
|
||||
str = addRec(s,"",l);
|
||||
oldUrl = "";
|
||||
|
||||
gId('gen').innerHTML = str;
|
||||
if (gId('theme_bg_rnd').checked) {
|
||||
oldUrl = "";
|
||||
toggle("Image");
|
||||
randomBg();
|
||||
} else if (gId('theme_bg_url').value.startsWith('data:')) {
|
||||
gId("bg_url").classList.add("hide");
|
||||
} else oldUrl = gId("theme_bg_url").value;
|
||||
}
|
||||
function GetLS()
|
||||
@ -239,9 +240,31 @@
|
||||
url = "https://picsum.photos/1920/1080";
|
||||
if (gId(`${t}Grayscale`).checked) url += "?grayscale";
|
||||
if (gId(`${t}Blur`).checked) url += (url.includes("?") ? "&" : "?") + "blur";
|
||||
gId("theme_bg_img").value = "";
|
||||
gId("bg_url").classList.remove("hide");
|
||||
}
|
||||
gId("theme_bg_url").value = url;
|
||||
}
|
||||
// own BG image
|
||||
function ownBg(element) {
|
||||
const file = element.files[0];
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
gId("theme_bg_url").value = reader.result;
|
||||
gId("bg_url").classList.add("hide");
|
||||
if (gId("theme_bg_rnd").checked) toggle("Image");
|
||||
gId("theme_bg_rnd").checked = false;
|
||||
}
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
function removeBgImg() {
|
||||
gId("theme_bg_url").value = "";
|
||||
gId("theme_bg_img").value = "";
|
||||
gId("bg_url").classList.remove("hide");
|
||||
if (gId("theme_bg_rnd").checked) toggle("Image");
|
||||
gId("theme_bg_rnd").checked = false;
|
||||
}
|
||||
|
||||
function uploadFile(fO,name) {
|
||||
var req = new XMLHttpRequest();
|
||||
req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)});
|
||||
@ -267,10 +290,7 @@
|
||||
<h2>Web Setup</h2>
|
||||
Server description: <input type="text" name="DS" maxlength="32"><br>
|
||||
<!-- Sync button toggles both send and receive: <input type="checkbox" name="ST"><br> -->
|
||||
<div id="NoSimple" class="hide">
|
||||
<i class="warn">This firmware build does not include simplified UI support.<br></i>
|
||||
</div>
|
||||
<div id="Simple">Enable simplified UI: <input type="checkbox" name="SU"><br></div>
|
||||
Enable simplified UI: <input type="checkbox" name="SU"><br>
|
||||
<i>The following UI customization settings are unique both to the WLED device and this browser.<br>
|
||||
You will need to set them again if using a different browser, device or WLED IP address.<br>
|
||||
Refresh the main UI to apply changes.</i><br>
|
||||
@ -293,9 +313,12 @@
|
||||
<span class="l"></span>: <input type="number" min=0.0 max=1.0 step=0.01 id="theme_alpha_tab" class="agi"><br>
|
||||
<span class="l"></span>: <input type="number" min=0.0 max=1.0 step=0.01 id="theme_alpha_bg" class="agi"><br>
|
||||
<span class="l"></span>: <input type="text" id="theme_color_bg" maxlength="9" class="agi"><br>
|
||||
BG image: <input type="file" id="theme_bg_img" accept="image/*" onchange="ownBg(this)"> <input type="button" value="Remove" onclick="removeBgImg()"><br>
|
||||
<span class="l"></span>: <input type="checkbox" id="theme_bg_rnd" class="agi cb" onchange="randomBg();toggle('Image');">
|
||||
<div id="Image">
|
||||
<span class="l"></span>: <input type="text" id="theme_bg_url" class="agi"><br>
|
||||
<div id="bg_url">
|
||||
<span class="l"></span>: <input type="text" id="theme_bg_url" class="agi"><br>
|
||||
</div>
|
||||
</div>
|
||||
<div id="NoImage" class="hide">
|
||||
<h4>Random BG image settings</h4>
|
||||
|
@ -194,6 +194,7 @@
|
||||
</select><br>
|
||||
AP IP: <span class="sip"> Not active </span><br>
|
||||
<h3>Experimental</h3>
|
||||
Force 802.11g mode (ESP8266 only): <input type="checkbox" name="FG"><br>
|
||||
Disable WiFi sleep: <input type="checkbox" name="WS"><br>
|
||||
<i>Can help with connectivity issues.<br>
|
||||
Do not enable if WiFi is working correctly, increases power consumption.</i>
|
||||
|
@ -1,933 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "WIcons";
|
||||
src: url(data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAnUAAsAAAAAE1AAAAmFAAGZmgAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgXwRCAqcYJZIATYCJANwCzoABCAFgwYHIBs7D8iOwzgm3MXMnzZCktnjcbN+QlJLaJ3ulULplpW6UqWioeS91Jye0jUlJwZr5nTdE3LntdPvAg+ft/fbsLsGlNLuhlmQjKi7NPDEIgwTmP//a6mdl+SHUBhEIdHFxak7s4E/yzhJSjC7BQQLfDwopF/i6aqSElEFDXx8ZVWjy3rym4N6FlZQ4hu+nXsGIDMQF3gAxa14AgArtVMhfkgjfEAbiChwuSIwEUCmudPhiQdT6rvIjLSRZEwDhF9BIsooI53TIRIoIUD8kyNZI7UjAyMrR/aM/DwaOpozah9LGCsY2zN2YOzs2L3xqeNp4zXjq8bXT/hMBLj/53YDAIS+7u668n3H+HRPdZd1u3TzdRZdVMTfIl5HfKgd1b7Svqd9W9uprdP8QTOmeaz5TPORJlDDjHVjG0ANMQYsmRrKlmpyqV7kubIQC2GSIkFS+MneCJ48JJFVChQfuwKMp2yU9pmq1VKUR6ret0Gp0SjVYRRF+Xj7+OiUSk/GIzu1miHZWx+g8Y1RUktPmqIitRTXVNzzCtuFPKcH0zRBG+Y9/CnhBa20v5oHfsEUMgXMPEfO5ZcJx0FIPiVywgjb6MIuV+oZ4v2kk6/znIxDKrguM22y+bW8wUGqi7aL8fQJzwnCj8tIppdI9bYDSVJVCQInipW0HbtclcT7vCyLmXaSVrQSNMybaJJBh2PiXrXbgd6AbqecdDTO9EQEIeW0VPWQcdQ8ltPOEu+76q2IxUToJeWpfjQiHHH5AsADLj1bHgQxXsUoHfKYbg+CxCxC69eHcOvWheJ1l6b0nD7jG+bSA1dCZVxmw8ZJ/IYtxPtbJxlpQ/LGjSq00TmdNIZxrGel+y+rZJro+nUh3PrNIGwK6WrXNMV2xTeRWHSjScktLJfe1rc7spyvk3b6V4k48Sr3Am1Pv/QifhsI2uMvc863OiQQRNoedpPfHnSwcete+aDEE67cKzTgBlQgjpjgTDnJtGnX2qbmXJ6FOBLZ7wsr+JZzYnbjdbkCuEfU0HvlwqbtUgJ7zRXFNJsvSxlwz2WYta4xjri/fsulnnFVPyonpP0RL5oVNKkkfElG4csTDNAsgzC38G7gSKVgSZ7m/cEvKALmxKz//u7h6egHF7MrH4jJp/Zx4q32a8T71xnHVRCGlfFZNttd2FcUaay6e9PkhucyR0oPu1z1z/DB+8wixAFdMU1gnmB4xAw68pwHcWjlFrBnXxLjj63UGgvNGVGAJFzxFw+Womn7MAibVbu6leHRB5sc10fLtbrdr/JqV6Yr+ovwFtRHE7M4zG90qNB6YREoo51kFJabq3NeHVKdef/hsMFFSpt5m8XmJqDDAnR0c418mxmxrQzQuyPnspRwfAYkpthzr7gST1xNSf4WtBMM9DQT19uL+gb47gFLP3cT08F8I4dZxJl41Gsx9WHzLBOHzWjRS9NLCOUBCFQ+uGhB/V7ZzUwKESTmDriJ+UecdD/bFXFMLLsjgiAt4pp7ulpxb2tzE8I8xhyHODBK3SGg6QP12BiP3YMw2rDFtWUDXL+esnv3H9QxqfmbDnbMLjGUFpqqZbnWSg0lhWv9wU35qTHqP9zqUrL7kqKj8YjZzg01pb9+yQ8sXZpYxKGiFJTNsIwwpyR44gEOnV/+ennFdHD/2lQ3uS5y1qzIztXUNPE6odYJ0PqUiWJtgKGKMILY60dxeYynbb+sFKKqNn0Wz2rLtMbBQWPnYtmJa4WqFRob/9mmuycQVv7ifCNvXrlhzgDLDvAGA+8H5xjK948cDet+FaXfS+Lko/Wt+vScqarq6kZTbk4NaKqpObkEEpsac9L1rRNXJgPbrWyDdYje6tBQAztkbYC0wDe4UnNipmnZtInu/ujf6Kf7ve112Huf92Ev/7enB/+nP7pbrPiQJZbi0jCSpoN9UNPTkj7JMwpbWgopAbhtbOWkytAF3K+/qo0SASNW2G2bLfnshpB4a9dmz7/Hx//dc3OXNZ46YRyXUV2dYRsD97qKL79qazu+vSI1vPXT7375bWSGocBofD2eIRzJ0cMC0tenwQ0gfvuSdvd14f1uEooLPE3JJHL6uCd/n5n8d35UOKPn6nhr8kyrV3ad3nz2iTiNL414EnefL/JGLlWZtZWaqoEh4xSjvsGb/6m9raFlsLm4uHkQWlv7T/weZzjHHe7xZiUzpJ5WAWBLDNwRKxwRYnFoXGxcaKxN6DR8BNn2o9Nqmmutvra5TnIjXMBlmIFZ3yPYX3Mt9v5mmHuwYvvxPverL9eSvszXNjUXrkbqcGOVW2bEbDGKi3MLVTWzzWHF54Bu/2rA1qko6l9fFgVbBurfVBWFFlVW1ugxOwcs+8W//FcUZJieLl9WXA8eGL5crB7fhOMyxl8bjQWGjB1bW/ok6Ucqensr7F8H7utsmdqoHmz99rvyeE/Pz7u64mvVXLjyY8v8j5XhZeH3aPX75dpiO5eN/OzwcG7zkflt/sd5e7YcqbOowfRg22R5585at2vXX87W1Y0gQ079497eYT1EkyoEqMYABmHd8QvKGrRG6bJYTDCCZYGEWcm5G1jXM2i54Y9WtiBuklP57YtBZMAWlu2fYzDM7Q+5FmxKS3Oz5jwK6IactbWPowuQgNyHluKlaw9wnbOmtuajo/VSw9FrBSRwMcuUV2ZwFhh6s7hsqriWCsgA2s3nFcri4I7O+asxwxZbtLL03E9bhcR6Yz9mIbF0U96K0xGA7bx9y+l2//73j+H2i0EGd27uAVNI/WhCYuWqIDaYxads0lcVFV+dOlHmBx/qO7c6/uZX0tReUtJQv64y3adAvX6xDezAX/8Wm8Cgh/95O9OxsNCYnsXWQ+7pCz8/NMZ57ZAIGEdTw+ap8V+I3NUVe375wiv+lccqj172X7Yw5gJAUQGYPQ6QyxRfgeC+Qc5WnAMCAHFv6TJtet3pn/83b4YCAIBv35ofpTRyt5PjZEwT8KYAEQK8nFgBcE/yUwn2oqHSBKoEG7KZQLMpjo5uha/PI2yuBWOCTSDZajpqQ68+Za18jgGgYMT8nBhjKcFrKCYF6yKSZRLF5tR5YKhUzzNWM52mBvuPMiL7xPx4UaRgFiJZAVFscZ2HUIhUPcEaH5WWDvvmvdPfl5KaCvO8o1+fFCBb6hvuLz8lMROwfjPN8iar90RCCiRCJr3ugqHf6LqgUYYs5hzvu9tMIOUr/xpvRsNVvdZ/p+mB8n7V2Spo0T+aRhPpNhsNFOqxoE2u0suqTipgx58IJA0AAAA=) format('woff');
|
||||
}
|
||||
|
||||
:root {
|
||||
--c-1: #111;
|
||||
--c-f: #fff;
|
||||
--c-2: #222;
|
||||
--c-3: #333;
|
||||
--c-4: #444;
|
||||
--c-5: #555;
|
||||
--c-6: #666;
|
||||
--c-8: #888;
|
||||
--c-b: #bbb;
|
||||
--c-c: #ccc;
|
||||
--c-e: #eee;
|
||||
--c-d: #ddd;
|
||||
--c-r: #e42;
|
||||
--c-g: #4e2;
|
||||
--c-l: #48a;
|
||||
--t-b: .5;
|
||||
--c-o: rgba(34, 34, 34, .9);
|
||||
--c-tb : rgba(34, 34, 34, var(--t-b));
|
||||
--c-tba: rgba(102, 102, 102, var(--t-b));
|
||||
--c-tbh: rgba(51, 51, 51, var(--t-b));
|
||||
/*following are internal*/
|
||||
--th: 70px;
|
||||
--tp: 70px;
|
||||
--bh: 63px;
|
||||
--tbp: 14px 8px 10px;
|
||||
--bbp: 9px 0 7px 0;
|
||||
--bhd: none;
|
||||
--bmt: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
touch-action: manipulation;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
background-color: var(--c-1);
|
||||
font-family: Helvetica, Verdana, sans-serif;
|
||||
font-size: 17px;
|
||||
color: var(--c-f);
|
||||
text-align: center;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
scrollbar-width: 6px;
|
||||
scrollbar-color: var(--c-sb) transparent;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
#bg {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
position: fixed;
|
||||
z-index: -10;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
opacity: 0;
|
||||
transition: opacity 2s;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 10px 0 2px 0;
|
||||
}
|
||||
a, p, a:visited {
|
||||
color: var(--c-d);
|
||||
}
|
||||
a, a:visited {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
button {
|
||||
outline: 0;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
transition: color .3s, background-color .3s;
|
||||
font-size: 19px;
|
||||
color: var(--c-c);
|
||||
min-width: 40px;
|
||||
min-height: 40px;
|
||||
}
|
||||
button:hover {
|
||||
background: var(--c-4);
|
||||
}
|
||||
|
||||
.label {
|
||||
margin: 0;
|
||||
padding: 6px 0 0;
|
||||
}
|
||||
|
||||
#namelabel {
|
||||
position: fixed;
|
||||
bottom: calc(var(--bh) + 6px);
|
||||
right: 4px;
|
||||
color: var(--c-6);
|
||||
cursor: pointer;
|
||||
writing-mode: vertical-rl;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: var(--c-tb);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin: 0 auto;
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.icons {
|
||||
font-family: 'WIcons';
|
||||
font-style: normal;
|
||||
font-size: 24px;
|
||||
line-height: 1;
|
||||
display: inline-block;
|
||||
margin: -2px 0 4px 0;
|
||||
text-shadow: -1px -1px 0 var(--c-3), 1px -1px 0 var(--c-3), -1px 1px 0 var(--c-3), 1px 1px 0 var(--c-3);
|
||||
}
|
||||
|
||||
.huge {
|
||||
font-size: 42px;
|
||||
}
|
||||
|
||||
.infot {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.keytd {
|
||||
text-align: left;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.valtd {
|
||||
text-align: right;
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.valtd i {
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.slider-icon
|
||||
{
|
||||
transform: translate(4px,3px);
|
||||
color: var(--c-d);
|
||||
}
|
||||
|
||||
.il {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.tab {
|
||||
background-color: transparent;
|
||||
color: var(--c-d);
|
||||
}
|
||||
|
||||
.tab button {
|
||||
background-color: transparent;
|
||||
float: left;
|
||||
border: 0;
|
||||
transition: color .3s, background-color .3s;
|
||||
font-size: 17px;
|
||||
color: var(--c-c);
|
||||
min-width: 44px;
|
||||
}
|
||||
|
||||
.top button {
|
||||
padding: var(--tbp);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tab button:hover {
|
||||
background-color: var(--c-tbh);
|
||||
color: var(--c-e);
|
||||
}
|
||||
|
||||
.tab button.active {
|
||||
background-color: var(--c-tba) !important;
|
||||
color: var(--c-f);
|
||||
}
|
||||
|
||||
.active {
|
||||
background-color: var(--c-6) !important;
|
||||
color: var(--c-f);
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
height: calc(100% - var(--tp) - var(--bh));
|
||||
margin-top: var(--tp);
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
.tabcontent {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 0;
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
.smooth { transition: transform calc(var(--f, 1)*.5s) ease-out }
|
||||
|
||||
.tab-label {
|
||||
margin: 0 0 -5px 0;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position: fixed;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: var(--c-3);
|
||||
font-size: 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 11;
|
||||
opacity: .95;
|
||||
transition: .7s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#toast {
|
||||
opacity: 0;
|
||||
background-color: var(--c-5);
|
||||
max-width: 90%;
|
||||
color: var(--c-f);
|
||||
text-align: center;
|
||||
border-radius: 5px;
|
||||
padding: 16px;
|
||||
position: fixed;
|
||||
z-index: 5;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: calc(var(--bh) + 22px);
|
||||
font-size: 17px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#toast.show {
|
||||
opacity: 1;
|
||||
animation: fadein .5s, fadein .5s 2.5s reverse;
|
||||
}
|
||||
|
||||
#toast.error {
|
||||
opacity: 1;
|
||||
background-color: #b21;
|
||||
animation: fadein .5s;
|
||||
}
|
||||
|
||||
.modal {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
top: calc(var(--th) - 1px);
|
||||
background-color: var(--c-o);
|
||||
transform: translateY(100%);
|
||||
transition: transform .4s;
|
||||
padding: 8px;
|
||||
font-size: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#info, #nodes {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
#rover {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
#ndlt {
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
#roverstar {
|
||||
position: fixed;
|
||||
top: calc(var(--th) + 5px);
|
||||
left: 1px;
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#connind {
|
||||
position: fixed;
|
||||
bottom: calc(var(--bh) + 5px);
|
||||
left: 4px;
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
background-color: #a90;
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
#imgw {
|
||||
display: inline-block;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
#kv, #kn {
|
||||
/*max-width: 490px;*/
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#info table, #nodes table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#info td, #nodes td {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
#info .btn {
|
||||
margin: 5px;
|
||||
}
|
||||
#info table .btn, #nodes table .btn {
|
||||
margin: 0;
|
||||
width: 180px;
|
||||
}
|
||||
#info div, #nodes div {
|
||||
width: 490px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
#kn td {
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
#heart {
|
||||
transition: color .9s;
|
||||
font-size: 16px;
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.wi {
|
||||
image-rendering: pixelated;
|
||||
image-rendering: crisp-edges;
|
||||
width: 210px;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
from {bottom: 0; opacity: 0;}
|
||||
to {bottom: calc(var(--bh) + 22px); opacity: 1;}
|
||||
}
|
||||
|
||||
.sliderwrap {
|
||||
height: 30px;
|
||||
width: 250px;
|
||||
position: relative;
|
||||
margin: 4px 0;
|
||||
}
|
||||
#Colors .sliderwrap {
|
||||
width: 260px;
|
||||
margin: 10px 0 0;
|
||||
}
|
||||
|
||||
.sliderdisplay {
|
||||
content:'';
|
||||
position: absolute;
|
||||
top: 10px; left: 8px; right: 8px;
|
||||
height: 8px;
|
||||
background: var(--c-4);
|
||||
border-radius: 16px;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
#Colors .sliderdisplay {
|
||||
height: 28px;
|
||||
top: 0; bottom: 0;
|
||||
left: 0; right: 0;
|
||||
/*border: 1px solid var(--c-b);*/
|
||||
}
|
||||
#rwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #f00); }
|
||||
#gwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #0f0); }
|
||||
#bwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #00f); }
|
||||
#wwrap .sliderdisplay { background: linear-gradient(90deg, #000 0%, #fff); }
|
||||
#kwrap .sliderdisplay { background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #cbdbff); }
|
||||
#wbal .sliderdisplay { background: linear-gradient(90deg, #ff8f1f 0%, #fff 50%, #d4e0ff); }
|
||||
|
||||
.sliderbubble {
|
||||
width: 24px;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
border-radius: 10px;
|
||||
background: var(--c-3);
|
||||
color: var(--c-f);
|
||||
padding: 4px 4px 2px;
|
||||
font-size: 14px;
|
||||
right: 3px;
|
||||
transition: visibility .25s ease, opacity .25s ease;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
output.sliderbubbleshow {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type=range] {
|
||||
-webkit-appearance: none;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
#Colors input[type=range] {
|
||||
width: 252px;
|
||||
margin: 0;
|
||||
}
|
||||
input[type=range]::-webkit-slider-runnable-track {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
}
|
||||
input[type=range]::-webkit-slider-thumb {
|
||||
border: 2px solid #000;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-f);
|
||||
cursor: pointer;
|
||||
-webkit-appearance: none;
|
||||
margin-top: 4px;
|
||||
}
|
||||
input[type=range]::-moz-range-track {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
background-color: var(--c-0);
|
||||
}
|
||||
input[type=range]::-moz-range-thumb {
|
||||
border: 2px solid var(--c-3);
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-f);
|
||||
transform: translateY(5px);
|
||||
}
|
||||
#Colors input[type=range]::-webkit-slider-thumb {
|
||||
border: 2px solid #000;
|
||||
}
|
||||
#Colors input[type=range]::-moz-range-thumb {
|
||||
border: 2px solid var(--c-1);
|
||||
}
|
||||
|
||||
#Presets .list {
|
||||
max-height: 215px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
width: 280px;
|
||||
margin: 0 0 0 20px;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
#Presets .list::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#Segments .sliderwrap{
|
||||
width: 225px;
|
||||
}
|
||||
|
||||
#picker, #rgbwrap, #kwrap, #vwrap, #wwrap, #wbal {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hd {
|
||||
display: var(--bhd);
|
||||
}
|
||||
|
||||
#briwrap {
|
||||
float: right;
|
||||
margin-top: var(--bmt);
|
||||
}
|
||||
|
||||
#picker {
|
||||
width: 260px;
|
||||
}
|
||||
|
||||
#picker, #csl, #segcont {
|
||||
margin: 10px auto 0;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin: 10px auto 0;
|
||||
width: 280px;
|
||||
font-size: 19px;
|
||||
background-color: var(--c-3);
|
||||
color: var(--c-d);
|
||||
cursor: pointer;
|
||||
border: 1px solid var(--c-3);
|
||||
border-radius: 25px;
|
||||
transition-duration: .3s;
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translate3d(0,0,0);
|
||||
overflow: clip;
|
||||
text-overflow: clip;
|
||||
min-height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
.btn:hover {
|
||||
background-color: var(--c-4);
|
||||
border: 1px solid var(--c-4);
|
||||
}
|
||||
|
||||
.btn-xs {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
margin: 4px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#fxBtn, #palBtn {
|
||||
background-color: var(--c-2);
|
||||
border: 1px solid var(--c-2);
|
||||
}
|
||||
#fxBtn:hover, #palBtn:hover {
|
||||
background-color: var(--c-3);
|
||||
border: 1px solid var(--c-3);
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
margin-right: 8px;
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.qcs {
|
||||
margin: 2px;
|
||||
border-radius: 14px;
|
||||
display: inline-block;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;}
|
||||
.qcsb {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid var(--c-f);
|
||||
}
|
||||
option {
|
||||
background-color: var(--c-3);
|
||||
color: var(--c-f);
|
||||
}
|
||||
input[type=number], input[type=text] {
|
||||
background: var(--c-3);
|
||||
color: var(--c-f);
|
||||
border: 0 solid var(--c-f);
|
||||
border-radius: 5px;
|
||||
padding: 8px;
|
||||
margin: 6px 6px 6px 0;
|
||||
font-size: 19px;
|
||||
transition: background-color .2s;
|
||||
outline: 0;
|
||||
width: 50px;
|
||||
-webkit-appearance: textfield;
|
||||
-moz-appearance: textfield;
|
||||
appearance: textfield;
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: var(--c-b);
|
||||
}
|
||||
|
||||
input[type=number]:focus, input[type=text]:focus {
|
||||
background: var(--c-6);
|
||||
}
|
||||
|
||||
input[type=number]::-webkit-inner-spin-button,
|
||||
input[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.pid {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 12px 0 0 12px;
|
||||
font-size: 16px;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
color: var(--c-b);
|
||||
}
|
||||
|
||||
.xxs {
|
||||
border: 2px solid var(--c-e) !important;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
margin: 5px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.xxs-w {
|
||||
border-width: 4px !important;
|
||||
margin: 2px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.qcs, .xxs {
|
||||
text-shadow: -1px -1px 0 var(--c-6), 1px -1px 0 var(--c-6), -1px 1px 0 var(--c-6), 1px 1px 0 var(--c-6);
|
||||
}
|
||||
|
||||
.psts {
|
||||
color: var(--c-f);
|
||||
margin: 6px;
|
||||
}
|
||||
|
||||
.pwr {
|
||||
color: var(--c-6);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.act {
|
||||
color: var(--c-f);
|
||||
}
|
||||
|
||||
.check, .radio {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.schkl {
|
||||
width: 24px;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.check input, .radio input {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.checkmark, .radiomark {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: var(--c-3);
|
||||
border: 1px solid var(--c-2);
|
||||
}
|
||||
|
||||
.radiomark {
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.checkmark {
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.check:hover input ~ .checkmark {
|
||||
background-color: var(--c-4);
|
||||
}
|
||||
|
||||
.check input:checked ~ .checkmark {
|
||||
background-color: var(--c-6);
|
||||
}
|
||||
|
||||
.checkmark:after, .radiomark:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.check input:checked ~ .checkmark:after, .radio input:checked ~ .radiomark:after {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.check .checkmark:after {
|
||||
left: 9px;
|
||||
top: 5px;
|
||||
width: 5px;
|
||||
height: 10px;
|
||||
border: solid var(--c-f);
|
||||
border-width: 0 3px 3px 0;
|
||||
-webkit-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.radio .radiomark:after {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin: -6px;
|
||||
border-radius: 50%;
|
||||
background: var(--c-f);
|
||||
}
|
||||
|
||||
.h {
|
||||
font-size: 13px;
|
||||
color: var(--c-b);
|
||||
}
|
||||
|
||||
.list {
|
||||
position: relative;
|
||||
width: 280px;
|
||||
transition: background-color .5s;
|
||||
margin: auto auto 20px;
|
||||
font-size: 19px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.lstI {
|
||||
cursor: pointer;
|
||||
background-color: var(--c-2);
|
||||
overflow: hidden;
|
||||
border-radius: 20px;
|
||||
display: block;
|
||||
position: relative;
|
||||
border: 1px solid var(--c-2);
|
||||
padding: 8px 10px;
|
||||
margin: 10px 0;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
.selected { /* has to be after .lstI */
|
||||
background: var(--c-5);
|
||||
}
|
||||
|
||||
.lstI:hover {
|
||||
background: var(--c-4);
|
||||
}
|
||||
/*
|
||||
.lstI:last-child {
|
||||
border: 0;
|
||||
border-radius: 0 0 20px 20px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
*/
|
||||
.lstIcontent {
|
||||
width: 100%;
|
||||
vertical-align: middle;
|
||||
padding: 0 20px 0 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lstIname {
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.lstIprev {
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
/* Dropdown Content (Hidden by Default) */
|
||||
.dd-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 284px;
|
||||
z-index: 1;
|
||||
height: 260px;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding: 0 18px;
|
||||
margin-top: 10px;
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.dd-content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.fnd {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
width: 280px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 13px;
|
||||
pointer-events: none;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-top: -1px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.clear-icon {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 10px;
|
||||
right: 13px;
|
||||
cursor: pointer;
|
||||
margin-top: -1px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
input[type=text].fnd {
|
||||
display: block;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 8px 48px 8px 48px;
|
||||
margin: 5px auto 0;
|
||||
text-align: left;
|
||||
border-radius: 25px;
|
||||
background-color: var(--c-2);
|
||||
border: 1px solid var(--c-4);
|
||||
}
|
||||
|
||||
input[type=text].fnd:focus {
|
||||
background-color: var(--c-4);
|
||||
}
|
||||
|
||||
input[type=text].fnd:not(:placeholder-shown), input[type=text].fnd:hover {
|
||||
background-color: var(--c-3);
|
||||
}
|
||||
|
||||
.h, .c {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: var(--c-sb);
|
||||
opacity: .2;
|
||||
border-radius: 5px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--c-sbh);
|
||||
}
|
||||
|
||||
@media not all and (hover: none) {
|
||||
.sliderwrap:hover + output.sliderbubble {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 335px) {
|
||||
.sliderbubble {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 550px) and (min-width: 374px) {
|
||||
#info .btn, #nodes .btn {
|
||||
width: 150px;
|
||||
}
|
||||
#info div, #nodes div {
|
||||
width: 320px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 540px) {
|
||||
.top button {
|
||||
width: 16.6%;
|
||||
padding: 8px 0 4px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-width: 541px) and (max-width: 719px) {
|
||||
.top button {
|
||||
width: 14.2%;
|
||||
padding: 8px 0 4px 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 719px) {
|
||||
.hd {
|
||||
display: none !important;
|
||||
}
|
||||
#briwrap {
|
||||
margin-top: 0 !important;
|
||||
float: none;
|
||||
}
|
||||
}
|
@ -1,263 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
|
||||
<meta charset="utf-8">
|
||||
<meta name="theme-color" content="#222222">
|
||||
<meta content="yes" name="apple-mobile-web-app-capable">
|
||||
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
|
||||
<title>WLED</title>
|
||||
<script>
|
||||
function feedback(){}
|
||||
// instead of including [script src="iro.js"][/script] and [script src="rangetouch.js"][/script]
|
||||
// (which would be inlined by nodeJS inliner during minimization and compression) we need to load them dynamically
|
||||
// the following is needed to load iro.js and rangetouch.js as consecutive requests to allow ESP8266
|
||||
// to keep up with requests (if requests happent too fast some may not get processed)
|
||||
// it will also call onLoad() after last is loaded (it was removed from [body onload="onLoad()"]).
|
||||
var h = document.getElementsByTagName('head')[0];
|
||||
var l = document.createElement('script');
|
||||
l.type = 'application/javascript';
|
||||
l.src = 'iro.js';
|
||||
l.addEventListener('load', (e) => {
|
||||
// after iro is loaded initialize global variable
|
||||
cpick = new iro.ColorPicker("#picker", {
|
||||
width: 260,
|
||||
wheelLightness: false,
|
||||
wheelAngle: 270,
|
||||
wheelDirection: "clockwise",
|
||||
layout: [{
|
||||
component: iro.ui.Wheel,
|
||||
options: {}
|
||||
}]
|
||||
});
|
||||
cpick.on("input:end", () => {setColor(1);});
|
||||
cpick.on("color:change", () => {updatePSliders()});
|
||||
var l = document.createElement('script');
|
||||
l.type = 'application/javascript';
|
||||
l.src = 'rangetouch.js';
|
||||
l.addEventListener('load', (e) => {
|
||||
// after rangetouch is loaded initialize global variable
|
||||
ranges = RangeTouch.setup('input[type="range"]', {});
|
||||
let stateCheck = setInterval(() => {
|
||||
if (document.readyState === 'complete') {
|
||||
clearInterval(stateCheck);
|
||||
// document ready, start processing UI
|
||||
onLoad();
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
setTimeout(function(){h.appendChild(l)},50);
|
||||
});
|
||||
setTimeout(function(){h.appendChild(l)},50);
|
||||
</script>
|
||||
<link rel="stylesheet" href="simple.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="cv" class="overlay">Loading WLED UI...</div>
|
||||
<noscript><div class="overlay" style="opacity:1;">Sorry, WLED UI needs JavaScript!</div></noscript>
|
||||
<div id="bg"></div>
|
||||
|
||||
<div class="wrapper" id="top">
|
||||
<div class="tab top">
|
||||
<div class="btnwrap">
|
||||
<button id="buttonPower" onclick="togglePower()"><i class="icons"></i><p class="tab-label">Power</p></button>
|
||||
<button id="buttonI" onclick="toggleInfo()"><i class="icons"></i><p class="tab-label">Info</p></button>
|
||||
<button id="buttonNodes" onclick="toggleNodes()"><i class="icons"></i><p class="tab-label">Nodes</p></button></div>
|
||||
<button onclick="window.location.href='/settings';"><i class="icons"></i><p class="tab-label">Config</p></button>
|
||||
<button id="buttonCP" onclick="tglCP()"><i class="icons"></i><p class="tab-label">Expand</p></button>
|
||||
<!--button id="buttonBri" onclick="tglBri()"><i class="icons"></i><p class="tab-label">Brightness</p></button-->
|
||||
</div>
|
||||
<div id="briwrap">
|
||||
<p class="label hd">Global brightness</p>
|
||||
<div class="il">
|
||||
<i class="icons slider-icon" onclick="tglTheme()"></i>
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderBri" onchange="setBri()" oninput="updateTrail(this)" max="255" min="1" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
<output class="sliderbubble"></output>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class ="container">
|
||||
<div class="tabcontent">
|
||||
<div id="QuickLoad" class="center">
|
||||
<p class="label h">Quick Load</p>
|
||||
<div id="pql"></div>
|
||||
</div>
|
||||
|
||||
<div id="QCS" class="center">
|
||||
<p class="label h">Solid color</p>
|
||||
<div id="qcs-w" class="center">
|
||||
<div class="qcs" onclick="pC('#ff0000');" title="Red" style="background-color:#ff0000;"></div>
|
||||
<div class="qcs" onclick="pC('#ffa000');" title="Orange" style="background-color:#ffa000;"></div>
|
||||
<div class="qcs" onclick="pC('#ffc800');" title="Yellow" style="background-color:#ffc800;"></div>
|
||||
<div class="qcs" onclick="pC('#ffe0a0');" title="Warm White" style="background-color:#ffe0a0;"></div>
|
||||
<div class="qcs" onclick="pC('#ffffff');" title="White" style="background-color:#ffffff;"></div>
|
||||
<div class="qcs qcsb" onclick="pC('#000000');" title="Black" style="background-color:#000000;"></div><br>
|
||||
<div class="qcs" onclick="pC('#ff00ff');" title="Pink" style="background-color:#ff00ff;"></div>
|
||||
<div class="qcs" onclick="pC('#0000ff');" title="Blue" style="background-color:#0000ff;"></div>
|
||||
<div class="qcs" onclick="pC('#00ffc8');" title="Cyan" style="background-color:#00ffc8;"></div>
|
||||
<div class="qcs" onclick="pC('#08ff00');" title="Green" style="background-color:#08ff00;"></div>
|
||||
<div class="qcs" onclick="pC('rnd');" title="Random" style="background:linear-gradient(to right, red, orange, yellow, green, blue, purple);transform: translateY(-11px);">R</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="picker" class="center"></div>
|
||||
|
||||
<div id="Colors" class="center">
|
||||
<div id="vwrap">
|
||||
<!--p class="label h">Value</p-->
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderV" class="noslide" oninput="fromV()" onchange="setColor(0)" max="100" min="0" type="range" value="100" step="any" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div><br>
|
||||
</div>
|
||||
<div id="kwrap">
|
||||
<!--p class="label h">Temperature</p-->
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderK" class="noslide" oninput="fromK()" onchange="setColor(0)" max="10091" min="1900" type="range" value="6550" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="rgbwrap" class="center">
|
||||
<p class="label h">RGB channels</p>
|
||||
<div id="rwrap" class="il">
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderR" class="noslide" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
</div><br>
|
||||
<div id="gwrap" class="il">
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderG" class="noslide" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
</div><br>
|
||||
<div id="bwrap" class="il">
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderB" class="noslide" onchange="fromRgb()" max="255" min="0" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
</div><br>
|
||||
</div>
|
||||
<div id="wwrap" class="center">
|
||||
<p class="label h">White channel</p>
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderW" class="noslide" onchange="setColor(0)" max="255" min="0" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wbal">
|
||||
<p class="label h">White balance</p>
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderA" class="noslide" onchange="setBalance(this.value)" max="255" min="0" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="Slots" class="center">
|
||||
<p class="label h">Color slots</p>
|
||||
<div id="csl" class="center" style="display: none;">
|
||||
<button class="xxs btn" onclick="selectSlot(0);">1</button>
|
||||
<button class="xxs btn" onclick="selectSlot(1);">2</button>
|
||||
<button class="xxs btn" onclick="selectSlot(2);">3</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="Segments" class="center">
|
||||
<div id="segcont"></div>
|
||||
</div>
|
||||
|
||||
<div id="Presets" class="center">
|
||||
<p class="label h">Presets</p>
|
||||
<div class="fnd">
|
||||
<input type="text" class="fnd" placeholder="Search" oninput="search(this,'pcont')" onfocus="search(this)" />
|
||||
<i class="icons clear-icon" onclick="clean(this);"></i>
|
||||
<i class="icons search-icon"></i>
|
||||
</div>
|
||||
<div id="pcont" class="list"></div>
|
||||
</div>
|
||||
|
||||
<div id="Effects" class="center">
|
||||
<p class="label h">Effect</p>
|
||||
<div title="Effect speed">
|
||||
<i class="icons slider-icon"></i>
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderSpeed" onchange="setSpeed()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
<output class="sliderbubble"></output>
|
||||
</div>
|
||||
<div title="Effect intensity">
|
||||
<i class="icons slider-icon" onclick="tglLabels()"></i>
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderIntensity" onchange="setIntensity()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
|
||||
<div class="sliderdisplay"></div>
|
||||
</div>
|
||||
<output class="sliderbubble"></output>
|
||||
</div>
|
||||
<div style="padding-bottom:20px;">
|
||||
<div onclick="tglFxDropdown()" class="c btn" id="fxBtn"><i class="icons"></i> Solid</div>
|
||||
<div onclick="tglPalDropdown()" class="c btn" id="palBtn"><i class="icons"></i>Default</div>
|
||||
<div id="fxDropdown" class="dd-content">
|
||||
<div class="fnd">
|
||||
<input type="text" class="fnd" placeholder="Search" oninput="search(this,'fxlist')" onfocus="search(this)" />
|
||||
<i class="icons clear-icon" onclick="clean(this);"></i>
|
||||
<i class="icons search-icon"></i>
|
||||
</div>
|
||||
<div id="fxlist" class="list">
|
||||
<div class="lstI" data-id="0" onClick="setEffect(0)"><a href="#0" onClick="setEffect(0)">Solid</a></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="palDropdown" class="dd-content">
|
||||
<div class="fnd">
|
||||
<input type="text" class="fnd" placeholder="Search" oninput="search(this,'pallist')" onfocus="search(this)" />
|
||||
<i class="icons clear-icon" onclick="clean(this);"></i>
|
||||
<i class="icons search-icon"></i>
|
||||
</div>
|
||||
<div id="pallist" class="list">
|
||||
<div class="lstI" data-id="0" onClick="setPalette(0)"><a href="#0" onClick="setPalette(0)">Default</a><div class="lstIprev"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="connind"></div>
|
||||
<div id="toast"></div>
|
||||
<div id="namelabel" onclick="toggleNodes()"></div>
|
||||
|
||||
<div id="info" class="modal">
|
||||
<div id="imgw">
|
||||
<img class="wi" alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAFCAYAAAC5Fuf5AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABbSURBVChTlY9bDoAwDMNW7n9nwCipytQN4Z8tbrTHmDmF4oPzyldwRqp1SSdnV/NuZuzqerAByxXznBw3igkeFEfXyUuhK/yFM0CxJfyqXZEOc6/Sr9/bf7uIC5Nwd7orMvAPAAAAAElFTkSuQmCC" />
|
||||
</div><br>
|
||||
<div id="kv">Loading...</div><br>
|
||||
<div>
|
||||
<button class="btn" onclick="requestJson()">Refresh</button>
|
||||
<button class="btn" onclick="toggleInfo()">Close Info</button>
|
||||
<button class="btn" onclick="toggleNodes()">Instance List</button>
|
||||
<button class="btn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button>
|
||||
</div>
|
||||
<span class="h">Made with <span id="heart">❤︎</span> by Aircoookie and the <a href="https://wled.discourse.group/" target="_blank">WLED community</a></span>
|
||||
</div>
|
||||
|
||||
<div id="nodes" class="modal">
|
||||
<div id="ndlt">WLED instances</div>
|
||||
<div id="kn">Loading...</div><br>
|
||||
<div>
|
||||
<button class="btn" onclick="loadNodes()">Refresh</button>
|
||||
<button class="btn" onclick="toggleNodes()">Close list</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<i id="roverstar" class="icons huge" onclick="setLor(0)"></i><br>
|
||||
<script src="simple.js"></script>
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load Diff
@ -360,6 +360,22 @@ um_data_t* simulateSound(uint8_t simulationId);
|
||||
void enumerateLedmaps();
|
||||
uint8_t get_random_wheel_index(uint8_t pos);
|
||||
|
||||
// RAII guard class for the JSON Buffer lock
|
||||
// Modeled after std::lock_guard
|
||||
class JSONBufferGuard {
|
||||
bool holding_lock;
|
||||
public:
|
||||
inline JSONBufferGuard(uint8_t module=255) : holding_lock(requestJSONBufferLock(module)) {};
|
||||
inline ~JSONBufferGuard() { if (holding_lock) releaseJSONBufferLock(); };
|
||||
inline JSONBufferGuard(const JSONBufferGuard&) = delete; // Noncopyable
|
||||
inline JSONBufferGuard& operator=(const JSONBufferGuard&) = delete;
|
||||
inline JSONBufferGuard(JSONBufferGuard&& r) : holding_lock(r.holding_lock) { r.holding_lock = false; }; // but movable
|
||||
inline JSONBufferGuard& operator=(JSONBufferGuard&& r) { holding_lock |= r.holding_lock; r.holding_lock = false; return *this; };
|
||||
inline bool owns_lock() const { return holding_lock; }
|
||||
explicit inline operator bool() const { return owns_lock(); };
|
||||
inline void release() { if (holding_lock) releaseJSONBufferLock(); holding_lock = false; }
|
||||
};
|
||||
|
||||
#ifdef WLED_ADD_EEPROM_SUPPORT
|
||||
//wled_eeprom.cpp
|
||||
void applyMacro(byte index);
|
||||
|
@ -377,27 +377,27 @@ void updateFSInfo() {
|
||||
|
||||
//Un-comment any file types you need
|
||||
static String getContentType(AsyncWebServerRequest* request, String filename){
|
||||
if(request->hasArg("download")) return "application/octet-stream";
|
||||
else if(filename.endsWith(".htm")) return "text/html";
|
||||
else if(filename.endsWith(".html")) return "text/html";
|
||||
else if(filename.endsWith(".css")) return "text/css";
|
||||
else if(filename.endsWith(".js")) return "application/javascript";
|
||||
else if(filename.endsWith(".json")) return "application/json";
|
||||
else if(filename.endsWith(".png")) return "image/png";
|
||||
else if(filename.endsWith(".gif")) return "image/gif";
|
||||
else if(filename.endsWith(".jpg")) return "image/jpeg";
|
||||
else if(filename.endsWith(".ico")) return "image/x-icon";
|
||||
// else if(filename.endsWith(".xml")) return "text/xml";
|
||||
// else if(filename.endsWith(".pdf")) return "application/x-pdf";
|
||||
// else if(filename.endsWith(".zip")) return "application/x-zip";
|
||||
// else if(filename.endsWith(".gz")) return "application/x-gzip";
|
||||
if(request->hasArg(F("download"))) return SET_F("application/octet-stream");
|
||||
else if(filename.endsWith(F(".htm"))) return SET_F("text/html");
|
||||
else if(filename.endsWith(F(".html"))) return SET_F("text/html");
|
||||
else if(filename.endsWith(F(".css"))) return SET_F("text/css");
|
||||
else if(filename.endsWith(F(".js"))) return SET_F("application/javascript");
|
||||
else if(filename.endsWith(F(".json"))) return SET_F("application/json");
|
||||
else if(filename.endsWith(F(".png"))) return SET_F("image/png");
|
||||
else if(filename.endsWith(F(".gif"))) return SET_F("image/gif");
|
||||
else if(filename.endsWith(F(".jpg"))) return SET_F("image/jpeg");
|
||||
else if(filename.endsWith(F(".ico"))) return SET_F("image/x-icon");
|
||||
// else if(filename.endsWith(F(".xml"))) return SET_F("text/xml");
|
||||
// else if(filename.endsWith(F(".pdf"))) return SET_F("application/x-pdf");
|
||||
// else if(filename.endsWith(F(".zip"))) return SET_F("application/x-zip");
|
||||
// else if(filename.endsWith(F(".gz"))) return SET_F("application/x-gzip");
|
||||
return "text/plain";
|
||||
}
|
||||
|
||||
bool handleFileRead(AsyncWebServerRequest* request, String path){
|
||||
DEBUG_PRINTLN("WS FileRead: " + path);
|
||||
if(path.endsWith("/")) path += "index.htm";
|
||||
if(path.indexOf("sec") > -1) return false;
|
||||
if(path.indexOf(F("sec")) > -1) return false;
|
||||
String contentType = getContentType(request, path);
|
||||
/*String pathWithGz = path + ".gz";
|
||||
if(WLED_FS.exists(pathWithGz)){
|
||||
|
@ -1,308 +0,0 @@
|
||||
/*
|
||||
* Binary array for the Web UI.
|
||||
* gzip is used for smaller size and improved speeds.
|
||||
*
|
||||
* Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
|
||||
* to find out how to easily modify the web UI source!
|
||||
*/
|
||||
|
||||
// Autogenerated from wled00/data/cpal/cpal.htm, do not edit!!
|
||||
const uint16_t PAGE_cpal_L = 4721;
|
||||
const uint8_t PAGE_cpal[] PROGMEM = {
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xbd, 0x3b, 0x7f, 0x73, 0xdb, 0xb6,
|
||||
0x92, 0xff, 0xe7, 0x53, 0x20, 0x4c, 0x5f, 0x42, 0xd6, 0x14, 0x45, 0xd2, 0xb6, 0x64, 0x4b, 0xa2,
|
||||
0x3b, 0xa9, 0x93, 0x77, 0xce, 0x8d, 0xdd, 0x64, 0x5e, 0x7c, 0x6e, 0x7b, 0x3e, 0xbf, 0x31, 0x4d,
|
||||
0x42, 0x12, 0x1b, 0x8a, 0xe0, 0x03, 0x21, 0xd9, 0xae, 0xac, 0xef, 0x7e, 0xbb, 0x00, 0x48, 0x91,
|
||||
0x94, 0xe4, 0x24, 0xd7, 0x37, 0xd7, 0xf1, 0x44, 0x20, 0xb0, 0x58, 0xec, 0x2e, 0xf6, 0x17, 0x16,
|
||||
0xe8, 0xe8, 0xe5, 0xbb, 0x8f, 0xa7, 0x97, 0xbf, 0x7f, 0x7a, 0x4f, 0xa6, 0x62, 0x96, 0x9e, 0x90,
|
||||
0x51, 0xf9, 0x43, 0xc3, 0x18, 0x7e, 0x66, 0x54, 0x84, 0x30, 0x22, 0xf2, 0x0e, 0xfd, 0xd7, 0x3c,
|
||||
0x59, 0x04, 0xc6, 0x69, 0x18, 0x4d, 0x69, 0xe7, 0x94, 0x65, 0x82, 0xb3, 0xd4, 0x20, 0x2f, 0x22,
|
||||
0x68, 0xd1, 0x4c, 0x04, 0x46, 0xc6, 0x3a, 0x11, 0x8e, 0xd9, 0x04, 0x5a, 0x85, 0x60, 0x1c, 0x5a,
|
||||
0xb3, 0x79, 0x21, 0x3a, 0x9c, 0x2e, 0xc2, 0x34, 0x89, 0x43, 0x41, 0x8d, 0x6d, 0x08, 0x3f, 0xf1,
|
||||
0x70, 0x32, 0x0b, 0xb7, 0x61, 0xda, 0x0a, 0xfe, 0xfe, 0x21, 0x4f, 0x38, 0x2d, 0x0c, 0x52, 0x81,
|
||||
0xbb, 0x08, 0x27, 0x12, 0x91, 0xd2, 0x93, 0x17, 0xbf, 0x9e, 0xbf, 0x7f, 0x47, 0x4e, 0x61, 0x55,
|
||||
0x36, 0x23, 0x9f, 0xc2, 0x94, 0x0a, 0x41, 0xc9, 0xfb, 0x38, 0x01, 0x6a, 0x46, 0x5d, 0x05, 0x42,
|
||||
0x46, 0x45, 0xc4, 0x93, 0x5c, 0x10, 0xf1, 0x98, 0xd3, 0xc0, 0x10, 0xf4, 0x41, 0x74, 0xff, 0x08,
|
||||
0x17, 0xa1, 0xea, 0x35, 0x4e, 0x5e, 0x8c, 0xe7, 0x59, 0x24, 0x12, 0x96, 0x91, 0xc9, 0x87, 0xd8,
|
||||
0xa4, 0xd6, 0x92, 0x53, 0x31, 0xe7, 0x19, 0x89, 0x9d, 0x09, 0x15, 0xef, 0x53, 0x3a, 0x83, 0x35,
|
||||
0x7f, 0x7e, 0x94, 0x43, 0xab, 0x0a, 0x34, 0x7a, 0xdf, 0x80, 0x8c, 0x38, 0x05, 0x6e, 0x35, 0x30,
|
||||
0x02, 0x2e, 0x42, 0x4e, 0xe2, 0x20, 0x66, 0xd1, 0x1c, 0x7b, 0x5e, 0x8c, 0xba, 0x6a, 0x35, 0x24,
|
||||
0x46, 0x3c, 0x22, 0xdd, 0x77, 0x2c, 0x7e, 0x5c, 0x8e, 0x81, 0xa3, 0xce, 0x38, 0x9c, 0x25, 0xe9,
|
||||
0xe3, 0xe0, 0x2d, 0x4f, 0xc2, 0xd4, 0x2e, 0xc2, 0xac, 0xe8, 0x14, 0x94, 0x27, 0xe3, 0xe1, 0x5d,
|
||||
0x18, 0x7d, 0x99, 0x70, 0x36, 0xcf, 0xe2, 0x4e, 0xc4, 0x52, 0xc6, 0x07, 0xaf, 0x3c, 0xcf, 0x1b,
|
||||
0xca, 0x29, 0x45, 0xf2, 0x27, 0x1d, 0x78, 0xbd, 0xfc, 0x61, 0xa8, 0x47, 0xe2, 0x38, 0x1e, 0xce,
|
||||
0x42, 0x3e, 0x49, 0xb2, 0x81, 0x4b, 0x3c, 0x17, 0x06, 0xd2, 0x24, 0xa3, 0x9d, 0x29, 0x4d, 0x26,
|
||||
0x53, 0x31, 0x70, 0x0e, 0x57, 0xaf, 0xf2, 0x90, 0x03, 0x21, 0x1d, 0x94, 0x61, 0x08, 0x43, 0x7c,
|
||||
0x99, 0xb3, 0x22, 0x41, 0x56, 0x06, 0x9c, 0xa6, 0xa1, 0x48, 0x16, 0x74, 0x78, 0x9f, 0xc4, 0x62,
|
||||
0x3a, 0xf0, 0x5c, 0xf7, 0x6f, 0x43, 0x3d, 0xd1, 0x07, 0x4c, 0xab, 0x57, 0x77, 0x4c, 0x80, 0x74,
|
||||
0x4f, 0x37, 0x67, 0x86, 0x77, 0x05, 0x4b, 0xe7, 0x82, 0xea, 0xa5, 0x3b, 0x82, 0xe5, 0x83, 0x43,
|
||||
0x39, 0x65, 0xc2, 0xc3, 0x38, 0xc1, 0xf5, 0xee, 0xd8, 0xc3, 0x72, 0x13, 0x2f, 0xb6, 0x57, 0x8e,
|
||||
0xa4, 0xbd, 0x03, 0x73, 0xbf, 0x50, 0x6e, 0xeb, 0xaf, 0x3c, 0x89, 0xe0, 0x4b, 0x77, 0x6e, 0x59,
|
||||
0xe9, 0x8e, 0xf1, 0x18, 0xc6, 0x11, 0xfd, 0xbc, 0x18, 0xec, 0x03, 0xa3, 0x1b, 0x62, 0x2a, 0x92,
|
||||
0x74, 0x41, 0xb9, 0x86, 0x1c, 0xf8, 0xf9, 0x03, 0x81, 0xb9, 0x49, 0x4c, 0xf8, 0xe4, 0x2e, 0x34,
|
||||
0x7b, 0x47, 0xb6, 0xfa, 0x73, 0x0e, 0xad, 0xe1, 0x9f, 0x9d, 0x24, 0x8b, 0xe9, 0xc3, 0xc0, 0x6f,
|
||||
0xd2, 0xb2, 0xd4, 0x54, 0xee, 0xa3, 0x1c, 0x15, 0xf1, 0x7d, 0x68, 0x29, 0xee, 0xfe, 0x36, 0x14,
|
||||
0x1c, 0xf6, 0x68, 0xcc, 0xf8, 0x6c, 0x20, 0x5b, 0x20, 0x3c, 0xfa, 0xbb, 0xd9, 0x81, 0x11, 0x6b,
|
||||
0xb5, 0x95, 0x09, 0x8d, 0xad, 0xbf, 0x81, 0xcc, 0x3b, 0x44, 0x29, 0xc4, 0x14, 0x94, 0x96, 0xee,
|
||||
0xe6, 0x58, 0x4f, 0x3f, 0xac, 0xa6, 0x63, 0xeb, 0x1b, 0xc4, 0xf0, 0x6a, 0x3c, 0x1e, 0x97, 0x42,
|
||||
0xd8, 0xaf, 0x84, 0xf0, 0xea, 0xf8, 0xce, 0x3f, 0xf2, 0x8f, 0xe4, 0xfa, 0xbe, 0x0f, 0xdc, 0x6c,
|
||||
0xc8, 0x40, 0x11, 0xbf, 0x9b, 0x10, 0xaf, 0x22, 0xc4, 0xab, 0x08, 0x91, 0xcd, 0x92, 0xa5, 0x0a,
|
||||
0xa5, 0x57, 0x92, 0x59, 0x53, 0xdf, 0xad, 0x4a, 0xbd, 0x72, 0xee, 0xe6, 0xa0, 0x62, 0x59, 0x94,
|
||||
0x86, 0x45, 0xb1, 0xcc, 0xc3, 0x38, 0x4e, 0xb2, 0xc9, 0xc0, 0xad, 0x34, 0x7a, 0x08, 0xfb, 0x29,
|
||||
0x92, 0x28, 0x4c, 0x3b, 0xe0, 0x56, 0x26, 0xd9, 0x40, 0x29, 0xe4, 0x0e, 0x5c, 0x6d, 0x75, 0x25,
|
||||
0x45, 0x1e, 0x66, 0xcb, 0x38, 0x29, 0xf2, 0x34, 0x7c, 0x1c, 0x24, 0x99, 0x34, 0x8c, 0x71, 0x4a,
|
||||
0x1f, 0x86, 0x12, 0x59, 0x27, 0x11, 0x74, 0x56, 0x0c, 0x22, 0x50, 0x56, 0x50, 0x9a, 0x9a, 0xe8,
|
||||
0x6a, 0x86, 0x06, 0x3a, 0xd4, 0x26, 0x61, 0x96, 0xc4, 0x71, 0x4a, 0x57, 0xaf, 0x92, 0x6c, 0xcc,
|
||||
0x2a, 0xe4, 0x86, 0x31, 0x44, 0xef, 0xa2, 0x41, 0xbe, 0x8a, 0x72, 0xd3, 0x02, 0x6b, 0x76, 0xb4,
|
||||
0x61, 0xc4, 0x20, 0xa5, 0x7b, 0x1e, 0xe6, 0xda, 0x9a, 0x8e, 0x5c, 0x1c, 0xaf, 0x4c, 0x3e, 0x9c,
|
||||
0x0b, 0xb6, 0x72, 0x72, 0xe5, 0xff, 0x96, 0x75, 0xeb, 0x2d, 0x3b, 0xff, 0x43, 0x5b, 0x64, 0xb1,
|
||||
0x44, 0xde, 0x61, 0x6f, 0x6a, 0x40, 0x9b, 0xea, 0x54, 0x4d, 0x2b, 0x2e, 0x40, 0x88, 0xcb, 0x96,
|
||||
0x7d, 0xd7, 0x3c, 0x85, 0x04, 0xbc, 0x64, 0x79, 0xb9, 0xe6, 0x38, 0x51, 0x3e, 0x06, 0x56, 0xfa,
|
||||
0x8b, 0xb2, 0x68, 0xf1, 0x0e, 0xcb, 0x94, 0x2c, 0x7c, 0x92, 0xae, 0xac, 0x92, 0xfa, 0xae, 0xbd,
|
||||
0xdc, 0x42, 0x51, 0x5b, 0xbe, 0xff, 0x56, 0x0a, 0x95, 0x0e, 0x17, 0xef, 0x92, 0xc5, 0x56, 0x6d,
|
||||
0xd3, 0x6b, 0xa7, 0x74, 0xdc, 0x30, 0x66, 0xb9, 0x47, 0x14, 0x02, 0xd6, 0x67, 0x50, 0x53, 0xdb,
|
||||
0x29, 0x68, 0x16, 0x63, 0x6b, 0x19, 0xcd, 0x79, 0x01, 0x94, 0xe4, 0x2c, 0x41, 0xba, 0x56, 0x18,
|
||||
0x41, 0x64, 0xe0, 0x20, 0xa3, 0xae, 0x0e, 0xd4, 0x18, 0x41, 0xe0, 0x27, 0x4e, 0x16, 0x24, 0x89,
|
||||
0x03, 0x03, 0x95, 0x03, 0x62, 0x24, 0x9a, 0x90, 0xfe, 0xd0, 0x83, 0x2f, 0xe4, 0xc4, 0xc0, 0x68,
|
||||
0xc8, 0xeb, 0x0f, 0x88, 0x98, 0xc9, 0xf8, 0xb1, 0x94, 0x8c, 0x66, 0x1f, 0xa7, 0x4c, 0xbd, 0xed,
|
||||
0x33, 0x36, 0x25, 0x8c, 0xd0, 0xc5, 0x62, 0x52, 0x81, 0x2b, 0x8e, 0xf6, 0x31, 0x2c, 0x95, 0x1e,
|
||||
0xb4, 0x57, 0x29, 0x69, 0x87, 0xcb, 0x1e, 0xe8, 0x30, 0xc8, 0x22, 0xa1, 0xf7, 0x3f, 0xb3, 0x07,
|
||||
0x08, 0xe4, 0xc4, 0x25, 0xfb, 0x3e, 0xfc, 0x19, 0x27, 0xa3, 0x3c, 0x14, 0x53, 0xf2, 0x62, 0x9c,
|
||||
0xa4, 0x69, 0x60, 0xbc, 0x72, 0xdd, 0x7d, 0xd8, 0x02, 0x03, 0x42, 0xa8, 0x71, 0xd1, 0x23, 0xbe,
|
||||
0x3f, 0x3d, 0x5a, 0x1c, 0x9c, 0xf5, 0xfe, 0xbc, 0xf0, 0x0e, 0x88, 0x77, 0x30, 0x3d, 0x58, 0x1c,
|
||||
0x4d, 0x3b, 0x07, 0xf0, 0x75, 0x04, 0xb1, 0xae, 0xfa, 0xf2, 0x7d, 0xd2, 0x43, 0xb8, 0x69, 0xe7,
|
||||
0xe8, 0x4f, 0xa3, 0x7b, 0x02, 0x02, 0x5b, 0x4c, 0x4e, 0x5e, 0x00, 0x89, 0x20, 0x4e, 0x29, 0x21,
|
||||
0x94, 0x9b, 0x71, 0xf2, 0x5c, 0xc2, 0x80, 0xa0, 0x52, 0xc2, 0x1e, 0xfe, 0x0b, 0xc2, 0x2b, 0x45,
|
||||
0x88, 0xd3, 0xdb, 0x11, 0xd4, 0xa8, 0x09, 0xbf, 0x1e, 0xef, 0x80, 0x17, 0x3d, 0xb5, 0x8e, 0xe1,
|
||||
0xfb, 0x36, 0xa1, 0xc4, 0x5b, 0x5a, 0x21, 0x26, 0x4b, 0x6a, 0x67, 0xeb, 0x76, 0xd9, 0x82, 0x04,
|
||||
0x33, 0xac, 0x14, 0x40, 0x7f, 0x02, 0xff, 0xa7, 0x73, 0x8e, 0x74, 0xa7, 0x8f, 0x24, 0xc9, 0xc8,
|
||||
0xbc, 0xa0, 0x24, 0x52, 0xbc, 0x97, 0x88, 0x48, 0x8b, 0xda, 0xbf, 0x4e, 0x34, 0xfa, 0x44, 0xb9,
|
||||
0x72, 0x0a, 0xa1, 0x84, 0x40, 0xb2, 0x24, 0xa6, 0x94, 0x94, 0x12, 0x22, 0x54, 0xca, 0x9a, 0x08,
|
||||
0x46, 0xc0, 0xcf, 0x93, 0x8c, 0xde, 0x13, 0x69, 0x73, 0xa4, 0x80, 0xf0, 0x04, 0x79, 0x00, 0x02,
|
||||
0xab, 0x19, 0xb2, 0x9b, 0xc6, 0x04, 0x44, 0x4a, 0xee, 0x68, 0xca, 0xee, 0x65, 0xaf, 0x02, 0xc3,
|
||||
0xe9, 0xd1, 0x34, 0xcc, 0x26, 0x94, 0x24, 0xa2, 0x50, 0xa0, 0x8e, 0x5e, 0x10, 0xa1, 0x9a, 0xf3,
|
||||
0x20, 0x1c, 0x81, 0xeb, 0xc6, 0x55, 0xcd, 0x30, 0x8b, 0x31, 0x8f, 0x1c, 0x27, 0x7c, 0x66, 0x21,
|
||||
0x12, 0x15, 0x7d, 0x1d, 0xf2, 0x31, 0x8b, 0x28, 0x19, 0x27, 0x59, 0x52, 0x4c, 0x69, 0x6c, 0x83,
|
||||
0x14, 0x4b, 0x4c, 0x21, 0xe7, 0x88, 0x21, 0x42, 0x36, 0x18, 0x99, 0xe7, 0x29, 0x0b, 0x63, 0x40,
|
||||
0x08, 0x6d, 0x1c, 0x8d, 0x69, 0x91, 0xe0, 0x5a, 0x45, 0xca, 0x84, 0x43, 0x2e, 0x99, 0xe4, 0x8e,
|
||||
0xd0, 0x87, 0x04, 0x64, 0x94, 0x4d, 0x4a, 0x19, 0xd7, 0xf1, 0xe5, 0x34, 0x8b, 0x92, 0x54, 0x22,
|
||||
0x74, 0xc8, 0x8b, 0x2d, 0x42, 0xff, 0x7e, 0x99, 0x4b, 0xed, 0x2c, 0x04, 0x38, 0xa5, 0xe8, 0x53,
|
||||
0xa5, 0x2f, 0x5f, 0x51, 0x17, 0x04, 0xdf, 0xa9, 0x32, 0x6f, 0x17, 0x61, 0x92, 0x86, 0x77, 0x29,
|
||||
0x48, 0x5b, 0x62, 0xfd, 0x9a, 0xae, 0xc8, 0x9f, 0x51, 0x57, 0x3b, 0x24, 0x9d, 0x6d, 0xbf, 0xd8,
|
||||
0x95, 0x6e, 0x63, 0x6a, 0x5c, 0x6a, 0x03, 0x7a, 0x01, 0xcc, 0xba, 0x9b, 0x06, 0x64, 0xd9, 0x11,
|
||||
0xac, 0x18, 0x05, 0x1d, 0xcf, 0xce, 0x1f, 0x4e, 0x59, 0x1a, 0x2c, 0x57, 0xb6, 0xd0, 0xbf, 0x9c,
|
||||
0x46, 0x22, 0xa8, 0x4d, 0xc7, 0x24, 0xfd, 0x67, 0xcc, 0x01, 0x40, 0xde, 0xb0, 0xff, 0xd0, 0xf9,
|
||||
0x0f, 0x80, 0x30, 0x2d, 0xbb, 0x84, 0x39, 0xa7, 0xd9, 0x44, 0x4c, 0x03, 0x9c, 0xe7, 0x48, 0x0f,
|
||||
0x65, 0xcf, 0x3e, 0x8e, 0xc7, 0x45, 0x70, 0x01, 0xfe, 0xc6, 0x91, 0xd9, 0x83, 0xd9, 0x04, 0xed,
|
||||
0xfa, 0x87, 0xbd, 0xae, 0x6f, 0x75, 0x0e, 0x6d, 0xcd, 0xf6, 0x5b, 0xce, 0xc3, 0xc7, 0xe0, 0xfa,
|
||||
0xc6, 0x06, 0x87, 0xf2, 0x39, 0x5c, 0xd0, 0xe0, 0x8d, 0x74, 0x7b, 0x0d, 0xaf, 0xe7, 0x1f, 0xae,
|
||||
0xbd, 0x1e, 0xb6, 0x5b, 0x4e, 0xce, 0x3f, 0x80, 0xbf, 0xd2, 0xc9, 0x49, 0x1f, 0x87, 0x21, 0x46,
|
||||
0xba, 0x37, 0xdf, 0xb7, 0x3d, 0xff, 0xad, 0xe7, 0xda, 0x1e, 0x02, 0xc2, 0x0f, 0xf1, 0x7c, 0xdb,
|
||||
0x6f, 0xf6, 0x6c, 0x05, 0x69, 0x42, 0x20, 0xc8, 0x45, 0x1f, 0xfe, 0x39, 0x87, 0x31, 0xaf, 0x7f,
|
||||
0xe5, 0x1d, 0x9c, 0x79, 0xbd, 0x2b, 0xcf, 0x3d, 0xf3, 0xfc, 0xab, 0xfe, 0x39, 0x0e, 0xfc, 0x77,
|
||||
0xe5, 0x14, 0xdf, 0x20, 0x27, 0xe8, 0xf3, 0xfe, 0xbd, 0x9c, 0x20, 0x51, 0xa7, 0x3d, 0xe7, 0xa0,
|
||||
0x6f, 0xfb, 0x40, 0x31, 0x36, 0x24, 0xe1, 0xa7, 0x48, 0x8f, 0x73, 0xb8, 0x4f, 0xd4, 0x90, 0xaf,
|
||||
0xf8, 0x3b, 0x95, 0x7d, 0xf8, 0xe9, 0x97, 0xe3, 0xbe, 0x82, 0xd6, 0x53, 0xf5, 0xb8, 0x84, 0xbe,
|
||||
0xf0, 0x0e, 0x1d, 0xcf, 0xee, 0x3b, 0x6e, 0xff, 0x14, 0x5a, 0xfe, 0x81, 0x6c, 0x12, 0x68, 0xee,
|
||||
0x1f, 0x41, 0xd3, 0xf3, 0xb1, 0x79, 0x08, 0x2d, 0x7f, 0xff, 0xdc, 0xeb, 0x39, 0xfd, 0xbe, 0x7d,
|
||||
0xe4, 0x1c, 0xc2, 0x02, 0xf0, 0xd3, 0x87, 0xb1, 0xbe, 0x7d, 0x2c, 0xc1, 0xe5, 0xc8, 0xb1, 0xe3,
|
||||
0x1f, 0x9d, 0x03, 0x38, 0x34, 0x3d, 0x57, 0xb6, 0xf7, 0x01, 0x08, 0x20, 0x71, 0xee, 0x01, 0x36,
|
||||
0x11, 0xcd, 0x29, 0x34, 0x8f, 0x7c, 0x8d, 0xfb, 0xc0, 0x39, 0xee, 0x55, 0x2b, 0x2a, 0x32, 0x2e,
|
||||
0x60, 0x96, 0xb7, 0x0f, 0xb3, 0x8e, 0x3c, 0x44, 0xe6, 0x1d, 0x23, 0xb2, 0xa3, 0xfe, 0xf9, 0x31,
|
||||
0xf6, 0xc2, 0x42, 0xc7, 0xfb, 0x67, 0x08, 0x76, 0x85, 0x68, 0xfa, 0xe7, 0x6b, 0xe0, 0xda, 0x1e,
|
||||
0x0c, 0xab, 0xb3, 0x24, 0xa8, 0xe6, 0xc7, 0xb1, 0x89, 0xa7, 0xc9, 0xff, 0x37, 0xd5, 0xae, 0x1d,
|
||||
0x64, 0xd3, 0xe4, 0xcb, 0xc7, 0xac, 0x4c, 0xad, 0xd4, 0xa1, 0x76, 0xc6, 0x16, 0xf4, 0x92, 0x87,
|
||||
0xc5, 0x34, 0x0a, 0x33, 0xe8, 0xb1, 0xc1, 0x51, 0x9f, 0x9a, 0x35, 0xa4, 0xd4, 0x61, 0xb0, 0x0c,
|
||||
0x15, 0xbf, 0x75, 0x9b, 0xe8, 0x7f, 0x04, 0xf4, 0x56, 0xed, 0x90, 0x2c, 0xe7, 0x51, 0x1b, 0x4e,
|
||||
0xec, 0x86, 0xb5, 0x04, 0x53, 0x22, 0x1c, 0x4d, 0x9a, 0x05, 0x2f, 0x3d, 0xc8, 0xb3, 0xb2, 0x42,
|
||||
0x90, 0xb0, 0xc1, 0xee, 0xbf, 0xe6, 0x94, 0x3f, 0x7e, 0x06, 0x87, 0x1c, 0x81, 0xab, 0x7e, 0x9b,
|
||||
0xa6, 0xa6, 0xd1, 0x38, 0x96, 0x19, 0xd6, 0x30, 0x19, 0x9b, 0xa1, 0x03, 0x47, 0xaf, 0xf7, 0x61,
|
||||
0x34, 0x35, 0x4d, 0x61, 0x73, 0x2b, 0x38, 0x59, 0x0a, 0x94, 0xd3, 0x5b, 0x21, 0x78, 0x02, 0x19,
|
||||
0x18, 0x35, 0x8d, 0x38, 0x14, 0x61, 0x47, 0xf0, 0x39, 0x85, 0x8c, 0xcd, 0xb0, 0x82, 0x80, 0xbe,
|
||||
0x7e, 0x6d, 0xc2, 0x9a, 0xae, 0xb5, 0x02, 0x4e, 0x9c, 0x54, 0x52, 0x7a, 0xe2, 0xf5, 0xcb, 0x5e,
|
||||
0x9b, 0x59, 0xea, 0x18, 0x8f, 0xd8, 0xe9, 0x89, 0xfb, 0xfa, 0x35, 0x1d, 0xf9, 0x87, 0x87, 0x16,
|
||||
0x2c, 0x63, 0xa2, 0xab, 0xca, 0x02, 0x6f, 0x98, 0x8d, 0x02, 0xaf, 0xf7, 0xfa, 0x35, 0x1f, 0x41,
|
||||
0x73, 0x6f, 0xcf, 0x92, 0x1e, 0x4b, 0x92, 0x76, 0xa1, 0x28, 0xdb, 0xcb, 0xac, 0xa7, 0x27, 0x93,
|
||||
0x07, 0x99, 0x35, 0xa4, 0x29, 0x84, 0x58, 0x1e, 0xd0, 0xa1, 0x61, 0x04, 0x81, 0x80, 0x45, 0x80,
|
||||
0xfb, 0x57, 0xc6, 0x9e, 0xe9, 0xf5, 0xfa, 0xfd, 0xbe, 0xef, 0x1d, 0xfe, 0xa8, 0xe4, 0x08, 0x71,
|
||||
0x88, 0xcd, 0x4c, 0x6b, 0x34, 0x72, 0x2d, 0x47, 0xb0, 0xcf, 0x40, 0x7c, 0x36, 0x01, 0x18, 0x0b,
|
||||
0xf2, 0xdc, 0xf8, 0xb3, 0x08, 0xb9, 0x30, 0x7b, 0xb6, 0xe1, 0x1a, 0x96, 0xa5, 0x25, 0x95, 0x06,
|
||||
0xd1, 0x7b, 0xd3, 0xc0, 0xfc, 0x04, 0xc4, 0x90, 0x3a, 0xd2, 0x65, 0xff, 0x12, 0xce, 0xc0, 0x6a,
|
||||
0x1b, 0x22, 0xb2, 0x53, 0x07, 0xbd, 0x7b, 0x83, 0x36, 0xbe, 0x5e, 0xc0, 0x82, 0xf1, 0x62, 0xb7,
|
||||
0xb0, 0x6c, 0xfa, 0x0c, 0x00, 0xe0, 0x34, 0x6c, 0xb1, 0x03, 0x40, 0xe9, 0x83, 0xa1, 0xf4, 0x0f,
|
||||
0x61, 0x60, 0xeb, 0xdf, 0x2f, 0x50, 0x31, 0x20, 0x12, 0x52, 0x48, 0x96, 0x40, 0x5e, 0x18, 0x02,
|
||||
0x0d, 0x1b, 0x72, 0x8f, 0xfc, 0xef, 0x73, 0x0e, 0xa1, 0x90, 0x7f, 0xe2, 0x2c, 0x97, 0xf8, 0xd0,
|
||||
0xfd, 0x38, 0x98, 0x18, 0x3f, 0xaf, 0xb9, 0x3f, 0x52, 0x6b, 0x4f, 0x2e, 0xb0, 0x67, 0x80, 0x5b,
|
||||
0xd2, 0x82, 0x49, 0xa4, 0x60, 0x92, 0x2c, 0x9f, 0x0b, 0x54, 0x10, 0x47, 0x45, 0x1d, 0x29, 0x00,
|
||||
0xc3, 0x4e, 0x9c, 0x45, 0x98, 0xce, 0x69, 0x20, 0xa0, 0xb5, 0x21, 0x32, 0x75, 0xd0, 0x45, 0xa0,
|
||||
0x4a, 0x64, 0x9f, 0x54, 0x57, 0x53, 0x64, 0xc9, 0x16, 0x66, 0xd4, 0x7a, 0xf6, 0x3c, 0xc7, 0x22,
|
||||
0x57, 0x69, 0x3c, 0xdb, 0x41, 0x35, 0xdf, 0x51, 0x7e, 0x9a, 0x7e, 0x29, 0x77, 0xb3, 0xa8, 0xef,
|
||||
0x66, 0xb1, 0x8b, 0xb4, 0x6a, 0x53, 0x8b, 0x36, 0x85, 0x5b, 0xb7, 0xb6, 0x78, 0x66, 0x71, 0x96,
|
||||
0xe2, 0xea, 0x00, 0x52, 0x93, 0x75, 0x5d, 0xf0, 0x40, 0xf9, 0x8e, 0x11, 0x4d, 0x71, 0x5c, 0xa7,
|
||||
0x98, 0xa3, 0x95, 0x70, 0xb4, 0x12, 0xd0, 0xef, 0xb8, 0x4e, 0x7e, 0xa3, 0x98, 0x61, 0xd8, 0xb1,
|
||||
0x24, 0x5c, 0x75, 0x6e, 0xa5, 0x39, 0xde, 0x4d, 0x33, 0x05, 0xd3, 0x56, 0x33, 0x4f, 0x91, 0x71,
|
||||
0x2c, 0xaa, 0x21, 0xfc, 0x0e, 0x32, 0xd7, 0x7a, 0xb4, 0xae, 0x0a, 0xc8, 0x79, 0x81, 0xd6, 0x81,
|
||||
0x8a, 0xf7, 0x5d, 0xe3, 0x75, 0x4f, 0x14, 0xe6, 0x90, 0xa6, 0xc5, 0xa7, 0xd3, 0x24, 0x8d, 0xcd,
|
||||
0xc4, 0xda, 0x39, 0x94, 0xee, 0x1e, 0x02, 0x23, 0x70, 0x5f, 0x06, 0xfc, 0xf5, 0x6b, 0x10, 0x92,
|
||||
0xfc, 0xdd, 0x05, 0x18, 0x5b, 0x76, 0x5d, 0x9c, 0xb3, 0xf0, 0x0b, 0xbd, 0xa0, 0xef, 0x78, 0x38,
|
||||
0x31, 0xd1, 0xcb, 0xa0, 0x39, 0x5b, 0xb0, 0x6f, 0x54, 0x5c, 0x32, 0x96, 0x8a, 0x24, 0x57, 0x52,
|
||||
0xac, 0x8f, 0x35, 0x75, 0xd0, 0xac, 0xb9, 0xdf, 0xf6, 0xc8, 0x52, 0x6d, 0x25, 0xfd, 0x4e, 0xa7,
|
||||
0xbb, 0x91, 0x82, 0xd1, 0x0d, 0x17, 0xac, 0x10, 0x33, 0x99, 0xca, 0xd1, 0x6b, 0x7e, 0x03, 0x94,
|
||||
0x39, 0x9c, 0x42, 0xfe, 0x1a, 0xd1, 0xa6, 0xa3, 0xb4, 0x1b, 0x76, 0x66, 0x59, 0x4a, 0xf6, 0xc3,
|
||||
0xef, 0x9b, 0xa7, 0xfb, 0x60, 0xf6, 0xf6, 0x1d, 0x65, 0xb6, 0xc4, 0xf5, 0xfc, 0xe0, 0x33, 0x4e,
|
||||
0x8e, 0x59, 0x55, 0x78, 0x92, 0xb0, 0xcf, 0x85, 0x17, 0x3b, 0xfb, 0x8a, 0xcf, 0x0a, 0xb5, 0x00,
|
||||
0xaf, 0xb3, 0x1b, 0x58, 0x1b, 0x45, 0x78, 0x1d, 0x42, 0x6b, 0xb5, 0x56, 0x1d, 0x65, 0x0c, 0x81,
|
||||
0x81, 0xa5, 0x82, 0x90, 0x77, 0xca, 0x6e, 0x13, 0x8e, 0x18, 0xf2, 0xcc, 0x6c, 0xd8, 0x1f, 0xef,
|
||||
0xfe, 0xc0, 0x10, 0x0f, 0x9d, 0x3c, 0xa1, 0x85, 0x29, 0xf1, 0x59, 0xeb, 0x4d, 0xb8, 0x86, 0x10,
|
||||
0x7b, 0x83, 0xdb, 0xd0, 0xc4, 0xb8, 0x17, 0xdc, 0xda, 0xe4, 0x87, 0xa5, 0x58, 0xc1, 0x3f, 0x74,
|
||||
0x95, 0x3f, 0xdc, 0x6e, 0xac, 0xb9, 0x17, 0x18, 0x96, 0xd1, 0x50, 0xe1, 0xb6, 0xcc, 0x82, 0xe6,
|
||||
0x84, 0xb5, 0x6e, 0xb5, 0xdc, 0x38, 0xe6, 0x0d, 0xd4, 0xc1, 0x4e, 0xfc, 0x0a, 0x27, 0x21, 0x02,
|
||||
0xd5, 0x75, 0x51, 0x79, 0xa0, 0xed, 0xe9, 0xc5, 0x96, 0x89, 0xb6, 0xd4, 0x08, 0xa7, 0xe0, 0x91,
|
||||
0xae, 0xa9, 0x37, 0x34, 0xa3, 0x52, 0x0a, 0xd4, 0x01, 0xe9, 0x2e, 0x1a, 0x4b, 0xe5, 0x3b, 0x56,
|
||||
0x5a, 0x48, 0x1f, 0xfd, 0x2c, 0x99, 0x35, 0xf3, 0x03, 0x04, 0x18, 0xfe, 0x45, 0xe0, 0xda, 0xfc,
|
||||
0x9b, 0xb2, 0x32, 0x16, 0x70, 0x47, 0x6e, 0x98, 0x1d, 0x42, 0x4b, 0x7a, 0xd5, 0x2c, 0x60, 0x9d,
|
||||
0x70, 0xcf, 0x5b, 0xa7, 0x7a, 0xa9, 0xc9, 0xad, 0x25, 0x24, 0x0a, 0xfc, 0xe9, 0xe9, 0x1e, 0x4e,
|
||||
0xa5, 0xec, 0xde, 0x51, 0x54, 0x39, 0x39, 0x97, 0x8d, 0x77, 0x74, 0x1c, 0xce, 0x53, 0xc4, 0x26,
|
||||
0x3a, 0x1c, 0x59, 0x83, 0xbe, 0xdf, 0x20, 0x81, 0x5a, 0xb7, 0x67, 0x0c, 0xce, 0xf0, 0x9f, 0x58,
|
||||
0xf1, 0xa1, 0xca, 0xd9, 0x02, 0xd1, 0x31, 0x61, 0x11, 0x98, 0x02, 0x4a, 0x09, 0x23, 0x75, 0x85,
|
||||
0xdc, 0x84, 0xee, 0x66, 0x32, 0x4b, 0xb3, 0x59, 0x1a, 0x5f, 0x6a, 0x78, 0xfa, 0xbc, 0x86, 0x6b,
|
||||
0xb4, 0xe8, 0xa4, 0x74, 0x53, 0xb9, 0xaa, 0x35, 0x86, 0x97, 0x81, 0x1e, 0xc0, 0x74, 0x47, 0x83,
|
||||
0xf4, 0x0e, 0x7e, 0x12, 0xd3, 0xa4, 0xf8, 0x28, 0x13, 0x83, 0xc0, 0x1d, 0x94, 0x58, 0xbc, 0x63,
|
||||
0xbf, 0x3e, 0xd0, 0x1f, 0xd4, 0x3e, 0xf6, 0xe5, 0xe6, 0x6c, 0x4b, 0x06, 0x32, 0x69, 0x4b, 0x1a,
|
||||
0x47, 0x3d, 0x0b, 0xd0, 0x8a, 0xf2, 0x7f, 0xf2, 0x1b, 0x72, 0x91, 0xfa, 0x8a, 0x5f, 0x45, 0xd6,
|
||||
0x88, 0x64, 0x7f, 0x01, 0x4f, 0xcb, 0x09, 0xee, 0x42, 0x43, 0x9f, 0x4d, 0xd6, 0x4a, 0x69, 0x6c,
|
||||
0x46, 0x07, 0xba, 0x19, 0x15, 0x6a, 0x3a, 0x9e, 0x40, 0x24, 0x88, 0x1d, 0x96, 0x49, 0xdd, 0x98,
|
||||
0xe7, 0x41, 0x36, 0x4f, 0x53, 0xbb, 0xea, 0x40, 0x93, 0x91, 0x5d, 0x2b, 0x5a, 0x76, 0x81, 0x9a,
|
||||
0x66, 0x41, 0x39, 0x7d, 0xb7, 0x61, 0x99, 0x34, 0xa0, 0x5f, 0x57, 0x6b, 0xe0, 0xb0, 0x54, 0xe5,
|
||||
0x3a, 0x11, 0x49, 0x8b, 0x82, 0x74, 0x55, 0xf3, 0x35, 0x9b, 0xfc, 0x2d, 0xdb, 0xa2, 0x91, 0x57,
|
||||
0x7d, 0x86, 0x7d, 0x0b, 0xae, 0xee, 0x59, 0x6d, 0x5e, 0x91, 0x01, 0x79, 0x06, 0x06, 0xfd, 0xbf,
|
||||
0xb5, 0xba, 0xad, 0x49, 0xab, 0x99, 0x82, 0x68, 0x97, 0x80, 0xb9, 0x50, 0x9c, 0x2c, 0x20, 0x38,
|
||||
0xa2, 0xf6, 0xbe, 0xab, 0x69, 0x45, 0x50, 0x77, 0x5a, 0x36, 0x8e, 0x9e, 0xae, 0x77, 0x5e, 0xc6,
|
||||
0xc7, 0xf6, 0x8c, 0x86, 0x9a, 0xa8, 0xd5, 0x4a, 0x0d, 0x01, 0xdd, 0x58, 0xa3, 0xa8, 0xeb, 0xf0,
|
||||
0xf7, 0x22, 0xaa, 0x54, 0xad, 0x8d, 0xee, 0x5b, 0x11, 0xed, 0xd0, 0x5c, 0x9b, 0x43, 0x1e, 0x43,
|
||||
0xb9, 0x32, 0xdf, 0xdf, 0x02, 0xcf, 0xd5, 0x1d, 0xbf, 0x35, 0xc4, 0xb0, 0xcb, 0x63, 0x3a, 0x0f,
|
||||
0x9d, 0xc6, 0x7c, 0x3d, 0xf9, 0xf7, 0x6f, 0x9b, 0xfc, 0xb8, 0x07, 0x67, 0x6a, 0x21, 0x13, 0x4c,
|
||||
0x81, 0x9a, 0x68, 0xe0, 0x47, 0x06, 0x19, 0xe4, 0xd9, 0xe5, 0xc5, 0xb9, 0x2e, 0x6c, 0x6c, 0xa9,
|
||||
0x5c, 0x90, 0x87, 0x59, 0x9a, 0x15, 0x81, 0x81, 0x37, 0xcc, 0x83, 0x6e, 0xf7, 0xfe, 0xfe, 0xde,
|
||||
0xb9, 0xdf, 0x77, 0x18, 0x9f, 0x74, 0x7d, 0xd7, 0x75, 0xf1, 0x68, 0x6e, 0x10, 0x79, 0x96, 0x0e,
|
||||
0x0c, 0xbc, 0xff, 0x33, 0x88, 0x2a, 0x85, 0xe8, 0x2f, 0x5d, 0xf7, 0xd0, 0x05, 0x13, 0x2c, 0x7f,
|
||||
0x0c, 0x5e, 0x1d, 0x1d, 0xc1, 0x44, 0x77, 0x08, 0x9d, 0x9c, 0x7d, 0xa1, 0x03, 0x02, 0x1d, 0xf8,
|
||||
0x5f, 0xd9, 0xd1, 0x51, 0x65, 0x15, 0xd2, 0xc1, 0x4b, 0x04, 0xdd, 0x15, 0x03, 0xbd, 0x21, 0x56,
|
||||
0x95, 0x06, 0xc4, 0x75, 0x3c, 0x9b, 0x1c, 0x0d, 0x55, 0xa9, 0xfb, 0xd8, 0xde, 0xbf, 0x3a, 0x38,
|
||||
0x3b, 0xb8, 0xea, 0x9d, 0x1d, 0x5e, 0x79, 0xc7, 0x6f, 0x7d, 0xdb, 0x97, 0xe5, 0x1d, 0x97, 0xf4,
|
||||
0x6d, 0xdf, 0x3b, 0xf3, 0xfa, 0xb5, 0x1e, 0x2c, 0x39, 0x1c, 0x03, 0xa0, 0xef, 0xc2, 0x0c, 0xef,
|
||||
0xf0, 0x6a, 0xff, 0xec, 0xf8, 0xa2, 0x6f, 0xf7, 0xce, 0xb0, 0xf4, 0x73, 0x7c, 0xd6, 0xbf, 0xea,
|
||||
0x01, 0xb2, 0xa3, 0x2b, 0xaf, 0x7f, 0xe6, 0x79, 0x57, 0x47, 0x30, 0x86, 0x05, 0x08, 0xf9, 0x79,
|
||||
0x08, 0x9f, 0xde, 0x7e, 0xbd, 0x18, 0x24, 0xb4, 0xcf, 0x29, 0x6f, 0x38, 0x02, 0xa3, 0xbc, 0xf3,
|
||||
0x33, 0xaa, 0x31, 0xe9, 0x9c, 0xf4, 0xe6, 0x2a, 0xc7, 0x5b, 0x8e, 0x40, 0x30, 0xd5, 0x03, 0xbf,
|
||||
0xab, 0x81, 0xd8, 0xc1, 0x42, 0x60, 0x23, 0xc9, 0x05, 0xef, 0x20, 0x9e, 0xcf, 0xf4, 0x85, 0xa3,
|
||||
0xca, 0xeb, 0xbf, 0xb0, 0x98, 0x3a, 0xca, 0xbf, 0xac, 0xa7, 0xb6, 0xf5, 0x73, 0x17, 0x68, 0x0b,
|
||||
0x6e, 0x87, 0xf1, 0x3c, 0x37, 0x7d, 0x03, 0xd8, 0x6a, 0xdb, 0xf0, 0x57, 0x67, 0xef, 0x58, 0xfb,
|
||||
0x1b, 0x57, 0xdd, 0x92, 0xcf, 0x6f, 0x4f, 0x90, 0x9e, 0x39, 0x39, 0x35, 0xdd, 0xf3, 0x57, 0x32,
|
||||
0x9e, 0x8d, 0x74, 0x6c, 0x29, 0xad, 0x49, 0x55, 0x65, 0x95, 0x61, 0x21, 0x06, 0x11, 0x72, 0x30,
|
||||
0x44, 0x0c, 0xf4, 0xd0, 0x83, 0x89, 0x80, 0xfc, 0x31, 0xe5, 0xef, 0x4e, 0xd6, 0x70, 0x10, 0x29,
|
||||
0x55, 0x9d, 0xdf, 0x44, 0x6c, 0x3d, 0x8f, 0x9b, 0x7e, 0xf9, 0xb5, 0x7e, 0x68, 0x41, 0x82, 0xe4,
|
||||
0xbd, 0x16, 0x46, 0x11, 0xf9, 0x25, 0x2f, 0x74, 0xac, 0x61, 0x59, 0x8e, 0xfa, 0x15, 0x0d, 0x6d,
|
||||
0xd4, 0x73, 0xdd, 0x9f, 0x4a, 0xdd, 0xd4, 0x45, 0x74, 0x7c, 0x60, 0x92, 0x51, 0x63, 0xb0, 0xd1,
|
||||
0xad, 0xee, 0xe7, 0x8c, 0xda, 0x9a, 0x61, 0x1a, 0xfd, 0xe7, 0xe7, 0x8f, 0xbf, 0x98, 0xaa, 0x5e,
|
||||
0x45, 0x83, 0x37, 0xcb, 0xb2, 0x84, 0x6e, 0x0c, 0xae, 0xdf, 0x0c, 0xf5, 0x83, 0x8f, 0x56, 0x42,
|
||||
0x2e, 0x5a, 0xf9, 0x38, 0x9c, 0x8a, 0x64, 0x3e, 0x2e, 0x30, 0x67, 0x32, 0x29, 0xa4, 0xd9, 0x36,
|
||||
0x0a, 0x11, 0x12, 0x72, 0x4c, 0xc7, 0x6d, 0xe3, 0x87, 0x25, 0x77, 0x0a, 0x60, 0x9f, 0x9a, 0x9e,
|
||||
0xb5, 0x32, 0x30, 0x2f, 0x47, 0x98, 0x9b, 0x15, 0x98, 0x42, 0x2d, 0x4c, 0x67, 0x60, 0x8c, 0xa0,
|
||||
0x09, 0xff, 0x25, 0xaf, 0x1c, 0x70, 0x63, 0xd4, 0xe5, 0x83, 0x24, 0x6f, 0x4d, 0xa7, 0x7d, 0xdb,
|
||||
0xd5, 0x04, 0x62, 0x96, 0xef, 0xfc, 0x51, 0xb0, 0xec, 0xb6, 0x71, 0x06, 0xac, 0xe6, 0xc0, 0x29,
|
||||
0x41, 0xc5, 0x2f, 0x1e, 0xe0, 0xad, 0xcb, 0x6f, 0x17, 0xe7, 0x67, 0xe0, 0x03, 0xff, 0x41, 0xe1,
|
||||
0x04, 0x58, 0x08, 0xc8, 0x5e, 0xb1, 0xf3, 0xe7, 0x94, 0xdd, 0xc1, 0x79, 0xe2, 0xc6, 0x5e, 0x62,
|
||||
0x1d, 0x65, 0x60, 0x80, 0x11, 0xa7, 0x78, 0x75, 0x02, 0xa8, 0xba, 0x88, 0xda, 0x58, 0xc1, 0xe9,
|
||||
0x7f, 0x8b, 0xe6, 0xe1, 0x22, 0x86, 0x6d, 0x96, 0x67, 0x41, 0x86, 0x1e, 0x83, 0x4d, 0xa4, 0x72,
|
||||
0xc3, 0xee, 0x17, 0x39, 0xf4, 0xd1, 0x4b, 0xfa, 0x20, 0x6c, 0x83, 0x74, 0x88, 0x21, 0x6d, 0xc3,
|
||||
0xc1, 0xbb, 0x85, 0x39, 0x16, 0x8b, 0x18, 0x70, 0xf3, 0x19, 0x4e, 0x9f, 0xe1, 0xa4, 0xd4, 0x9f,
|
||||
0x0f, 0x82, 0xce, 0x60, 0xb3, 0x53, 0x1a, 0x7f, 0x0a, 0x53, 0xbc, 0x0f, 0xd0, 0x59, 0x05, 0x82,
|
||||
0x22, 0x2d, 0xce, 0x94, 0xd3, 0x71, 0x60, 0x74, 0x81, 0x1c, 0x7b, 0x1b, 0x39, 0x94, 0x73, 0x2c,
|
||||
0xff, 0xd0, 0x16, 0x39, 0xc6, 0x7b, 0xec, 0x1f, 0x10, 0x59, 0xe8, 0x6a, 0x0c, 0x90, 0xcf, 0x92,
|
||||
0x98, 0x41, 0x9b, 0x36, 0x4c, 0x3d, 0x92, 0x19, 0x65, 0x73, 0x61, 0x4a, 0xe6, 0x56, 0xb6, 0x47,
|
||||
0xf7, 0x2d, 0xb9, 0x2a, 0x03, 0xf7, 0x66, 0x1a, 0x9f, 0x3e, 0x7e, 0xbe, 0x84, 0xdd, 0xed, 0x2a,
|
||||
0x39, 0x83, 0x32, 0xa2, 0x80, 0x43, 0x29, 0xcb, 0xbf, 0x33, 0x3e, 0x7b, 0x07, 0x89, 0x45, 0xa9,
|
||||
0x34, 0xa1, 0x76, 0x89, 0x2a, 0xdd, 0x80, 0x63, 0x26, 0x56, 0xd3, 0xb8, 0xbc, 0xf1, 0x35, 0x43,
|
||||
0xcb, 0x7e, 0xe9, 0xad, 0xc2, 0xe2, 0x31, 0x8b, 0xc8, 0xfa, 0x39, 0x12, 0x15, 0x1f, 0xb2, 0x31,
|
||||
0x03, 0x5d, 0x4c, 0xc6, 0xe6, 0xb4, 0x10, 0xc1, 0x9a, 0x7d, 0x06, 0x3b, 0x06, 0x3d, 0x65, 0x35,
|
||||
0xd3, 0xb5, 0x04, 0x7f, 0xac, 0x2c, 0x25, 0xbc, 0x0f, 0x13, 0x41, 0xc6, 0x54, 0x80, 0x32, 0x96,
|
||||
0x71, 0xce, 0xd8, 0x03, 0xf0, 0x3d, 0x43, 0x6e, 0x62, 0x57, 0x5e, 0xd0, 0xa1, 0x15, 0x29, 0x48,
|
||||
0x2a, 0xb5, 0xc6, 0xb4, 0x86, 0x72, 0x4a, 0x79, 0x85, 0x64, 0x9a, 0xea, 0x12, 0x46, 0x38, 0xf2,
|
||||
0x17, 0x42, 0xb0, 0xb0, 0x3a, 0xa0, 0xaf, 0x40, 0x02, 0xe0, 0xa5, 0x56, 0x25, 0x59, 0x29, 0x6c,
|
||||
0x2c, 0xcf, 0xc8, 0xd2, 0x67, 0xb3, 0xd7, 0x00, 0x9b, 0xce, 0x98, 0x20, 0x49, 0x0c, 0xfb, 0x93,
|
||||
0x8c, 0x1f, 0x09, 0x52, 0x0e, 0x19, 0x56, 0x8b, 0xd3, 0xe6, 0xc2, 0x80, 0xbb, 0x7e, 0xf3, 0xa2,
|
||||
0x99, 0x0c, 0xdc, 0x21, 0x96, 0x64, 0xd1, 0x2c, 0xe1, 0x3c, 0x31, 0x14, 0xa3, 0x80, 0x0e, 0xc5,
|
||||
0xde, 0xde, 0xda, 0x41, 0xdc, 0x6a, 0x56, 0x7f, 0x58, 0x02, 0xab, 0xab, 0xb5, 0x55, 0x08, 0x6d,
|
||||
0x15, 0xc3, 0xb5, 0x8c, 0x44, 0x43, 0x46, 0xa0, 0x0c, 0x5c, 0x77, 0x88, 0x52, 0x14, 0x0d, 0x02,
|
||||
0xf2, 0x79, 0x31, 0x85, 0x83, 0x9b, 0x66, 0x5d, 0xb4, 0x59, 0xbf, 0x95, 0x6a, 0xa5, 0x90, 0xe1,
|
||||
0xad, 0x1f, 0x5a, 0x1b, 0x19, 0x73, 0x36, 0x93, 0x07, 0xef, 0x01, 0xb9, 0x85, 0x8d, 0x5e, 0xad,
|
||||
0xb6, 0xb0, 0x34, 0xf2, 0xc0, 0x3f, 0x6c, 0xae, 0x54, 0x72, 0x3f, 0xb8, 0x76, 0xed, 0x7e, 0xf9,
|
||||
0x07, 0x47, 0xae, 0xea, 0xe3, 0x66, 0x55, 0x56, 0x28, 0x44, 0x80, 0x8b, 0xa1, 0x03, 0x2e, 0xa8,
|
||||
0xd9, 0x30, 0x24, 0x54, 0x9e, 0x96, 0x15, 0xc9, 0xfa, 0x39, 0x50, 0x8f, 0x62, 0xd4, 0x42, 0xc3,
|
||||
0x3b, 0x61, 0x08, 0xbd, 0x52, 0xc3, 0xe8, 0x89, 0x7f, 0x70, 0x68, 0xe9, 0x9a, 0x1b, 0xf6, 0x82,
|
||||
0x1f, 0xc0, 0x65, 0x44, 0x92, 0xcd, 0xe9, 0x4a, 0x4d, 0xe0, 0x81, 0xee, 0xc7, 0x6d, 0xc0, 0xf2,
|
||||
0xf9, 0xb0, 0x8e, 0x8c, 0x8d, 0x09, 0x97, 0xa8, 0x5e, 0x2a, 0x6e, 0x92, 0x42, 0xfe, 0x82, 0x80,
|
||||
0x9f, 0x9e, 0x0e, 0x5e, 0x06, 0x01, 0xd5, 0x7c, 0x5b, 0x4b, 0x79, 0x07, 0x70, 0xc7, 0x69, 0xf8,
|
||||
0x65, 0xb5, 0x46, 0x20, 0x10, 0x01, 0xb5, 0x60, 0xbe, 0x91, 0xcd, 0x67, 0x77, 0x90, 0x61, 0x42,
|
||||
0xbc, 0x01, 0x37, 0x04, 0xbd, 0xe2, 0xe9, 0x49, 0x8c, 0x5c, 0xf8, 0xe7, 0x04, 0xe4, 0xf0, 0xf4,
|
||||
0xf4, 0xf2, 0x17, 0x39, 0x0e, 0x0b, 0x7c, 0xc8, 0x04, 0x9d, 0x80, 0xc9, 0x0b, 0xab, 0x81, 0x74,
|
||||
0x85, 0x44, 0xb0, 0xaf, 0x30, 0x03, 0xc7, 0xf4, 0x6b, 0xae, 0x49, 0xea, 0x78, 0x37, 0x28, 0x1d,
|
||||
0x59, 0xad, 0x0b, 0xc2, 0x6b, 0xf7, 0x66, 0xad, 0x57, 0xd7, 0x8e, 0xe3, 0x84, 0x37, 0x43, 0x0a,
|
||||
0x9d, 0x01, 0xee, 0x02, 0x57, 0xbb, 0x04, 0x0a, 0xbf, 0x2a, 0x41, 0xda, 0xf1, 0x00, 0x24, 0xea,
|
||||
0xcc, 0xc2, 0x7c, 0x5d, 0x9a, 0x31, 0x97, 0xb0, 0x3e, 0xc4, 0x9f, 0x71, 0x1a, 0xca, 0x90, 0xbe,
|
||||
0x4d, 0xc1, 0x60, 0x99, 0xd2, 0x88, 0x60, 0x8c, 0x0b, 0xd3, 0xb8, 0xc4, 0x5b, 0x70, 0x7c, 0x17,
|
||||
0x89, 0x82, 0xa9, 0xee, 0x60, 0x21, 0xd8, 0x92, 0x59, 0x52, 0x14, 0xc9, 0x44, 0x29, 0xd9, 0x23,
|
||||
0x9b, 0x73, 0x72, 0xc7, 0xd9, 0x7d, 0x01, 0x12, 0x21, 0xbf, 0xb3, 0x39, 0x29, 0xa6, 0x6c, 0x9e,
|
||||
0xc6, 0x24, 0xe7, 0xec, 0x2e, 0xbc, 0x4b, 0x1f, 0x89, 0x76, 0x40, 0xfa, 0xce, 0x7a, 0x16, 0xc2,
|
||||
0xa6, 0x43, 0x2a, 0x00, 0xcb, 0x64, 0x31, 0xc1, 0x8d, 0x04, 0xc5, 0x97, 0xd7, 0xda, 0x30, 0x21,
|
||||
0xa7, 0x1c, 0x26, 0x8c, 0xf1, 0x82, 0x1e, 0x2f, 0xab, 0xcb, 0x35, 0x15, 0x15, 0x58, 0x91, 0x02,
|
||||
0x69, 0x83, 0x8b, 0x85, 0xb8, 0x44, 0xee, 0x28, 0x80, 0x51, 0x8d, 0x1c, 0xf5, 0x7e, 0x4a, 0x39,
|
||||
0x75, 0xc0, 0x19, 0x5e, 0x20, 0x71, 0xf0, 0x2d, 0x27, 0xc5, 0x15, 0x92, 0x97, 0xe0, 0x1d, 0xcb,
|
||||
0xc9, 0xda, 0xd6, 0xdf, 0x25, 0x8b, 0xa2, 0x9e, 0x8c, 0x6c, 0x1d, 0xae, 0x36, 0x62, 0xe3, 0x41,
|
||||
0xe6, 0xfa, 0x79, 0x04, 0x3a, 0xb3, 0xcd, 0xe1, 0xd6, 0x9d, 0x38, 0x9a, 0xb9, 0x92, 0x37, 0xca,
|
||||
0x0d, 0x0e, 0xe8, 0x11, 0xa6, 0x29, 0x90, 0xba, 0x40, 0xec, 0x4e, 0x52, 0x81, 0x07, 0xcb, 0xe0,
|
||||
0x44, 0x1e, 0xdb, 0x67, 0xd2, 0xd0, 0xbb, 0xff, 0xd4, 0xf8, 0xff, 0x27, 0xfe, 0xa1, 0x0b, 0x5b,
|
||||
0xd6, 0xd2, 0x54, 0x6e, 0xb5, 0x33, 0xd5, 0xca, 0x41, 0x71, 0x70, 0x50, 0x7c, 0xb4, 0xc5, 0xe2,
|
||||
0x87, 0x7c, 0xed, 0xb1, 0x58, 0x50, 0x07, 0xb8, 0xe6, 0x37, 0x76, 0x18, 0xb4, 0x5f, 0x92, 0xea,
|
||||
0x53, 0x66, 0xe8, 0xd4, 0x1e, 0x83, 0x18, 0x7b, 0xdc, 0x0e, 0x55, 0xd1, 0x1d, 0x23, 0x1e, 0x86,
|
||||
0xbf, 0x4a, 0x12, 0x46, 0xe9, 0x18, 0xb2, 0x52, 0x27, 0xbf, 0xd0, 0xc7, 0xc2, 0x64, 0x16, 0x28,
|
||||
0x2f, 0x60, 0xc1, 0xc0, 0x03, 0x21, 0x0d, 0x2b, 0xbc, 0xf2, 0xf8, 0xa1, 0xbc, 0x47, 0x21, 0x6b,
|
||||
0x7b, 0xe0, 0x9d, 0x4d, 0x76, 0x9d, 0xdd, 0xac, 0x6f, 0x9c, 0x76, 0x10, 0x93, 0xd6, 0x89, 0x29,
|
||||
0xf3, 0x54, 0x20, 0xaa, 0xba, 0x90, 0xd9, 0x31, 0x4f, 0xdd, 0xb3, 0xac, 0x5f, 0x49, 0x21, 0x1f,
|
||||
0x49, 0x9b, 0x8f, 0xda, 0xf0, 0xfa, 0xb2, 0x64, 0x03, 0x61, 0x75, 0x73, 0x22, 0x9f, 0x32, 0xe8,
|
||||
0x27, 0x53, 0x88, 0xaf, 0x70, 0xf0, 0x15, 0x21, 0x24, 0x96, 0xeb, 0x7a, 0x05, 0x38, 0xa4, 0x66,
|
||||
0x26, 0x05, 0x8e, 0x1c, 0x2f, 0x03, 0xb6, 0x95, 0x0f, 0x8c, 0xcf, 0x14, 0xdf, 0x87, 0xa8, 0x17,
|
||||
0x33, 0xb5, 0x97, 0x2a, 0xf8, 0xbc, 0x83, 0x00, 0x7e, 0xbc, 0x41, 0x59, 0x9f, 0x31, 0xf5, 0x73,
|
||||
0x00, 0xbb, 0x68, 0x33, 0x51, 0x51, 0x54, 0xb2, 0x10, 0xed, 0x64, 0x21, 0x92, 0x2c, 0x94, 0xef,
|
||||
0xbf, 0x90, 0x85, 0x68, 0x1b, 0x0b, 0x48, 0x38, 0xe4, 0x13, 0x78, 0x67, 0x2f, 0xe9, 0x8f, 0x76,
|
||||
0x94, 0x3f, 0x4e, 0x59, 0xfe, 0xa8, 0xa8, 0x85, 0x1c, 0x73, 0x55, 0x9a, 0x1e, 0xb2, 0xa0, 0x98,
|
||||
0xb9, 0x85, 0xbc, 0xa7, 0xc9, 0x01, 0xa2, 0x84, 0xbe, 0x16, 0x07, 0x15, 0x41, 0x78, 0xaf, 0xb2,
|
||||
0x5d, 0xd5, 0xaa, 0x07, 0x85, 0xa8, 0x12, 0xa0, 0xf3, 0x79, 0x60, 0x18, 0x95, 0x01, 0x50, 0x30,
|
||||
0x00, 0x3a, 0x42, 0x75, 0x2a, 0x15, 0x1f, 0x32, 0x5c, 0xdf, 0xaa, 0xc2, 0x2f, 0x8e, 0xa0, 0x47,
|
||||
0x46, 0x5f, 0xaf, 0xd4, 0x0f, 0x6f, 0x4b, 0x95, 0xaf, 0x57, 0x63, 0x7b, 0xde, 0x8d, 0x95, 0x43,
|
||||
0xc6, 0xfc, 0xea, 0x87, 0x65, 0xd5, 0x81, 0x95, 0x6c, 0xd1, 0x05, 0x1f, 0xfc, 0xa3, 0xe7, 0xba,
|
||||
0xab, 0xbf, 0xd9, 0xe4, 0x56, 0x5e, 0xb7, 0x2e, 0x11, 0x4e, 0xbe, 0xee, 0xad, 0xc3, 0x62, 0xed,
|
||||
0x5b, 0x7f, 0xf9, 0x8d, 0xaf, 0x7d, 0xfc, 0xf2, 0xac, 0x0d, 0x5c, 0x98, 0x84, 0xfb, 0x10, 0xa7,
|
||||
0x83, 0x5c, 0x27, 0xe7, 0xae, 0xdd, 0xf1, 0xb7, 0xdd, 0x2b, 0x7d, 0x98, 0x81, 0xf3, 0x0c, 0x6e,
|
||||
0x77, 0xd5, 0xeb, 0x71, 0xa9, 0x7c, 0x65, 0xdd, 0x96, 0x46, 0xaa, 0x6e, 0xc6, 0x36, 0xde, 0x2f,
|
||||
0x82, 0xb6, 0x95, 0x46, 0x1b, 0x04, 0xd9, 0x4f, 0x49, 0xeb, 0xfa, 0x68, 0x10, 0xe9, 0x75, 0xd5,
|
||||
0xf3, 0xb9, 0x73, 0x3c, 0x7f, 0x1b, 0xf2, 0x3d, 0x86, 0xcd, 0x5f, 0x06, 0x32, 0x25, 0x7b, 0xfd,
|
||||
0xba, 0x39, 0x29, 0xc2, 0xfb, 0xed, 0xd6, 0xfd, 0x54, 0xd8, 0xbe, 0xcb, 0x6a, 0x2c, 0x4a, 0x1b,
|
||||
0xa3, 0xa1, 0x05, 0x11, 0xaa, 0xd9, 0x51, 0xab, 0xc2, 0xd5, 0x55, 0x90, 0x62, 0x05, 0x71, 0xe3,
|
||||
0xe6, 0xe8, 0x8d, 0xbc, 0x15, 0xbd, 0x4e, 0xe2, 0x7f, 0x36, 0xaf, 0x53, 0x6f, 0xde, 0xac, 0x0f,
|
||||
0x47, 0x98, 0x92, 0xd3, 0x5d, 0x07, 0x46, 0x7d, 0xc5, 0xb7, 0x89, 0x18, 0x8d, 0xa5, 0x86, 0x57,
|
||||
0x57, 0xa3, 0x6e, 0x6c, 0xd2, 0x1a, 0x68, 0xd4, 0x79, 0x1b, 0xc3, 0x8d, 0x32, 0xd6, 0x77, 0x11,
|
||||
0x34, 0x54, 0x19, 0x67, 0x2d, 0xcf, 0x9a, 0xd4, 0x42, 0x8f, 0xb1, 0x47, 0xad, 0x6d, 0xc5, 0xc4,
|
||||
0xd2, 0xc3, 0x1a, 0x96, 0xd5, 0x32, 0x0a, 0xb1, 0xcd, 0x22, 0x20, 0xaf, 0xaa, 0xb2, 0xaa, 0xad,
|
||||
0x46, 0x21, 0x94, 0x45, 0x30, 0xf9, 0x98, 0x40, 0x7d, 0x28, 0xdd, 0x67, 0x01, 0x68, 0xfe, 0x25,
|
||||
0x3b, 0xa3, 0x0f, 0xa6, 0xea, 0xb6, 0x85, 0xd4, 0x78, 0xf9, 0xb3, 0x7f, 0x63, 0x29, 0xad, 0x96,
|
||||
0x2f, 0x31, 0xb8, 0xcd, 0xaa, 0x93, 0x54, 0x11, 0x71, 0x06, 0x92, 0x75, 0x6d, 0xb7, 0xbe, 0xc7,
|
||||
0x15, 0x2a, 0x48, 0x5b, 0x6c, 0xbe, 0x0e, 0x54, 0x26, 0x1d, 0x8d, 0xbc, 0x1e, 0xa4, 0x60, 0xa3,
|
||||
0xa3, 0x27, 0xde, 0x7c, 0xb0, 0xa0, 0x4f, 0x37, 0x48, 0x96, 0xe1, 0x1a, 0x58, 0x37, 0x04, 0x37,
|
||||
0x67, 0xf6, 0x3a, 0xac, 0xcc, 0xf5, 0xf6, 0xd8, 0xaa, 0x3a, 0xc8, 0x94, 0xab, 0xef, 0x3a, 0x40,
|
||||
0xe2, 0x91, 0xff, 0x19, 0x20, 0x38, 0x49, 0x26, 0x7f, 0xd2, 0x12, 0xac, 0x71, 0xa3, 0xba, 0xf3,
|
||||
0xe6, 0xbb, 0xf1, 0xbc, 0x45, 0x3f, 0x65, 0x71, 0xf5, 0x2f, 0x3e, 0xf3, 0xd8, 0xa8, 0xb7, 0xd4,
|
||||
0xff, 0x5f, 0x8d, 0xae, 0xfa, 0x5f, 0x63, 0xfe, 0x17, 0x66, 0xba, 0xb1, 0x98, 0x32, 0x33, 0x00,
|
||||
0x00
|
||||
};
|
1145
wled00/html_other.h
1145
wled00/html_other.h
File diff suppressed because it is too large
Load Diff
@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Binary array for the Web UI.
|
||||
* gzip is used for smaller size and improved speeds.
|
||||
*
|
||||
* Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
|
||||
* to find out how to easily modify the web UI source!
|
||||
*/
|
||||
|
||||
// Autogenerated from wled00/data/pixart/pixart.htm, do not edit!!
|
||||
const uint16_t PAGE_pixart_L = 8364;
|
||||
const uint8_t PAGE_pixart[] PROGMEM = {
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xd5, 0x3c, 0x6b, 0x7b, 0xda, 0x38,
|
||||
0xb3, 0xdf, 0xf3, 0x2b, 0x54, 0x77, 0xb7, 0xc5, 0x8b, 0x31, 0xb6, 0xb9, 0x06, 0xe2, 0xf4, 0x21,
|
||||
0xe4, 0x42, 0xb6, 0xb9, 0x93, 0xa4, 0x4d, 0xf3, 0xe6, 0xe9, 0x1a, 0x2c, 0xb0, 0x13, 0x63, 0x53,
|
||||
0xdb, 0x40, 0x08, 0xe5, 0xbf, 0x9f, 0x19, 0xc9, 0x06, 0x73, 0x49, 0x93, 0xf6, 0x74, 0xdf, 0xf3,
|
||||
0x9c, 0xed, 0x06, 0xdb, 0xd2, 0x48, 0x1a, 0xcd, 0x8c, 0xe6, 0x26, 0xd9, 0x5b, 0x6f, 0x76, 0x4f,
|
||||
0xeb, 0x97, 0x37, 0x67, 0x7b, 0xc4, 0x0a, 0x7b, 0xce, 0x36, 0xd9, 0x8a, 0x2f, 0xd4, 0x30, 0xe1,
|
||||
0xd2, 0xa3, 0xa1, 0x01, 0x35, 0x61, 0x3f, 0x43, 0xbf, 0x0d, 0xec, 0xa1, 0x2e, 0xd4, 0x8d, 0xb6,
|
||||
0x45, 0x33, 0x75, 0xcf, 0x0d, 0x7d, 0xcf, 0x11, 0xc8, 0x46, 0x1b, 0xee, 0xa8, 0x1b, 0xea, 0x82,
|
||||
0xeb, 0x65, 0xda, 0x58, 0x27, 0x11, 0xb8, 0x0b, 0x42, 0xcf, 0x87, 0xbb, 0xde, 0x20, 0x08, 0x33,
|
||||
0x3e, 0x1d, 0x1a, 0x8e, 0x6d, 0x1a, 0x21, 0x15, 0xd6, 0x75, 0x78, 0xe6, 0x1b, 0xdd, 0x9e, 0xb1,
|
||||
0xae, 0xa7, 0xb5, 0xe0, 0x7b, 0x8f, 0x7d, 0xdb, 0xa7, 0x81, 0x40, 0x66, 0xe0, 0x0a, 0xc2, 0x85,
|
||||
0x76, 0xe8, 0xd0, 0xed, 0x8d, 0x4f, 0x47, 0x7b, 0xbb, 0xe4, 0xcc, 0x7e, 0xa4, 0x0e, 0xa9, 0xf9,
|
||||
0x21, 0x01, 0x34, 0x87, 0xd4, 0x0f, 0xa9, 0xbf, 0x95, 0xe5, 0x00, 0x64, 0x2b, 0x08, 0xc7, 0x08,
|
||||
0x28, 0xb7, 0xbc, 0xc7, 0x49, 0xcb, 0xf3, 0x4d, 0xea, 0x57, 0xb4, 0xfe, 0x23, 0x09, 0x3c, 0x40,
|
||||
0x91, 0xbc, 0xed, 0x74, 0x3a, 0xd3, 0x96, 0x67, 0x8e, 0x27, 0x1d, 0xe8, 0x3d, 0xd3, 0x31, 0x7a,
|
||||
0xb6, 0x33, 0xae, 0xd4, 0x7c, 0xdb, 0x70, 0xa4, 0xc0, 0x70, 0x83, 0x4c, 0x40, 0x7d, 0xbb, 0x53,
|
||||
0x6d, 0x19, 0xed, 0x87, 0xae, 0xef, 0x0d, 0x5c, 0x33, 0xd3, 0xf6, 0x1c, 0xcf, 0xaf, 0xbc, 0x55,
|
||||
0x55, 0x75, 0x2a, 0x87, 0x5e, 0x3f, 0xd3, 0x37, 0xfc, 0x70, 0x32, 0xb2, 0xcd, 0xd0, 0xaa, 0x14,
|
||||
0x15, 0xa5, 0xff, 0x58, 0xed, 0x19, 0x7e, 0xd7, 0x76, 0x2b, 0x0a, 0x31, 0x06, 0xa1, 0x37, 0x95,
|
||||
0x11, 0x6b, 0xc3, 0x76, 0xa9, 0x3f, 0xe9, 0x19, 0x8f, 0x19, 0x0e, 0xa8, 0x2a, 0xca, 0x9f, 0x24,
|
||||
0x93, 0x47, 0x68, 0x8e, 0x51, 0xc6, 0x37, 0x4c, 0x7b, 0x10, 0x54, 0x94, 0x6a, 0xdf, 0x30, 0x4d,
|
||||
0xdb, 0xed, 0x56, 0x34, 0xac, 0x0c, 0xe9, 0x63, 0x98, 0x01, 0x52, 0x76, 0xdd, 0x4a, 0x1b, 0x66,
|
||||
0x4e, 0xfd, 0xa9, 0xa5, 0x72, 0x44, 0x03, 0xfb, 0x89, 0x56, 0x34, 0x39, 0x47, 0x7b, 0xd5, 0x08,
|
||||
0x21, 0xd3, 0x34, 0xe3, 0xa1, 0x55, 0x98, 0x9e, 0x52, 0xfd, 0xe1, 0x84, 0x1c, 0xc0, 0x28, 0x63,
|
||||
0x51, 0xbb, 0x6b, 0x85, 0x15, 0xb9, 0x30, 0xb5, 0xb4, 0x44, 0xb7, 0xaa, 0xac, 0xce, 0xba, 0xf5,
|
||||
0xbb, 0x2d, 0x23, 0xa5, 0x69, 0xaa, 0x14, 0xff, 0xc9, 0x45, 0x55, 0xfc, 0xe5, 0x71, 0xd6, 0x4d,
|
||||
0x28, 0x97, 0x18, 0x59, 0x2e, 0xfd, 0x2b, 0x03, 0xab, 0x72, 0x7e, 0x75, 0xe4, 0x2a, 0x7b, 0xc8,
|
||||
0xd8, 0x21, 0xed, 0x05, 0x71, 0xd1, 0x3d, 0x48, 0xaf, 0xdd, 0x19, 0x67, 0x22, 0x49, 0x8b, 0x8b,
|
||||
0x4d, 0x3b, 0xe8, 0x3b, 0xc6, 0xb8, 0xd2, 0x71, 0xe8, 0xe3, 0xb4, 0x9f, 0xa4, 0xd4, 0x9c, 0xfc,
|
||||
0xa5, 0x52, 0x69, 0x69, 0xcc, 0xc2, 0x0f, 0x11, 0x9c, 0xbe, 0xed, 0xd8, 0xd4, 0x31, 0x2f, 0x8d,
|
||||
0x96, 0x43, 0x93, 0x3d, 0x92, 0x1f, 0x74, 0xf9, 0x42, 0x87, 0x41, 0xdb, 0x70, 0xe8, 0xef, 0xec,
|
||||
0xd0, 0xf4, 0x41, 0xbe, 0x9f, 0x3c, 0x97, 0x4e, 0x62, 0x0a, 0xb4, 0x1c, 0xaf, 0xfd, 0x50, 0x9d,
|
||||
0x0b, 0x71, 0x52, 0x86, 0x2b, 0x39, 0xe0, 0x8a, 0x69, 0x04, 0x16, 0x85, 0x65, 0x85, 0xd2, 0xb8,
|
||||
0x2c, 0xda, 0xab, 0x2c, 0x58, 0x10, 0xf6, 0x78, 0xdd, 0x54, 0xdb, 0x03, 0x3f, 0x00, 0x74, 0xfb,
|
||||
0x9e, 0xcd, 0x80, 0x7e, 0xc8, 0xe6, 0xc4, 0x44, 0x0b, 0xd0, 0xc7, 0x7c, 0xa2, 0x48, 0x5f, 0x87,
|
||||
0x66, 0xfa, 0x76, 0xfb, 0x01, 0x96, 0x5e, 0x8c, 0xbf, 0x0b, 0x93, 0x99, 0xca, 0x86, 0x69, 0xf4,
|
||||
0x43, 0x7b, 0x48, 0x2f, 0x77, 0x27, 0x49, 0xd6, 0x56, 0xf1, 0x27, 0x63, 0x82, 0xb2, 0x69, 0x87,
|
||||
0xb6, 0xe7, 0x56, 0x7c, 0x6f, 0xc4, 0x8b, 0x46, 0xbe, 0xd1, 0x87, 0xa6, 0x78, 0x59, 0x23, 0x35,
|
||||
0x53, 0xb9, 0x07, 0xeb, 0xbb, 0x49, 0x1d, 0x68, 0xe6, 0xf9, 0x93, 0x55, 0x55, 0xa1, 0x69, 0x5a,
|
||||
0x72, 0x91, 0x46, 0xd4, 0x52, 0xe7, 0x3a, 0x28, 0x97, 0xcb, 0x45, 0xb3, 0xcf, 0x80, 0x46, 0xa9,
|
||||
0xe4, 0x67, 0xc4, 0xc8, 0xb4, 0xbc, 0x30, 0xf4, 0x7a, 0xac, 0x24, 0xa6, 0x95, 0x42, 0xca, 0xf0,
|
||||
0x14, 0x71, 0x50, 0xc3, 0xfb, 0x25, 0x1a, 0x2c, 0x92, 0xbd, 0xd4, 0x8f, 0xe6, 0x05, 0x38, 0x8d,
|
||||
0x80, 0xe3, 0x0b, 0x13, 0x7e, 0xf5, 0x12, 0x98, 0xd3, 0xec, 0xff, 0xdb, 0x3c, 0x39, 0xc7, 0x03,
|
||||
0xda, 0xed, 0xc1, 0x44, 0x82, 0x5d, 0x7b, 0x18, 0xe9, 0xea, 0x5c, 0x71, 0x3e, 0x56, 0xc6, 0xa1,
|
||||
0x9d, 0xb0, 0x02, 0x7d, 0x4e, 0xff, 0x22, 0xb6, 0xdb, 0x1f, 0x84, 0xb7, 0xe1, 0xb8, 0x4f, 0x75,
|
||||
0xdf, 0x70, 0xbb, 0xf4, 0x6e, 0x62, 0xf4, 0xfb, 0xd4, 0x80, 0xfb, 0x36, 0x65, 0x9d, 0x55, 0x33,
|
||||
0x3d, 0xef, 0x29, 0xb3, 0x52, 0x38, 0xa2, 0xad, 0x07, 0x3b, 0x5c, 0x29, 0x4f, 0xa2, 0x34, 0x9b,
|
||||
0x59, 0x2c, 0xea, 0x30, 0x5d, 0x9c, 0x24, 0xc9, 0x33, 0x75, 0xb6, 0x42, 0xd0, 0x10, 0xfa, 0x09,
|
||||
0xc0, 0xbc, 0x00, 0xe2, 0xcb, 0x6b, 0x62, 0x0e, 0x5b, 0xc1, 0x05, 0x6d, 0xf8, 0x30, 0x06, 0xd0,
|
||||
0x01, 0x20, 0x53, 0xa1, 0x47, 0x7c, 0xa4, 0x99, 0xf4, 0xb6, 0xd5, 0x6a, 0x91, 0x82, 0xf2, 0xa7,
|
||||
0x84, 0x74, 0xc7, 0x1b, 0x71, 0x95, 0x64, 0xd3, 0x95, 0xe9, 0x56, 0x3a, 0x5e, 0x7b, 0x10, 0x4c,
|
||||
0xbc, 0x41, 0x88, 0x1d, 0x57, 0x94, 0x35, 0x10, 0x95, 0x78, 0xb2, 0x01, 0x70, 0x15, 0xbb, 0x1b,
|
||||
0xb8, 0x2e, 0x6a, 0x9d, 0x0c, 0x20, 0xdc, 0x7e, 0x98, 0x24, 0x59, 0xf6, 0x3c, 0xda, 0x0a, 0xce,
|
||||
0xf8, 0x15, 0xe8, 0x2c, 0x0f, 0x16, 0x5a, 0x83, 0x5e, 0x2b, 0x1e, 0x43, 0x45, 0x26, 0x46, 0xda,
|
||||
0xa8, 0xb8, 0x22, 0x12, 0x30, 0xe5, 0xe4, 0x88, 0x68, 0xea, 0x97, 0x11, 0x7a, 0x8e, 0x6d, 0x4b,
|
||||
0x52, 0xfa, 0x3a, 0x44, 0x51, 0x2e, 0xd8, 0xc3, 0x1a, 0x42, 0xac, 0x30, 0x97, 0xd9, 0x37, 0x45,
|
||||
0x62, 0xff, 0xc4, 0x9f, 0x1f, 0x80, 0x51, 0x21, 0x5a, 0x61, 0x4a, 0xb4, 0xbe, 0x92, 0xf2, 0xf2,
|
||||
0x2a, 0x02, 0x95, 0x16, 0x10, 0x63, 0x04, 0x9a, 0xca, 0x6c, 0x80, 0x13, 0xe8, 0x1e, 0xd4, 0x26,
|
||||
0x6f, 0xc9, 0xb4, 0x33, 0x7a, 0x55, 0x36, 0x18, 0x98, 0x48, 0x81, 0xf7, 0x6c, 0xd3, 0x74, 0x60,
|
||||
0x61, 0x75, 0x06, 0x8e, 0x73, 0x09, 0x7a, 0x7d, 0x1f, 0x8d, 0x19, 0x47, 0x17, 0xd5, 0xfc, 0xdd,
|
||||
0x33, 0xea, 0x61, 0xbd, 0x4e, 0x88, 0x97, 0xa1, 0xed, 0x32, 0xeb, 0x14, 0x84, 0xe0, 0x52, 0xe1,
|
||||
0x72, 0x7c, 0x59, 0x59, 0xc4, 0x24, 0xce, 0xaf, 0xf1, 0xa4, 0x7e, 0xc1, 0x6e, 0xac, 0x5a, 0xad,
|
||||
0xdf, 0xa5, 0x3e, 0x3b, 0xce, 0xe3, 0xe5, 0xbe, 0x63, 0xfe, 0x1e, 0xb2, 0xfc, 0x7f, 0x99, 0xf5,
|
||||
0x82, 0x36, 0x0d, 0x06, 0xad, 0x9e, 0xfd, 0x6b, 0x82, 0x01, 0x9e, 0x23, 0x38, 0x31, 0x73, 0xaf,
|
||||
0x63, 0x09, 0x5b, 0x46, 0x87, 0xd7, 0xce, 0x7b, 0xc9, 0x65, 0x06, 0x1c, 0x5b, 0x03, 0x10, 0x27,
|
||||
0xf7, 0x7f, 0xc1, 0x19, 0xc6, 0x93, 0xdf, 0x83, 0xdd, 0xa2, 0x3b, 0xff, 0x6b, 0x64, 0x5f, 0xd2,
|
||||
0x71, 0x91, 0x5f, 0x88, 0x96, 0xef, 0xa5, 0xfe, 0xd6, 0xaf, 0x71, 0x5c, 0xcf, 0xa0, 0x54, 0x8c,
|
||||
0x49, 0xd7, 0xb7, 0xcd, 0x0c, 0x13, 0x88, 0xac, 0x96, 0x9c, 0x6f, 0x2c, 0x8e, 0x2c, 0xfa, 0xf9,
|
||||
0x19, 0x32, 0x26, 0xd8, 0x20, 0x5b, 0xa0, 0xdd, 0x97, 0xdc, 0xb4, 0x60, 0x08, 0x14, 0x86, 0xb9,
|
||||
0x4d, 0xd6, 0xe3, 0xf5, 0xd6, 0xee, 0x19, 0xa0, 0x0a, 0xe7, 0xf1, 0x55, 0xdc, 0x1a, 0xf1, 0xac,
|
||||
0x32, 0x64, 0x61, 0x72, 0x50, 0x12, 0x52, 0xc4, 0x3a, 0xa8, 0xa8, 0x1d, 0x9f, 0xc0, 0xdf, 0xf4,
|
||||
0x2d, 0xe7, 0xf8, 0x9a, 0x96, 0x8c, 0x30, 0x31, 0x73, 0x23, 0x35, 0xa3, 0x2a, 0x09, 0x47, 0x01,
|
||||
0x35, 0x11, 0x16, 0x4c, 0x65, 0xde, 0x47, 0xdb, 0x31, 0x82, 0x60, 0x82, 0xcd, 0xe6, 0xf6, 0x9d,
|
||||
0x01, 0x15, 0xfa, 0x2b, 0x1d, 0xa1, 0x7f, 0x21, 0x77, 0x8d, 0xfe, 0x24, 0x26, 0x1d, 0x3c, 0xbf,
|
||||
0xe5, 0xab, 0x22, 0x8a, 0x5a, 0x2b, 0x95, 0x16, 0xed, 0x40, 0x18, 0x3d, 0x89, 0x19, 0x2a, 0x08,
|
||||
0x33, 0x19, 0x88, 0x94, 0x00, 0x77, 0xc0, 0x13, 0x44, 0x66, 0x44, 0xa8, 0x0c, 0x7c, 0x27, 0xf5,
|
||||
0x1e, 0x02, 0x6e, 0xa3, 0xc2, 0x9e, 0xb3, 0x40, 0xba, 0xf4, 0x63, 0xcf, 0xa9, 0x0e, 0xc2, 0x4e,
|
||||
0x59, 0x82, 0x10, 0x78, 0xd8, 0x25, 0x2c, 0x0c, 0xd6, 0x85, 0x48, 0xa5, 0x2f, 0x29, 0x4f, 0x81,
|
||||
0x0c, 0x6d, 0x3a, 0xda, 0xf1, 0x1e, 0x21, 0xb8, 0x26, 0x0a, 0xd1, 0xf2, 0xf0, 0xbf, 0x40, 0xb6,
|
||||
0xfa, 0x46, 0x68, 0x11, 0xf0, 0xa3, 0x1d, 0x5d, 0x00, 0xa1, 0x42, 0xc3, 0x52, 0x47, 0x96, 0x09,
|
||||
0xc4, 0xd4, 0x85, 0x63, 0x55, 0x93, 0x8a, 0xd7, 0x9b, 0x47, 0x6a, 0x51, 0x2a, 0x1c, 0xc1, 0xbd,
|
||||
0x7a, 0x9d, 0xaf, 0x95, 0xa5, 0x32, 0xb4, 0x06, 0x8b, 0x46, 0xf2, 0x92, 0xaa, 0xd5, 0xe1, 0x27,
|
||||
0x27, 0x17, 0x4a, 0x24, 0x2f, 0xe7, 0x8b, 0x92, 0x5a, 0x90, 0x15, 0x70, 0x43, 0x64, 0x0d, 0x4a,
|
||||
0x8b, 0xb2, 0x56, 0x3c, 0x2a, 0xca, 0x25, 0x49, 0xcd, 0xcb, 0xe5, 0x3a, 0x3c, 0x15, 0x10, 0x72,
|
||||
0xb3, 0x44, 0x00, 0x2c, 0x87, 0x3f, 0x5a, 0xad, 0x28, 0x15, 0x59, 0x57, 0x2a, 0xc1, 0x71, 0x8e,
|
||||
0xd5, 0xb2, 0x5c, 0x2a, 0x4a, 0x25, 0xb9, 0x94, 0x3f, 0x52, 0x4b, 0x72, 0x4e, 0xda, 0x94, 0xb5,
|
||||
0xba, 0x8a, 0x8f, 0x92, 0xaa, 0xc8, 0x4a, 0x9e, 0xa8, 0x65, 0x49, 0x55, 0xd9, 0xef, 0x52, 0x53,
|
||||
0xb5, 0x7c, 0xad, 0x16, 0x8e, 0xa0, 0x7c, 0x13, 0x91, 0xd4, 0x72, 0xd7, 0x9a, 0x92, 0x40, 0x53,
|
||||
0x53, 0x10, 0x4f, 0xfc, 0x55, 0xe4, 0x7c, 0x8e, 0xa8, 0x9b, 0x72, 0x21, 0x2f, 0x95, 0x11, 0x93,
|
||||
0xf9, 0x80, 0x5f, 0x04, 0x92, 0xdd, 0xde, 0x42, 0x92, 0x6e, 0xbf, 0x17, 0xab, 0x09, 0xef, 0x31,
|
||||
0xa2, 0x1f, 0xde, 0x03, 0x23, 0x61, 0xfd, 0xc2, 0x1a, 0x23, 0x7f, 0x4d, 0xd6, 0x71, 0x0c, 0x84,
|
||||
0x19, 0xea, 0x0f, 0x51, 0x1b, 0x32, 0x4b, 0x19, 0x44, 0x42, 0x50, 0xf8, 0xd9, 0x25, 0xf3, 0x1a,
|
||||
0x53, 0x99, 0xf9, 0xb1, 0x8d, 0x28, 0xfd, 0x84, 0x3e, 0x5a, 0xb4, 0x12, 0x53, 0x03, 0xbd, 0xcd,
|
||||
0x87, 0xc9, 0x8f, 0x22, 0xf4, 0x1f, 0x7a, 0xb1, 0x2c, 0x02, 0x34, 0x69, 0xdb, 0xf3, 0x0d, 0x16,
|
||||
0x61, 0xb1, 0x75, 0x6e, 0x54, 0x86, 0x76, 0x00, 0x7a, 0xc8, 0xfc, 0xed, 0xfd, 0x5a, 0x1e, 0xac,
|
||||
0xaa, 0x49, 0xd2, 0xca, 0xfd, 0x42, 0x27, 0x46, 0x1b, 0xc3, 0x9e, 0xdf, 0x8c, 0xdb, 0x06, 0xc8,
|
||||
0x13, 0x4b, 0x4b, 0x91, 0x2d, 0xa4, 0x28, 0xf1, 0x29, 0x2c, 0xb1, 0xc0, 0xf2, 0xfc, 0xb0, 0x3d,
|
||||
0x08, 0x09, 0x2a, 0x3d, 0x81, 0x6c, 0x58, 0x3e, 0xed, 0xe8, 0x42, 0x62, 0x55, 0xf7, 0xdd, 0x2e,
|
||||
0x8c, 0x15, 0xd0, 0x62, 0x5e, 0xb2, 0xaf, 0x77, 0x4e, 0x2f, 0x46, 0xca, 0xc7, 0x83, 0xae, 0x57,
|
||||
0x83, 0xff, 0x4e, 0x9a, 0x57, 0xd6, 0xde, 0x55, 0x17, 0xee, 0x76, 0xf0, 0xb1, 0x76, 0x5e, 0xaf,
|
||||
0xdd, 0xe0, 0xb5, 0x53, 0xce, 0x6e, 0x5a, 0xac, 0xe4, 0xf3, 0x49, 0xf3, 0x42, 0x39, 0xac, 0xf9,
|
||||
0x41, 0xbe, 0x5d, 0x3c, 0x87, 0xe7, 0x87, 0x93, 0xbf, 0x2f, 0xf6, 0xf6, 0xaf, 0x4e, 0xf7, 0xd2,
|
||||
0xce, 0x55, 0x10, 0x9e, 0x6a, 0x6a, 0xed, 0xca, 0x6d, 0x9c, 0x04, 0xfb, 0xca, 0x75, 0x5a, 0xd9,
|
||||
0xfb, 0x7c, 0x6d, 0x0f, 0x6b, 0x9f, 0x3b, 0x35, 0x5a, 0xfa, 0xe6, 0x1c, 0x95, 0xf6, 0xbe, 0xec,
|
||||
0xb5, 0xcf, 0x0b, 0xed, 0xf3, 0xb2, 0x5b, 0x3f, 0xac, 0xb7, 0x76, 0xff, 0xde, 0x2f, 0x5d, 0xfa,
|
||||
0x43, 0xcb, 0x08, 0x8a, 0x37, 0xad, 0xf1, 0xae, 0xb9, 0x33, 0xd0, 0xac, 0xe6, 0x43, 0xe9, 0xc1,
|
||||
0xb6, 0x82, 0xf6, 0x47, 0xb5, 0x73, 0xb5, 0xa9, 0x36, 0x2e, 0x3e, 0x7e, 0x34, 0xf6, 0x3b, 0xea,
|
||||
0xa3, 0xe5, 0x9f, 0x95, 0xe9, 0xfd, 0xb1, 0x5b, 0x6f, 0x94, 0x0b, 0xca, 0x59, 0x36, 0x3d, 0xcc,
|
||||
0xb6, 0xeb, 0xda, 0xb7, 0xf6, 0xb7, 0x51, 0xbe, 0x1b, 0x1c, 0xec, 0xe6, 0x1a, 0x0f, 0xd9, 0x03,
|
||||
0x2d, 0x97, 0x6e, 0x0d, 0x9b, 0xe6, 0xa8, 0xe4, 0x3e, 0xa8, 0x1f, 0xcb, 0xe5, 0xd2, 0x0e, 0xad,
|
||||
0x9f, 0xe7, 0x6b, 0x07, 0xc7, 0x35, 0x7b, 0xef, 0xbe, 0x7d, 0x60, 0xec, 0x94, 0xba, 0xae, 0xb9,
|
||||
0xd7, 0xb1, 0x2e, 0xbe, 0x99, 0x17, 0xe7, 0xcd, 0xfa, 0xa6, 0xdb, 0x3e, 0xb7, 0x1f, 0x6a, 0xd7,
|
||||
0x76, 0x50, 0xfb, 0x74, 0xb0, 0xb3, 0xdf, 0xed, 0x5e, 0x14, 0xce, 0x87, 0xe7, 0xa5, 0xab, 0xf6,
|
||||
0xe5, 0x89, 0xb9, 0xd9, 0x3b, 0x1a, 0xee, 0x9a, 0x75, 0xad, 0xaf, 0xf9, 0xd6, 0xe1, 0x89, 0x76,
|
||||
0x90, 0xbf, 0xca, 0x0e, 0x2f, 0x5a, 0x2e, 0x1d, 0x8f, 0xdd, 0x27, 0xab, 0x1f, 0x94, 0x14, 0xaf,
|
||||
0x76, 0xe6, 0x58, 0x27, 0x67, 0x47, 0xf7, 0x5f, 0x5c, 0x43, 0x1d, 0xe6, 0xb3, 0x8f, 0xd7, 0xbd,
|
||||
0xf0, 0xbc, 0x71, 0x55, 0x0e, 0x9f, 0xce, 0x3f, 0x9f, 0xe6, 0xea, 0xf5, 0x87, 0xbc, 0xeb, 0x9f,
|
||||
0xed, 0x96, 0x8f, 0x8f, 0x4e, 0xd2, 0xc5, 0x6f, 0x66, 0x99, 0x76, 0xca, 0xd4, 0x1f, 0xed, 0x7c,
|
||||
0x1c, 0x36, 0x4a, 0x05, 0xe5, 0xf3, 0x47, 0xf5, 0xf3, 0x38, 0xef, 0xd8, 0x9b, 0xd9, 0xce, 0xf9,
|
||||
0xbe, 0x3f, 0xda, 0x3c, 0xab, 0x1d, 0x34, 0x77, 0xbb, 0x65, 0xe3, 0x69, 0x30, 0xfa, 0x7b, 0xf7,
|
||||
0xa4, 0x78, 0xdf, 0x1a, 0xd0, 0x7e, 0xc9, 0x48, 0x1f, 0xec, 0xef, 0xe7, 0xe8, 0xd3, 0x89, 0x42,
|
||||
0xdd, 0x42, 0x67, 0xf7, 0x5b, 0xf9, 0xbc, 0xe3, 0xa6, 0xaf, 0xbe, 0x5d, 0x77, 0xef, 0xad, 0x4f,
|
||||
0x85, 0x16, 0x3d, 0xeb, 0x8f, 0xea, 0x1f, 0x47, 0x57, 0x8d, 0xfb, 0xa2, 0xa1, 0xd5, 0xea, 0x37,
|
||||
0xa5, 0x27, 0xbf, 0x6e, 0xd6, 0xeb, 0xb9, 0xfc, 0xd5, 0xbd, 0xff, 0x34, 0x08, 0xef, 0x8f, 0xbe,
|
||||
0xd8, 0xe7, 0xf5, 0xec, 0x83, 0xa5, 0x34, 0x9c, 0xf1, 0xd9, 0x78, 0xb0, 0x19, 0x7e, 0x7c, 0x3a,
|
||||
0xce, 0xdb, 0x07, 0x67, 0x9d, 0xd2, 0xe0, 0xa0, 0x10, 0xec, 0xee, 0x8d, 0x3e, 0xf5, 0x6f, 0x3e,
|
||||
0x0d, 0x7d, 0xab, 0x5c, 0xb8, 0xf8, 0x72, 0x03, 0xdc, 0x3d, 0xec, 0x97, 0xd2, 0x9f, 0x8d, 0xf1,
|
||||
0x49, 0xf8, 0x6d, 0x1c, 0x7e, 0xa6, 0x47, 0xdf, 0x3e, 0xb5, 0xee, 0xaf, 0xae, 0x4e, 0xda, 0x47,
|
||||
0xf5, 0x74, 0x67, 0x70, 0xa0, 0xf5, 0xfa, 0x47, 0x83, 0x52, 0x78, 0xe6, 0x14, 0x82, 0x2f, 0xbb,
|
||||
0x35, 0xb7, 0x7f, 0xf4, 0xa0, 0xf4, 0x9e, 0xf6, 0x77, 0x6d, 0x3f, 0xbd, 0xb3, 0xff, 0xb7, 0xf3,
|
||||
0x50, 0xdf, 0xab, 0x1b, 0x1f, 0xf7, 0x07, 0xcd, 0x9d, 0x9b, 0xa6, 0x53, 0xcb, 0xf7, 0x8f, 0x3e,
|
||||
0x85, 0xf6, 0xc5, 0xfd, 0xde, 0xb8, 0x7b, 0x38, 0xde, 0xf3, 0xf7, 0x9f, 0xc6, 0x87, 0x1f, 0xef,
|
||||
0x7d, 0x7a, 0x73, 0xe9, 0xb4, 0xbe, 0x7c, 0xec, 0x1a, 0x0d, 0xff, 0xc2, 0x79, 0xf2, 0x1a, 0x5e,
|
||||
0x38, 0xa2, 0x9f, 0x69, 0xcd, 0xda, 0xb3, 0x0e, 0x1f, 0xcf, 0x76, 0x2e, 0x77, 0x77, 0xac, 0xf3,
|
||||
0x9b, 0xee, 0xde, 0x8d, 0x75, 0xd2, 0x1a, 0xb7, 0x0e, 0x4f, 0xac, 0xc7, 0x1b, 0x35, 0x68, 0x35,
|
||||
0x47, 0xa3, 0x87, 0x56, 0xe3, 0xf4, 0x8b, 0xff, 0x14, 0xe4, 0xae, 0x2f, 0x7a, 0xf7, 0x3d, 0xf7,
|
||||
0xf4, 0xa1, 0xd8, 0x3a, 0x7d, 0xf0, 0xbf, 0x3d, 0x1e, 0x37, 0x2e, 0x37, 0xc7, 0xf5, 0x6f, 0xe3,
|
||||
0xc7, 0x93, 0x71, 0xab, 0xb6, 0x7f, 0xdc, 0x55, 0x7b, 0x9f, 0x2e, 0x76, 0x0e, 0x6e, 0x9c, 0xae,
|
||||
0x46, 0x5b, 0xde, 0x69, 0x73, 0xff, 0xc0, 0xbc, 0x4c, 0x1f, 0x8e, 0x8e, 0x73, 0x7b, 0xb6, 0x53,
|
||||
0x7c, 0xda, 0x19, 0x7d, 0xfe, 0xb2, 0xaf, 0x3e, 0x3e, 0x34, 0x3f, 0x3d, 0x9c, 0x1a, 0xc5, 0x6f,
|
||||
0x61, 0xc3, 0xa1, 0x6d, 0x3a, 0x38, 0x1f, 0xd6, 0xd3, 0xdd, 0x7c, 0xff, 0xcb, 0x67, 0xdb, 0x38,
|
||||
0x0d, 0x37, 0xef, 0xc7, 0xbb, 0x2d, 0x2d, 0x7f, 0xae, 0x7d, 0xfb, 0x58, 0x2f, 0x7c, 0xbe, 0x6c,
|
||||
0x0e, 0x7d, 0xe7, 0x63, 0xee, 0x4b, 0xe3, 0xf8, 0x93, 0x92, 0x77, 0x8f, 0xcc, 0xe3, 0xb3, 0x8f,
|
||||
0xe1, 0xf9, 0xe9, 0xf1, 0x93, 0x77, 0x70, 0xf9, 0x74, 0xf6, 0x54, 0xdc, 0xbc, 0x39, 0x39, 0xd3,
|
||||
0x86, 0x76, 0x69, 0x57, 0x55, 0x3b, 0xe1, 0xf0, 0xfc, 0xd3, 0x4d, 0xfd, 0x69, 0x1c, 0x96, 0xee,
|
||||
0x3b, 0xa3, 0x53, 0x55, 0xb9, 0x3c, 0xef, 0x1e, 0x15, 0xac, 0x4b, 0xb6, 0x26, 0x6a, 0x3b, 0x7f,
|
||||
0x5f, 0x5c, 0x15, 0xf6, 0xfc, 0x87, 0xbf, 0xbb, 0xdd, 0xae, 0xae, 0x0b, 0xdb, 0x1b, 0x60, 0x3a,
|
||||
0xdb, 0xbe, 0xdd, 0x0f, 0x09, 0x73, 0x61, 0x05, 0x5c, 0xcb, 0xd9, 0x7b, 0x63, 0x68, 0xf0, 0x52,
|
||||
0x00, 0xe8, 0x0c, 0x5c, 0x96, 0x2c, 0x22, 0xdd, 0x43, 0x33, 0x45, 0xc5, 0x89, 0x4f, 0xc3, 0x81,
|
||||
0xef, 0x12, 0x53, 0xee, 0xd2, 0x70, 0xcf, 0xa1, 0x98, 0x74, 0xd8, 0x19, 0xb3, 0xaa, 0xe9, 0x0c,
|
||||
0xb4, 0xbd, 0xb7, 0x00, 0xd9, 0x06, 0xdf, 0x2a, 0xa4, 0x11, 0x30, 0x02, 0x0e, 0x0d, 0x1f, 0x0c,
|
||||
0xac, 0x09, 0x71, 0x38, 0x96, 0xa0, 0xaa, 0x60, 0xa3, 0x81, 0xae, 0xc8, 0x46, 0x39, 0x7a, 0x4c,
|
||||
0x58, 0xcf, 0x2f, 0x26, 0x98, 0x1d, 0xe6, 0x88, 0x00, 0x82, 0x51, 0x42, 0x5a, 0x88, 0x8a, 0x37,
|
||||
0x22, 0xab, 0xbf, 0xe0, 0xe0, 0xac, 0x77, 0x1b, 0xb1, 0x89, 0xa5, 0xae, 0x6f, 0xb1, 0xea, 0x2b,
|
||||
0x22, 0x34, 0x7a, 0x15, 0x1b, 0x0b, 0x6e, 0xc5, 0xb2, 0x59, 0x8c, 0xad, 0x12, 0x4b, 0x48, 0x54,
|
||||
0x8a, 0x2b, 0x7e, 0x46, 0x4e, 0x83, 0xff, 0x85, 0x6d, 0xee, 0x67, 0x6c, 0x70, 0x47, 0xe3, 0xad,
|
||||
0xa2, 0xe4, 0x20, 0x10, 0xe5, 0x3e, 0x46, 0x91, 0x68, 0x9a, 0x55, 0x1e, 0xe6, 0x1b, 0xc5, 0xa7,
|
||||
0x63, 0x15, 0xac, 0x7c, 0xde, 0xca, 0x0f, 0xcb, 0x56, 0x26, 0x0f, 0x4f, 0x65, 0xa2, 0x2a, 0xb3,
|
||||
0x27, 0x4d, 0x23, 0x45, 0x84, 0xb3, 0x32, 0xe5, 0x27, 0x21, 0xb6, 0xd6, 0x1b, 0xe4, 0xb9, 0xcd,
|
||||
0x01, 0xa4, 0xa4, 0x8a, 0xf4, 0x04, 0x1a, 0xe1, 0xb4, 0xb5, 0xed, 0x8d, 0xa8, 0x8e, 0x30, 0x4d,
|
||||
0x4b, 0x42, 0x8f, 0xb7, 0xfd, 0xbb, 0x79, 0x7a, 0x42, 0x52, 0x7d, 0xd6, 0x03, 0x90, 0x95, 0x00,
|
||||
0xf7, 0x58, 0x79, 0xcf, 0x08, 0x7d, 0xfb, 0x51, 0x84, 0x6e, 0x34, 0x68, 0xdf, 0xc7, 0xed, 0x08,
|
||||
0xcc, 0x80, 0x90, 0x0d, 0x1b, 0xb0, 0x9e, 0x27, 0x76, 0x85, 0x45, 0xaf, 0x8b, 0x79, 0xcb, 0x0c,
|
||||
0x30, 0x03, 0xa4, 0xf5, 0x06, 0x61, 0xa5, 0x03, 0x3d, 0x9b, 0x11, 0x79, 0x57, 0xd9, 0x11, 0xfa,
|
||||
0x28, 0x81, 0xa1, 0x19, 0xf7, 0xb2, 0xd6, 0x0f, 0x46, 0x40, 0xc7, 0x68, 0x01, 0x82, 0xe0, 0x3a,
|
||||
0xea, 0x82, 0x43, 0xcd, 0x26, 0x48, 0x56, 0x3f, 0xce, 0xd3, 0x09, 0xdb, 0x47, 0x14, 0x3a, 0xc0,
|
||||
0xa2, 0x0a, 0x88, 0x12, 0x83, 0xc4, 0x99, 0x87, 0x28, 0x47, 0xd0, 0x75, 0x24, 0x38, 0xf3, 0x94,
|
||||
0x28, 0xe3, 0x2c, 0x6b, 0x4c, 0x70, 0x32, 0x2b, 0xfd, 0x91, 0x8d, 0xa8, 0x49, 0x32, 0xeb, 0x89,
|
||||
0x8d, 0xbc, 0x3e, 0x93, 0xee, 0xa1, 0xe1, 0x0c, 0x28, 0xd6, 0x22, 0x85, 0x80, 0x00, 0x0c, 0x82,
|
||||
0x42, 0x4f, 0xf1, 0x9d, 0xb0, 0xad, 0xed, 0x92, 0x63, 0x56, 0x0d, 0x08, 0xf1, 0x56, 0x2b, 0xcd,
|
||||
0x7d, 0xcd, 0x11, 0xb6, 0x9b, 0xd4, 0xef, 0x03, 0x31, 0xc0, 0xd1, 0x91, 0xc0, 0x0b, 0xf5, 0x83,
|
||||
0x90, 0x80, 0x1f, 0xcf, 0xb3, 0x5b, 0xc8, 0x21, 0xcc, 0xda, 0x91, 0x77, 0x4e, 0x58, 0xcd, 0xcc,
|
||||
0xba, 0xd9, 0x58, 0xee, 0xc7, 0xd1, 0xfc, 0xe7, 0xfa, 0x61, 0xcd, 0xe3, 0x6c, 0x19, 0xc9, 0xbc,
|
||||
0xeb, 0x86, 0xd5, 0x39, 0x3a, 0xb8, 0xea, 0x18, 0xbe, 0x33, 0x5a, 0x65, 0x81, 0x1b, 0x8c, 0x25,
|
||||
0x3f, 0xc1, 0x91, 0x0d, 0xc6, 0x12, 0xf8, 0x01, 0x6a, 0xcc, 0x49, 0x75, 0x3a, 0x08, 0xc1, 0x0f,
|
||||
0x24, 0xbc, 0xb8, 0xf2, 0x4a, 0x9e, 0x6c, 0x24, 0x99, 0xb2, 0xd4, 0x23, 0x79, 0x15, 0x47, 0x46,
|
||||
0xc0, 0x4a, 0xe0, 0xde, 0x3a, 0x86, 0xcc, 0x64, 0xfd, 0x59, 0x7e, 0x80, 0xfb, 0x0f, 0x0c, 0xa9,
|
||||
0x5f, 0x5d, 0x1c, 0x25, 0x69, 0xb4, 0x08, 0x63, 0x19, 0xc2, 0x76, 0xc3, 0xeb, 0x51, 0x52, 0x0b,
|
||||
0x02, 0x1b, 0x3c, 0x53, 0x37, 0x24, 0x37, 0xb5, 0xe3, 0x44, 0x83, 0x17, 0x68, 0xba, 0xf1, 0x13,
|
||||
0x62, 0xce, 0xfc, 0xac, 0xfd, 0x25, 0xc2, 0x6e, 0xb0, 0xe8, 0x84, 0xb4, 0x3d, 0x93, 0xfe, 0x24,
|
||||
0x75, 0x63, 0xe2, 0xb2, 0xf5, 0xbb, 0xae, 0xef, 0xd7, 0x91, 0xd8, 0xa2, 0x8f, 0xcf, 0x50, 0xb8,
|
||||
0xb1, 0xf7, 0x99, 0xa4, 0xde, 0x7d, 0x1b, 0x78, 0x61, 0xb5, 0x93, 0xc7, 0x7f, 0xfc, 0x5e, 0x7c,
|
||||
0x96, 0xe0, 0xe0, 0x31, 0xc2, 0x84, 0x76, 0xf7, 0xea, 0x24, 0xa5, 0xe5, 0xf3, 0x52, 0xf4, 0x27,
|
||||
0xfe, 0x2b, 0xc4, 0x84, 0x98, 0xc2, 0xa7, 0xc0, 0x33, 0xb7, 0x3b, 0x9f, 0x5a, 0x6d, 0x56, 0xf6,
|
||||
0x4b, 0x6a, 0x63, 0x4d, 0x97, 0xaf, 0x54, 0x1c, 0xd6, 0xb8, 0x05, 0xa1, 0xfb, 0x7a, 0xc5, 0xb1,
|
||||
0xd1, 0x60, 0x95, 0x33, 0x4a, 0x2a, 0xf8, 0x8f, 0xdf, 0x43, 0x04, 0x27, 0x11, 0xb5, 0x24, 0x91,
|
||||
0x57, 0x11, 0x79, 0x23, 0x56, 0x33, 0x98, 0xec, 0x14, 0xb6, 0x2f, 0xf0, 0x42, 0x52, 0xbf, 0xd4,
|
||||
0x05, 0xce, 0x11, 0x29, 0xda, 0x64, 0xd7, 0x97, 0x98, 0xfc, 0x3c, 0xd3, 0x36, 0x7e, 0x52, 0xd1,
|
||||
0xb7, 0x98, 0xde, 0x72, 0x81, 0xc8, 0x3c, 0x59, 0x2b, 0x6c, 0xef, 0xcc, 0x4a, 0xd6, 0xb2, 0xec,
|
||||
0x87, 0x12, 0x51, 0x7d, 0x85, 0xbd, 0x67, 0xc9, 0x3c, 0xb2, 0xc1, 0x5d, 0x21, 0x4e, 0x39, 0xc6,
|
||||
0xeb, 0x15, 0x4c, 0x48, 0xcf, 0x76, 0x75, 0x41, 0x85, 0xab, 0x01, 0x86, 0x5e, 0x2b, 0x14, 0x84,
|
||||
0x98, 0xb9, 0xaa, 0x56, 0x66, 0x82, 0xd2, 0x37, 0x5c, 0xbe, 0xd6, 0xe6, 0x6d, 0xaf, 0x11, 0x42,
|
||||
0xd8, 0x06, 0x08, 0x20, 0x12, 0xd4, 0xff, 0x2e, 0x25, 0x71, 0x64, 0xf7, 0xec, 0x30, 0x26, 0xd1,
|
||||
0xc6, 0xb1, 0xf1, 0x48, 0x5c, 0x8f, 0x78, 0x1d, 0xc2, 0x2a, 0x83, 0x2c, 0x6a, 0xbd, 0xca, 0x7f,
|
||||
0x93, 0x5a, 0x2b, 0x48, 0x2d, 0x52, 0xab, 0xa0, 0x6a, 0x33, 0x6a, 0x69, 0x85, 0xe2, 0x22, 0xb5,
|
||||
0xe6, 0x6d, 0x23, 0x6a, 0x01, 0xc4, 0x33, 0xd4, 0x8a, 0x57, 0xa8, 0x65, 0x64, 0x30, 0xb5, 0x26,
|
||||
0xfc, 0x3c, 0xf5, 0x2c, 0xe3, 0x10, 0x56, 0x75, 0xa3, 0x46, 0x76, 0xe9, 0xd0, 0x6e, 0x53, 0x72,
|
||||
0xb8, 0xbb, 0x86, 0x4e, 0x1b, 0xeb, 0x35, 0x01, 0x9f, 0x7c, 0x54, 0xb5, 0xb0, 0x47, 0x20, 0x24,
|
||||
0x5c, 0x69, 0x4e, 0x10, 0x36, 0xce, 0x6c, 0x39, 0x31, 0x5f, 0xeb, 0x2b, 0xf8, 0x5a, 0x5f, 0xdb,
|
||||
0xfc, 0xc4, 0x89, 0x43, 0xfd, 0xaf, 0x8a, 0xa2, 0x0a, 0xff, 0xca, 0x0c, 0xaf, 0x16, 0xa7, 0x78,
|
||||
0xe5, 0xda, 0xdf, 0x06, 0x8b, 0x33, 0xdd, 0x78, 0x41, 0xe7, 0xbd, 0x76, 0xa6, 0x1b, 0x7c, 0xaa,
|
||||
0x38, 0x20, 0x79, 0x61, 0xaa, 0xc6, 0x6b, 0xe6, 0xfa, 0xb3, 0xea, 0xc2, 0x32, 0x4e, 0x8c, 0x1e,
|
||||
0x4d, 0x4e, 0x16, 0x9f, 0xff, 0xb5, 0x79, 0xb2, 0xc1, 0xe2, 0x89, 0xce, 0x3d, 0xf0, 0x8f, 0x76,
|
||||
0xd8, 0xb6, 0xa8, 0x2b, 0xfc, 0x8e, 0xc5, 0x0d, 0x1e, 0xc9, 0x15, 0x3a, 0x25, 0xb1, 0x78, 0x9e,
|
||||
0x65, 0x2d, 0x0f, 0x5c, 0x3b, 0x37, 0x39, 0xad, 0x0d, 0xf2, 0x3b, 0xa7, 0x15, 0x0f, 0xc9, 0xe7,
|
||||
0xf5, 0x1b, 0x3c, 0xc3, 0x10, 0xc2, 0x23, 0x0a, 0x4e, 0x06, 0xdb, 0x9c, 0x16, 0xb6, 0x2f, 0xd9,
|
||||
0x23, 0x89, 0x36, 0xab, 0x61, 0x71, 0xbc, 0xde, 0x39, 0x5c, 0x9c, 0x07, 0xdf, 0x6c, 0x8a, 0x67,
|
||||
0xe0, 0x46, 0x7a, 0xc6, 0x66, 0xb6, 0xb4, 0x9b, 0x90, 0x40, 0x25, 0x52, 0x3e, 0x4a, 0xa4, 0x7c,
|
||||
0x8a, 0xb9, 0x65, 0x4f, 0x73, 0x11, 0xc3, 0xe5, 0xc1, 0x93, 0x56, 0x7c, 0x6e, 0xd9, 0x58, 0xe0,
|
||||
0x89, 0x8d, 0xe7, 0x2d, 0x71, 0xe3, 0x7d, 0xd6, 0x3a, 0xb1, 0x19, 0x0f, 0xb1, 0x5f, 0x14, 0x83,
|
||||
0x25, 0x49, 0x99, 0x65, 0x31, 0xd2, 0x3c, 0xa8, 0x8a, 0xdb, 0xcd, 0xce, 0xb7, 0xd4, 0xb1, 0x20,
|
||||
0x9a, 0xd0, 0xac, 0x50, 0x58, 0x0a, 0x46, 0x7f, 0x21, 0xda, 0x7a, 0x9d, 0x10, 0xe2, 0xfc, 0x66,
|
||||
0x43, 0xb3, 0x49, 0xbc, 0x26, 0x16, 0x5e, 0x9f, 0x62, 0xc7, 0x2d, 0x04, 0xbb, 0xfd, 0x00, 0x9d,
|
||||
0x8d, 0x70, 0x69, 0x34, 0xb1, 0xcb, 0x94, 0x88, 0xbe, 0x12, 0xdb, 0xc4, 0x01, 0x25, 0xc1, 0x77,
|
||||
0x71, 0xe2, 0x20, 0x79, 0x5d, 0x32, 0x7e, 0x83, 0x65, 0xe3, 0x4b, 0xa4, 0xd4, 0x28, 0x19, 0x05,
|
||||
0x52, 0xc0, 0xd4, 0x36, 0x51, 0x32, 0x78, 0x37, 0x7b, 0xc2, 0x3b, 0x4b, 0x55, 0x8c, 0x44, 0x41,
|
||||
0x26, 0x51, 0x9d, 0x81, 0xa7, 0xe3, 0x12, 0x51, 0x0b, 0x46, 0x8e, 0xe4, 0x58, 0x91, 0x9a, 0xc9,
|
||||
0x65, 0xf0, 0x3e, 0x7a, 0x22, 0x4b, 0x4f, 0x24, 0xf1, 0x84, 0x35, 0x18, 0x74, 0x6f, 0xf0, 0xa8,
|
||||
0x9b, 0xbc, 0x73, 0x5b, 0x41, 0xbf, 0xca, 0x66, 0x12, 0x45, 0xd3, 0x8b, 0x3c, 0x7e, 0xc5, 0x1a,
|
||||
0x99, 0x49, 0x50, 0x94, 0x55, 0x9f, 0xc5, 0xd1, 0xc9, 0x0d, 0xa2, 0x25, 0x7d, 0x80, 0xa0, 0x9f,
|
||||
0x21, 0x94, 0x21, 0x15, 0x32, 0x5b, 0x35, 0x1c, 0x95, 0xd8, 0x14, 0xc7, 0x62, 0xb4, 0x98, 0x89,
|
||||
0x5f, 0xbb, 0x4a, 0x58, 0x5f, 0x33, 0xc3, 0x1c, 0x3b, 0x2f, 0x45, 0xcc, 0x08, 0xf1, 0x3e, 0x93,
|
||||
0xbf, 0x2b, 0x68, 0xdc, 0x80, 0x9a, 0xfd, 0x5d, 0x68, 0xdc, 0xac, 0x45, 0x23, 0x26, 0xe9, 0xc6,
|
||||
0xfa, 0x75, 0x93, 0xed, 0x47, 0x59, 0x89, 0x04, 0x62, 0x89, 0xe3, 0x50, 0x49, 0x21, 0x9e, 0x9d,
|
||||
0xf1, 0xc2, 0xb9, 0xed, 0xc2, 0x43, 0xc4, 0x33, 0x8b, 0xfa, 0xc0, 0xb8, 0x96, 0xbf, 0x0d, 0x01,
|
||||
0x15, 0x5e, 0x48, 0x1d, 0xe5, 0x14, 0xe3, 0xe5, 0x48, 0x3b, 0x18, 0x28, 0x8b, 0x09, 0xde, 0xce,
|
||||
0x14, 0x55, 0x34, 0x76, 0xac, 0x93, 0xf8, 0xb4, 0x10, 0x96, 0x4f, 0x2a, 0x89, 0xc7, 0x73, 0x6c,
|
||||
0x85, 0x3e, 0x16, 0xd2, 0x57, 0xc9, 0x05, 0xbd, 0x7c, 0x88, 0x8c, 0x69, 0xf1, 0x5e, 0x97, 0xf5,
|
||||
0xdd, 0xf7, 0x29, 0x2e, 0x32, 0x61, 0x25, 0x8b, 0x95, 0x38, 0xd4, 0x11, 0x1d, 0xcc, 0x84, 0xb1,
|
||||
0xfd, 0x76, 0x94, 0x5d, 0x67, 0x69, 0x3d, 0x3c, 0x05, 0x1b, 0x67, 0xd7, 0xe7, 0x04, 0x9e, 0x8b,
|
||||
0xa2, 0x6f, 0x8c, 0x32, 0x4b, 0x3b, 0x8e, 0xcf, 0xe2, 0x1f, 0xe3, 0xc3, 0xe0, 0x11, 0x9b, 0x1f,
|
||||
0x0c, 0x45, 0x0c, 0x27, 0xd4, 0x85, 0x0b, 0x63, 0x74, 0xc8, 0xe8, 0xce, 0x9b, 0xcc, 0xc7, 0x07,
|
||||
0x4a, 0x30, 0x8a, 0xce, 0xf0, 0x78, 0x2d, 0x0e, 0x31, 0x83, 0x39, 0xbc, 0xed, 0x76, 0xbc, 0xf5,
|
||||
0x64, 0x99, 0xab, 0xe0, 0x78, 0xa3, 0x97, 0x35, 0x43, 0xbf, 0x98, 0x25, 0x0c, 0xa0, 0xc0, 0xf4,
|
||||
0x5c, 0x67, 0x0c, 0x14, 0x88, 0xee, 0x04, 0x5c, 0xea, 0x31, 0xf0, 0x22, 0xa5, 0x98, 0x4b, 0xbf,
|
||||
0xb4, 0xbb, 0xfa, 0x2c, 0x86, 0x1c, 0x30, 0xf6, 0x6c, 0xfb, 0xe3, 0x68, 0x48, 0x5e, 0x3c, 0xb3,
|
||||
0x16, 0x89, 0x8d, 0x56, 0x44, 0x95, 0x3f, 0x26, 0x86, 0xeb, 0x1a, 0x7d, 0x75, 0x06, 0x0c, 0x0f,
|
||||
0x0c, 0x3b, 0x8e, 0x51, 0x34, 0x00, 0xb7, 0x7b, 0xae, 0xf9, 0x73, 0xfd, 0xcf, 0x67, 0x85, 0x5e,
|
||||
0x84, 0x95, 0xdb, 0x9e, 0x8d, 0x08, 0x6a, 0x2b, 0x80, 0x68, 0x4e, 0xd8, 0xbe, 0xe6, 0x37, 0x44,
|
||||
0x95, 0x15, 0xb9, 0xcc, 0x1b, 0xf0, 0xa5, 0x9e, 0x89, 0x15, 0x83, 0x11, 0xef, 0xe2, 0xe0, 0x81,
|
||||
0xe6, 0xa0, 0x92, 0xcd, 0x76, 0xed, 0xd0, 0x1a, 0xb4, 0xe4, 0xb6, 0xd7, 0xcb, 0x8e, 0xa8, 0xff,
|
||||
0x10, 0x80, 0xdb, 0xd7, 0xcb, 0x62, 0xfa, 0x25, 0xc3, 0x9c, 0x24, 0xf0, 0x91, 0x66, 0x49, 0xca,
|
||||
0x6c, 0xcb, 0xf1, 0x5a, 0x59, 0x0c, 0x96, 0xb3, 0x17, 0x7b, 0xb5, 0xdd, 0xe3, 0x3d, 0xb9, 0x87,
|
||||
0xf9, 0x1b, 0x6e, 0x91, 0x75, 0xe1, 0x6b, 0xcb, 0x31, 0xdc, 0x07, 0xd0, 0x34, 0xd4, 0xe9, 0x67,
|
||||
0x6b, 0x2d, 0xb0, 0x6f, 0x5b, 0x59, 0x03, 0x26, 0x00, 0x98, 0xce, 0x17, 0xe5, 0x12, 0x67, 0xd8,
|
||||
0x46, 0x34, 0x4f, 0x10, 0xaf, 0x97, 0x85, 0x19, 0x51, 0x12, 0x90, 0x33, 0xf9, 0x68, 0x1b, 0xee,
|
||||
0xd0, 0x08, 0xf8, 0x42, 0x43, 0x64, 0xeb, 0xec, 0x99, 0xd1, 0x9b, 0x57, 0x6d, 0xbf, 0x9c, 0x2e,
|
||||
0xf7, 0xfc, 0x14, 0xa6, 0xb7, 0xbb, 0xe0, 0x49, 0xe9, 0x98, 0x32, 0x9f, 0xf9, 0x54, 0xa2, 0x14,
|
||||
0x3c, 0x7d, 0xe6, 0x45, 0x5c, 0xfb, 0x62, 0xc1, 0xcd, 0xbc, 0xe0, 0x86, 0x15, 0x80, 0x2d, 0x98,
|
||||
0x17, 0xa1, 0x61, 0x10, 0xa5, 0xbe, 0x3f, 0xe2, 0x45, 0xf1, 0xe2, 0x07, 0xb8, 0xc3, 0xdd, 0x08,
|
||||
0x8a, 0x79, 0x3b, 0xa2, 0xf4, 0xf7, 0x51, 0x54, 0x10, 0x4b, 0xb5, 0x28, 0x85, 0xcd, 0x2e, 0x2f,
|
||||
0x5a, 0xf4, 0x70, 0x44, 0xa9, 0xe5, 0x77, 0x2d, 0x5e, 0xb3, 0x12, 0xd7, 0x42, 0xcf, 0x74, 0x86,
|
||||
0xc1, 0x92, 0x73, 0x23, 0x4a, 0xed, 0xfb, 0x56, 0x34, 0xa5, 0x15, 0x59, 0x16, 0xa5, 0x8e, 0xdf,
|
||||
0xe3, 0x95, 0x4b, 0xa9, 0x3b, 0x68, 0x76, 0x74, 0x12, 0x37, 0x5b, 0x0a, 0x0c, 0x45, 0x09, 0x43,
|
||||
0x23, 0xca, 0x6b, 0x59, 0x94, 0x84, 0x25, 0x57, 0xb3, 0x82, 0xab, 0xa8, 0xe4, 0x64, 0x56, 0xc2,
|
||||
0xbc, 0x6e, 0x51, 0x32, 0x9a, 0xbc, 0x60, 0x4d, 0x12, 0x06, 0xc6, 0xdb, 0x6f, 0x26, 0xc6, 0xdb,
|
||||
0x5f, 0x46, 0xc7, 0x69, 0x46, 0xd5, 0x2b, 0x89, 0x5f, 0x51, 0xb2, 0xd1, 0x12, 0xb1, 0xca, 0x84,
|
||||
0x52, 0xc1, 0xe2, 0xf6, 0x42, 0xf1, 0x7c, 0xe5, 0x03, 0x35, 0xe3, 0xaa, 0x15, 0xad, 0x80, 0xed,
|
||||
0x12, 0xad, 0x90, 0xb8, 0xed, 0x39, 0x7b, 0x63, 0xd7, 0x4a, 0x94, 0x46, 0xfa, 0xc8, 0x76, 0x4d,
|
||||
0x6f, 0x24, 0x71, 0x19, 0x8b, 0x78, 0x9d, 0x90, 0x3f, 0xc6, 0xb2, 0xeb, 0x65, 0x96, 0xf1, 0x00,
|
||||
0x19, 0xc9, 0x7b, 0xbd, 0x4c, 0xde, 0xb8, 0x0a, 0xd7, 0x64, 0xcd, 0xf7, 0x8d, 0xb1, 0x7e, 0x7b,
|
||||
0x27, 0xa1, 0x59, 0x42, 0xa6, 0xe9, 0x82, 0x20, 0x61, 0x88, 0x85, 0x96, 0xf4, 0xc2, 0x1b, 0x05,
|
||||
0xba, 0x29, 0x43, 0x48, 0xe8, 0x8f, 0x63, 0x32, 0xd4, 0x1c, 0x27, 0x25, 0xc8, 0x71, 0x1c, 0x06,
|
||||
0x93, 0xd0, 0x95, 0xaa, 0xbd, 0x95, 0x6c, 0x21, 0x3b, 0xd4, 0xed, 0x86, 0x56, 0xd5, 0x4e, 0xa7,
|
||||
0xc5, 0x64, 0xf9, 0xad, 0x7d, 0x27, 0xb3, 0xe5, 0x75, 0x64, 0x07, 0xa1, 0x0c, 0xbc, 0x01, 0x8e,
|
||||
0xb1, 0x3e, 0xaa, 0xb8, 0x22, 0x8c, 0x76, 0x3b, 0xf6, 0xe8, 0x74, 0xe1, 0x2d, 0xa5, 0x54, 0x90,
|
||||
0x78, 0x11, 0x06, 0x24, 0x71, 0x71, 0xa9, 0x54, 0x12, 0x40, 0xe0, 0x03, 0x78, 0x86, 0xa7, 0x76,
|
||||
0xbb, 0x2d, 0x48, 0x5d, 0x9f, 0x52, 0x37, 0xae, 0x57, 0x0a, 0xc5, 0x96, 0x62, 0x08, 0x92, 0x4f,
|
||||
0xcd, 0xb8, 0x08, 0x0a, 0x0a, 0x0a, 0xc0, 0x71, 0x3f, 0xd9, 0xeb, 0x76, 0x1d, 0x7a, 0xda, 0xe9,
|
||||
0x70, 0x8f, 0x51, 0x02, 0x8f, 0xb1, 0x56, 0x90, 0x0a, 0xf1, 0x61, 0x08, 0x3c, 0x3c, 0x31, 0x7f,
|
||||
0x2c, 0x49, 0x6a, 0xa9, 0xa1, 0x2e, 0x00, 0x2c, 0x41, 0x60, 0x0f, 0xc7, 0x00, 0x56, 0xa8, 0xe5,
|
||||
0xa4, 0x5c, 0x74, 0xe4, 0x02, 0x0f, 0x7e, 0x24, 0x1e, 0x4b, 0xd2, 0x66, 0xe2, 0x49, 0x55, 0x96,
|
||||
0x6b, 0xd5, 0xc2, 0x97, 0x45, 0xdc, 0xdc, 0xdf, 0x88, 0x9a, 0xba, 0x84, 0x9b, 0xba, 0x84, 0x9c,
|
||||
0xba, 0x88, 0x9d, 0xa6, 0xac, 0x54, 0x73, 0xf4, 0x62, 0x55, 0x91, 0x58, 0xf2, 0xcd, 0xeb, 0x03,
|
||||
0xf4, 0xc7, 0x05, 0x31, 0xb9, 0x3d, 0xf7, 0xea, 0xbd, 0x42, 0x1a, 0x32, 0x6d, 0x7f, 0x71, 0xb0,
|
||||
0xc3, 0x64, 0x31, 0xc0, 0xfd, 0xc0, 0xf5, 0xd2, 0xf8, 0xcf, 0x44, 0x00, 0xfd, 0x51, 0x09, 0xfd,
|
||||
0x01, 0x95, 0x50, 0xba, 0x85, 0xca, 0x1f, 0x13, 0xd4, 0x50, 0x32, 0x73, 0x06, 0xa7, 0x12, 0xaa,
|
||||
0x38, 0xa1, 0x32, 0x11, 0x6c, 0x13, 0x6b, 0x40, 0xa9, 0xcd, 0x2a, 0x00, 0xf4, 0xf6, 0x9f, 0xaa,
|
||||
0x03, 0xf1, 0x64, 0x08, 0x22, 0x1a, 0x62, 0x54, 0x48, 0x1f, 0x05, 0x5d, 0x47, 0x18, 0xa6, 0xfa,
|
||||
0xe5, 0x48, 0xf3, 0x7f, 0x98, 0xb5, 0xaa, 0x80, 0xe2, 0xe4, 0x77, 0x55, 0x58, 0xa7, 0x10, 0x4b,
|
||||
0x3b, 0x3a, 0x58, 0x80, 0x00, 0xdc, 0xd4, 0x30, 0x05, 0x6a, 0x8a, 0x57, 0x89, 0xac, 0x4f, 0x57,
|
||||
0x7f, 0xa3, 0x4a, 0x86, 0x9e, 0x51, 0xab, 0x86, 0x0e, 0xba, 0x4d, 0x8e, 0x73, 0xb4, 0x87, 0xae,
|
||||
0x49, 0x1f, 0xa3, 0xd6, 0x36, 0xab, 0xe1, 0xa9, 0xcf, 0xe0, 0xd6, 0xb8, 0x8b, 0xba, 0x36, 0x74,
|
||||
0xd0, 0x31, 0x6b, 0x1b, 0x78, 0xac, 0x66, 0x4d, 0x03, 0xd0, 0x59, 0x4b, 0x0d, 0x10, 0x87, 0x40,
|
||||
0x7f, 0xa3, 0x54, 0x59, 0xa2, 0x5c, 0x67, 0x10, 0xcb, 0x0d, 0xdf, 0xbd, 0x4b, 0x01, 0x88, 0x0a,
|
||||
0xfa, 0x50, 0x37, 0xd6, 0xb5, 0xf7, 0x59, 0xfb, 0x28, 0x7f, 0xab, 0x23, 0xcc, 0x72, 0x0f, 0x1f,
|
||||
0x00, 0x44, 0xad, 0xc4, 0x29, 0xe9, 0xb5, 0x20, 0x30, 0x08, 0xd0, 0x42, 0xe1, 0x54, 0x19, 0xa0,
|
||||
0xf6, 0x30, 0xf1, 0xa7, 0xad, 0xbf, 0x17, 0xde, 0x4b, 0x16, 0xfe, 0x56, 0x83, 0xef, 0xdf, 0x53,
|
||||
0xe0, 0xff, 0xdd, 0x82, 0x62, 0xd1, 0x85, 0x3b, 0x81, 0x83, 0xf6, 0x91, 0x80, 0xe0, 0x18, 0x08,
|
||||
0x6c, 0xf5, 0x77, 0xf5, 0xf6, 0x1e, 0xa8, 0xa8, 0x58, 0xa1, 0x81, 0x62, 0xc4, 0x0d, 0x64, 0x7c,
|
||||
0xe7, 0x0a, 0xa4, 0x28, 0x25, 0x68, 0xa6, 0x20, 0x4d, 0x46, 0x10, 0xfa, 0x5d, 0x80, 0x0b, 0xb6,
|
||||
0xef, 0x53, 0xd0, 0x48, 0x6e, 0xe8, 0x8c, 0x2b, 0x6f, 0x94, 0xa9, 0x28, 0x0d, 0x75, 0x97, 0x8e,
|
||||
0x08, 0xf3, 0x1e, 0xab, 0x43, 0x19, 0x5d, 0x4d, 0x2a, 0x0d, 0x65, 0x70, 0xd4, 0x3c, 0xc3, 0xd4,
|
||||
0x63, 0x99, 0x4b, 0x89, 0x13, 0x1c, 0x95, 0xea, 0x4c, 0xc9, 0xca, 0x6d, 0xcb, 0x76, 0xc0, 0x36,
|
||||
0xb8, 0xb7, 0xca, 0xdd, 0xc2, 0x3d, 0x0c, 0x5a, 0x0b, 0x43, 0xdf, 0x06, 0x6d, 0x4d, 0x53, 0xe8,
|
||||
0xaa, 0xa3, 0x61, 0x36, 0x74, 0x30, 0xcd, 0x7c, 0xb6, 0xd2, 0x18, 0xee, 0x6f, 0x22, 0xbe, 0xa4,
|
||||
0xe8, 0x1b, 0x3d, 0xa1, 0xb6, 0xbe, 0x7f, 0x37, 0xb6, 0xd4, 0xef, 0xdf, 0xc7, 0x5b, 0xaa, 0x08,
|
||||
0x44, 0x31, 0xf4, 0xa1, 0xcc, 0xdc, 0x76, 0x68, 0x32, 0x94, 0x79, 0x1c, 0x2c, 0xa5, 0xa2, 0xb2,
|
||||
0xed, 0x82, 0xaa, 0x7d, 0xff, 0x1e, 0x17, 0xe3, 0x13, 0x6f, 0xa2, 0x16, 0x01, 0x5a, 0x2d, 0x8a,
|
||||
0xa2, 0xd4, 0xe5, 0x80, 0xba, 0x01, 0x77, 0x1c, 0x4a, 0x1f, 0x23, 0xb9, 0xc0, 0x1f, 0xfe, 0xc4,
|
||||
0x82, 0x01, 0x22, 0xa4, 0x8d, 0xb4, 0x20, 0x91, 0x06, 0x8f, 0xb0, 0xe1, 0x71, 0x9c, 0x16, 0x48,
|
||||
0xaa, 0x67, 0x3c, 0x50, 0x12, 0x0c, 0x20, 0x76, 0x09, 0x2d, 0x3b, 0xc0, 0x7d, 0xda, 0xb6, 0x45,
|
||||
0x03, 0x02, 0xe1, 0xbf, 0x4f, 0xc0, 0xa2, 0x45, 0x1b, 0xb7, 0x7c, 0x3f, 0x54, 0x44, 0xcf, 0x5a,
|
||||
0x90, 0x7a, 0xb2, 0xe9, 0x47, 0xde, 0x77, 0x6a, 0xc8, 0x0e, 0x64, 0x1b, 0xd2, 0x98, 0x2b, 0xe5,
|
||||
0xa6, 0xde, 0x43, 0x92, 0xb0, 0xba, 0x5d, 0x70, 0xdf, 0x53, 0x71, 0xad, 0x8c, 0xce, 0xbc, 0x74,
|
||||
0x08, 0x4b, 0x95, 0x31, 0xf3, 0x0f, 0x5d, 0xad, 0xb2, 0xad, 0x46, 0x5d, 0xf7, 0x60, 0x22, 0x7f,
|
||||
0xe8, 0x20, 0x0f, 0xb1, 0xab, 0x33, 0x82, 0xd5, 0x37, 0xda, 0x6a, 0xc6, 0x56, 0x61, 0x94, 0xd6,
|
||||
0xf3, 0xe2, 0x04, 0x2b, 0x5a, 0x7a, 0xf3, 0x76, 0x74, 0x27, 0x3d, 0xe2, 0x25, 0xad, 0xde, 0x49,
|
||||
0x27, 0xec, 0x46, 0xbb, 0x93, 0x2e, 0xd9, 0x4d, 0x8e, 0x77, 0x4d, 0xf5, 0x51, 0x36, 0x2f, 0x85,
|
||||
0xfa, 0x31, 0x68, 0x1b, 0xb9, 0xe3, 0x78, 0xd0, 0x2b, 0xcd, 0x1a, 0x60, 0xa7, 0x75, 0x5a, 0xb5,
|
||||
0x3b, 0xa9, 0x78, 0x9f, 0x15, 0x06, 0x16, 0xab, 0xd4, 0x09, 0x20, 0x80, 0xe8, 0xa4, 0x52, 0x61,
|
||||
0xfa, 0x0f, 0xf1, 0x4f, 0x4d, 0x47, 0x34, 0xb0, 0x6c, 0xe2, 0xe8, 0xe1, 0x5f, 0x46, 0x3a, 0x65,
|
||||
0x64, 0xd4, 0x4c, 0xca, 0xc9, 0xc0, 0xbd, 0x28, 0x4e, 0x0f, 0xe5, 0xfe, 0x20, 0xb0, 0x52, 0xb7,
|
||||
0x2d, 0xe9, 0x51, 0x3a, 0x91, 0x2e, 0x25, 0x47, 0xa2, 0x52, 0x78, 0x87, 0xe5, 0x81, 0xe7, 0x87,
|
||||
0xa9, 0x14, 0x3c, 0x89, 0xfa, 0x36, 0xbd, 0x2d, 0xdc, 0x65, 0x42, 0xf8, 0xe1, 0x52, 0x7b, 0xaa,
|
||||
0xdf, 0xca, 0xb2, 0x7c, 0x78, 0x57, 0x3d, 0x5d, 0x82, 0xca, 0x23, 0x54, 0x3e, 0x82, 0xaa, 0xe1,
|
||||
0x0a, 0xd8, 0x05, 0xe5, 0x20, 0x5d, 0xe8, 0xa7, 0xd1, 0xc4, 0xa5, 0x7b, 0x5d, 0x91, 0xea, 0x48,
|
||||
0x30, 0x24, 0x0c, 0x9f, 0x99, 0x52, 0xa5, 0x5b, 0x17, 0x55, 0x0a, 0x76, 0x72, 0xc2, 0xf5, 0xd4,
|
||||
0xe9, 0x2d, 0xbd, 0x03, 0x71, 0x0b, 0x41, 0x14, 0xc1, 0xb0, 0x86, 0xb7, 0x40, 0x15, 0x0f, 0x2e,
|
||||
0x40, 0x93, 0x01, 0x5c, 0x72, 0x77, 0x7c, 0x6d, 0x75, 0x50, 0xed, 0xc0, 0x34, 0x7d, 0x11, 0x7e,
|
||||
0x76, 0xb7, 0x14, 0xa0, 0xf8, 0xae, 0x4e, 0x45, 0x09, 0x3a, 0xcb, 0xa8, 0x89, 0xae, 0x80, 0xa8,
|
||||
0x55, 0xec, 0x0a, 0xd6, 0xed, 0xbb, 0x77, 0xd8, 0x99, 0xae, 0xdb, 0x78, 0xa3, 0xc1, 0x8d, 0x07,
|
||||
0x6b, 0xb2, 0xa3, 0x03, 0x08, 0x74, 0xb9, 0xab, 0xeb, 0xb0, 0x8c, 0xdd, 0x0f, 0x02, 0x50, 0xb1,
|
||||
0xf6, 0x81, 0x82, 0x54, 0x09, 0x15, 0x41, 0xa8, 0xec, 0xe2, 0x4d, 0xba, 0x83, 0xbf, 0xe2, 0x94,
|
||||
0x91, 0x76, 0xd6, 0x20, 0xad, 0xea, 0x7a, 0xe7, 0xc7, 0x4d, 0x18, 0xe1, 0x59, 0x35, 0xa0, 0x57,
|
||||
0x43, 0xf4, 0x00, 0x47, 0x40, 0x9d, 0x71, 0x6d, 0xb0, 0xa5, 0x15, 0x0a, 0x50, 0xde, 0x47, 0xcd,
|
||||
0x21, 0x75, 0xb6, 0xe7, 0x68, 0x1b, 0xac, 0x07, 0x9b, 0xfd, 0x7a, 0x08, 0x1a, 0x88, 0x13, 0xa6,
|
||||
0x1c, 0x6f, 0x29, 0x70, 0xc8, 0xbd, 0xd3, 0x6f, 0x0d, 0xc9, 0x96, 0xbc, 0x3b, 0x54, 0xe8, 0x42,
|
||||
0x3a, 0x2a, 0x94, 0x7b, 0x46, 0x3f, 0x45, 0x81, 0x0d, 0x72, 0xe8, 0x35, 0x41, 0x1c, 0xdc, 0x6e,
|
||||
0x0a, 0x16, 0x91, 0xdc, 0x37, 0xcc, 0x26, 0x9e, 0x0f, 0x4c, 0x69, 0x92, 0xa0, 0x08, 0xa2, 0x28,
|
||||
0xdf, 0x7b, 0xb6, 0x9b, 0x12, 0x60, 0x36, 0xb5, 0xb4, 0x6e, 0xa6, 0xdb, 0xe9, 0x30, 0x6d, 0xcd,
|
||||
0x2d, 0x4d, 0x2d, 0x1d, 0x17, 0xdd, 0xa7, 0x75, 0x55, 0xba, 0xff, 0xd3, 0x01, 0xf9, 0xf9, 0xfe,
|
||||
0x9d, 0xea, 0x3a, 0x50, 0xf5, 0x43, 0xaa, 0xce, 0xc5, 0xa5, 0x26, 0x4a, 0xc8, 0x5d, 0xb1, 0x02,
|
||||
0x5d, 0x00, 0x8e, 0x8c, 0xcb, 0xd3, 0x29, 0x16, 0x2d, 0xf1, 0xb5, 0x1e, 0x0b, 0xfc, 0x8c, 0xbd,
|
||||
0xce, 0xcf, 0x1a, 0xb3, 0xc8, 0x88, 0xfd, 0x31, 0xa9, 0x83, 0x58, 0x4c, 0xef, 0xa6, 0xd3, 0x7f,
|
||||
0xaa, 0x33, 0x23, 0xc9, 0xb1, 0x71, 0x62, 0x63, 0xf4, 0x0f, 0x86, 0x11, 0x24, 0xf3, 0x99, 0x9c,
|
||||
0x9d, 0x36, 0x2f, 0x09, 0x8b, 0xb6, 0x20, 0xd8, 0xfa, 0x63, 0x82, 0x71, 0x46, 0xd4, 0x7b, 0xf6,
|
||||
0x3e, 0xf0, 0xdc, 0x6c, 0x10, 0xe2, 0x5b, 0xa9, 0x24, 0x63, 0x92, 0xf7, 0x7f, 0x4c, 0x9c, 0xe9,
|
||||
0x7b, 0x92, 0x69, 0x10, 0xa1, 0xce, 0x73, 0x81, 0x99, 0x4b, 0x30, 0xdc, 0x15, 0x62, 0xf4, 0xfb,
|
||||
0x8e, 0xdd, 0x66, 0x87, 0xf5, 0x58, 0x1b, 0xe1, 0x9f, 0x2a, 0xdd, 0x46, 0x21, 0xc3, 0x29, 0xff,
|
||||
0xc7, 0xdd, 0x3a, 0xd9, 0xfb, 0x7c, 0x49, 0xea, 0xa7, 0xc7, 0xc7, 0xb5, 0x93, 0x5d, 0x50, 0x38,
|
||||
0x03, 0x27, 0xb4, 0xfb, 0x0e, 0x25, 0x10, 0xd2, 0xf5, 0x0c, 0xd7, 0x0c, 0x88, 0xeb, 0x81, 0x69,
|
||||
0x1a, 0xf4, 0xfb, 0xb0, 0x3e, 0x40, 0xe1, 0xd8, 0x2e, 0xa9, 0x9d, 0x1d, 0x66, 0x21, 0x38, 0x09,
|
||||
0x58, 0x6a, 0x17, 0xf5, 0xce, 0xf6, 0x7f, 0x5c, 0x41, 0x1a, 0x40, 0x6f, 0xe4, 0xdd, 0x3b, 0x02,
|
||||
0x0a, 0x16, 0x3a, 0x76, 0xf0, 0xd9, 0x9d, 0x9a, 0xfa, 0x3f, 0x6f, 0xaf, 0x5c, 0xec, 0x8a, 0x25,
|
||||
0x80, 0x3b, 0xa8, 0xb8, 0x08, 0x04, 0xdd, 0xef, 0x43, 0x62, 0x38, 0x0e, 0x06, 0xe0, 0x63, 0x62,
|
||||
0x19, 0x43, 0xd4, 0x6e, 0xd0, 0x1f, 0x31, 0x69, 0x07, 0x7c, 0x69, 0x36, 0x08, 0xd3, 0x70, 0x3c,
|
||||
0x89, 0x08, 0xa3, 0x70, 0x3f, 0xc3, 0xeb, 0xf0, 0x62, 0x10, 0xa0, 0x8e, 0x0d, 0xa4, 0x60, 0x73,
|
||||
0x92, 0xc7, 0x46, 0xcf, 0xf9, 0x8f, 0xfb, 0x36, 0x43, 0xf0, 0x68, 0x34, 0x86, 0x23, 0x95, 0x18,
|
||||
0xf7, 0xaf, 0x78, 0xa6, 0xf4, 0x3f, 0x2e, 0x21, 0x6f, 0x79, 0x47, 0x34, 0xa8, 0xe0, 0x13, 0x21,
|
||||
0x7f, 0x4c, 0x58, 0x24, 0x12, 0x51, 0x92, 0x97, 0x11, 0xd2, 0xf1, 0x6d, 0x88, 0xaa, 0x9d, 0xf1,
|
||||
0x57, 0x96, 0x72, 0x67, 0x40, 0x27, 0xcb, 0x30, 0x03, 0xb6, 0xa3, 0xf2, 0xd5, 0x36, 0x79, 0xfd,
|
||||
0xd5, 0x72, 0x7d, 0x3c, 0xb2, 0xe7, 0x56, 0xc8, 0x76, 0x5c, 0x88, 0x03, 0x0e, 0x56, 0x41, 0x3a,
|
||||
0x9d, 0x05, 0x98, 0x5f, 0x60, 0x39, 0x97, 0xbf, 0x8e, 0x01, 0x4b, 0xf3, 0x95, 0xac, 0xc7, 0xd0,
|
||||
0x51, 0x4e, 0x1e, 0xa0, 0x00, 0x1d, 0xf2, 0xa1, 0x56, 0xe1, 0xe7, 0x21, 0xf0, 0x7e, 0x50, 0xc1,
|
||||
0x73, 0x0f, 0x78, 0x67, 0x56, 0x84, 0xbd, 0x8b, 0x8b, 0xd3, 0x8b, 0x37, 0x59, 0x97, 0xad, 0x60,
|
||||
0x02, 0xf6, 0xc7, 0x70, 0x81, 0x02, 0x0f, 0xae, 0x37, 0x72, 0xa3, 0x03, 0x09, 0xb2, 0x30, 0x5b,
|
||||
0x71, 0xc0, 0x7f, 0x90, 0x69, 0x81, 0x49, 0xf0, 0x57, 0x1d, 0x63, 0x2b, 0xa9, 0xc1, 0x2e, 0xd5,
|
||||
0x3e, 0x08, 0x5b, 0x27, 0xcd, 0x8c, 0xdd, 0x56, 0x6b, 0xfb, 0x53, 0xed, 0xe2, 0xe4, 0xf0, 0xe4,
|
||||
0xe0, 0xcd, 0x56, 0xb6, 0xb5, 0x4d, 0x2e, 0x67, 0x27, 0x4b, 0xdb, 0x63, 0x82, 0xf1, 0x17, 0xc8,
|
||||
0x40, 0xc8, 0xfc, 0x1a, 0x14, 0x02, 0x16, 0x49, 0xc9, 0x8b, 0x40, 0x29, 0xc3, 0xe9, 0x5b, 0x86,
|
||||
0x08, 0x62, 0x13, 0x90, 0x16, 0xc4, 0x0a, 0xc4, 0xee, 0xba, 0x1e, 0x04, 0x08, 0x00, 0xe6, 0x11,
|
||||
0xea, 0x32, 0x5b, 0x89, 0x52, 0x86, 0x3b, 0x0f, 0x20, 0x55, 0x04, 0x04, 0x15, 0x44, 0x9a, 0x0b,
|
||||
0x1e, 0x0d, 0x6c, 0x7c, 0xa9, 0x7b, 0x00, 0xa2, 0x86, 0x89, 0x9f, 0xe8, 0x20, 0x32, 0xdf, 0x39,
|
||||
0x9d, 0x09, 0x1d, 0x1f, 0x94, 0xd9, 0x52, 0x51, 0xfa, 0x2a, 0xdb, 0x2e, 0x44, 0x77, 0x8d, 0xcb,
|
||||
0xe3, 0x23, 0xbd, 0x23, 0x35, 0x16, 0x3d, 0x4d, 0x5d, 0x60, 0x87, 0xa1, 0xc1, 0x45, 0x02, 0x83,
|
||||
0xbb, 0xe3, 0x3d, 0x82, 0xe3, 0x7b, 0xc8, 0xcc, 0xe9, 0x74, 0xfa, 0x2b, 0x6e, 0xf4, 0xbc, 0x97,
|
||||
0x10, 0x6c, 0x97, 0xc1, 0xad, 0xaa, 0x1d, 0x87, 0x8b, 0xae, 0xce, 0xdd, 0xa9, 0x57, 0x3b, 0x52,
|
||||
0x55, 0x3b, 0xc2, 0x9d, 0x79, 0x14, 0x5b, 0xd1, 0x13, 0xf3, 0x36, 0x3e, 0x44, 0x5d, 0x71, 0x9f,
|
||||
0x24, 0x61, 0x8a, 0xe5, 0xcd, 0xf2, 0x5f, 0x0b, 0xcd, 0xc4, 0xca, 0x2b, 0x40, 0x59, 0x9f, 0x5c,
|
||||
0x75, 0x39, 0x49, 0x90, 0x64, 0xd3, 0x2c, 0x58, 0x0c, 0x4b, 0x4f, 0x25, 0x5b, 0x64, 0xe8, 0x5f,
|
||||
0x8e, 0x98, 0xd5, 0xaa, 0x11, 0x58, 0xe4, 0x16, 0x39, 0x60, 0xd9, 0x55, 0x65, 0xa6, 0x7d, 0x79,
|
||||
0x3c, 0x6a, 0xb0, 0xe8, 0x33, 0x2e, 0x33, 0xa0, 0xcc, 0xd8, 0x02, 0x47, 0x3a, 0x56, 0xc5, 0x16,
|
||||
0x58, 0x53, 0xfb, 0x2f, 0x9a, 0x36, 0xee, 0x24, 0x88, 0x11, 0xfd, 0x6e, 0x2b, 0x25, 0xa4, 0x2d,
|
||||
0xb0, 0x94, 0xe8, 0x50, 0xe1, 0x9d, 0x3a, 0xbb, 0xd3, 0xe0, 0x4e, 0x64, 0x3e, 0x2d, 0x42, 0xa9,
|
||||
0x1a, 0x1e, 0xb0, 0x67, 0x7f, 0xa2, 0x50, 0x75, 0x65, 0x74, 0x10, 0x9b, 0x2c, 0x8d, 0xe4, 0x4b,
|
||||
0xfc, 0xe9, 0x02, 0x64, 0x31, 0x65, 0xfc, 0xe5, 0x48, 0x36, 0xfc, 0xc1, 0x3f, 0x11, 0xca, 0x31,
|
||||
0xc9, 0xf5, 0x40, 0x39, 0x9c, 0xf0, 0xb6, 0xcc, 0xfe, 0x13, 0xa0, 0x1c, 0xb5, 0x0d, 0x9b, 0x18,
|
||||
0x98, 0x9b, 0x18, 0x6a, 0x5d, 0x7b, 0x3c, 0x8f, 0xae, 0x0b, 0xf8, 0xbe, 0x04, 0x61, 0x67, 0xd5,
|
||||
0x05, 0x29, 0x39, 0xb2, 0x09, 0x4f, 0xc8, 0xdc, 0x1a, 0xe6, 0x84, 0x75, 0x21, 0x4a, 0x0a, 0x47,
|
||||
0x85, 0x3b, 0x06, 0xb8, 0xfd, 0x30, 0x8c, 0x2e, 0x44, 0x9b, 0x0b, 0x51, 0x53, 0x0c, 0xaa, 0x53,
|
||||
0x16, 0x38, 0x2c, 0x60, 0xcf, 0x61, 0xb4, 0xb4, 0x93, 0xd5, 0x70, 0x44, 0xbc, 0xf2, 0xf3, 0x97,
|
||||
0xbe, 0xee, 0xae, 0x7a, 0x7e, 0x49, 0xfe, 0x48, 0x0b, 0x5c, 0x10, 0x81, 0x18, 0x6d, 0x87, 0x1a,
|
||||
0x3e, 0xc3, 0xff, 0x05, 0xd8, 0x85, 0x3a, 0x3d, 0xc9, 0x61, 0xc0, 0xae, 0x3f, 0x48, 0x0c, 0xea,
|
||||
0x4b, 0x96, 0xa4, 0x88, 0x3f, 0xb3, 0x38, 0x90, 0xbb, 0x26, 0x1d, 0x1e, 0x7b, 0x26, 0x85, 0x00,
|
||||
0xa3, 0x3a, 0x57, 0x86, 0x3a, 0xac, 0x3c, 0xae, 0xff, 0x71, 0x97, 0x34, 0x0a, 0xb8, 0xa0, 0xf6,
|
||||
0xcc, 0xf0, 0x8d, 0x5e, 0xc0, 0x42, 0x88, 0xab, 0x8b, 0xa3, 0x26, 0x4c, 0xa1, 0x6d, 0xf1, 0xb2,
|
||||
0x14, 0x5f, 0x48, 0xf2, 0xac, 0x61, 0xc0, 0x2a, 0xc1, 0xb3, 0x9d, 0xc7, 0xb1, 0x18, 0x57, 0xa0,
|
||||
0xc3, 0x39, 0x0b, 0x10, 0xd0, 0x50, 0xce, 0x22, 0x84, 0x6d, 0xf0, 0x1f, 0x04, 0x96, 0x57, 0xd4,
|
||||
0x75, 0x96, 0xbb, 0x5b, 0x54, 0x07, 0xe0, 0xf3, 0xcf, 0xf1, 0x8b, 0xdc, 0x05, 0x6c, 0xcf, 0x9b,
|
||||
0xbc, 0xd1, 0xfb, 0xfe, 0x68, 0xa9, 0x41, 0x14, 0xc3, 0xb0, 0x0a, 0xbf, 0x8d, 0xee, 0x91, 0x8d,
|
||||
0x89, 0x1e, 0xdb, 0xdc, 0x61, 0xc9, 0xf4, 0x03, 0x28, 0xa0, 0xa2, 0x68, 0xf7, 0xa2, 0x28, 0x68,
|
||||
0x5d, 0x9c, 0xcd, 0xb2, 0x55, 0xcf, 0xa8, 0xa5, 0xd6, 0x6a, 0x8d, 0x10, 0x39, 0xd0, 0xcc, 0x39,
|
||||
0x5b, 0xa7, 0x90, 0xf7, 0x71, 0x13, 0xc4, 0xf4, 0x28, 0xb7, 0xfb, 0xfc, 0x3d, 0x52, 0xdc, 0x25,
|
||||
0x69, 0x51, 0x62, 0x10, 0xf6, 0x19, 0x0c, 0xae, 0x20, 0x99, 0x7e, 0xac, 0xa2, 0x7a, 0x4f, 0x68,
|
||||
0xc8, 0x90, 0xa5, 0xd4, 0x9e, 0xc1, 0x66, 0x1d, 0xa2, 0x8c, 0x32, 0x49, 0x9b, 0x04, 0x4b, 0x93,
|
||||
0x73, 0xfb, 0xdd, 0x3b, 0x64, 0xa9, 0x07, 0xc0, 0x8e, 0xd7, 0x4d, 0x09, 0x97, 0xa0, 0xc9, 0x03,
|
||||
0xe6, 0x0a, 0x92, 0xf7, 0x42, 0x1a, 0x1c, 0xd4, 0xf7, 0x68, 0x8e, 0x18, 0x8a, 0x11, 0x56, 0x7c,
|
||||
0xff, 0x21, 0xd2, 0xde, 0xe0, 0x13, 0x4e, 0x81, 0x78, 0x6b, 0xd8, 0x21, 0xf2, 0x7c, 0x5c, 0xb3,
|
||||
0x2b, 0x88, 0x20, 0x00, 0x2b, 0xd1, 0xa1, 0x94, 0x08, 0x00, 0xa3, 0x60, 0xe3, 0x55, 0x0d, 0x66,
|
||||
0x59, 0x2d, 0x31, 0x8a, 0x72, 0xc2, 0x66, 0xb7, 0x4a, 0xd7, 0x4f, 0x97, 0x26, 0x28, 0x06, 0x13,
|
||||
0xc6, 0x24, 0xc5, 0x12, 0x1c, 0x4b, 0x6d, 0x4c, 0xa7, 0x46, 0x30, 0x76, 0xdb, 0x64, 0x26, 0x9e,
|
||||
0x7d, 0x10, 0x74, 0xc6, 0xff, 0x60, 0x16, 0xfd, 0x46, 0x59, 0x61, 0xd7, 0x6c, 0x0e, 0xbb, 0x67,
|
||||
0x10, 0x89, 0xd3, 0xb5, 0x28, 0xf2, 0x0c, 0x9b, 0x18, 0x25, 0x4f, 0xde, 0xa8, 0x73, 0xd7, 0x16,
|
||||
0x5d, 0xaa, 0x99, 0x0f, 0x2a, 0x86, 0xfe, 0x78, 0xb2, 0x96, 0xfc, 0x20, 0x66, 0xeb, 0xcb, 0x23,
|
||||
0xb2, 0x8a, 0xd1, 0xfa, 0x03, 0x7f, 0x7f, 0x64, 0xd8, 0x21, 0xe9, 0x50, 0xf0, 0xb6, 0x52, 0xb1,
|
||||
0x0f, 0x23, 0xa4, 0x17, 0x33, 0xe3, 0x9c, 0x23, 0x69, 0x21, 0xe9, 0xce, 0x48, 0x93, 0x1e, 0x0d,
|
||||
0x2d, 0x0f, 0x7c, 0x0e, 0x74, 0x7f, 0x04, 0x09, 0x0f, 0x86, 0x53, 0x3f, 0x00, 0xe7, 0x39, 0xe9,
|
||||
0xd1, 0x40, 0x50, 0xb2, 0xe2, 0xd2, 0x4c, 0x25, 0x3c, 0x36, 0x5e, 0xa1, 0x53, 0x50, 0xad, 0xd1,
|
||||
0xf0, 0xa1, 0x8c, 0x35, 0x29, 0xb1, 0xba, 0x16, 0x69, 0x57, 0x9c, 0xb6, 0x31, 0x8c, 0xc6, 0x24,
|
||||
0x55, 0x5c, 0x4e, 0x7d, 0x1f, 0x03, 0x51, 0x11, 0x02, 0x53, 0x30, 0x9d, 0xe1, 0x87, 0xd4, 0x7a,
|
||||
0x42, 0xc6, 0x79, 0x48, 0x4c, 0x9c, 0x87, 0x97, 0x76, 0x8f, 0x7a, 0x03, 0x88, 0x19, 0x13, 0x39,
|
||||
0x09, 0xfa, 0x2a, 0x11, 0x01, 0x54, 0x55, 0x9a, 0x13, 0xc5, 0xca, 0x33, 0xc3, 0xcc, 0x73, 0xa0,
|
||||
0xbf, 0x34, 0xd0, 0xe2, 0x20, 0xd3, 0x95, 0x45, 0xb0, 0xa5, 0x82, 0x3f, 0x96, 0xd0, 0xa4, 0xc2,
|
||||
0xb1, 0xcd, 0x92, 0xea, 0x5f, 0x1b, 0x20, 0x60, 0x3c, 0xf1, 0x8f, 0xe9, 0xdc, 0xbd, 0x21, 0xf4,
|
||||
0x85, 0xb9, 0x5d, 0x0a, 0xc2, 0x0a, 0xec, 0xc3, 0xfd, 0x52, 0x18, 0x02, 0x65, 0x32, 0x05, 0x31,
|
||||
0x72, 0x24, 0x81, 0xb0, 0x76, 0x99, 0xd4, 0x61, 0x32, 0x0a, 0x28, 0x8e, 0x22, 0xc4, 0x99, 0xe0,
|
||||
0x1a, 0x43, 0xbb, 0x6b, 0x84, 0x9e, 0x0f, 0x86, 0xc4, 0xee, 0xb7, 0x3c, 0xc3, 0x37, 0xe5, 0x91,
|
||||
0x6f, 0x87, 0x94, 0xd9, 0xaa, 0xc8, 0x6f, 0x4e, 0xb0, 0x62, 0xde, 0xd2, 0x94, 0xe9, 0x23, 0x6d,
|
||||
0xd7, 0xb9, 0x9b, 0xcc, 0xb7, 0x1f, 0x84, 0x67, 0x79, 0x26, 0xec, 0x1b, 0x36, 0x26, 0x42, 0x40,
|
||||
0x45, 0x21, 0x20, 0x41, 0x13, 0x52, 0x21, 0xb0, 0xc8, 0x40, 0x03, 0x4c, 0x59, 0xfa, 0x7f, 0xdd,
|
||||
0x5c, 0x2c, 0x76, 0x7e, 0x0d, 0x14, 0xaa, 0xcb, 0xb6, 0x65, 0x5e, 0x06, 0xf9, 0xfc, 0x12, 0x08,
|
||||
0x26, 0xec, 0x5e, 0x00, 0x31, 0x5e, 0x84, 0x60, 0xc1, 0xe3, 0x4b, 0x03, 0x1d, 0x9d, 0xbc, 0x04,
|
||||
0xc2, 0x83, 0x9b, 0x17, 0x81, 0xae, 0x5e, 0x01, 0x73, 0xf2, 0x22, 0x0c, 0x13, 0xa4, 0x97, 0xe8,
|
||||
0x07, 0x2a, 0xee, 0x05, 0x10, 0xb4, 0x81, 0xab, 0x20, 0x98, 0xf3, 0x8b, 0x00, 0x30, 0xab, 0xfb,
|
||||
0x7c, 0x1f, 0x4c, 0x22, 0x03, 0xaf, 0xcf, 0xd2, 0xc1, 0x71, 0x4e, 0x93, 0xa5, 0x86, 0x93, 0x69,
|
||||
0xd2, 0x3b, 0x69, 0x66, 0xd8, 0x75, 0x00, 0x66, 0x59, 0x2f, 0x58, 0x47, 0xf2, 0xa3, 0x34, 0xb3,
|
||||
0xf1, 0x0b, 0xe5, 0x63, 0x89, 0xb9, 0x04, 0x20, 0x47, 0x33, 0x45, 0xbb, 0xb4, 0x11, 0xf6, 0x9a,
|
||||
0x85, 0x12, 0x6d, 0x96, 0x82, 0xd3, 0xa0, 0x2f, 0xbb, 0x20, 0x7d, 0xdf, 0x0b, 0x3d, 0x88, 0x3f,
|
||||
0x3e, 0x18, 0x0e, 0xf5, 0xc1, 0x9f, 0xff, 0x04, 0xcb, 0x98, 0x87, 0x26, 0x68, 0x6f, 0x87, 0x20,
|
||||
0xda, 0xec, 0xc4, 0xd0, 0xc8, 0x82, 0x38, 0x27, 0xa0, 0xfe, 0x10, 0x04, 0x1d, 0xdf, 0x01, 0x64,
|
||||
0x3a, 0x9b, 0xa4, 0x3c, 0x9f, 0xbf, 0xbd, 0x01, 0x96, 0xd0, 0x1f, 0xb8, 0xf3, 0x9a, 0x40, 0x14,
|
||||
0xc4, 0x4a, 0xd2, 0x5a, 0x4c, 0x23, 0xd1, 0xf2, 0x5c, 0x76, 0x86, 0x41, 0x67, 0x68, 0xe1, 0x2e,
|
||||
0x13, 0x73, 0x2a, 0x23, 0x0d, 0xab, 0xcf, 0x53, 0x17, 0x91, 0x0d, 0x53, 0x15, 0xe5, 0xaf, 0x59,
|
||||
0xc2, 0x7c, 0x5e, 0x0b, 0x3e, 0x7b, 0xa1, 0xc0, 0xf2, 0x89, 0xa1, 0xfe, 0xcf, 0xf2, 0xe7, 0x3a,
|
||||
0x36, 0x15, 0x93, 0x76, 0x25, 0xc2, 0x3e, 0xd6, 0xf1, 0xc7, 0x84, 0x4e, 0xff, 0x94, 0xd8, 0x8b,
|
||||
0x9e, 0xfc, 0x5e, 0xfc, 0xa7, 0xca, 0xba, 0xe1, 0xe6, 0x6e, 0xfe, 0x9a, 0x21, 0xf3, 0x10, 0xf5,
|
||||
0x70, 0xca, 0x84, 0x7b, 0x01, 0x49, 0x8e, 0x08, 0x14, 0x57, 0xdb, 0x47, 0x8b, 0xd8, 0xd2, 0x04,
|
||||
0xaa, 0xe1, 0x22, 0xaa, 0xb1, 0x72, 0xc9, 0x16, 0x54, 0x8d, 0xe1, 0xe9, 0xbe, 0x84, 0x67, 0x98,
|
||||
0xc0, 0x33, 0x64, 0x78, 0xd2, 0x67, 0x90, 0x74, 0xa7, 0xb8, 0xf7, 0xf9, 0x92, 0x24, 0xc6, 0xc9,
|
||||
0x52, 0x9e, 0x3b, 0x5a, 0xb7, 0x9b, 0x46, 0x97, 0x77, 0xd3, 0x68, 0x72, 0x37, 0x2d, 0x64, 0x9b,
|
||||
0x47, 0xd1, 0x86, 0x9a, 0x84, 0x11, 0xf9, 0x1b, 0x9d, 0xed, 0x3e, 0xf0, 0x89, 0xc5, 0x62, 0x19,
|
||||
0x99, 0x5d, 0x3c, 0xf3, 0xf2, 0x05, 0x5c, 0x0b, 0xee, 0x0e, 0xcc, 0x4f, 0xc0, 0x88, 0x2c, 0x36,
|
||||
0x3f, 0x63, 0x67, 0x53, 0xa2, 0xdd, 0xda, 0xc4, 0x61, 0x15, 0x5c, 0x73, 0x6c, 0x87, 0x19, 0xfd,
|
||||
0xcf, 0xb9, 0x13, 0x8c, 0x2d, 0xd9, 0xd9, 0x18, 0xca, 0x5e, 0x00, 0xa3, 0x32, 0x42, 0xc1, 0x4c,
|
||||
0x77, 0x69, 0xc7, 0x80, 0x40, 0x3a, 0x95, 0xec, 0x54, 0x66, 0xb2, 0x9e, 0x4a, 0xbc, 0x0b, 0x06,
|
||||
0x31, 0x6c, 0x77, 0x0f, 0x23, 0x96, 0x67, 0xda, 0x62, 0x16, 0x7b, 0x79, 0xd7, 0x10, 0xdb, 0x64,
|
||||
0x50, 0x78, 0x85, 0xa5, 0x8e, 0x4e, 0x87, 0xcf, 0xf5, 0x93, 0x84, 0xf3, 0xc0, 0x47, 0x35, 0x5f,
|
||||
0x37, 0x9c, 0x4f, 0x7b, 0x30, 0xce, 0xc2, 0x88, 0xd5, 0x41, 0x1f, 0x3f, 0xec, 0x76, 0xc6, 0x49,
|
||||
0x01, 0xa2, 0x83, 0x6b, 0x9f, 0x25, 0x1c, 0x3a, 0x30, 0x3f, 0x9c, 0x6a, 0x00, 0x81, 0x64, 0x62,
|
||||
0xc0, 0xd9, 0xec, 0xd9, 0x98, 0xcb, 0xad, 0xf9, 0xee, 0xfb, 0xba, 0x76, 0x4b, 0x90, 0x51, 0x1a,
|
||||
0x14, 0x44, 0x17, 0x43, 0x15, 0xf4, 0xba, 0x2f, 0x98, 0xcb, 0x53, 0x0d, 0xe3, 0xad, 0x0e, 0x26,
|
||||
0x48, 0x11, 0x8b, 0x58, 0x00, 0x80, 0xf8, 0x63, 0x2e, 0x43, 0x5a, 0x09, 0x24, 0xc0, 0x8d, 0x9c,
|
||||
0x4a, 0x58, 0x6d, 0x98, 0xb5, 0x00, 0x23, 0x2d, 0x08, 0x7d, 0x16, 0x5e, 0xd1, 0x5b, 0x13, 0x56,
|
||||
0x44, 0x2f, 0xec, 0x81, 0xbb, 0x13, 0x8b, 0xcf, 0x1a, 0xa1, 0x46, 0x42, 0x45, 0x01, 0xe8, 0x8c,
|
||||
0xb3, 0xe0, 0x0b, 0xfe, 0xb8, 0x01, 0x23, 0xac, 0x14, 0x33, 0xf0, 0x05, 0x70, 0xaf, 0x2f, 0x48,
|
||||
0x11, 0x0f, 0x7f, 0x08, 0x19, 0x69, 0xd5, 0x84, 0x74, 0x2e, 0x08, 0xe2, 0xf3, 0xeb, 0x71, 0xce,
|
||||
0xaf, 0xf9, 0x1e, 0xc6, 0x7f, 0x7b, 0x43, 0x7c, 0xc6, 0x87, 0x85, 0x53, 0x91, 0xaf, 0xd9, 0xc1,
|
||||
0x92, 0x50, 0xd1, 0xad, 0xdd, 0xc5, 0x72, 0x31, 0x98, 0x0b, 0xc1, 0xa6, 0x24, 0x9c, 0xbe, 0x0f,
|
||||
0xa9, 0x50, 0x5f, 0x72, 0x36, 0x01, 0x6e, 0x69, 0xab, 0x5c, 0x5a, 0x13, 0xba, 0x46, 0xa1, 0x09,
|
||||
0x78, 0xa4, 0x61, 0xb2, 0xbf, 0xa5, 0xc6, 0xee, 0x33, 0x6d, 0x01, 0x9b, 0xf5, 0xfe, 0x68, 0xb8,
|
||||
0x5a, 0x01, 0xe6, 0xdc, 0x8d, 0xf5, 0x57, 0x32, 0xf0, 0xa6, 0x3e, 0xac, 0x8e, 0x68, 0x37, 0xfa,
|
||||
0x94, 0xdb, 0x6f, 0xe6, 0x15, 0x82, 0x09, 0x4f, 0x46, 0x4b, 0x33, 0x16, 0xb2, 0x4d, 0xe0, 0xad,
|
||||
0xd8, 0xa5, 0xad, 0x86, 0x98, 0x0a, 0xe2, 0xaa, 0x1e, 0x77, 0x1e, 0xb9, 0x07, 0x20, 0x60, 0x1a,
|
||||
0x83, 0x5b, 0x75, 0x7a, 0x1b, 0x46, 0x1b, 0x9c, 0x51, 0x26, 0x85, 0x97, 0xe0, 0x1d, 0x14, 0xcc,
|
||||
0xfc, 0x00, 0x5e, 0xfa, 0x98, 0x28, 0x1a, 0xf3, 0xa2, 0x31, 0xf7, 0x3f, 0x40, 0x4c, 0x5d, 0xb3,
|
||||
0x8e, 0xec, 0x81, 0x30, 0x42, 0x52, 0x80, 0xfa, 0x21, 0x6e, 0x98, 0xce, 0xbc, 0x0c, 0x88, 0x1e,
|
||||
0x12, 0x2e, 0x86, 0xbb, 0xd6, 0xc1, 0x48, 0xf4, 0x2d, 0xae, 0xc4, 0x78, 0x89, 0x2d, 0x79, 0x9e,
|
||||
0x8a, 0x68, 0x0f, 0xf5, 0xb9, 0xab, 0x2e, 0xb5, 0x87, 0xf3, 0x40, 0x16, 0x1d, 0x66, 0x6e, 0x63,
|
||||
0x6e, 0xef, 0x22, 0x43, 0xe0, 0x3e, 0x13, 0x7f, 0xb5, 0x87, 0x8b, 0xd1, 0x56, 0x9c, 0xab, 0x4b,
|
||||
0x45, 0xae, 0x7a, 0x14, 0x2f, 0x61, 0x80, 0xdb, 0x8d, 0x37, 0x5f, 0x52, 0x13, 0xdb, 0xac, 0x40,
|
||||
0xa8, 0x6a, 0x4a, 0x2e, 0x5c, 0x5c, 0xe9, 0x31, 0xa8, 0xa0, 0x4d, 0x34, 0xfc, 0x50, 0x7a, 0xa4,
|
||||
0xec, 0xd6, 0xeb, 0x4b, 0xe3, 0x59, 0xe1, 0x8d, 0x34, 0x8e, 0x4b, 0x6f, 0xa6, 0xa2, 0xb8, 0xc4,
|
||||
0x27, 0x27, 0xc9, 0x27, 0xca, 0x37, 0x3b, 0x26, 0x7c, 0x8f, 0xde, 0x41, 0xf2, 0xc2, 0x28, 0xcc,
|
||||
0x71, 0x67, 0x0f, 0x2e, 0x6e, 0x7c, 0xda, 0xe8, 0xaf, 0xe1, 0x36, 0x68, 0x54, 0xcf, 0xd2, 0x76,
|
||||
0x8f, 0x1c, 0xe0, 0x91, 0x66, 0xf8, 0x35, 0x90, 0xc6, 0xbc, 0x64, 0x1c, 0x95, 0x8c, 0x03, 0x30,
|
||||
0x8a, 0xcf, 0x4a, 0x93, 0xb4, 0x72, 0x56, 0x20, 0x0a, 0xb5, 0xd7, 0xc5, 0xe0, 0x3c, 0x56, 0x7f,
|
||||
0x21, 0xf8, 0x7f, 0x45, 0xa4, 0xf6, 0x13, 0xf9, 0x86, 0x28, 0x64, 0xfb, 0x41, 0x78, 0xfa, 0x42,
|
||||
0x67, 0x2f, 0xc6, 0xa7, 0x3f, 0x8f, 0xcc, 0x3a, 0x9a, 0x71, 0xd2, 0x3c, 0x9b, 0xb7, 0x60, 0x7b,
|
||||
0x8b, 0xff, 0x15, 0x4c, 0x57, 0x42, 0xea, 0x5f, 0xc0, 0xf6, 0x39, 0x25, 0xc4, 0x52, 0x22, 0xc8,
|
||||
0x84, 0xb9, 0x24, 0xdf, 0xde, 0x81, 0x42, 0x54, 0xaa, 0xee, 0x16, 0xad, 0xba, 0x20, 0xc7, 0xe1,
|
||||
0x82, 0x1c, 0xbb, 0x5c, 0x82, 0x85, 0x66, 0xfc, 0xb6, 0x03, 0x0a, 0x30, 0xc8, 0xaf, 0x0b, 0x12,
|
||||
0x19, 0xbd, 0x1b, 0x1f, 0x4e, 0xff, 0xef, 0x5d, 0xc7, 0x29, 0x3f, 0x09, 0x10, 0xbd, 0xb3, 0x80,
|
||||
0xbe, 0x82, 0xbe, 0x76, 0xe2, 0xaa, 0xf2, 0xec, 0x42, 0x4a, 0xb4, 0x8d, 0x4e, 0x10, 0x26, 0x54,
|
||||
0xf4, 0x7b, 0xf6, 0xea, 0x80, 0x6d, 0xea, 0x8b, 0x87, 0x8b, 0xc8, 0x8f, 0xdf, 0xab, 0x5f, 0xfc,
|
||||
0xc4, 0xd3, 0x0b, 0xaf, 0x16, 0x2c, 0xe8, 0xc8, 0xf8, 0x45, 0x02, 0x18, 0x11, 0xa4, 0xe5, 0xd9,
|
||||
0x8f, 0xfb, 0x14, 0xe5, 0x02, 0xd1, 0x94, 0xf3, 0xbc, 0xac, 0x69, 0x70, 0x25, 0x9a, 0x5c, 0xc4,
|
||||
0xaf, 0xeb, 0xb0, 0x6f, 0xe4, 0x10, 0xb5, 0x28, 0x97, 0x0b, 0x78, 0xcd, 0xcb, 0x85, 0x32, 0x5e,
|
||||
0xa1, 0x36, 0x07, 0x20, 0x6a, 0x89, 0xa8, 0xaa, 0xac, 0x92, 0x9c, 0x9c, 0x2b, 0x90, 0x4d, 0xfc,
|
||||
0xf0, 0x4f, 0x41, 0xd6, 0xf0, 0x4e, 0x2d, 0xc0, 0x5d, 0xb1, 0x4c, 0x4a, 0x58, 0x01, 0x3f, 0x65,
|
||||
0x78, 0x2c, 0xe5, 0xa0, 0x42, 0xc1, 0x6f, 0x03, 0x41, 0x07, 0x6a, 0x74, 0x91, 0xcb, 0x39, 0x7e,
|
||||
0xa7, 0xc9, 0x79, 0x2c, 0x2b, 0x6e, 0x12, 0x95, 0x7d, 0x33, 0xa8, 0x8c, 0xd7, 0xa2, 0xac, 0x5e,
|
||||
0x43, 0x8d, 0x5a, 0x38, 0x82, 0x91, 0x8b, 0x44, 0x55, 0xe4, 0xe2, 0x91, 0x0a, 0x57, 0xed, 0x48,
|
||||
0xd5, 0x00, 0xa9, 0xa3, 0x32, 0xde, 0x6e, 0xca, 0xf9, 0xa8, 0x86, 0x75, 0xa3, 0x16, 0xae, 0xa1,
|
||||
0xd9, 0x39, 0xe0, 0x00, 0xcd, 0xf3, 0x05, 0x52, 0x96, 0x15, 0x44, 0x61, 0x33, 0x4f, 0x4a, 0x30,
|
||||
0x3e, 0x4c, 0x07, 0x71, 0x6e, 0xc0, 0x6c, 0xcf, 0x0b, 0x58, 0xc3, 0x30, 0x51, 0x72, 0xd8, 0x52,
|
||||
0xc1, 0x17, 0x1c, 0xd4, 0x1c, 0x96, 0xe6, 0xd8, 0x54, 0xf1, 0x52, 0x90, 0x37, 0x0b, 0x11, 0x04,
|
||||
0xce, 0x0e, 0x5b, 0x94, 0x09, 0xd2, 0x4a, 0x2d, 0x37, 0x80, 0x3c, 0x85, 0x73, 0xfc, 0x82, 0x10,
|
||||
0x2b, 0xd4, 0x14, 0x59, 0x83, 0xbe, 0x4b, 0xf8, 0xab, 0x31, 0x9a, 0x41, 0x39, 0xde, 0x14, 0x64,
|
||||
0x7e, 0xcd, 0x23, 0x3a, 0x11, 0x54, 0x0e, 0xc9, 0x11, 0x35, 0xcd, 0x21, 0x9d, 0xf1, 0xda, 0x50,
|
||||
0x4b, 0xd7, 0xaa, 0x7a, 0xae, 0x22, 0xa2, 0x65, 0xec, 0x80, 0xa1, 0x5f, 0x2a, 0x32, 0x2c, 0x60,
|
||||
0x0e, 0xd8, 0x04, 0xe6, 0x72, 0x0d, 0xb4, 0x28, 0x9f, 0x73, 0x9e, 0x14, 0x58, 0x0f, 0x30, 0x3d,
|
||||
0x98, 0x97, 0xac, 0x01, 0xe4, 0x26, 0xd9, 0xc4, 0x1f, 0x15, 0x0f, 0xb7, 0xb1, 0x06, 0xaa, 0x0c,
|
||||
0xfc, 0x04, 0x3a, 0x23, 0xd9, 0x10, 0x11, 0x36, 0xc5, 0x52, 0x99, 0xdd, 0x14, 0xa2, 0x02, 0xc6,
|
||||
0x21, 0x00, 0x42, 0xea, 0x97, 0xf1, 0x17, 0xda, 0x62, 0x89, 0xc2, 0x31, 0xd3, 0x94, 0x63, 0xa4,
|
||||
0xb7, 0x0a, 0xb3, 0x4f, 0x7e, 0x1a, 0x89, 0xa5, 0xc1, 0x96, 0xe5, 0x3a, 0x7e, 0xd7, 0x21, 0xfa,
|
||||
0x92, 0x97, 0x40, 0x7e, 0xfe, 0x15, 0x99, 0xed, 0x97, 0x3e, 0x43, 0xb5, 0x29, 0x69, 0x6a, 0xa3,
|
||||
0x7c, 0x5d, 0x6a, 0xa8, 0x9b, 0xf8, 0x50, 0x68, 0x94, 0x6b, 0x9a, 0xa4, 0x45, 0xe7, 0x00, 0x8b,
|
||||
0x52, 0xe9, 0x5a, 0x53, 0x13, 0x05, 0x65, 0x49, 0x03, 0xca, 0x6e, 0x26, 0x4a, 0xf0, 0x4b, 0x3e,
|
||||
0xea, 0x75, 0x29, 0x51, 0x82, 0xbd, 0x1c, 0xab, 0x45, 0x49, 0x6d, 0xe4, 0x93, 0x70, 0x52, 0xee,
|
||||
0x5a, 0x2d, 0x35, 0xf2, 0xd7, 0xd0, 0xbe, 0x78, 0xad, 0xb2, 0xb9, 0x13, 0x3e, 0xf9, 0xe8, 0xb8,
|
||||
0x77, 0x9d, 0x25, 0xd4, 0x3c, 0x32, 0x4b, 0xe0, 0xbd, 0x7f, 0x3e, 0x0f, 0xf2, 0x2f, 0x52, 0x0a,
|
||||
0x97, 0x76, 0x94, 0xe2, 0xfe, 0x2f, 0xae, 0xef, 0x32, 0x2e, 0x84, 0x32, 0x2e, 0xae, 0x12, 0x3e,
|
||||
0xe6, 0x71, 0x7d, 0x43, 0x33, 0x58, 0x8d, 0x1a, 0xfe, 0xe4, 0x51, 0x28, 0xf3, 0xd8, 0xf7, 0x66,
|
||||
0x11, 0x00, 0xf1, 0x93, 0x5d, 0x9b, 0xb8, 0x1a, 0x4b, 0xff, 0x82, 0x7c, 0x36, 0xd4, 0xdc, 0x39,
|
||||
0xae, 0x7d, 0x5e, 0xa6, 0xca, 0x05, 0x5c, 0x04, 0xa8, 0x51, 0xd8, 0x27, 0xc2, 0x50, 0xc9, 0xb0,
|
||||
0x1b, 0x54, 0x26, 0xe5, 0x02, 0xd7, 0x18, 0xb0, 0x1a, 0x51, 0x7f, 0xe4, 0x50, 0x95, 0x6c, 0x32,
|
||||
0xad, 0x92, 0x8b, 0xb4, 0x0c, 0xd6, 0xa8, 0x4c, 0x23, 0x94, 0x0b, 0xd7, 0xff, 0xea, 0x32, 0x2f,
|
||||
0x23, 0x89, 0xb0, 0x21, 0x28, 0x27, 0x39, 0xcf, 0x86, 0x56, 0x80, 0xa8, 0x48, 0xc0, 0x22, 0x10,
|
||||
0x13, 0x2a, 0x8b, 0x00, 0x03, 0x15, 0xac, 0x36, 0x82, 0xff, 0x7d, 0xfa, 0x6b, 0xf3, 0x3a, 0x5a,
|
||||
0xd9, 0xb9, 0x35, 0xa2, 0xdd, 0x04, 0x81, 0x42, 0xd1, 0x36, 0xd9, 0xcb, 0x96, 0xef, 0xa5, 0xb5,
|
||||
0x1b, 0x77, 0x3f, 0xe1, 0x2d, 0x2d, 0x7c, 0xd5, 0x26, 0xfa, 0x8e, 0x0d, 0xbf, 0x6e, 0xb1, 0xd7,
|
||||
0x63, 0xb6, 0xff, 0x07, 0xa0, 0xe7, 0x12, 0xe4, 0xa6, 0x5e, 0x00, 0x00
|
||||
};
|
@ -1,562 +0,0 @@
|
||||
/*
|
||||
* Binary array for the Web UI.
|
||||
* gzip is used for smaller size and improved speeds.
|
||||
*
|
||||
* Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
|
||||
* to find out how to easily modify the web UI source!
|
||||
*/
|
||||
|
||||
// Autogenerated from wled00/data/pxmagic/pxmagic.htm, do not edit!!
|
||||
const uint16_t PAGE_pxmagic_L = 8795;
|
||||
const uint8_t PAGE_pxmagic[] PROGMEM = {
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xcd, 0x3d, 0xeb, 0x7a, 0xdb, 0xc6,
|
||||
0xb1, 0xff, 0xf9, 0x14, 0x30, 0xec, 0x38, 0x84, 0x05, 0x42, 0x24, 0x75, 0xb1, 0x02, 0x0a, 0x52,
|
||||
0x13, 0xdb, 0x69, 0x7c, 0x3e, 0xe7, 0x72, 0x62, 0xb5, 0x4d, 0x3e, 0x55, 0x5f, 0xbc, 0x24, 0x96,
|
||||
0x24, 0x62, 0x10, 0xcb, 0x02, 0xa0, 0x2e, 0xa1, 0xf8, 0x40, 0xe7, 0xf7, 0x79, 0x84, 0xbe, 0xd8,
|
||||
0x99, 0x99, 0xdd, 0x05, 0x16, 0x17, 0x4a, 0xb4, 0xd3, 0x1f, 0xc7, 0x6d, 0x05, 0x60, 0xb1, 0x97,
|
||||
0xd9, 0xb9, 0xcf, 0xec, 0x80, 0x3d, 0x7d, 0xf2, 0xfa, 0xc7, 0x57, 0x17, 0xbf, 0xfe, 0xf4, 0xc6,
|
||||
0x9a, 0xe7, 0x8b, 0xf8, 0xcc, 0x3a, 0xc5, 0x8b, 0x15, 0xb3, 0x64, 0x16, 0xd8, 0x3c, 0xb1, 0xb1,
|
||||
0x81, 0xb3, 0x10, 0x2e, 0x0b, 0x9e, 0x33, 0x6b, 0x32, 0x67, 0x69, 0xc6, 0xf3, 0xc0, 0xfe, 0xdb,
|
||||
0xc5, 0xb7, 0xbd, 0x13, 0x5b, 0x37, 0x77, 0x12, 0xb6, 0xe0, 0x81, 0x7d, 0x1d, 0xf1, 0x9b, 0xa5,
|
||||
0x48, 0x73, 0xdb, 0x9a, 0x88, 0x24, 0xe7, 0x09, 0xf4, 0xbb, 0x89, 0xc2, 0x7c, 0x1e, 0x84, 0xfc,
|
||||
0x3a, 0x9a, 0xf0, 0x1e, 0x3d, 0xb8, 0x51, 0x12, 0xe5, 0x11, 0x8b, 0x7b, 0xd9, 0x84, 0xc5, 0x3c,
|
||||
0x18, 0xd4, 0x27, 0x61, 0xab, 0x7c, 0x2e, 0x52, 0x63, 0x8a, 0xbf, 0xb0, 0xdf, 0x45, 0xce, 0x92,
|
||||
0x09, 0x76, 0xcc, 0xa3, 0x3c, 0xe6, 0x67, 0x3f, 0x45, 0xb7, 0x3c, 0xb6, 0xbe, 0x67, 0xb3, 0x68,
|
||||
0x62, 0x5d, 0x08, 0x11, 0x9f, 0xee, 0xcb, 0x76, 0xeb, 0x34, 0xcb, 0xef, 0xe0, 0xda, 0xf1, 0x53,
|
||||
0x21, 0xf2, 0x75, 0xaf, 0x97, 0xf5, 0xf2, 0xf9, 0x6a, 0x31, 0xf6, 0x9f, 0xf6, 0xfb, 0xfd, 0xe3,
|
||||
0x11, 0x3e, 0x8f, 0xd9, 0xe4, 0xe3, 0x2c, 0x15, 0xab, 0x24, 0xa4, 0xc6, 0x03, 0x68, 0x14, 0xd7,
|
||||
0x3c, 0x8d, 0xd9, 0x9d, 0x9f, 0xce, 0xc6, 0xac, 0xdb, 0x77, 0x2d, 0xf5, 0x5f, 0xef, 0xc8, 0x81,
|
||||
0x97, 0x66, 0xff, 0xc1, 0x60, 0x00, 0x2d, 0x39, 0xbf, 0xcd, 0xfd, 0xa7, 0xe3, 0xf1, 0x18, 0xee,
|
||||
0x67, 0x29, 0xbb, 0xeb, 0x85, 0x2c, 0xfd, 0xe8, 0x3f, 0x1d, 0x0e, 0x87, 0xba, 0x61, 0xc1, 0xc3,
|
||||
0x68, 0xb5, 0xf0, 0x9f, 0x1e, 0x1c, 0x1c, 0xe8, 0xa6, 0x38, 0x9a, 0xcd, 0x61, 0x14, 0xa7, 0x7f,
|
||||
0x38, 0x6d, 0xbc, 0xe2, 0x7a, 0xe0, 0xc9, 0xe1, 0xc1, 0xd1, 0x50, 0xb7, 0x15, 0x63, 0xc7, 0x2f,
|
||||
0xfb, 0x27, 0x63, 0xdd, 0xaa, 0x86, 0x1f, 0x9e, 0x30, 0xdc, 0xc4, 0x6a, 0x32, 0xe1, 0x59, 0xa6,
|
||||
0x86, 0xf7, 0x0f, 0x0e, 0x0f, 0xfb, 0x13, 0xa3, 0x59, 0xcf, 0x70, 0x74, 0x78, 0x32, 0x19, 0x4e,
|
||||
0x8d, 0x17, 0x6a, 0x92, 0x13, 0x36, 0xf9, 0x6a, 0x88, 0xc8, 0xe0, 0x69, 0x2a, 0x52, 0x35, 0x0b,
|
||||
0x3b, 0xe9, 0xb3, 0x3e, 0x2b, 0x1a, 0xf5, 0x1c, 0xd8, 0x73, 0x38, 0x2e, 0x9a, 0xd5, 0x0c, 0xd3,
|
||||
0xe9, 0xd1, 0x57, 0x47, 0xb8, 0x8b, 0x1b, 0x96, 0x26, 0x51, 0x32, 0x53, 0x73, 0x84, 0xb0, 0x5c,
|
||||
0x7f, 0x68, 0x34, 0xeb, 0x59, 0xf8, 0xc9, 0x51, 0xd8, 0x3f, 0x34, 0x5e, 0xe8, 0x79, 0x00, 0xc2,
|
||||
0xfe, 0xf1, 0xc6, 0xf7, 0x7b, 0x37, 0x7c, 0xfc, 0x31, 0xca, 0x81, 0x23, 0x52, 0x11, 0xc7, 0x63,
|
||||
0x96, 0xae, 0x89, 0x53, 0xfc, 0xe3, 0xe5, 0x6d, 0xdb, 0xdb, 0x5e, 0x9e, 0x02, 0x55, 0xd6, 0x06,
|
||||
0x69, 0xfa, 0x56, 0xbf, 0xbd, 0x23, 0x52, 0xdf, 0xec, 0x78, 0xcd, 0xd2, 0x6e, 0xc1, 0x16, 0xce,
|
||||
0x48, 0x2c, 0xd9, 0x24, 0xca, 0xef, 0x7c, 0x6f, 0x38, 0x1a, 0x8b, 0x34, 0xe4, 0x69, 0x2f, 0x65,
|
||||
0x00, 0x73, 0xe6, 0x1f, 0x6d, 0x5b, 0x99, 0xd8, 0x69, 0x8e, 0x2c, 0xd3, 0x36, 0x6d, 0xd9, 0xe4,
|
||||
0xc0, 0xf0, 0x8c, 0xc7, 0x7c, 0x92, 0x47, 0x22, 0x69, 0x76, 0x2d, 0xa9, 0xea, 0x6c, 0x5e, 0xac,
|
||||
0xa7, 0xc0, 0xea, 0xbd, 0x29, 0x5b, 0x44, 0xf1, 0x9d, 0xff, 0x1d, 0x8f, 0xaf, 0x79, 0x1e, 0x4d,
|
||||
0x98, 0xfb, 0x77, 0x9e, 0x86, 0x2c, 0x61, 0x6e, 0xc6, 0x92, 0xac, 0x97, 0xf1, 0x34, 0x9a, 0x02,
|
||||
0x90, 0xb7, 0xbd, 0x2c, 0xfa, 0x03, 0x70, 0xe8, 0x2b, 0x78, 0xa1, 0x65, 0xb4, 0x60, 0xe9, 0x2c,
|
||||
0x4a, 0xfc, 0xfe, 0x68, 0xc9, 0xc2, 0x10, 0xdf, 0xf5, 0x37, 0x63, 0x11, 0xde, 0xad, 0x8b, 0xf6,
|
||||
0x30, 0xca, 0x96, 0xc8, 0xe1, 0xd3, 0x98, 0xdf, 0x8e, 0x7e, 0x5f, 0x65, 0x79, 0x34, 0xbd, 0xeb,
|
||||
0x29, 0xf9, 0xf2, 0x27, 0xf0, 0x87, 0xa7, 0x23, 0x06, 0xd0, 0x24, 0xbd, 0x28, 0xe7, 0x8b, 0x4c,
|
||||
0x37, 0x2d, 0xa2, 0xa4, 0x37, 0xe7, 0x44, 0xab, 0x41, 0xbf, 0x7f, 0x3d, 0x1f, 0x35, 0xb7, 0x61,
|
||||
0xec, 0x77, 0xc2, 0x92, 0x6b, 0x96, 0x29, 0xca, 0x41, 0xff, 0x2f, 0x36, 0xd9, 0x82, 0xc5, 0xf1,
|
||||
0x5a, 0x2f, 0x3e, 0x8e, 0xc5, 0xe4, 0xe3, 0x88, 0xb6, 0x7a, 0x23, 0x27, 0x3d, 0xec, 0xf7, 0x35,
|
||||
0xec, 0xc3, 0xe5, 0xad, 0xd5, 0xb7, 0x00, 0xeb, 0xa3, 0x89, 0x88, 0x45, 0xaa, 0xa6, 0x2f, 0x45,
|
||||
0xc7, 0x91, 0x03, 0x61, 0xef, 0xdc, 0xf7, 0x5e, 0x1e, 0xa5, 0x7c, 0xb1, 0x99, 0x82, 0x88, 0x03,
|
||||
0x15, 0x76, 0xd9, 0x9b, 0x5c, 0xa4, 0x47, 0x10, 0xf8, 0xc3, 0x3e, 0xd0, 0x96, 0xad, 0x51, 0x8c,
|
||||
0x7b, 0x21, 0x9f, 0x88, 0x94, 0x21, 0x89, 0xfc, 0x44, 0x24, 0xbc, 0xb2, 0xb8, 0x41, 0xa2, 0xc6,
|
||||
0xe2, 0x95, 0x6d, 0x1c, 0xf7, 0xfb, 0x1b, 0xe6, 0x47, 0x59, 0x57, 0xf2, 0x85, 0xeb, 0x4f, 0xc5,
|
||||
0x64, 0x95, 0xb9, 0x3e, 0x03, 0xda, 0x5f, 0x73, 0x67, 0xdd, 0x98, 0x54, 0xca, 0x85, 0xb3, 0x79,
|
||||
0x7a, 0x13, 0xf3, 0xf0, 0x4d, 0x18, 0xe5, 0x6b, 0x4d, 0xb8, 0x81, 0x07, 0x28, 0xb0, 0x4e, 0x00,
|
||||
0x0d, 0x0f, 0x71, 0x8c, 0xde, 0x4f, 0xcc, 0xa7, 0x39, 0xca, 0x48, 0x8d, 0x77, 0x0f, 0xb7, 0x63,
|
||||
0x71, 0xe3, 0x21, 0x66, 0x58, 0x94, 0xf0, 0xd4, 0x20, 0x54, 0x95, 0x3f, 0x5a, 0x18, 0x61, 0x0b,
|
||||
0x5a, 0xb1, 0x7b, 0x2f, 0x8c, 0x52, 0xc9, 0xe4, 0x3e, 0xac, 0xb9, 0x5a, 0x24, 0x72, 0x09, 0xe8,
|
||||
0xa0, 0x16, 0x00, 0x26, 0xea, 0xbe, 0x3c, 0x86, 0x2d, 0xb9, 0xa0, 0xee, 0x27, 0x5d, 0x5c, 0xcf,
|
||||
0xea, 0x59, 0x87, 0x40, 0x04, 0xa7, 0xd8, 0x48, 0x94, 0xc4, 0x00, 0x92, 0xa4, 0x8c, 0x97, 0x8a,
|
||||
0x9b, 0x2a, 0x51, 0x69, 0x99, 0x9b, 0x94, 0x2d, 0x81, 0x46, 0x78, 0x69, 0x80, 0x93, 0x81, 0x14,
|
||||
0xf3, 0xde, 0x98, 0xe7, 0x37, 0x9c, 0x27, 0x7a, 0xce, 0x5c, 0x2c, 0xd5, 0x84, 0x00, 0xd7, 0x9a,
|
||||
0xe6, 0x18, 0xb3, 0x2c, 0x82, 0x3d, 0x21, 0x18, 0x47, 0x04, 0xc5, 0x00, 0xa1, 0x18, 0x2d, 0x45,
|
||||
0x16, 0xd1, 0x06, 0x52, 0x1e, 0x33, 0x24, 0x99, 0x96, 0x23, 0x0d, 0xd7, 0x91, 0x9a, 0xa5, 0x37,
|
||||
0x5d, 0xc5, 0x95, 0xa9, 0x08, 0x79, 0xbb, 0x0f, 0x97, 0xf2, 0x60, 0x8c, 0x3f, 0x38, 0xf0, 0xc0,
|
||||
0x46, 0x1c, 0xec, 0x3a, 0x07, 0x1a, 0xe2, 0x3a, 0xc7, 0xb7, 0xd2, 0xa0, 0x18, 0x6d, 0x70, 0xbc,
|
||||
0x1a, 0x6d, 0x79, 0x64, 0x2a, 0xd7, 0x25, 0x47, 0x0f, 0x3d, 0xe2, 0x68, 0x5c, 0x46, 0x4b, 0xbb,
|
||||
0x6a, 0x32, 0x99, 0xfc, 0x04, 0x64, 0x75, 0x9b, 0x68, 0x16, 0xab, 0x89, 0x3c, 0x17, 0x0b, 0x13,
|
||||
0x56, 0xcb, 0xcb, 0x56, 0xe3, 0xfa, 0x82, 0x4a, 0x84, 0xcc, 0xd9, 0x50, 0x18, 0x9d, 0x72, 0x50,
|
||||
0x0a, 0x1c, 0x3a, 0x06, 0x36, 0x30, 0x84, 0x00, 0xc1, 0x03, 0xfd, 0x3b, 0x43, 0x1e, 0x07, 0x9a,
|
||||
0x77, 0x73, 0x61, 0xa5, 0xb8, 0xba, 0xfb, 0x94, 0x4f, 0x8f, 0x0e, 0x8e, 0xfa, 0x2e, 0x5a, 0x93,
|
||||
0xe9, 0x78, 0xe0, 0x3e, 0x7d, 0xc9, 0x8f, 0x5e, 0x4e, 0x86, 0xee, 0xd3, 0xe1, 0xe0, 0xab, 0xe3,
|
||||
0xe9, 0x01, 0x5c, 0x8f, 0x27, 0xc7, 0x21, 0x73, 0x9f, 0x1e, 0x1e, 0xb0, 0xfe, 0xe1, 0x4b, 0xe8,
|
||||
0xcf, 0xa7, 0xd3, 0x43, 0xe8, 0x37, 0xfd, 0x8a, 0x9d, 0x0c, 0x8f, 0x5c, 0xb4, 0x66, 0x2f, 0x87,
|
||||
0x43, 0xb0, 0xf5, 0x4a, 0xd9, 0x97, 0x8b, 0xf6, 0x26, 0x71, 0xb4, 0xf4, 0x11, 0xb6, 0xe2, 0x25,
|
||||
0x69, 0x8d, 0x69, 0x14, 0xc7, 0x3d, 0x09, 0x3e, 0x58, 0xa2, 0x04, 0xd8, 0x2f, 0x05, 0x90, 0x0c,
|
||||
0x91, 0x55, 0x88, 0x45, 0x56, 0xc7, 0x3f, 0x23, 0x96, 0x44, 0x0b, 0xa9, 0x65, 0xd4, 0xce, 0xac,
|
||||
0xa3, 0xcc, 0x92, 0x3b, 0xb2, 0xa2, 0x64, 0x8a, 0x0e, 0x11, 0x1f, 0xd1, 0x54, 0x92, 0x0b, 0x8c,
|
||||
0x99, 0x34, 0x67, 0x58, 0x1e, 0x0c, 0xe1, 0x2c, 0xe3, 0x9b, 0x98, 0x8d, 0x79, 0x5c, 0x65, 0x02,
|
||||
0xad, 0xdf, 0x0a, 0xfc, 0x57, 0x48, 0xf7, 0xb2, 0x46, 0x3a, 0x42, 0x76, 0x8b, 0x98, 0x6f, 0xa2,
|
||||
0x64, 0xb9, 0xca, 0x2f, 0xf3, 0xbb, 0x25, 0x0f, 0x12, 0x30, 0x73, 0x3c, 0xbd, 0x72, 0x8d, 0x26,
|
||||
0x1c, 0x76, 0xe5, 0x4a, 0x9b, 0xe6, 0xe2, 0x03, 0xec, 0x9a, 0x99, 0x5a, 0xa4, 0x50, 0x62, 0xfd,
|
||||
0x86, 0x4a, 0x3a, 0xea, 0x57, 0x54, 0x5a, 0xaf, 0xc1, 0x49, 0x4a, 0x25, 0xaa, 0x61, 0xfe, 0x00,
|
||||
0xb4, 0x60, 0x26, 0xe2, 0x28, 0xb4, 0x5a, 0xfa, 0x88, 0x55, 0x4e, 0x32, 0xd1, 0xdf, 0xc5, 0x56,
|
||||
0x9c, 0x48, 0x63, 0xe1, 0xd1, 0x46, 0x7a, 0xb8, 0xfc, 0x72, 0xfd, 0x79, 0xe6, 0xb0, 0x32, 0x87,
|
||||
0x45, 0xf7, 0xa0, 0x90, 0xf2, 0xae, 0xc4, 0x0e, 0x10, 0x6f, 0xc6, 0xaf, 0x9c, 0x75, 0x73, 0xdf,
|
||||
0x60, 0xd7, 0xc0, 0xb2, 0x91, 0x08, 0x9a, 0x13, 0xa8, 0x87, 0x90, 0x83, 0x73, 0x11, 0x2d, 0xc9,
|
||||
0x4b, 0x30, 0x70, 0xb9, 0x60, 0xb7, 0xd2, 0x5b, 0xf6, 0x0f, 0xd0, 0x1a, 0x28, 0xb9, 0xa4, 0xfb,
|
||||
0xcf, 0x34, 0xe6, 0x0d, 0x5c, 0xa1, 0xd3, 0xe6, 0x34, 0xed, 0x8c, 0x89, 0xc7, 0xea, 0x66, 0xe4,
|
||||
0x2e, 0xe4, 0x9f, 0xfe, 0x83, 0x94, 0xaa, 0x0e, 0x27, 0x33, 0xd5, 0x6f, 0x12, 0xa5, 0xa2, 0x72,
|
||||
0x06, 0x75, 0x2a, 0x81, 0xea, 0xf8, 0xd7, 0x0a, 0x58, 0xac, 0x05, 0xa3, 0x4f, 0xa2, 0x05, 0x46,
|
||||
0x19, 0x0c, 0x64, 0xce, 0xb4, 0x84, 0x83, 0x26, 0x8e, 0xe5, 0x14, 0x92, 0x58, 0xd2, 0xe2, 0x13,
|
||||
0x66, 0x34, 0x4e, 0xaa, 0x1e, 0x64, 0xe9, 0x3e, 0xe9, 0xcd, 0xf5, 0xb7, 0x60, 0x6d, 0x53, 0xb0,
|
||||
0x7f, 0xca, 0x69, 0x47, 0xe4, 0x3c, 0x54, 0x01, 0x3d, 0x21, 0xad, 0x0f, 0xe4, 0x11, 0x8b, 0x9e,
|
||||
0x14, 0x1a, 0x4b, 0x5e, 0xd6, 0x6c, 0xb9, 0x04, 0xc1, 0x87, 0x80, 0x46, 0x8d, 0xd3, 0xba, 0xa5,
|
||||
0xd1, 0xbe, 0x10, 0x7f, 0x34, 0x1a, 0x0d, 0x21, 0x02, 0x9d, 0x32, 0x53, 0xad, 0x5a, 0x03, 0xa7,
|
||||
0x92, 0x4d, 0xbe, 0x42, 0x0f, 0x60, 0x95, 0x66, 0x00, 0xfa, 0x52, 0x44, 0x92, 0x79, 0xab, 0xa0,
|
||||
0x90, 0x12, 0xf1, 0x7d, 0x36, 0x45, 0x17, 0x4a, 0x33, 0x8f, 0x6d, 0x97, 0x86, 0x88, 0x8d, 0x81,
|
||||
0xaa, 0x2b, 0x54, 0x4b, 0x60, 0x47, 0x0b, 0x93, 0xb9, 0x67, 0x1d, 0xa3, 0xc5, 0x94, 0xcb, 0x0c,
|
||||
0x81, 0xf6, 0x52, 0x6b, 0x4d, 0x45, 0xba, 0x80, 0x90, 0x2b, 0x67, 0x39, 0xef, 0x0e, 0x0e, 0x8e,
|
||||
0x42, 0x3e, 0x73, 0x46, 0x85, 0x07, 0xaf, 0x99, 0xd7, 0x70, 0x54, 0xc8, 0x36, 0x3f, 0xce, 0x38,
|
||||
0x6a, 0x99, 0x07, 0x3a, 0xaa, 0xdd, 0xf5, 0xf8, 0x35, 0xc0, 0x9f, 0x11, 0x2e, 0x36, 0x5e, 0x98,
|
||||
0x8a, 0xe5, 0x1f, 0x70, 0x67, 0xca, 0x93, 0xc1, 0xad, 0x21, 0xcb, 0xe6, 0xbc, 0x75, 0xd5, 0x07,
|
||||
0xf4, 0x93, 0x14, 0x96, 0x6d, 0xfa, 0xa6, 0xc9, 0x59, 0x9a, 0x95, 0xd0, 0xcf, 0xb1, 0x5a, 0x14,
|
||||
0x22, 0x0a, 0x72, 0xcd, 0x51, 0x31, 0x0d, 0x00, 0xf8, 0x09, 0x85, 0xc2, 0x07, 0x17, 0xa0, 0x07,
|
||||
0x2a, 0xaf, 0xdc, 0x97, 0x0a, 0x3f, 0xaa, 0x04, 0x7e, 0x5c, 0xbe, 0x7b, 0xdb, 0xa0, 0x57, 0x90,
|
||||
0x6d, 0x61, 0xf5, 0x62, 0x59, 0xb8, 0x61, 0xb3, 0x5a, 0xe0, 0xb3, 0x55, 0x91, 0x83, 0x1b, 0x87,
|
||||
0x0a, 0xb1, 0x97, 0x01, 0xdd, 0x60, 0xc4, 0x03, 0x5c, 0xbc, 0x0d, 0x2a, 0xc5, 0x35, 0x88, 0xa8,
|
||||
0x06, 0x1d, 0x35, 0x16, 0x09, 0xb1, 0xa5, 0x39, 0xa8, 0xb8, 0xf9, 0x03, 0x72, 0x43, 0x4c, 0x28,
|
||||
0x20, 0x9e, 0x43, 0x89, 0x92, 0x4d, 0x14, 0xc8, 0xb9, 0xf5, 0xf7, 0x3a, 0xde, 0xa3, 0x67, 0x15,
|
||||
0x3d, 0xd6, 0x61, 0xd7, 0x0a, 0xeb, 0xb8, 0x84, 0xec, 0x78, 0xbb, 0x75, 0x33, 0xdd, 0xf6, 0xba,
|
||||
0x26, 0xfb, 0xa2, 0x26, 0xa4, 0x85, 0xda, 0xd9, 0x78, 0xd9, 0x4d, 0x94, 0x4f, 0xe6, 0xeb, 0xa6,
|
||||
0x5f, 0xa8, 0xb5, 0xbf, 0xf4, 0x0b, 0xe5, 0x5e, 0x47, 0x4d, 0x4b, 0x21, 0x5d, 0x3e, 0x39, 0x8b,
|
||||
0x52, 0x7f, 0x25, 0x9e, 0xf4, 0x1c, 0x52, 0x5c, 0x64, 0x27, 0x4d, 0xa9, 0xa6, 0x02, 0xa8, 0xc1,
|
||||
0x88, 0xec, 0xda, 0x1f, 0x29, 0x9d, 0x2e, 0x25, 0x14, 0xf5, 0x25, 0x79, 0x1e, 0xfd, 0x4f, 0xb0,
|
||||
0xf1, 0x1a, 0x0d, 0x07, 0x87, 0x55, 0xd6, 0xf7, 0x0e, 0xb3, 0x1a, 0x4c, 0xfe, 0x98, 0x83, 0x82,
|
||||
0xe1, 0x6d, 0xa0, 0x95, 0x8a, 0x4b, 0x53, 0xe5, 0xb0, 0xa4, 0x0a, 0xde, 0x12, 0x9c, 0x07, 0x24,
|
||||
0x7e, 0x04, 0xe1, 0x41, 0x1b, 0xa5, 0xc0, 0x05, 0x9c, 0xb6, 0x10, 0xa7, 0x06, 0x94, 0xb4, 0xf8,
|
||||
0x93, 0x39, 0x9f, 0x7c, 0xe4, 0xe1, 0x5e, 0x0d, 0x6d, 0x8f, 0x53, 0x5f, 0x8d, 0xa7, 0xd8, 0xb0,
|
||||
0x31, 0x1a, 0xc3, 0xfa, 0x39, 0x0b, 0xc5, 0x0d, 0xda, 0x21, 0x0b, 0xb5, 0xd4, 0xb6, 0xf1, 0xed,
|
||||
0xeb, 0x6b, 0x14, 0x95, 0xda, 0x98, 0xee, 0x80, 0x67, 0xf8, 0x2f, 0xdd, 0x01, 0xf0, 0x05, 0x04,
|
||||
0x9b, 0xb9, 0x60, 0x59, 0xde, 0x2b, 0xe3, 0xbf, 0x02, 0x9d, 0xd3, 0xe8, 0x96, 0x87, 0x1a, 0x41,
|
||||
0xa4, 0x89, 0xd2, 0x82, 0x87, 0x46, 0x7f, 0x80, 0xfa, 0x09, 0xf9, 0xad, 0xff, 0x15, 0xfc, 0xdb,
|
||||
0x78, 0x34, 0xc7, 0xfa, 0xb1, 0x70, 0x51, 0xe2, 0x9f, 0xad, 0x72, 0x51, 0xe8, 0xc1, 0x63, 0x54,
|
||||
0x83, 0xc3, 0xaa, 0xd2, 0xdb, 0xa2, 0x16, 0x5b, 0xf6, 0xf0, 0x6b, 0xf7, 0x80, 0x22, 0x35, 0x9d,
|
||||
0xae, 0xe9, 0x8f, 0xae, 0xa3, 0x2c, 0x1a, 0x47, 0x31, 0x3e, 0xcc, 0xa3, 0x30, 0xe4, 0x89, 0x82,
|
||||
0xcd, 0x92, 0x97, 0x1e, 0xe5, 0x3f, 0xaa, 0x51, 0xd0, 0x49, 0xcd, 0x2d, 0x3e, 0x6e, 0x75, 0x8b,
|
||||
0x63, 0x9e, 0xa3, 0x41, 0xc1, 0x90, 0x12, 0xe1, 0xf6, 0x48, 0x8b, 0xd0, 0x9c, 0x9e, 0xca, 0xa3,
|
||||
0x6d, 0xa3, 0x75, 0x35, 0xff, 0xe6, 0xe8, 0x51, 0x94, 0x39, 0xdb, 0x36, 0xc6, 0x48, 0xab, 0x15,
|
||||
0x03, 0x54, 0x92, 0x6c, 0xdb, 0x90, 0x4a, 0x0e, 0x4d, 0x0f, 0xea, 0x2d, 0x53, 0x31, 0x4b, 0x11,
|
||||
0xb8, 0xa6, 0x90, 0x90, 0x08, 0x1c, 0x96, 0x22, 0x50, 0x4a, 0x88, 0x19, 0x90, 0x23, 0x8f, 0x14,
|
||||
0x6e, 0x66, 0x85, 0x0a, 0x94, 0xa6, 0xfd, 0xa5, 0xdb, 0x77, 0xca, 0xb6, 0x9e, 0x00, 0x0e, 0x89,
|
||||
0x12, 0x1f, 0xa7, 0x6e, 0x73, 0x7b, 0x2a, 0xf8, 0xb2, 0xea, 0x20, 0xee, 0x12, 0xd5, 0x55, 0x51,
|
||||
0x2a, 0xf7, 0xea, 0xb6, 0xe2, 0xb9, 0x8a, 0xe8, 0x3f, 0xb1, 0x98, 0x49, 0x8b, 0x4a, 0x53, 0x7d,
|
||||
0x21, 0x45, 0x81, 0x3f, 0xb1, 0x54, 0x95, 0x86, 0xb5, 0xc6, 0x72, 0xb9, 0x09, 0x83, 0xd9, 0xb2,
|
||||
0x7a, 0xb0, 0x57, 0x66, 0xe4, 0xbe, 0x30, 0x2d, 0x63, 0xdd, 0xdf, 0x1b, 0xaf, 0x80, 0xda, 0x49,
|
||||
0x8b, 0x0f, 0xd4, 0xaf, 0x04, 0x6a, 0xd6, 0xe0, 0xa4, 0x3d, 0x5a, 0x6b, 0x8a, 0x46, 0xcd, 0x10,
|
||||
0x54, 0x83, 0xce, 0x41, 0xbf, 0x2d, 0x69, 0xb5, 0x73, 0x6c, 0x27, 0x9d, 0x95, 0x87, 0x3d, 0xa0,
|
||||
0x96, 0x08, 0xa2, 0x9e, 0x86, 0x53, 0xbb, 0xde, 0x96, 0xa0, 0x35, 0xfd, 0xa2, 0xc7, 0x03, 0xcd,
|
||||
0x62, 0xb6, 0x98, 0x14, 0xe7, 0x3c, 0x8a, 0xc3, 0x75, 0x75, 0xd3, 0xc5, 0x82, 0xd9, 0x2e, 0x49,
|
||||
0x19, 0x23, 0x33, 0xfa, 0x54, 0x9d, 0x39, 0xd4, 0x95, 0x70, 0xc5, 0xb8, 0x1a, 0xa4, 0x33, 0x69,
|
||||
0xbe, 0x45, 0x2f, 0xa8, 0x19, 0x9d, 0xaa, 0x75, 0xd7, 0x0b, 0x79, 0xb1, 0x60, 0x44, 0xf3, 0xa6,
|
||||
0xcb, 0x5f, 0xcd, 0xcf, 0x3e, 0x12, 0x00, 0xf4, 0xac, 0xc1, 0x57, 0xa8, 0x29, 0x08, 0xc4, 0x46,
|
||||
0xab, 0x84, 0x78, 0x68, 0x38, 0xfd, 0xc3, 0xd2, 0xeb, 0x27, 0x1b, 0xf0, 0x88, 0xc7, 0x0f, 0x6b,
|
||||
0x6d, 0xf3, 0xbd, 0x9b, 0xf6, 0xb9, 0xcc, 0xaa, 0x64, 0xcb, 0x28, 0xb1, 0x06, 0x8d, 0x94, 0xca,
|
||||
0xe6, 0x29, 0x50, 0x00, 0xa2, 0xb4, 0x9c, 0x87, 0x6f, 0x31, 0x56, 0x5a, 0x37, 0xf3, 0xc0, 0x10,
|
||||
0x2e, 0x5e, 0x83, 0x05, 0x0b, 0xd7, 0x5b, 0xf8, 0xa1, 0x3c, 0x23, 0x71, 0xca, 0xa8, 0x73, 0xe3,
|
||||
0x69, 0xc5, 0x90, 0x65, 0x38, 0x6d, 0x15, 0x83, 0x4d, 0xfd, 0x2e, 0x37, 0x50, 0xb5, 0x46, 0x87,
|
||||
0x2d, 0xd6, 0xa8, 0x91, 0xe2, 0xfe, 0x0b, 0x72, 0x22, 0xb3, 0xba, 0x65, 0x36, 0xe0, 0xe5, 0xf1,
|
||||
0x4b, 0x40, 0xf4, 0x9a, 0x92, 0xa4, 0x65, 0x5e, 0x94, 0xb2, 0xa2, 0xed, 0x4c, 0xa7, 0xcf, 0x00,
|
||||
0x28, 0x03, 0xe9, 0x16, 0x59, 0x4c, 0xb7, 0x3d, 0x21, 0xa9, 0x72, 0x0f, 0xd5, 0xb8, 0xa4, 0x3c,
|
||||
0x55, 0xd8, 0xfc, 0xe5, 0x23, 0xbf, 0x9b, 0xa6, 0x0c, 0x36, 0x6e, 0x21, 0xce, 0xd7, 0xb9, 0x58,
|
||||
0x37, 0x02, 0xc0, 0x83, 0xe3, 0x3e, 0x06, 0x80, 0x95, 0xce, 0x85, 0x8e, 0xac, 0x0c, 0x50, 0x96,
|
||||
0x65, 0x50, 0xed, 0x3b, 0x65, 0x21, 0x7f, 0x9b, 0xac, 0x8f, 0xbe, 0x58, 0x6b, 0x73, 0x3f, 0x30,
|
||||
0xcd, 0x3d, 0xdd, 0xc6, 0xbc, 0xdd, 0x4d, 0xe8, 0x3b, 0x9b, 0xaf, 0x2a, 0x03, 0xb7, 0xf5, 0x32,
|
||||
0x17, 0xd4, 0xd9, 0xc6, 0xfe, 0x17, 0xeb, 0x96, 0xc4, 0x1b, 0x9d, 0x2d, 0x21, 0x5e, 0x5a, 0x5f,
|
||||
0x52, 0x8e, 0x0f, 0x10, 0xd3, 0x39, 0xdd, 0x97, 0x47, 0x8f, 0xd6, 0xe9, 0xbe, 0x3a, 0x2f, 0x45,
|
||||
0x17, 0x04, 0x2e, 0x61, 0x74, 0x6d, 0x4d, 0x40, 0x83, 0x64, 0x81, 0x5d, 0xf8, 0x5e, 0x76, 0xb3,
|
||||
0x1d, 0x84, 0x11, 0x5b, 0x11, 0x54, 0xab, 0x13, 0x85, 0x81, 0x8d, 0x77, 0x7f, 0xe5, 0xd0, 0x19,
|
||||
0x40, 0xb6, 0xad, 0x44, 0x10, 0x9b, 0xc2, 0x7d, 0x75, 0xa8, 0xcc, 0x98, 0xe2, 0x48, 0xf0, 0x58,
|
||||
0x12, 0xdd, 0x4a, 0x19, 0x57, 0xfb, 0xec, 0xa7, 0xb7, 0xbf, 0xbc, 0x79, 0x67, 0x75, 0x2a, 0xaf,
|
||||
0xd4, 0x66, 0xed, 0xb3, 0xef, 0xbf, 0xfe, 0xeb, 0xdb, 0x57, 0x00, 0x35, 0xbc, 0x3b, 0xb3, 0x2e,
|
||||
0x7e, 0xfc, 0xf1, 0x9d, 0xbe, 0xaf, 0x74, 0xd7, 0xe9, 0x5b, 0xfb, 0xac, 0xf3, 0x36, 0xb7, 0xa2,
|
||||
0xcc, 0x62, 0x56, 0x2e, 0x44, 0x6c, 0xe5, 0x73, 0x96, 0xe3, 0x09, 0x2d, 0x68, 0x97, 0x1c, 0x1a,
|
||||
0x93, 0x3b, 0x8b, 0xb2, 0x11, 0x20, 0x7a, 0x60, 0xea, 0x26, 0x22, 0xc4, 0x3b, 0x3c, 0x8d, 0x4d,
|
||||
0x45, 0x32, 0x3b, 0xfb, 0xaf, 0xf7, 0x3f, 0xfe, 0x60, 0xfd, 0xe3, 0xdd, 0x9b, 0xd7, 0x88, 0x24,
|
||||
0x6a, 0xe9, 0x58, 0xb8, 0x3d, 0x98, 0x02, 0x2e, 0x45, 0xb7, 0xe1, 0x6b, 0xeb, 0x7b, 0x96, 0xa7,
|
||||
0xd1, 0x6d, 0xd1, 0xcd, 0x02, 0x48, 0x78, 0x9c, 0x15, 0x90, 0xed, 0xc3, 0xce, 0xab, 0xfb, 0x4f,
|
||||
0x71, 0x2b, 0xb0, 0xc5, 0x0a, 0x36, 0x63, 0xdb, 0x32, 0xb0, 0x45, 0xa9, 0x0e, 0x5c, 0x08, 0xb0,
|
||||
0x25, 0xb2, 0x1c, 0x0f, 0x99, 0xed, 0xb3, 0xef, 0xd4, 0xdd, 0xe9, 0x3e, 0xbd, 0x86, 0x6e, 0xe4,
|
||||
0x5e, 0x5b, 0x1d, 0x4a, 0xe6, 0xd9, 0x68, 0xf0, 0x00, 0xe9, 0x74, 0x1e, 0x5d, 0x0c, 0xb2, 0x90,
|
||||
0x2c, 0xe5, 0x53, 0xca, 0xff, 0xb5, 0x02, 0x69, 0x0b, 0x5b, 0xe1, 0x22, 0x20, 0x3a, 0xed, 0x50,
|
||||
0x48, 0x08, 0x7e, 0x02, 0x79, 0xe0, 0xb9, 0xf5, 0x43, 0x0b, 0x10, 0x4d, 0x18, 0xe4, 0x8a, 0xc4,
|
||||
0x17, 0xf2, 0x16, 0x66, 0x5e, 0x41, 0xfb, 0x0f, 0xfc, 0xc6, 0x92, 0x13, 0xb5, 0xc1, 0xb3, 0x0d,
|
||||
0x5d, 0xd4, 0xd2, 0xd9, 0x82, 0x2e, 0x73, 0x13, 0x66, 0xca, 0xc8, 0xae, 0x6e, 0x62, 0xc9, 0xd0,
|
||||
0x4f, 0x4e, 0x60, 0x1f, 0xf2, 0xa6, 0x53, 0x6e, 0x42, 0xa5, 0x98, 0x24, 0xe4, 0xba, 0x1f, 0x21,
|
||||
0xaf, 0x78, 0x30, 0x60, 0x15, 0x94, 0xfb, 0xd4, 0x1b, 0x1a, 0xc0, 0x2e, 0x89, 0xe1, 0x02, 0xfb,
|
||||
0xf2, 0xcb, 0x29, 0xfd, 0xfb, 0xf2, 0xca, 0x3e, 0x7b, 0x9b, 0x00, 0x58, 0x51, 0xb8, 0x62, 0xf1,
|
||||
0xe9, 0xbe, 0x1c, 0xd0, 0x18, 0x39, 0xb4, 0x2d, 0x3d, 0xb0, 0xef, 0x5a, 0xc6, 0xd8, 0xce, 0x5b,
|
||||
0x0c, 0x60, 0xb6, 0x8e, 0x3b, 0xa8, 0x8c, 0x3b, 0x32, 0x87, 0xaa, 0x84, 0x1d, 0x07, 0xc8, 0xf5,
|
||||
0x1d, 0x4c, 0x67, 0xfd, 0x8c, 0x39, 0x03, 0xcb, 0x98, 0x70, 0x5f, 0xbe, 0x7d, 0x08, 0xf1, 0x6d,
|
||||
0x58, 0xee, 0xec, 0x80, 0x66, 0x70, 0x7b, 0x80, 0x23, 0xec, 0xb3, 0x1f, 0xe9, 0xba, 0x05, 0xc7,
|
||||
0xaa, 0x93, 0xe4, 0x0f, 0xfd, 0xb0, 0x15, 0xc5, 0xbf, 0x67, 0x22, 0x69, 0xdf, 0x1a, 0x8a, 0xa8,
|
||||
0x85, 0xc2, 0xda, 0xd9, 0x8a, 0xad, 0x39, 0x43, 0xd9, 0x59, 0x70, 0xeb, 0xeb, 0x0c, 0xec, 0x05,
|
||||
0x1a, 0xc3, 0xad, 0x5d, 0xc1, 0x5d, 0x8c, 0xed, 0xb3, 0x57, 0x7f, 0xfb, 0xf9, 0x5d, 0x67, 0x07,
|
||||
0x5c, 0xb5, 0xf2, 0xaa, 0x55, 0xec, 0x8c, 0x94, 0x6b, 0x60, 0x9b, 0xbe, 0x8d, 0xfd, 0x30, 0x86,
|
||||
0x0d, 0x24, 0xca, 0xea, 0x13, 0xfb, 0xec, 0x35, 0x5d, 0x3b, 0x8f, 0x8b, 0x9b, 0x1a, 0x40, 0x3c,
|
||||
0xab, 0xef, 0xdb, 0xc5, 0xbd, 0xf3, 0xf8, 0xea, 0xab, 0x24, 0xfa, 0xd7, 0x8a, 0xbf, 0x05, 0xfc,
|
||||
0xfe, 0x8d, 0xee, 0xac, 0xb7, 0xe1, 0x0e, 0x5a, 0xa7, 0x18, 0x45, 0x40, 0x94, 0x4f, 0x9f, 0xad,
|
||||
0x75, 0xa6, 0x29, 0x44, 0x22, 0x61, 0x7c, 0xf7, 0x03, 0x69, 0x9f, 0x6f, 0xd5, 0xd3, 0xa3, 0xfa,
|
||||
0x47, 0x15, 0xe5, 0x54, 0x46, 0x13, 0x48, 0xd5, 0x96, 0xdd, 0x95, 0x4f, 0xe7, 0x31, 0xb1, 0xd8,
|
||||
0x41, 0x2a, 0x32, 0x3e, 0x5b, 0x60, 0xc2, 0x17, 0xa4, 0xf1, 0xbd, 0xbc, 0xad, 0x20, 0xb5, 0x22,
|
||||
0x1c, 0x45, 0x5f, 0x82, 0xba, 0x1c, 0x59, 0x67, 0xd7, 0x3e, 0xec, 0x15, 0xa0, 0x60, 0xd2, 0xd1,
|
||||
0x02, 0x4d, 0x74, 0x6c, 0x5b, 0xf4, 0x2c, 0x3d, 0x59, 0x6a, 0x38, 0xb3, 0xf4, 0x72, 0xfd, 0x1d,
|
||||
0xe4, 0x7f, 0x57, 0xab, 0x34, 0xa6, 0xd0, 0x30, 0x01, 0xf7, 0xc8, 0x3e, 0xfb, 0xa6, 0xb8, 0x2f,
|
||||
0xb7, 0x63, 0xf2, 0x99, 0x71, 0xba, 0x61, 0xd7, 0xe8, 0x45, 0xa9, 0x4c, 0xcd, 0x3e, 0xc6, 0x9c,
|
||||
0xb4, 0x6f, 0xf3, 0xb9, 0xb3, 0x88, 0x12, 0xda, 0x2f, 0xb8, 0x95, 0xa0, 0x37, 0x8f, 0x8e, 0x0a,
|
||||
0x73, 0x32, 0x18, 0x9e, 0xd8, 0xa5, 0xa3, 0x50, 0x66, 0x46, 0xed, 0x56, 0x28, 0x8c, 0xa3, 0x2b,
|
||||
0x4b, 0x1e, 0xb4, 0xd8, 0x0f, 0xc8, 0x54, 0x09, 0xc1, 0xdf, 0x71, 0x31, 0xa5, 0xad, 0x1a, 0xad,
|
||||
0x06, 0x24, 0xdb, 0x74, 0xc4, 0x9f, 0xf5, 0x02, 0x8a, 0xb8, 0xc1, 0x3e, 0xfb, 0x5a, 0xdf, 0x96,
|
||||
0xd8, 0x96, 0x1d, 0xf5, 0x4e, 0x65, 0x96, 0xad, 0xbe, 0x2f, 0x4a, 0xc2, 0x8d, 0xc5, 0xad, 0xde,
|
||||
0x5b, 0x39, 0x23, 0x21, 0xdb, 0x78, 0x94, 0x2c, 0x25, 0x0f, 0x88, 0x2b, 0x2b, 0xd7, 0xdc, 0x2c,
|
||||
0x33, 0x99, 0x67, 0x9f, 0x95, 0x0e, 0x8f, 0x86, 0xea, 0xd3, 0x38, 0xca, 0x38, 0x95, 0xa6, 0xc0,
|
||||
0xc7, 0x3e, 0xbb, 0x28, 0x5b, 0x2c, 0x6a, 0xea, 0xd4, 0x77, 0xfc, 0x49, 0x1b, 0x6e, 0x2c, 0x20,
|
||||
0xa9, 0xd9, 0x6c, 0xae, 0x6c, 0xbf, 0x09, 0x96, 0xc2, 0x42, 0xe7, 0xd3, 0xd0, 0xf0, 0x38, 0x16,
|
||||
0x3a, 0x84, 0x06, 0x79, 0x38, 0xa7, 0x96, 0xfa, 0x99, 0x1e, 0xe4, 0xe6, 0x77, 0xdc, 0x7b, 0xa7,
|
||||
0x7d, 0xf3, 0xe6, 0xb4, 0x44, 0xef, 0x4a, 0x43, 0x65, 0xc7, 0x95, 0x37, 0x1d, 0x95, 0xbb, 0x55,
|
||||
0x33, 0xa2, 0xc5, 0xfd, 0x2c, 0x2e, 0x68, 0x63, 0x06, 0x34, 0x96, 0x95, 0xed, 0xee, 0x6a, 0x1b,
|
||||
0x49, 0xdb, 0x81, 0x1e, 0xfd, 0x07, 0x5e, 0xdb, 0x0d, 0x81, 0xac, 0x05, 0xd0, 0xbb, 0x97, 0x03,
|
||||
0x68, 0xdf, 0xea, 0x56, 0x8b, 0xec, 0xb1, 0xfd, 0xc9, 0x8c, 0x2a, 0x75, 0x2b, 0xb8, 0x14, 0x74,
|
||||
0xdd, 0x62, 0x16, 0xab, 0xeb, 0xab, 0x21, 0xd2, 0x19, 0x57, 0xf7, 0x2d, 0x10, 0xb4, 0x19, 0x69,
|
||||
0x44, 0x92, 0x21, 0x9b, 0x9f, 0xeb, 0x53, 0x74, 0x94, 0x3d, 0xc5, 0xe0, 0x11, 0x2d, 0x29, 0x5e,
|
||||
0x77, 0xc1, 0x9c, 0x1a, 0xa1, 0xac, 0xa7, 0xbc, 0xef, 0x28, 0xd0, 0x0f, 0xed, 0x4f, 0xe0, 0x6e,
|
||||
0xe9, 0xd4, 0xac, 0x52, 0xa5, 0x4a, 0x5e, 0xab, 0xbb, 0x4e, 0xd5, 0x64, 0x3c, 0x6e, 0x31, 0xaa,
|
||||
0xe0, 0x15, 0x13, 0x4a, 0x59, 0x2e, 0x1f, 0xb5, 0x81, 0xf4, 0x8e, 0x4a, 0x3b, 0x8f, 0xac, 0x2d,
|
||||
0xef, 0xc0, 0x8c, 0x28, 0x73, 0x92, 0xe5, 0x7c, 0x89, 0xdd, 0xd0, 0x87, 0xa7, 0x65, 0x16, 0x10,
|
||||
0x07, 0xd2, 0x2a, 0x3c, 0x8d, 0x26, 0x76, 0x1b, 0x58, 0x86, 0x09, 0xd1, 0xc2, 0x70, 0x96, 0xf1,
|
||||
0x49, 0x2d, 0xe0, 0xeb, 0xec, 0xee, 0x57, 0xd7, 0x95, 0x60, 0x24, 0xa7, 0xbe, 0x28, 0xee, 0xff,
|
||||
0x24, 0x92, 0x8c, 0x49, 0x0d, 0x95, 0x17, 0xd5, 0x10, 0x35, 0xfc, 0x7f, 0x82, 0xa8, 0x76, 0xa7,
|
||||
0xba, 0xa9, 0xa5, 0xdb, 0x25, 0xa1, 0x2e, 0xc4, 0x94, 0x38, 0xda, 0x86, 0x6d, 0xca, 0x7a, 0x81,
|
||||
0xbb, 0x3f, 0x17, 0x22, 0xe3, 0x16, 0xb3, 0xe8, 0xb9, 0xc0, 0x75, 0xe7, 0x94, 0x52, 0x4d, 0x67,
|
||||
0xd6, 0x2b, 0x6c, 0x96, 0xd9, 0x83, 0x9b, 0x28, 0x8e, 0x01, 0x4d, 0xb0, 0xe2, 0x84, 0x43, 0x0b,
|
||||
0x2f, 0xf2, 0x00, 0x06, 0x7c, 0xd6, 0x12, 0x2b, 0xbd, 0x33, 0x23, 0x6f, 0x10, 0x25, 0xd4, 0x57,
|
||||
0x66, 0x1b, 0xa0, 0x5d, 0x4e, 0x5b, 0x35, 0x56, 0x04, 0x8a, 0x22, 0x98, 0x7a, 0x40, 0x52, 0xa9,
|
||||
0x5b, 0x2d, 0x72, 0x4f, 0xfb, 0xfd, 0x6f, 0xbe, 0xfd, 0xf6, 0x5b, 0x7b, 0xc7, 0x78, 0x79, 0x3b,
|
||||
0x1e, 0x3a, 0x3b, 0xfb, 0xad, 0x04, 0x75, 0x56, 0x10, 0x90, 0xb0, 0x9f, 0x59, 0xab, 0x25, 0x26,
|
||||
0x67, 0xad, 0x5c, 0x50, 0x8e, 0xa4, 0x53, 0xd0, 0x94, 0x49, 0x25, 0xab, 0x6a, 0x44, 0x6d, 0x6b,
|
||||
0x9e, 0xf2, 0x29, 0xe8, 0xbc, 0x3c, 0x5f, 0xfa, 0xfb, 0xfb, 0x97, 0xd8, 0xde, 0x8b, 0x96, 0x57,
|
||||
0xfb, 0x9c, 0x5e, 0xe6, 0x2c, 0x9d, 0x61, 0x5d, 0xfe, 0x6f, 0xe3, 0x98, 0x25, 0x1f, 0x61, 0x09,
|
||||
0x35, 0x2b, 0x4c, 0xc7, 0x4c, 0x13, 0x52, 0xf1, 0x8d, 0x15, 0x3c, 0xb4, 0x4e, 0x09, 0x9b, 0xe9,
|
||||
0x17, 0x9f, 0xbd, 0x97, 0xfd, 0x23, 0xe5, 0x33, 0x7c, 0x4a, 0x1c, 0x47, 0x5a, 0x44, 0x15, 0x0f,
|
||||
0x14, 0x6e, 0x65, 0xd9, 0x60, 0xc6, 0x29, 0xcb, 0x4a, 0xe7, 0x77, 0x08, 0x2b, 0x46, 0xda, 0xaf,
|
||||
0x53, 0x36, 0x03, 0x8d, 0x1d, 0x5a, 0xf8, 0x06, 0x98, 0x6a, 0x1a, 0xc5, 0xdc, 0x9a, 0xf3, 0x94,
|
||||
0x5b, 0xc0, 0x44, 0x93, 0x38, 0x9a, 0x7c, 0x44, 0xac, 0xa9, 0x2d, 0x31, 0x2b, 0x16, 0x13, 0x16,
|
||||
0xcb, 0x4e, 0xa7, 0xfb, 0xcb, 0xba, 0x19, 0xc1, 0x76, 0xcd, 0x15, 0x99, 0x58, 0xa5, 0x3a, 0xc0,
|
||||
0xd3, 0xf7, 0x6c, 0x32, 0xe1, 0xcb, 0x5c, 0x21, 0x62, 0xff, 0xc5, 0x76, 0xa9, 0xf8, 0x24, 0x36,
|
||||
0xc1, 0x44, 0x20, 0x1d, 0x11, 0x28, 0xe6, 0x94, 0x0f, 0x76, 0x61, 0x93, 0xf4, 0x33, 0x39, 0xc3,
|
||||
0x79, 0x52, 0x64, 0xfc, 0xce, 0x2c, 0x7d, 0x0b, 0x7b, 0x91, 0x9d, 0xb6, 0x46, 0x9e, 0x32, 0x8f,
|
||||
0x2b, 0xe7, 0x98, 0x8d, 0xd1, 0x24, 0x6f, 0x31, 0x6d, 0x3b, 0x41, 0x22, 0x12, 0xc2, 0x2c, 0x9a,
|
||||
0xf7, 0x24, 0x14, 0x37, 0x1e, 0x62, 0x15, 0x89, 0xee, 0x11, 0xff, 0x21, 0x8b, 0xfe, 0x06, 0x31,
|
||||
0x3d, 0x4c, 0xf7, 0x0d, 0x03, 0xfc, 0x37, 0x80, 0x2b, 0x75, 0x10, 0xa6, 0xf8, 0x0c, 0x56, 0x58,
|
||||
0xa6, 0x1c, 0xbf, 0x0f, 0x79, 0xd0, 0xee, 0x4a, 0x6f, 0xca, 0xcc, 0xd9, 0x03, 0x1b, 0xe8, 0x09,
|
||||
0x75, 0xd1, 0x55, 0xe9, 0x86, 0x2d, 0x45, 0x92, 0x95, 0x3e, 0x98, 0x7a, 0x02, 0x62, 0xc0, 0x6e,
|
||||
0x4e, 0x50, 0x05, 0xb3, 0x50, 0x24, 0xf1, 0x1d, 0xbe, 0x94, 0x77, 0xc8, 0x53, 0xc5, 0xbf, 0xd3,
|
||||
0x7d, 0x3d, 0x61, 0x95, 0x74, 0xea, 0x44, 0xc7, 0xde, 0x81, 0xc4, 0xc4, 0x0e, 0xad, 0x48, 0x6d,
|
||||
0xa7, 0xee, 0x2b, 0xb1, 0xbc, 0xbb, 0x10, 0xaf, 0xe2, 0x68, 0x39, 0x16, 0x2c, 0x45, 0xff, 0x0f,
|
||||
0x5b, 0x90, 0x87, 0x8b, 0x36, 0xc4, 0x5f, 0x1b, 0xb9, 0x2b, 0x8b, 0xee, 0xb4, 0x66, 0x47, 0x2d,
|
||||
0xfa, 0x9e, 0x5d, 0x03, 0x16, 0xf1, 0xef, 0x67, 0xcf, 0xbc, 0x85, 0x59, 0x5f, 0x8b, 0x9b, 0x04,
|
||||
0x95, 0x8c, 0xca, 0x40, 0x9e, 0x59, 0xba, 0xa1, 0x85, 0x65, 0xdb, 0xdd, 0x31, 0x25, 0x81, 0xd1,
|
||||
0x62, 0x15, 0x53, 0x9a, 0x7b, 0x27, 0x97, 0xac, 0x2e, 0x58, 0x9d, 0x5d, 0x50, 0xff, 0x5e, 0xad,
|
||||
0x51, 0xc0, 0xaa, 0x1b, 0x1e, 0xe2, 0xe0, 0xb6, 0x8b, 0xfc, 0xec, 0x80, 0xd4, 0x73, 0xa7, 0xd4,
|
||||
0xc8, 0x19, 0xa8, 0xe4, 0x59, 0x94, 0xcf, 0x57, 0x63, 0x6f, 0x22, 0x16, 0xfb, 0xea, 0x8b, 0xa5,
|
||||
0x7d, 0xfa, 0x50, 0x89, 0xbe, 0x53, 0xc2, 0xcf, 0x94, 0x9a, 0x5a, 0xba, 0x63, 0xfd, 0x95, 0x06,
|
||||
0x59, 0xcf, 0x27, 0xc0, 0x08, 0x23, 0xab, 0xfe, 0x61, 0x93, 0xa5, 0xb4, 0x77, 0xb1, 0x68, 0x4d,
|
||||
0xbd, 0xd6, 0x6a, 0x3a, 0x0c, 0x61, 0xd1, 0x3d, 0xd4, 0xf9, 0x1f, 0x46, 0x13, 0x6a, 0x1b, 0xea,
|
||||
0x5c, 0x42, 0xfa, 0x13, 0x67, 0x1d, 0x18, 0x9c, 0xe5, 0x56, 0x18, 0x84, 0x62, 0xb2, 0xc2, 0xd4,
|
||||
0x86, 0x0b, 0x96, 0x97, 0x2d, 0xb2, 0x20, 0xe1, 0x37, 0x16, 0xc8, 0xf9, 0x7b, 0xce, 0xd2, 0xc9,
|
||||
0xfc, 0x27, 0x6a, 0xeb, 0xd6, 0x35, 0x42, 0x46, 0x2f, 0x1d, 0x17, 0x93, 0xe2, 0x81, 0x1c, 0xe7,
|
||||
0xc1, 0xfe, 0xba, 0xf6, 0x3c, 0xb1, 0x9d, 0xf3, 0x7a, 0x83, 0xdf, 0x50, 0x28, 0x30, 0xec, 0xbc,
|
||||
0xad, 0xd1, 0x07, 0xe7, 0x88, 0xfe, 0x63, 0xbb, 0xcb, 0x54, 0xe4, 0x02, 0x88, 0x2e, 0xf5, 0xb7,
|
||||
0x6f, 0x07, 0x41, 0x50, 0x1f, 0xa1, 0xbb, 0x9c, 0x4b, 0xdb, 0x68, 0xfb, 0xdb, 0x3a, 0x60, 0x71,
|
||||
0x87, 0xa5, 0x15, 0x58, 0xf0, 0xe1, 0xd9, 0x5a, 0xbf, 0xd8, 0xec, 0xef, 0x3f, 0x5b, 0xe3, 0xc2,
|
||||
0x9b, 0x0f, 0x23, 0x89, 0x0f, 0x9d, 0xe6, 0x0f, 0x66, 0x6f, 0xc3, 0x6e, 0x99, 0xf4, 0x77, 0x46,
|
||||
0xfa, 0xd6, 0x93, 0x5e, 0x04, 0x3e, 0xba, 0x45, 0x1b, 0x0b, 0xc3, 0x37, 0x58, 0x89, 0xf8, 0x2e,
|
||||
0x02, 0x17, 0x0f, 0xe8, 0xd1, 0xb5, 0xc7, 0xf1, 0x2a, 0xb5, 0x5d, 0x96, 0xdd, 0x25, 0x93, 0xae,
|
||||
0x13, 0x9c, 0xad, 0x1f, 0x5c, 0xbd, 0x9c, 0x77, 0xf3, 0xc1, 0x65, 0x37, 0x2c, 0xc2, 0x92, 0x51,
|
||||
0x99, 0xaf, 0xea, 0x3a, 0xaa, 0x41, 0x9a, 0xe9, 0xae, 0x53, 0x2c, 0x4a, 0xc6, 0xb2, 0xeb, 0x6c,
|
||||
0x1c, 0x97, 0x40, 0x25, 0xfd, 0xef, 0x78, 0x24, 0x48, 0x9e, 0x92, 0x23, 0xe5, 0x34, 0x3c, 0x8c,
|
||||
0x3b, 0x3c, 0x05, 0xb4, 0x7d, 0x9b, 0x44, 0x8e, 0x10, 0x85, 0x79, 0x62, 0xd4, 0x1a, 0x08, 0x72,
|
||||
0x70, 0x79, 0xe5, 0xd2, 0x33, 0x4f, 0x42, 0x7a, 0x5e, 0x6f, 0x46, 0xd3, 0x55, 0x42, 0x27, 0x8d,
|
||||
0x16, 0xae, 0xcb, 0x9d, 0x75, 0xca, 0xf3, 0x55, 0x9a, 0x58, 0x21, 0x12, 0xfc, 0x4d, 0xcc, 0x11,
|
||||
0xec, 0x6f, 0xee, 0xe8, 0xd5, 0xa6, 0xe8, 0x5a, 0x03, 0x7a, 0x4d, 0x20, 0x17, 0x1e, 0x8e, 0x53,
|
||||
0x35, 0x31, 0x7b, 0xb6, 0xf4, 0x6d, 0x36, 0x84, 0x3e, 0xab, 0x98, 0x04, 0xb7, 0x14, 0x03, 0x86,
|
||||
0xbb, 0xf8, 0x69, 0x0d, 0x10, 0x6b, 0x4d, 0x28, 0xf3, 0xf9, 0x46, 0x12, 0xab, 0x08, 0x5c, 0x1c,
|
||||
0x57, 0xbd, 0xc9, 0xd5, 0x1b, 0xc3, 0x57, 0x2f, 0xde, 0x31, 0xf5, 0x4e, 0x92, 0xd7, 0x4d, 0xcc,
|
||||
0xd5, 0x97, 0xa4, 0x2b, 0x32, 0x8f, 0x32, 0xe6, 0x6e, 0x66, 0xbe, 0xa2, 0xa6, 0x51, 0x9e, 0xde,
|
||||
0x49, 0x10, 0x2c, 0x11, 0x48, 0xf2, 0x4c, 0x39, 0x44, 0xf0, 0xdd, 0xc4, 0x71, 0x23, 0xd5, 0x20,
|
||||
0x68, 0x34, 0xd0, 0x2b, 0x0d, 0x7e, 0x1c, 0xff, 0x0e, 0x7e, 0x8a, 0xf7, 0x91, 0xdf, 0x65, 0xdd,
|
||||
0xc8, 0x71, 0xe3, 0x20, 0xf5, 0x80, 0xa7, 0x41, 0xae, 0xbb, 0x3c, 0x38, 0xb3, 0x05, 0xbd, 0x05,
|
||||
0x1a, 0xa1, 0x36, 0x13, 0x53, 0x2b, 0xba, 0xe4, 0x57, 0xcf, 0x9f, 0x3f, 0xc1, 0x8b, 0xa7, 0x77,
|
||||
0xfc, 0xfc, 0x39, 0x3d, 0x26, 0xfa, 0x0a, 0x64, 0x66, 0x69, 0x9e, 0xfd, 0x03, 0x74, 0x48, 0x97,
|
||||
0x39, 0x8e, 0x3b, 0xa1, 0x29, 0x93, 0xf0, 0x81, 0x09, 0x1f, 0x9c, 0x0f, 0x18, 0x84, 0x39, 0xf7,
|
||||
0xf7, 0x4b, 0xfc, 0xc6, 0xf3, 0x6d, 0x92, 0x77, 0x53, 0x6f, 0x29, 0x96, 0x5d, 0xc7, 0xd9, 0x1b,
|
||||
0xb8, 0x61, 0xb0, 0x5e, 0x66, 0xc0, 0x0d, 0x7e, 0xf1, 0x72, 0x02, 0xd8, 0xf2, 0x99, 0x2b, 0x12,
|
||||
0xff, 0x49, 0xdf, 0x15, 0xfe, 0x93, 0x81, 0xab, 0xa7, 0xf5, 0xa1, 0xab, 0x1f, 0xbb, 0x40, 0x08,
|
||||
0xff, 0xeb, 0x34, 0x65, 0x77, 0xde, 0x34, 0x15, 0x8b, 0xee, 0x3a, 0xe6, 0xc9, 0x2c, 0x9f, 0xfb,
|
||||
0xb1, 0x27, 0x6f, 0x36, 0x2e, 0x4a, 0xc4, 0xa0, 0xff, 0x82, 0x3b, 0xae, 0x51, 0xf8, 0xb1, 0xcb,
|
||||
0x88, 0x1c, 0xd0, 0xc9, 0x97, 0xe0, 0x24, 0xf8, 0x7d, 0x97, 0x63, 0xf1, 0xf6, 0x66, 0xe3, 0xce,
|
||||
0x82, 0xf5, 0x82, 0xe7, 0x73, 0x11, 0xfa, 0xf6, 0x4f, 0x3f, 0xbe, 0xbf, 0xb0, 0x5d, 0xd4, 0x73,
|
||||
0x3e, 0x9e, 0x66, 0x00, 0x96, 0xd2, 0x28, 0x99, 0x45, 0xd3, 0xbb, 0x6e, 0xe8, 0x6c, 0x0c, 0xa2,
|
||||
0xf1, 0x0a, 0xd1, 0x32, 0x77, 0x06, 0x5c, 0xa1, 0xaa, 0x8b, 0x90, 0x67, 0xe4, 0x4b, 0xae, 0x08,
|
||||
0x38, 0x02, 0x6c, 0x91, 0xba, 0xed, 0x7e, 0xf8, 0x49, 0xed, 0xd3, 0xb2, 0x9f, 0xad, 0xd9, 0x06,
|
||||
0xac, 0x16, 0xe0, 0xc5, 0x52, 0x03, 0xd1, 0x36, 0xdd, 0x7d, 0xc0, 0xaf, 0xe1, 0x70, 0x4e, 0x10,
|
||||
0x0b, 0x39, 0xc6, 0x7e, 0x43, 0xd5, 0x49, 0xd0, 0x13, 0x2b, 0x87, 0x24, 0x63, 0xf9, 0x96, 0xbd,
|
||||
0xc7, 0x5d, 0x9b, 0x6a, 0x04, 0x6c, 0x67, 0x53, 0x1f, 0x62, 0xbe, 0xaa, 0x49, 0x40, 0x04, 0x8e,
|
||||
0x4e, 0x8a, 0x3d, 0xf2, 0x00, 0xd0, 0xce, 0x82, 0x23, 0x7e, 0xa0, 0x64, 0xc1, 0xfa, 0x34, 0x06,
|
||||
0x46, 0x39, 0x17, 0x41, 0x7f, 0x94, 0xcd, 0xc5, 0x4d, 0xd7, 0x51, 0xba, 0x2f, 0x0a, 0xb8, 0xb7,
|
||||
0x60, 0xcb, 0xae, 0x5c, 0x14, 0x58, 0x29, 0xa1, 0x53, 0x46, 0xb1, 0x88, 0x32, 0xde, 0xed, 0xe6,
|
||||
0x6e, 0x84, 0x8a, 0x0c, 0xe6, 0xbd, 0x88, 0x16, 0x5c, 0xac, 0xf2, 0x6e, 0xa9, 0xdd, 0x4a, 0xd4,
|
||||
0xb2, 0xba, 0x3c, 0x68, 0x01, 0x61, 0x5a, 0x1e, 0xa2, 0x8a, 0x3c, 0x08, 0x14, 0x90, 0x48, 0x32,
|
||||
0x6f, 0xde, 0xc2, 0xbc, 0xe2, 0x32, 0x47, 0x69, 0xc0, 0x8b, 0xc1, 0xbd, 0xf4, 0x88, 0x5c, 0xcb,
|
||||
0xbd, 0xc4, 0xe4, 0xdb, 0xa8, 0xe4, 0xdb, 0x58, 0x2f, 0x03, 0x4e, 0x41, 0x34, 0x4b, 0x00, 0x67,
|
||||
0x75, 0x3e, 0x4e, 0x51, 0x77, 0x4e, 0x76, 0xe1, 0x9e, 0xb8, 0xc2, 0x3d, 0x79, 0x8d, 0x7b, 0x26,
|
||||
0x06, 0xf7, 0x30, 0xcd, 0x3d, 0xb9, 0xe6, 0x1e, 0xf6, 0xfc, 0x79, 0x57, 0xb3, 0x8f, 0x3c, 0xf9,
|
||||
0x05, 0xe6, 0x01, 0xb0, 0xdb, 0xd9, 0xc7, 0x55, 0x7a, 0x5a, 0x46, 0xc1, 0xb0, 0x9b, 0x2c, 0xff,
|
||||
0x5e, 0x16, 0x9b, 0x74, 0xed, 0xd2, 0xe3, 0xca, 0x6c, 0x57, 0x53, 0xd4, 0xf9, 0x0f, 0x73, 0x1c,
|
||||
0x10, 0x02, 0x42, 0x8a, 0xbb, 0x35, 0x28, 0x59, 0x90, 0x2d, 0xf6, 0x42, 0xec, 0xed, 0x01, 0x9a,
|
||||
0x60, 0x1b, 0xb4, 0x2b, 0xc5, 0x0c, 0x1e, 0x74, 0x41, 0x4d, 0x96, 0x9f, 0xb7, 0x72, 0x83, 0xec,
|
||||
0x5b, 0x6a, 0x6b, 0x0f, 0x02, 0xf7, 0xa4, 0x4b, 0xaf, 0xe6, 0x51, 0xc8, 0xd1, 0x66, 0x79, 0x6a,
|
||||
0x9d, 0x6a, 0x2b, 0x2c, 0xe8, 0xf8, 0xea, 0xa1, 0xce, 0xf9, 0xca, 0xfc, 0x15, 0x12, 0x5c, 0x33,
|
||||
0x16, 0xe7, 0xb8, 0x54, 0xb0, 0x6f, 0x83, 0x64, 0x90, 0x5a, 0x57, 0x51, 0xad, 0xa3, 0x39, 0x7c,
|
||||
0x1b, 0x87, 0x72, 0x54, 0xfd, 0x35, 0x0e, 0xcd, 0x82, 0x4b, 0xfb, 0xf7, 0x25, 0x9f, 0xd9, 0x2e,
|
||||
0x5c, 0xf0, 0xef, 0x32, 0xc1, 0xbf, 0xc0, 0x0a, 0xf6, 0x15, 0xf0, 0x73, 0x62, 0x68, 0x6f, 0x65,
|
||||
0x88, 0xd0, 0x88, 0xa0, 0xe6, 0xe0, 0xee, 0x25, 0x73, 0x93, 0xab, 0x20, 0xf7, 0xc0, 0xfe, 0x46,
|
||||
0x40, 0x0b, 0x0f, 0x20, 0x50, 0xf6, 0x11, 0x68, 0x8e, 0x7e, 0x45, 0xee, 0xa9, 0xd4, 0x47, 0xd7,
|
||||
0x06, 0x68, 0x6d, 0x30, 0x3d, 0x99, 0x17, 0x41, 0xe4, 0xb5, 0x0a, 0x61, 0x7b, 0x09, 0xb2, 0x64,
|
||||
0x14, 0x5c, 0xd2, 0x27, 0x2b, 0xbe, 0x6d, 0xc6, 0xe0, 0xb6, 0x2b, 0xed, 0x96, 0x6d, 0x6f, 0xae,
|
||||
0x46, 0x42, 0x29, 0xc6, 0xb3, 0x3e, 0x70, 0x17, 0x30, 0xfd, 0x2a, 0x9b, 0x77, 0x3d, 0xcf, 0x13,
|
||||
0x24, 0xbe, 0x5d, 0x09, 0x0e, 0xdf, 0x00, 0x6a, 0xbb, 0x72, 0x26, 0xae, 0x06, 0x83, 0xf3, 0xa1,
|
||||
0xf1, 0xb6, 0x01, 0xdf, 0x03, 0xdc, 0x0d, 0xa0, 0x2d, 0xd0, 0x11, 0x20, 0x00, 0xaf, 0xe5, 0xbb,
|
||||
0x8b, 0xef, 0xdf, 0x05, 0xb6, 0xed, 0x82, 0x38, 0x8a, 0xf4, 0x0d, 0x03, 0xec, 0xd4, 0x86, 0x33,
|
||||
0x9c, 0xb2, 0xd0, 0x37, 0xa8, 0x1d, 0x7e, 0xa4, 0xb4, 0x00, 0x30, 0x10, 0x73, 0x46, 0x7d, 0x90,
|
||||
0x47, 0xaa, 0x19, 0x06, 0x98, 0xd0, 0x45, 0x54, 0xe7, 0xcc, 0x4f, 0xfa, 0xb8, 0x00, 0x16, 0xd3,
|
||||
0x27, 0xe1, 0x2b, 0xac, 0xa5, 0xa3, 0x5d, 0x3a, 0x3b, 0xf0, 0xa0, 0xe2, 0x84, 0x3a, 0x2b, 0x94,
|
||||
0xae, 0x51, 0xc1, 0x0c, 0x44, 0xf2, 0xe2, 0x88, 0xcf, 0xd1, 0x4c, 0x20, 0xf3, 0xd4, 0xe0, 0x41,
|
||||
0x29, 0x6f, 0x4e, 0x66, 0x8d, 0x5b, 0x78, 0x22, 0xa9, 0x6b, 0xc8, 0xfd, 0x0c, 0x4b, 0x9a, 0x50,
|
||||
0x75, 0xd6, 0xd4, 0x19, 0xe8, 0xbf, 0x99, 0x2f, 0xb4, 0x94, 0x67, 0xa5, 0x52, 0x2b, 0x69, 0x26,
|
||||
0x0f, 0x0a, 0x5f, 0xf3, 0x29, 0x5b, 0xc5, 0xb9, 0x26, 0x5b, 0xdf, 0xd5, 0x9f, 0x0c, 0xb8, 0xc5,
|
||||
0x77, 0x04, 0x48, 0x48, 0xa2, 0x1f, 0x32, 0x0b, 0x30, 0x04, 0x20, 0xaa, 0x49, 0xcb, 0x28, 0x04,
|
||||
0xf4, 0x27, 0x7e, 0xee, 0x92, 0xc9, 0x07, 0xbb, 0x9b, 0x61, 0x7d, 0x56, 0x22, 0x1f, 0x7f, 0xf5,
|
||||
0x33, 0x7a, 0xfe, 0x15, 0x40, 0x2a, 0xa9, 0x9d, 0xdf, 0xdf, 0x17, 0x60, 0xa0, 0xdc, 0x2b, 0x37,
|
||||
0x49, 0x41, 0x90, 0xf4, 0x98, 0x06, 0x41, 0xf4, 0x32, 0xa4, 0xbf, 0xe3, 0xf2, 0x47, 0x18, 0x20,
|
||||
0x51, 0x73, 0x64, 0x6a, 0x0e, 0xa1, 0x67, 0x88, 0x36, 0x6e, 0x5a, 0xf2, 0x44, 0x6c, 0xf2, 0x04,
|
||||
0x80, 0xe8, 0x8c, 0x62, 0x0f, 0x8f, 0x45, 0x40, 0x4b, 0x78, 0xf2, 0x74, 0x55, 0xb8, 0x65, 0x8b,
|
||||
0x3a, 0x5f, 0x8d, 0x5c, 0x64, 0x9c, 0x14, 0x10, 0x11, 0x9b, 0x4c, 0x03, 0x3c, 0x23, 0x3d, 0x6d,
|
||||
0xe1, 0x32, 0x75, 0x17, 0x21, 0xa0, 0xe0, 0x6a, 0xa3, 0x3e, 0xfe, 0x13, 0xfc, 0x23, 0xb3, 0x0c,
|
||||
0xd2, 0x3a, 0x00, 0xc5, 0x0d, 0x17, 0x56, 0xab, 0x04, 0xa9, 0xb0, 0x40, 0xbc, 0x61, 0x39, 0xf4,
|
||||
0x4a, 0xbe, 0x59, 0x4d, 0xa7, 0x20, 0xef, 0x4e, 0xf9, 0xa2, 0x30, 0x05, 0x14, 0x2d, 0x45, 0x49,
|
||||
0x7e, 0x42, 0xee, 0x0b, 0x8c, 0x55, 0xe2, 0x6e, 0xe3, 0x2e, 0x7d, 0x99, 0x52, 0x02, 0xf5, 0x31,
|
||||
0x1a, 0xc3, 0x96, 0x8f, 0x0f, 0x5d, 0x7b, 0x6f, 0x0c, 0xe0, 0x76, 0xdf, 0x93, 0x69, 0x21, 0x67,
|
||||
0xe7, 0xd5, 0x9c, 0xa5, 0xaf, 0x04, 0x00, 0x0a, 0x34, 0xcf, 0x1d, 0xdc, 0x58, 0x01, 0x28, 0x2a,
|
||||
0x7c, 0xca, 0x85, 0x18, 0x20, 0xd6, 0x4c, 0x32, 0xab, 0x0b, 0x24, 0xf5, 0x1f, 0x25, 0x9e, 0xa0,
|
||||
0x78, 0x3c, 0x40, 0xf5, 0x9a, 0x23, 0xdf, 0x62, 0x0b, 0xe1, 0x27, 0x00, 0xe8, 0x19, 0xa9, 0x3d,
|
||||
0x2f, 0x4b, 0x27, 0x01, 0x68, 0x89, 0x3a, 0x7e, 0x66, 0x2a, 0xff, 0xd4, 0x90, 0x2f, 0x99, 0x2f,
|
||||
0x43, 0xdd, 0x1d, 0xf3, 0xec, 0xb2, 0x7f, 0x55, 0x77, 0xb3, 0xb5, 0xce, 0xad, 0xbb, 0xd8, 0xaa,
|
||||
0x98, 0xa3, 0x55, 0xee, 0xa8, 0x43, 0x91, 0xc3, 0x41, 0xdd, 0xab, 0x5a, 0x2a, 0xb9, 0x20, 0x74,
|
||||
0x23, 0xf2, 0x73, 0x29, 0x73, 0x75, 0xf2, 0xe5, 0x8e, 0x0f, 0x17, 0xaf, 0x49, 0xd5, 0xc2, 0x15,
|
||||
0x2f, 0xf1, 0x08, 0xde, 0xc6, 0x5a, 0xfe, 0x5c, 0x81, 0x9f, 0xba, 0xe3, 0x34, 0x02, 0x67, 0x15,
|
||||
0xe4, 0x6b, 0xe2, 0x46, 0x7e, 0xb8, 0x09, 0xf4, 0x9a, 0x60, 0xd9, 0x94, 0xb9, 0x33, 0x91, 0x8d,
|
||||
0x44, 0xaf, 0x7a, 0x14, 0x66, 0x5c, 0xe4, 0xae, 0xa5, 0x3b, 0x2c, 0xe7, 0x44, 0x1d, 0xb1, 0x2e,
|
||||
0x26, 0x06, 0x95, 0x4e, 0xd6, 0x4d, 0x79, 0x59, 0xb3, 0x40, 0x96, 0xc0, 0xc9, 0xca, 0x9e, 0x2e,
|
||||
0x73, 0x6b, 0xce, 0x86, 0x39, 0x2d, 0x18, 0xde, 0x44, 0x31, 0xff, 0x0c, 0xec, 0x84, 0xa9, 0x44,
|
||||
0xd3, 0x3f, 0x21, 0x01, 0x9a, 0xc2, 0xc5, 0x29, 0xf8, 0xe3, 0xa4, 0xae, 0x99, 0x55, 0xad, 0x52,
|
||||
0x0d, 0xca, 0x29, 0xa2, 0x27, 0xd5, 0xb8, 0x4a, 0xb5, 0x66, 0xaa, 0x55, 0x1d, 0x7f, 0x15, 0xed,
|
||||
0xa2, 0xc6, 0x22, 0xba, 0x3d, 0x6a, 0x89, 0xe9, 0x48, 0x13, 0xa5, 0x4a, 0x13, 0xc5, 0x1b, 0x34,
|
||||
0xb2, 0x4a, 0x5d, 0x48, 0x8d, 0x83, 0x70, 0x36, 0x59, 0x4c, 0x8a, 0xe8, 0xb7, 0x80, 0xf2, 0xd7,
|
||||
0x20, 0x91, 0xa3, 0x68, 0x0a, 0xda, 0xa3, 0x35, 0x0c, 0x88, 0x71, 0x53, 0xda, 0xf5, 0x1f, 0xc7,
|
||||
0x62, 0xdc, 0x45, 0xd7, 0x80, 0x06, 0x03, 0x12, 0xba, 0x97, 0xec, 0xca, 0x4d, 0x01, 0x08, 0x70,
|
||||
0x4b, 0x7d, 0xe6, 0xe1, 0x05, 0x28, 0xaa, 0xed, 0x9a, 0x42, 0x8c, 0xed, 0x82, 0x69, 0xe3, 0x71,
|
||||
0xc6, 0xad, 0xc6, 0x0b, 0xae, 0xc9, 0x3f, 0xa9, 0x2c, 0x5a, 0xe4, 0x90, 0xe8, 0xbc, 0x63, 0x81,
|
||||
0xf9, 0x1f, 0x2c, 0xb3, 0xf4, 0xae, 0x39, 0xe0, 0x3f, 0xc6, 0x49, 0xf6, 0xd9, 0x32, 0xda, 0xc7,
|
||||
0x48, 0x79, 0x5f, 0xe2, 0xee, 0x9c, 0x2d, 0xc4, 0x0a, 0x8f, 0x98, 0xf7, 0x32, 0xb7, 0xcd, 0x75,
|
||||
0xcd, 0x81, 0xdd, 0xd6, 0xaa, 0x40, 0xd9, 0x0f, 0x5d, 0x39, 0xc8, 0x9f, 0x69, 0x8b, 0x35, 0xd1,
|
||||
0x7e, 0x29, 0x20, 0xe2, 0xc9, 0xc4, 0x13, 0x1f, 0x1d, 0xa5, 0x58, 0xae, 0x45, 0x84, 0x47, 0x11,
|
||||
0xc8, 0x48, 0x61, 0xc1, 0x48, 0xa3, 0x5a, 0x2e, 0x40, 0xed, 0x61, 0x85, 0x69, 0x81, 0x25, 0xfe,
|
||||
0x99, 0x07, 0x03, 0x7e, 0xf0, 0x22, 0x72, 0x17, 0xc1, 0xac, 0x0c, 0x1d, 0x30, 0x3e, 0x29, 0xf5,
|
||||
0x12, 0x6b, 0x48, 0x21, 0x2f, 0xa5, 0x30, 0x23, 0x89, 0x11, 0x28, 0x85, 0x11, 0x08, 0x4b, 0x6a,
|
||||
0x48, 0x21, 0xc3, 0x48, 0xd9, 0x10, 0x2b, 0x51, 0x88, 0x95, 0xec, 0xb9, 0x01, 0xdf, 0x1d, 0xfc,
|
||||
0x99, 0x64, 0x63, 0x3d, 0x5b, 0xe7, 0x7b, 0x83, 0xcd, 0x87, 0xd1, 0x4a, 0x1a, 0x4f, 0x68, 0x9c,
|
||||
0x6c, 0xee, 0x9f, 0xad, 0x9b, 0x4e, 0x3c, 0xf8, 0xd7, 0x4b, 0xd9, 0x27, 0x73, 0x5c, 0x73, 0x6b,
|
||||
0xb2, 0xb1, 0x2a, 0xde, 0xb1, 0xbb, 0x4e, 0x40, 0x82, 0x21, 0xc0, 0xed, 0xa3, 0xbb, 0xd2, 0xe6,
|
||||
0x02, 0x2f, 0x34, 0x51, 0xef, 0x82, 0x15, 0x6d, 0xbf, 0xb0, 0x0c, 0x97, 0xa0, 0x9a, 0xaf, 0x20,
|
||||
0x3a, 0x51, 0x6e, 0xe0, 0x3d, 0x65, 0x18, 0x2a, 0x72, 0x2f, 0xd0, 0x65, 0x92, 0xb8, 0x07, 0x80,
|
||||
0x2f, 0xb1, 0xc0, 0xce, 0x95, 0xa5, 0x73, 0x57, 0xa5, 0x3f, 0x28, 0x9c, 0x73, 0xfb, 0xa9, 0xed,
|
||||
0xdb, 0xfb, 0xfb, 0x36, 0x6d, 0x73, 0xf3, 0xcf, 0x04, 0x77, 0xfc, 0x01, 0xa1, 0x51, 0x7a, 0xe1,
|
||||
0xce, 0xfb, 0x5d, 0x44, 0x49, 0xd7, 0xfe, 0x27, 0xca, 0x88, 0xa2, 0x1f, 0x84, 0x35, 0xea, 0x0b,
|
||||
0x92, 0x86, 0x26, 0x75, 0x97, 0xee, 0xfc, 0x53, 0x34, 0x47, 0xa1, 0x33, 0x0a, 0xba, 0xf0, 0x6a,
|
||||
0xf6, 0x45, 0x2b, 0x7f, 0x5d, 0xe2, 0xd9, 0xd0, 0xfe, 0x86, 0x5b, 0x56, 0x53, 0x11, 0x46, 0x6d,
|
||||
0x52, 0x43, 0x51, 0x68, 0xd7, 0xad, 0xa6, 0x27, 0xb4, 0x0b, 0x07, 0x0c, 0x24, 0x4b, 0x29, 0x90,
|
||||
0x65, 0xb4, 0x26, 0x2a, 0x8a, 0x20, 0x90, 0x73, 0x8a, 0x30, 0x2f, 0xc3, 0x20, 0xaf, 0x78, 0x42,
|
||||
0x0b, 0x20, 0x7d, 0x98, 0x50, 0xfb, 0x30, 0xb3, 0x06, 0xa0, 0x2d, 0x8a, 0x45, 0x7b, 0x2d, 0xee,
|
||||
0xaa, 0x9c, 0x0b, 0xf0, 0xbc, 0x2c, 0x9f, 0x66, 0x0e, 0x48, 0x03, 0x3a, 0xf9, 0x40, 0x52, 0x16,
|
||||
0x53, 0x59, 0x05, 0x88, 0x45, 0xd1, 0x20, 0x2b, 0x1d, 0xdc, 0xbb, 0x20, 0x3d, 0x8f, 0xfd, 0xb9,
|
||||
0x3b, 0x85, 0xeb, 0xc4, 0x5f, 0xb8, 0xd7, 0x70, 0x5d, 0xf9, 0x77, 0xee, 0x5b, 0xb8, 0x2e, 0xfd,
|
||||
0xa9, 0x7b, 0x13, 0x7c, 0xcf, 0xf2, 0xb9, 0x37, 0x8d, 0x85, 0x48, 0xbb, 0xdd, 0x55, 0xef, 0xce,
|
||||
0xd9, 0x1f, 0x3a, 0xee, 0xbb, 0x4a, 0xeb, 0xb2, 0x37, 0xa5, 0xd6, 0x71, 0x70, 0x78, 0xf2, 0xe2,
|
||||
0xda, 0x7d, 0x83, 0x97, 0xb7, 0xee, 0xef, 0xc1, 0xf8, 0x34, 0x78, 0x79, 0x7c, 0x72, 0x3e, 0x38,
|
||||
0xf4, 0x07, 0x27, 0xee, 0x7b, 0x14, 0xcf, 0xf5, 0x24, 0xbf, 0xf5, 0x6f, 0x37, 0x81, 0x24, 0xdd,
|
||||
0x2b, 0x92, 0xb9, 0xee, 0x9d, 0x3b, 0x75, 0x46, 0xb7, 0xf8, 0x55, 0xef, 0x8d, 0x92, 0x47, 0xb7,
|
||||
0x0f, 0xff, 0xa1, 0x66, 0xc9, 0xce, 0xaf, 0x83, 0x5b, 0x4c, 0xe6, 0xd1, 0x5b, 0xd4, 0x9a, 0x5d,
|
||||
0xfd, 0x9e, 0xb0, 0x50, 0x08, 0xef, 0x85, 0x8b, 0xd3, 0x3f, 0xab, 0x4d, 0x3f, 0x76, 0xdf, 0x38,
|
||||
0xa3, 0x67, 0x68, 0x39, 0xe2, 0xf7, 0x32, 0xab, 0x8f, 0xbf, 0xb7, 0x05, 0xff, 0x6c, 0x57, 0xb6,
|
||||
0xfe, 0x0c, 0xa8, 0xa5, 0x19, 0xa9, 0x27, 0x08, 0x45, 0x17, 0xb3, 0x11, 0x3c, 0xe8, 0x8f, 0xf8,
|
||||
0xe9, 0xdb, 0x11, 0x87, 0x80, 0x53, 0xb7, 0xe5, 0xd0, 0x96, 0x9f, 0x5e, 0x8f, 0x72, 0x68, 0x5b,
|
||||
0x63, 0x03, 0x0b, 0xf8, 0x8b, 0xeb, 0x3d, 0x90, 0x76, 0x90, 0x26, 0xd8, 0x34, 0x38, 0xc5, 0x78,
|
||||
0xe1, 0xe8, 0x1d, 0xf4, 0x6e, 0xc0, 0xde, 0xf3, 0xde, 0x3b, 0x20, 0xbd, 0xad, 0xd6, 0x43, 0x1d,
|
||||
0x07, 0x7e, 0xa5, 0x38, 0x0b, 0x20, 0x4c, 0x12, 0xa7, 0x77, 0xcf, 0x9f, 0x47, 0x74, 0x1b, 0x9d,
|
||||
0x4e, 0xef, 0xef, 0x9f, 0xc0, 0x9b, 0x1c, 0xdb, 0xf8, 0xe9, 0x54, 0x4f, 0x9e, 0x9e, 0x47, 0x2f,
|
||||
0xee, 0xf6, 0x84, 0xcf, 0xe1, 0x6f, 0x3e, 0x02, 0x1e, 0x42, 0xa5, 0x4c, 0x27, 0xd7, 0xdd, 0xd7,
|
||||
0x97, 0x87, 0x2f, 0xc0, 0x02, 0xd0, 0x65, 0x6f, 0xa0, 0x6f, 0x86, 0xfa, 0xe6, 0xe0, 0x8a, 0xbe,
|
||||
0x20, 0x5c, 0xa7, 0xa0, 0x31, 0x66, 0xc0, 0x5a, 0x63, 0xe4, 0xaa, 0x39, 0xbf, 0xbd, 0x10, 0x3f,
|
||||
0xcf, 0xc6, 0xa0, 0x7a, 0x46, 0xef, 0xa5, 0x8a, 0x01, 0x23, 0x63, 0xa2, 0xe6, 0x43, 0x0a, 0x6f,
|
||||
0x51, 0x5d, 0xb9, 0x20, 0xdd, 0x21, 0xfd, 0x9d, 0x6d, 0x9c, 0x0f, 0x26, 0xa2, 0xc0, 0x8d, 0x76,
|
||||
0x0f, 0x4f, 0xe0, 0xbf, 0xca, 0xb2, 0xa8, 0x89, 0xf4, 0x1e, 0x11, 0xd5, 0xf8, 0xf5, 0x0b, 0xf1,
|
||||
0x5b, 0x30, 0x80, 0x91, 0x78, 0x62, 0xfe, 0x91, 0x6b, 0xd4, 0x0f, 0xe8, 0x9f, 0x5d, 0xb4, 0xd7,
|
||||
0xe6, 0xa4, 0x44, 0xd0, 0x24, 0x48, 0xf6, 0x86, 0x87, 0x6e, 0x18, 0x64, 0x70, 0x41, 0xd2, 0x09,
|
||||
0xb0, 0x2f, 0xbf, 0xef, 0xd9, 0xcb, 0x5b, 0xeb, 0xeb, 0x34, 0x62, 0xb1, 0x5d, 0x81, 0x59, 0xaf,
|
||||
0x0c, 0x4e, 0x7b, 0x0c, 0xda, 0x49, 0xfe, 0xb2, 0x19, 0xe8, 0x28, 0x63, 0x29, 0xb4, 0xd4, 0x5f,
|
||||
0xe3, 0xe7, 0xa1, 0x81, 0x2d, 0xbf, 0x0c, 0xd5, 0x8d, 0xdf, 0x80, 0x08, 0x21, 0xb4, 0x81, 0xbd,
|
||||
0x88, 0xc2, 0x30, 0xe6, 0x7a, 0xe6, 0x0b, 0x78, 0x07, 0x9e, 0xd0, 0xc4, 0x0d, 0x9d, 0x8d, 0x2c,
|
||||
0x86, 0x02, 0xb7, 0x0e, 0xd8, 0x0c, 0x1c, 0x8b, 0x81, 0xed, 0x47, 0xc1, 0xfb, 0xd1, 0x18, 0x58,
|
||||
0xec, 0xe3, 0x88, 0x5a, 0x86, 0xd8, 0x42, 0x81, 0x66, 0xf7, 0xbd, 0x63, 0xbe, 0x38, 0xc0, 0x17,
|
||||
0x54, 0xbe, 0x08, 0x2f, 0x36, 0x52, 0xb7, 0x96, 0xbc, 0x8a, 0x36, 0xa4, 0x10, 0x56, 0x4c, 0xd4,
|
||||
0x86, 0xe5, 0x23, 0xd8, 0x9a, 0x08, 0x7c, 0x0e, 0x43, 0xdb, 0xd1, 0x2c, 0x5c, 0x32, 0x06, 0xb0,
|
||||
0x21, 0xb8, 0x06, 0x7d, 0xe0, 0x39, 0x8e, 0xae, 0x50, 0x86, 0x86, 0x90, 0x97, 0x21, 0x12, 0xb0,
|
||||
0x1f, 0x5a, 0x3b, 0x60, 0x36, 0xfe, 0x24, 0x08, 0x12, 0x67, 0xcd, 0x02, 0x31, 0x1a, 0x04, 0x01,
|
||||
0xeb, 0xe5, 0xe7, 0x99, 0xa4, 0x56, 0xe2, 0xf8, 0xea, 0x0e, 0xec, 0x02, 0x38, 0x09, 0xe0, 0x4e,
|
||||
0x89, 0x4d, 0x82, 0xce, 0xb7, 0xce, 0x0e, 0x0c, 0x28, 0x99, 0x25, 0xa3, 0xfa, 0xf6, 0x71, 0xfa,
|
||||
0x2d, 0x0e, 0xcf, 0x4a, 0x48, 0x0d, 0x1e, 0x05, 0xb3, 0x4b, 0xb3, 0x2b, 0xfd, 0xac, 0x35, 0x64,
|
||||
0x66, 0x66, 0xc1, 0xcd, 0xf2, 0x8f, 0x86, 0x76, 0x95, 0x85, 0x12, 0x05, 0x4c, 0x18, 0x97, 0x25,
|
||||
0xe7, 0xd9, 0xb9, 0x28, 0x53, 0x16, 0x4f, 0x29, 0x65, 0xe1, 0xe5, 0xe2, 0x9d, 0xb8, 0xe1, 0xe9,
|
||||
0x2b, 0xc0, 0x7a, 0xd7, 0xc1, 0xdf, 0xcf, 0xbb, 0x10, 0xdf, 0x01, 0x39, 0x86, 0x47, 0x47, 0xae,
|
||||
0xfa, 0x9f, 0xd1, 0x4a, 0x60, 0x99, 0x67, 0x01, 0x5a, 0x2c, 0x00, 0xbd, 0x07, 0xb0, 0x04, 0x58,
|
||||
0x4d, 0x5e, 0x5f, 0xc1, 0x51, 0x9b, 0x85, 0xa8, 0xd0, 0x7c, 0xbb, 0xdf, 0xf5, 0x9c, 0xfd, 0x99,
|
||||
0x6b, 0x3f, 0x1b, 0x3c, 0x1b, 0x40, 0xa7, 0x51, 0x61, 0x6b, 0x31, 0xe9, 0x82, 0xc9, 0x4b, 0xe4,
|
||||
0x9c, 0x7d, 0x6f, 0x3d, 0xdc, 0xec, 0xcf, 0x1c, 0x6d, 0x91, 0x0b, 0x2a, 0x73, 0x77, 0x70, 0xec,
|
||||
0xe8, 0xdd, 0x81, 0xa8, 0xe6, 0x20, 0xaa, 0x0c, 0x44, 0x35, 0x31, 0x09, 0x5f, 0x85, 0x5a, 0x85,
|
||||
0x5d, 0x85, 0xb8, 0xed, 0x75, 0xf9, 0xe9, 0xe9, 0xe0, 0xf8, 0x3e, 0x3f, 0x3d, 0x3d, 0xb9, 0x67,
|
||||
0x88, 0x08, 0x19, 0xca, 0x75, 0x71, 0x66, 0x2f, 0xa3, 0x30, 0xbe, 0x77, 0x6c, 0x6c, 0x56, 0xf2,
|
||||
0xa9, 0xb6, 0x99, 0xc0, 0x4a, 0xc0, 0x3b, 0x45, 0x42, 0xc8, 0x60, 0x21, 0x0a, 0xe4, 0x72, 0x49,
|
||||
0x6b, 0x06, 0xde, 0x22, 0x78, 0x71, 0xf9, 0xa6, 0x16, 0xb2, 0x2a, 0x05, 0x8b, 0xde, 0x55, 0xe1,
|
||||
0x5b, 0x85, 0x2a, 0xf0, 0x51, 0x07, 0x2f, 0x40, 0x43, 0xea, 0x64, 0xa3, 0x83, 0x20, 0x43, 0x6e,
|
||||
0x98, 0x5b, 0x87, 0xda, 0xf9, 0x48, 0x87, 0x5d, 0x0c, 0xf5, 0xfb, 0x2b, 0xfc, 0xfc, 0x08, 0x04,
|
||||
0xcf, 0x1e, 0x86, 0x36, 0x5a, 0x45, 0xd4, 0x38, 0x2c, 0xfc, 0x16, 0xeb, 0x96, 0x60, 0xaa, 0xf8,
|
||||
0x8e, 0x3c, 0x1f, 0x0d, 0x6d, 0xe2, 0x91, 0x27, 0xfb, 0x7e, 0x21, 0x44, 0x3e, 0x87, 0x1d, 0xff,
|
||||
0xf7, 0x8a, 0xe1, 0x67, 0x59, 0x81, 0x3d, 0x87, 0xa9, 0xc1, 0xf1, 0xad, 0xbd, 0x7e, 0x93, 0xb0,
|
||||
0x71, 0x8c, 0x81, 0xfc, 0xa0, 0x30, 0x17, 0x8c, 0xcc, 0x85, 0x89, 0xec, 0x8a, 0x43, 0x44, 0xdb,
|
||||
0x52, 0xc1, 0x33, 0x38, 0x43, 0x28, 0x0f, 0xe7, 0x77, 0x6c, 0x11, 0x63, 0x80, 0x27, 0x1d, 0x23,
|
||||
0x6a, 0xc2, 0x3b, 0x6c, 0x32, 0xb0, 0x13, 0xaa, 0xd3, 0x67, 0xf2, 0xd3, 0x15, 0xdd, 0x50, 0x6e,
|
||||
0x41, 0xcd, 0x8d, 0x94, 0x36, 0x61, 0x4a, 0x9b, 0x50, 0xf6, 0xdb, 0x07, 0xbd, 0x04, 0x9e, 0x35,
|
||||
0x10, 0x8b, 0x62, 0x8b, 0x7d, 0x9d, 0x25, 0x97, 0x6f, 0x4d, 0x8d, 0x02, 0x70, 0xd4, 0x3b, 0xdf,
|
||||
0xf6, 0x10, 0x28, 0xea, 0x4e, 0x37, 0x66, 0x77, 0x82, 0x12, 0x07, 0x20, 0x5a, 0xf7, 0x81, 0x65,
|
||||
0x23, 0x39, 0x6f, 0x7e, 0x9b, 0xdb, 0x1b, 0x7d, 0x5e, 0x84, 0x11, 0xc5, 0x37, 0x18, 0x5e, 0x5c,
|
||||
0xf2, 0x2b, 0x15, 0x4f, 0x24, 0x94, 0xf5, 0x6b, 0x8b, 0x62, 0x29, 0x3d, 0xde, 0xa0, 0x31, 0x43,
|
||||
0x19, 0x95, 0x67, 0x66, 0x91, 0x9b, 0x7a, 0x7a, 0xff, 0xe8, 0x0e, 0xe7, 0x1b, 0xef, 0xd9, 0x3a,
|
||||
0xdb, 0x7c, 0x80, 0x66, 0xaa, 0xe6, 0x80, 0x20, 0x06, 0xe7, 0x4d, 0xf9, 0x35, 0x28, 0xff, 0x72,
|
||||
0xde, 0xc8, 0x60, 0x51, 0x42, 0xf2, 0x16, 0xaf, 0x4e, 0x7d, 0x04, 0xd1, 0x70, 0xea, 0x2a, 0x1f,
|
||||
0x01, 0x34, 0x1c, 0xbb, 0xe2, 0xab, 0x85, 0x86, 0x5b, 0x67, 0x1c, 0xa8, 0x82, 0xbe, 0x2c, 0x08,
|
||||
0xae, 0xbf, 0x28, 0xbb, 0x10, 0xbf, 0x22, 0x30, 0x6b, 0x49, 0x35, 0x88, 0x5b, 0xd6, 0x97, 0xf9,
|
||||
0x95, 0xbf, 0xd6, 0xab, 0xfd, 0x46, 0x89, 0x4d, 0xe6, 0xca, 0xf9, 0x7f, 0x03, 0x0d, 0x9e, 0xb8,
|
||||
0x13, 0xb1, 0x58, 0xb0, 0x24, 0xfc, 0x0d, 0x02, 0x85, 0x0f, 0x88, 0x7f, 0xab, 0xf7, 0x8b, 0x85,
|
||||
0xe1, 0x90, 0xa5, 0x0b, 0xa6, 0x10, 0x1d, 0x66, 0x4e, 0xcf, 0xea, 0x85, 0xd6, 0x97, 0x98, 0xfb,
|
||||
0xfc, 0xd2, 0xea, 0x7d, 0x67, 0xd9, 0xaf, 0xe4, 0x37, 0x78, 0xbd, 0x0b, 0x24, 0x84, 0xd5, 0x60,
|
||||
0x8b, 0x0f, 0xe5, 0x02, 0xd3, 0xe9, 0xa7, 0xac, 0xb0, 0xb6, 0x91, 0xd3, 0xa6, 0x0c, 0x6c, 0xf6,
|
||||
0x8e, 0x2b, 0x6d, 0x36, 0x1b, 0xd3, 0xe1, 0x26, 0x46, 0xdf, 0x42, 0x16, 0x03, 0x8d, 0x2a, 0x84,
|
||||
0xd8, 0x02, 0x58, 0xfe, 0x67, 0xb6, 0x6e, 0xc0, 0x52, 0x21, 0x0f, 0x00, 0x55, 0xbc, 0x41, 0xb9,
|
||||
0x05, 0xdb, 0x58, 0x9e, 0x42, 0xd9, 0x96, 0x65, 0x7b, 0xf2, 0x90, 0xae, 0x5b, 0x44, 0x38, 0x96,
|
||||
0x0a, 0xad, 0x60, 0x35, 0x20, 0x65, 0x86, 0x29, 0x36, 0xca, 0x6e, 0x5e, 0x72, 0x37, 0xbb, 0x72,
|
||||
0xca, 0x63, 0x9f, 0x27, 0xfa, 0xd8, 0x27, 0xbb, 0xbf, 0x97, 0xe7, 0x81, 0x51, 0x26, 0x13, 0x6b,
|
||||
0x99, 0x73, 0x4e, 0xc1, 0x1e, 0x42, 0xef, 0x83, 0x9b, 0xa4, 0x01, 0x20, 0xd5, 0xa9, 0xd5, 0x46,
|
||||
0x7d, 0x16, 0x5e, 0x9f, 0x85, 0x3b, 0xe7, 0x80, 0x44, 0x1c, 0xb3, 0x37, 0x70, 0x36, 0xdd, 0x0c,
|
||||
0xed, 0xd2, 0x07, 0xbf, 0x9c, 0x18, 0xc3, 0xab, 0x1c, 0x9b, 0xf1, 0xf5, 0x07, 0xc7, 0x08, 0xad,
|
||||
0x94, 0x3b, 0x81, 0xfb, 0x35, 0x44, 0x47, 0x87, 0x4f, 0x39, 0x7e, 0x30, 0x49, 0xe7, 0x38, 0x36,
|
||||
0x60, 0x63, 0xc8, 0x0f, 0xc0, 0x57, 0x28, 0xea, 0x9e, 0x34, 0x6e, 0x64, 0x6a, 0x8b, 0x8e, 0xc4,
|
||||
0x1a, 0x12, 0x1d, 0x46, 0xd7, 0x40, 0x4b, 0xa1, 0x8e, 0xef, 0x8b, 0x5a, 0xe5, 0xc0, 0x96, 0x1f,
|
||||
0xc5, 0xda, 0x6e, 0xe3, 0x95, 0x2e, 0xfe, 0x0d, 0x00, 0xd6, 0x7e, 0x7f, 0xcf, 0x5e, 0x64, 0x2d,
|
||||
0x9d, 0x2e, 0xa2, 0x05, 0xe8, 0xe2, 0x6f, 0x15, 0xb8, 0x81, 0x2d, 0xbf, 0x93, 0xc6, 0x8e, 0x54,
|
||||
0x2c, 0x83, 0xe5, 0x0a, 0x94, 0x50, 0x95, 0xf5, 0x24, 0xb6, 0x9b, 0x97, 0x47, 0x81, 0x0d, 0x10,
|
||||
0xb1, 0x38, 0x11, 0xc5, 0xb6, 0x75, 0x28, 0xfd, 0xee, 0x86, 0x8d, 0xf9, 0x6b, 0x54, 0x7d, 0x8a,
|
||||
0xb1, 0xc0, 0xf4, 0x88, 0x4a, 0xce, 0x2a, 0xd2, 0xd3, 0xa7, 0xdb, 0x30, 0x90, 0xb6, 0xcf, 0xae,
|
||||
0x3f, 0x23, 0x86, 0x15, 0xd2, 0x26, 0x8e, 0x8a, 0xb7, 0xcd, 0x97, 0x6d, 0x58, 0x6a, 0x76, 0xe2,
|
||||
0x54, 0x2b, 0xd1, 0x27, 0x0c, 0x56, 0x73, 0x6c, 0xb2, 0xb6, 0xa2, 0x5e, 0x6d, 0xe3, 0x54, 0x7a,
|
||||
0x81, 0x8e, 0x36, 0x8e, 0xc1, 0xe8, 0x40, 0x4b, 0x13, 0x42, 0x7d, 0x8f, 0x0c, 0xbe, 0x63, 0xb3,
|
||||
0x47, 0xca, 0x17, 0xe2, 0x1a, 0x63, 0x6c, 0x17, 0x20, 0xa3, 0xa3, 0x2f, 0x1d, 0x85, 0x83, 0x9d,
|
||||
0xcb, 0xc1, 0xf1, 0xc9, 0xea, 0xc5, 0x1c, 0x54, 0xa2, 0x61, 0x70, 0x5f, 0x11, 0xe4, 0x93, 0xcd,
|
||||
0x0b, 0x0e, 0xf0, 0x30, 0x98, 0xec, 0x5e, 0xd0, 0x1f, 0x69, 0x96, 0xdb, 0x82, 0xe7, 0xac, 0x8e,
|
||||
0x67, 0x3d, 0x17, 0x26, 0x11, 0x4c, 0xbf, 0x84, 0x12, 0x39, 0x39, 0x3a, 0x82, 0xf7, 0xf7, 0x5d,
|
||||
0xde, 0x0e, 0x51, 0x2d, 0x33, 0xc9, 0xcb, 0x5c, 0xa7, 0x08, 0x64, 0x8d, 0x08, 0x85, 0x19, 0x51,
|
||||
0x59, 0x39, 0x92, 0x62, 0xc2, 0x31, 0x06, 0x56, 0xd4, 0x38, 0x89, 0xd0, 0x00, 0xd6, 0x71, 0x94,
|
||||
0x5f, 0x26, 0x57, 0xad, 0x2b, 0xba, 0xc9, 0xde, 0x9e, 0x9b, 0x9c, 0x05, 0x79, 0xe9, 0x25, 0xc2,
|
||||
0x9e, 0x01, 0xf2, 0x96, 0x01, 0xf4, 0xd5, 0x3d, 0x10, 0x1d, 0x0c, 0x21, 0xf9, 0xb3, 0xcf, 0x9f,
|
||||
0x03, 0x5e, 0xe9, 0x67, 0x7d, 0x2f, 0x04, 0x46, 0xa1, 0x84, 0xf9, 0x8d, 0xa8, 0x1e, 0x80, 0x54,
|
||||
0xd9, 0x20, 0x73, 0x68, 0x78, 0xd6, 0x52, 0xe6, 0xb3, 0x40, 0xa4, 0x61, 0xa9, 0x95, 0x4d, 0x25,
|
||||
0x0a, 0xf5, 0x4d, 0x6d, 0x1e, 0x1a, 0xb5, 0xca, 0xd5, 0xa0, 0xb4, 0x5b, 0x49, 0xfb, 0xcb, 0x14,
|
||||
0x66, 0x35, 0x21, 0xab, 0xab, 0xb9, 0x1c, 0x08, 0x3c, 0x6a, 0x94, 0x53, 0x3f, 0xf0, 0x60, 0xe3,
|
||||
0xe1, 0x48, 0xfb, 0xde, 0x75, 0xbb, 0xfc, 0x1d, 0x0f, 0xc4, 0x21, 0xfe, 0x68, 0x59, 0x0c, 0x1e,
|
||||
0x3c, 0xf8, 0x7d, 0xa1, 0x87, 0xa2, 0xab, 0xf9, 0x15, 0x96, 0x99, 0xc2, 0x0b, 0xf4, 0xea, 0xf0,
|
||||
0xc7, 0x75, 0x6c, 0xc3, 0x6b, 0xa7, 0x84, 0xd0, 0x2e, 0x50, 0x29, 0xc6, 0x7e, 0x08, 0x30, 0x49,
|
||||
0xc5, 0x3a, 0x5c, 0xa1, 0x3e, 0x32, 0xdb, 0x02, 0x13, 0xfe, 0xb0, 0x90, 0x01, 0x91, 0x2e, 0x23,
|
||||
0x46, 0x7b, 0xc4, 0x3d, 0xd4, 0xb6, 0x80, 0x64, 0x75, 0xec, 0x56, 0xd4, 0x34, 0xa8, 0xbc, 0x75,
|
||||
0xe5, 0xa3, 0x7a, 0xc7, 0x03, 0xef, 0x21, 0xbd, 0x93, 0xa7, 0xab, 0x22, 0xfd, 0x3a, 0x8e, 0xbb,
|
||||
0xb2, 0xda, 0xde, 0x55, 0x25, 0xc5, 0xae, 0xa5, 0x2b, 0x44, 0x6d, 0xc9, 0xba, 0x2c, 0x78, 0xd2,
|
||||
0x2f, 0x7c, 0x67, 0x7b, 0x09, 0xea, 0x8e, 0xa4, 0xb4, 0x9b, 0xb0, 0xeb, 0x68, 0xc6, 0x60, 0x0e,
|
||||
0x0f, 0x7f, 0x37, 0x7d, 0x05, 0x0e, 0xf0, 0xfd, 0x7d, 0xd9, 0x06, 0x44, 0x4e, 0xdf, 0xa9, 0x76,
|
||||
0xe7, 0xdc, 0x7e, 0x03, 0xe4, 0x07, 0x99, 0x5d, 0x2c, 0x85, 0xf5, 0xef, 0xff, 0xb1, 0x04, 0x66,
|
||||
0xbf, 0x58, 0xfe, 0xef, 0xff, 0x4d, 0x23, 0x01, 0xd1, 0xf3, 0xc5, 0x3c, 0xca, 0xac, 0x69, 0xc4,
|
||||
0xe3, 0x10, 0x3f, 0xb6, 0x2f, 0x3e, 0x1d, 0xd0, 0xf6, 0xb3, 0x94, 0x49, 0xf3, 0xf0, 0x09, 0xb1,
|
||||
0x2e, 0x32, 0x8e, 0x87, 0xfe, 0x97, 0x1a, 0x1b, 0x57, 0xd2, 0xb5, 0x7a, 0x92, 0xab, 0xc4, 0x2e,
|
||||
0xc1, 0x9f, 0xe1, 0x81, 0x9a, 0x08, 0x72, 0xca, 0xb6, 0x8c, 0x04, 0x84, 0xa9, 0x12, 0xc5, 0xa3,
|
||||
0x92, 0xa0, 0xaa, 0xf0, 0x80, 0xc2, 0x82, 0x05, 0xe0, 0x82, 0x87, 0x14, 0xee, 0x83, 0x76, 0xc3,
|
||||
0xe9, 0x24, 0xc5, 0x28, 0x46, 0x55, 0x44, 0xbc, 0xbf, 0xd7, 0x3c, 0x62, 0xb6, 0x3a, 0x6b, 0x58,
|
||||
0x6a, 0x20, 0x7d, 0xe2, 0x8d, 0x08, 0x84, 0x2a, 0x64, 0xf8, 0x41, 0x84, 0x7c, 0x03, 0xd3, 0x64,
|
||||
0x20, 0xa9, 0x4f, 0x00, 0x6a, 0x8c, 0x4c, 0xff, 0x8e, 0x00, 0x83, 0x72, 0xec, 0x3a, 0x30, 0x15,
|
||||
0xd5, 0x68, 0xd3, 0x44, 0x68, 0xba, 0x9f, 0x3f, 0xef, 0xd3, 0x3d, 0x9d, 0x3e, 0x28, 0x19, 0x77,
|
||||
0x90, 0xc8, 0x35, 0xd6, 0x57, 0xbf, 0xe1, 0x61, 0x3b, 0x85, 0xba, 0xe3, 0xc5, 0xe9, 0x22, 0xa9,
|
||||
0x52, 0x55, 0x3b, 0x71, 0x7f, 0x4f, 0xe5, 0x75, 0x88, 0x1f, 0x60, 0x9c, 0xa2, 0x31, 0x51, 0x65,
|
||||
0x30, 0x79, 0x95, 0x1f, 0xba, 0x76, 0xf5, 0x67, 0x3e, 0xd0, 0x30, 0x83, 0xf2, 0xdb, 0x66, 0xb5,
|
||||
0x9b, 0xc6, 0xb4, 0x36, 0xba, 0x76, 0xfa, 0x2d, 0x1c, 0x1c, 0x42, 0xea, 0x06, 0xd3, 0x1e, 0x01,
|
||||
0x78, 0x1b, 0x80, 0x32, 0x4a, 0xee, 0xac, 0xdb, 0xc4, 0xa8, 0xbe, 0x49, 0xb6, 0x03, 0xbc, 0xec,
|
||||
0xf9, 0x73, 0x3d, 0x81, 0x5c, 0x14, 0x54, 0x1c, 0xe8, 0x22, 0xb6, 0x79, 0x52, 0x3d, 0x09, 0x02,
|
||||
0x81, 0xfe, 0xd4, 0x72, 0xc3, 0xae, 0xb2, 0x89, 0x45, 0x3d, 0xbf, 0xd3, 0xa2, 0xe0, 0xf4, 0x2f,
|
||||
0x06, 0x82, 0x8c, 0x03, 0xbb, 0x36, 0x85, 0x73, 0xb3, 0xdb, 0x24, 0x62, 0xb9, 0x6d, 0x02, 0x57,
|
||||
0x9e, 0x50, 0x49, 0x0e, 0x51, 0x54, 0xa7, 0x6f, 0x7d, 0xa6, 0x3c, 0x95, 0x8d, 0xa3, 0x6a, 0x65,
|
||||
0x86, 0xd9, 0x1f, 0xcf, 0x89, 0x2a, 0xcb, 0xcb, 0xef, 0x0e, 0x9c, 0x8a, 0xef, 0xf2, 0x81, 0x72,
|
||||
0x24, 0x94, 0x74, 0x2f, 0xbe, 0x99, 0x7f, 0xf2, 0xc1, 0x35, 0x94, 0xce, 0x4e, 0x9b, 0xa0, 0x20,
|
||||
0x4c, 0xe9, 0x79, 0x05, 0x83, 0x8a, 0xcb, 0xf4, 0xf0, 0xe2, 0xac, 0xad, 0x65, 0xf0, 0x9c, 0x3e,
|
||||
0xed, 0x75, 0x4d, 0x99, 0x6f, 0x03, 0xdc, 0x88, 0xce, 0x40, 0x80, 0xa8, 0xd4, 0x18, 0x85, 0x96,
|
||||
0x39, 0x66, 0x79, 0x8a, 0xf1, 0xb2, 0x44, 0x43, 0xde, 0xbe, 0x67, 0x66, 0xee, 0x59, 0x9f, 0x68,
|
||||
0x99, 0x3d, 0xed, 0x4f, 0xfc, 0x42, 0x83, 0xe4, 0x7b, 0xd4, 0x82, 0xbc, 0x66, 0x85, 0xf6, 0x03,
|
||||
0x58, 0x2c, 0x4b, 0x8c, 0x5a, 0xaa, 0x80, 0xcc, 0xb2, 0x8d, 0x7c, 0x97, 0xaa, 0xae, 0xca, 0x41,
|
||||
0xeb, 0xe6, 0xd1, 0x42, 0x21, 0x70, 0x85, 0xca, 0x3a, 0xaf, 0x64, 0x53, 0x2b, 0x1a, 0x1a, 0x25,
|
||||
0xba, 0x4a, 0xd0, 0x7e, 0x6f, 0x54, 0x74, 0x59, 0xba, 0xc4, 0x3d, 0x54, 0x95, 0x58, 0xf6, 0xa7,
|
||||
0x1c, 0xbe, 0x18, 0x38, 0xc2, 0x5a, 0xfe, 0xdd, 0x31, 0x53, 0xe4, 0xfe, 0x74, 0x6d, 0x6c, 0xf9,
|
||||
0xf5, 0x63, 0xa3, 0x38, 0x56, 0xc5, 0x91, 0x5c, 0x1d, 0xaf, 0xab, 0x12, 0x43, 0xf3, 0x74, 0xcc,
|
||||
0x7d, 0xd2, 0x77, 0xfc, 0x4a, 0x8b, 0x51, 0xb1, 0xf2, 0xd8, 0x31, 0xda, 0x7a, 0xe3, 0x56, 0x0f,
|
||||
0xca, 0xb1, 0x96, 0x05, 0xab, 0x46, 0x37, 0x4e, 0xa1, 0x6b, 0x9a, 0x4b, 0x3a, 0x26, 0x83, 0xd4,
|
||||
0xbf, 0x9e, 0xf8, 0x24, 0x0e, 0xa9, 0x1d, 0x53, 0x83, 0xa7, 0x22, 0x99, 0x52, 0x91, 0x5a, 0x1d,
|
||||
0xf4, 0x17, 0x36, 0x7b, 0xa2, 0x57, 0xf1, 0x6e, 0xd2, 0x28, 0xe7, 0x94, 0x98, 0x56, 0xb5, 0xd9,
|
||||
0xfa, 0x78, 0xcd, 0xc6, 0x46, 0x08, 0x89, 0x97, 0x11, 0xa7, 0x8f, 0xb7, 0x26, 0x25, 0x60, 0x06,
|
||||
0x6d, 0x8b, 0xb9, 0x43, 0x8f, 0xdf, 0xf2, 0xc9, 0x2b, 0x99, 0x45, 0xc0, 0x1c, 0xeb, 0xf2, 0xce,
|
||||
0xfe, 0xb4, 0xa9, 0x1a, 0x55, 0xa1, 0x06, 0x6e, 0x6a, 0x9f, 0x62, 0x3c, 0xa6, 0x82, 0xda, 0xea,
|
||||
0xa6, 0x9b, 0x67, 0xf8, 0x79, 0xbd, 0x70, 0xa3, 0x96, 0x61, 0xb3, 0x49, 0xec, 0xec, 0xbd, 0x2e,
|
||||
0xe6, 0xb2, 0x5e, 0x03, 0x77, 0x3b, 0xe8, 0x37, 0xa0, 0xdb, 0x0b, 0x9a, 0x39, 0x2f, 0x35, 0x5b,
|
||||
0x79, 0xa0, 0xb6, 0x83, 0x6e, 0x53, 0xc7, 0x72, 0xb9, 0x3e, 0x96, 0x33, 0xf5, 0xd5, 0xf6, 0xf3,
|
||||
0xb8, 0x91, 0x79, 0x5a, 0xa8, 0x8e, 0x44, 0x6f, 0xdc, 0xca, 0x59, 0xa1, 0xae, 0xd8, 0xd7, 0x60,
|
||||
0xe9, 0x5d, 0xed, 0x04, 0x54, 0x81, 0x90, 0x07, 0x60, 0x19, 0x85, 0x0d, 0x83, 0x5c, 0xac, 0x51,
|
||||
0xaf, 0xc7, 0xa7, 0xc4, 0x66, 0x5e, 0xad, 0xba, 0x2f, 0xc8, 0x59, 0xfb, 0x4d, 0x84, 0x36, 0x08,
|
||||
0xc9, 0x4f, 0x7d, 0x10, 0x40, 0x70, 0x27, 0xf2, 0xd3, 0x60, 0x78, 0x74, 0x74, 0x9e, 0xfb, 0xf0,
|
||||
0x77, 0xd4, 0x38, 0x6a, 0x55, 0xf8, 0x60, 0x6e, 0xb1, 0x25, 0xd5, 0xd0, 0x84, 0xe3, 0x33, 0x41,
|
||||
0x18, 0x6d, 0xd9, 0x8e, 0x5c, 0x27, 0xd7, 0xeb, 0xe8, 0x62, 0x92, 0xcf, 0xb1, 0x7c, 0xad, 0x46,
|
||||
0xaf, 0x8d, 0x36, 0x64, 0x07, 0xf3, 0xd6, 0x00, 0x64, 0x44, 0x3e, 0x57, 0x6b, 0xe1, 0xcb, 0xe3,
|
||||
0xfe, 0x81, 0xfd, 0xd9, 0xdf, 0x28, 0x62, 0xe0, 0xa3, 0x3e, 0x45, 0x05, 0x4b, 0xd5, 0x1e, 0xb3,
|
||||
0x15, 0x22, 0xde, 0x3c, 0xb4, 0xd9, 0x89, 0x6d, 0xb5, 0xfe, 0x37, 0x89, 0xd2, 0xe4, 0xd2, 0x96,
|
||||
0xc9, 0xab, 0xd0, 0x6c, 0x61, 0xd4, 0xca, 0x59, 0xfb, 0x7f, 0x10, 0x9e, 0xea, 0xbc, 0x3b, 0x81,
|
||||
0x62, 0x18, 0xb6, 0x1d, 0xd9, 0xa8, 0xb9, 0xac, 0x69, 0x1c, 0x59, 0x95, 0x0f, 0xca, 0x3a, 0x83,
|
||||
0xc4, 0x80, 0x3c, 0x39, 0x57, 0x25, 0xdd, 0x5f, 0xbe, 0x9d, 0x5a, 0x77, 0x62, 0x65, 0xdd, 0xb0,
|
||||
0x04, 0x68, 0x1c, 0x03, 0x7d, 0xe5, 0x2f, 0xcb, 0x99, 0x1f, 0x2b, 0x63, 0x50, 0x09, 0x36, 0x2e,
|
||||
0x47, 0x6e, 0xb0, 0xfb, 0xf6, 0x97, 0xae, 0xad, 0x7e, 0xf0, 0xd3, 0x76, 0xb1, 0x7c, 0xdf, 0x65,
|
||||
0xc0, 0xb5, 0xf9, 0xd7, 0x39, 0xb8, 0x25, 0x63, 0x88, 0xba, 0x60, 0x47, 0xf4, 0x39, 0xaa, 0xed,
|
||||
0xaa, 0xef, 0x51, 0xb1, 0xea, 0xd8, 0x69, 0xb2, 0x09, 0xe1, 0x02, 0xac, 0xf2, 0x23, 0xa3, 0x5f,
|
||||
0xb4, 0x8d, 0x55, 0x79, 0xa4, 0xd2, 0x88, 0x18, 0x91, 0xf1, 0xc3, 0x96, 0xd5, 0x6a, 0xa5, 0x68,
|
||||
0x9d, 0x10, 0x28, 0x73, 0x86, 0xab, 0xe7, 0xac, 0xb7, 0xb8, 0x0e, 0xb2, 0x6e, 0x44, 0x67, 0x49,
|
||||
0xb7, 0x24, 0x2f, 0x5a, 0xcb, 0x01, 0x2b, 0xd9, 0x9a, 0x51, 0x55, 0x82, 0xf5, 0x37, 0x85, 0x60,
|
||||
0xdf, 0xcf, 0xb7, 0x64, 0xac, 0x94, 0xdf, 0xd1, 0x52, 0x06, 0x07, 0x18, 0xe5, 0xad, 0xa8, 0xae,
|
||||
0x0d, 0x81, 0x9e, 0x20, 0xa2, 0xf8, 0xc9, 0xb6, 0xfc, 0x9a, 0x0e, 0x7f, 0xfd, 0x8f, 0xfe, 0x5f,
|
||||
0xd4, 0xfe, 0x0f, 0xbf, 0x30, 0xb3, 0x23, 0x56, 0x6d, 0x00, 0x00
|
||||
};
|
File diff suppressed because it is too large
Load Diff
1141
wled00/html_simple.h
1141
wled00/html_simple.h
File diff suppressed because it is too large
Load Diff
2060
wled00/html_ui.h
2060
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -643,8 +643,8 @@ void decodeIRJson(uint32_t code)
|
||||
// this may fail for two reasons: ir.json does not exist or IR code not found
|
||||
// if the IR code is not found readObjectFromFile() will clean() doc JSON document
|
||||
// so we can differentiate between the two
|
||||
readObjectFromFile("/ir.json", objKey, &doc);
|
||||
fdo = doc.as<JsonObject>();
|
||||
readObjectFromFile("/ir.json", objKey, pDoc);
|
||||
fdo = pDoc->as<JsonObject>();
|
||||
lastValidCode = 0;
|
||||
if (fdo.isNull()) {
|
||||
//the received code does not exist
|
||||
|
@ -117,9 +117,8 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
if (stop > start && of > len -1) of = len -1;
|
||||
|
||||
// update segment (delete if necessary)
|
||||
// do not call seg.setUp() here, as it may cause a crash due to concurrent access if the segment is currently drawing effects
|
||||
// WS2812FX handles queueing of the change
|
||||
strip.setSegment(id, start, stop, grp, spc, of, startY, stopY);
|
||||
seg.setUp(start, stop, grp, spc, of, startY, stopY); // strip needs to be suspended for this to work without issues
|
||||
|
||||
if (newSeg) seg.refreshLightCapabilities(); // fix for #3403
|
||||
|
||||
if (seg.reset && seg.stop == 0) {
|
||||
@ -210,7 +209,14 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
#endif
|
||||
|
||||
byte fx = seg.mode;
|
||||
if (getVal(elem["fx"], &fx, 0, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 0-255 exact value)
|
||||
byte last = strip.getModeCount();
|
||||
// partial fix for #3605
|
||||
if (!elem["fx"].isNull() && elem["fx"].is<const char*>()) {
|
||||
const char *tmp = elem["fx"].as<const char *>();
|
||||
if (strlen(tmp) > 3 && (strchr(tmp,'r') || strchr(tmp,'~') != strrchr(tmp,'~'))) last = 0; // we have "X~Y(r|[w]~[-])" form
|
||||
}
|
||||
// end fix
|
||||
if (getVal(elem["fx"], &fx, 0, last)) { //load effect ('r' random, '~' inc/dec, 0-255 exact value, 5~10r pick random between 5 & 10)
|
||||
if (!presetId && currentPlaylist>=0) unloadPlaylist();
|
||||
if (fx != seg.mode) seg.setMode(fx, elem[F("fxdef")]);
|
||||
}
|
||||
@ -381,6 +387,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
|
||||
int it = 0;
|
||||
JsonVariant segVar = root["seg"];
|
||||
if (!segVar.isNull()) strip.suspend();
|
||||
if (segVar.is<JsonObject>())
|
||||
{
|
||||
int id = segVar["id"] | -1;
|
||||
@ -408,6 +415,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
}
|
||||
if (strip.getSegmentsNum() > 3 && deleted >= strip.getSegmentsNum()/2U) strip.purgeSegments(); // batch deleting more than half segments
|
||||
}
|
||||
strip.resume();
|
||||
|
||||
usermods.readFromJsonState(root);
|
||||
|
||||
@ -616,18 +624,18 @@ void serializeInfo(JsonObject root)
|
||||
root[F("vid")] = VERSION;
|
||||
root[F("cn")] = F(WLED_CODENAME);
|
||||
|
||||
JsonObject leds = root.createNestedObject("leds");
|
||||
JsonObject leds = root.createNestedObject(F("leds"));
|
||||
leds[F("count")] = strip.getLengthTotal();
|
||||
leds[F("pwr")] = strip.currentMilliamps;
|
||||
leds[F("pwr")] = BusManager::currentMilliamps();
|
||||
leds["fps"] = strip.getFps();
|
||||
leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0;
|
||||
leds[F("maxpwr")] = BusManager::currentMilliamps()>0 ? BusManager::ablMilliampsMax() : 0;
|
||||
leds[F("maxseg")] = strip.getMaxSegments();
|
||||
//leds[F("actseg")] = strip.getActiveSegmentsNum();
|
||||
//leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config
|
||||
|
||||
#ifndef WLED_DISABLE_2D
|
||||
if (strip.isMatrix) {
|
||||
JsonObject matrix = leds.createNestedObject("matrix");
|
||||
JsonObject matrix = leds.createNestedObject(F("matrix"));
|
||||
matrix["w"] = Segment::maxWidth;
|
||||
matrix["h"] = Segment::maxHeight;
|
||||
}
|
||||
@ -663,6 +671,7 @@ void serializeInfo(JsonObject root)
|
||||
|
||||
root[F("name")] = serverDescription;
|
||||
root[F("udpport")] = udpPort;
|
||||
root[F("simplifiedui")] = simplifiedUI;
|
||||
root["live"] = (bool)realtimeMode;
|
||||
root[F("liveseg")] = useMainSegmentOnly ? strip.getMainSegmentId() : -1; // if using main segment only for live
|
||||
|
||||
@ -706,7 +715,7 @@ void serializeInfo(JsonObject root)
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject wifi_info = root.createNestedObject("wifi");
|
||||
JsonObject wifi_info = root.createNestedObject(F("wifi"));
|
||||
wifi_info[F("bssid")] = WiFi.BSSIDstr();
|
||||
int qrssi = WiFi.RSSI();
|
||||
wifi_info[F("rssi")] = qrssi;
|
||||
@ -1021,15 +1030,19 @@ void serializeModeNames(JsonArray arr)
|
||||
}
|
||||
}
|
||||
|
||||
static volatile bool servingClient = false;
|
||||
|
||||
// Global buffer locking response helper class
|
||||
class GlobalBufferAsyncJsonResponse: public JSONBufferGuard, public AsyncJsonResponse {
|
||||
public:
|
||||
inline GlobalBufferAsyncJsonResponse(bool isArray) : JSONBufferGuard(17), AsyncJsonResponse(pDoc, isArray) {};
|
||||
virtual ~GlobalBufferAsyncJsonResponse() {};
|
||||
|
||||
// Other members are inherited
|
||||
};
|
||||
|
||||
|
||||
void serveJson(AsyncWebServerRequest* request)
|
||||
{
|
||||
if (servingClient) {
|
||||
serveJsonError(request, 503, ERR_CONCURRENCY);
|
||||
return;
|
||||
}
|
||||
servingClient = true;
|
||||
|
||||
byte subJson = 0;
|
||||
const String& url = request->url();
|
||||
if (url.indexOf("state") > 0) subJson = JSON_PATH_STATE;
|
||||
@ -1043,31 +1056,27 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
#ifdef WLED_ENABLE_JSONLIVE
|
||||
else if (url.indexOf("live") > 0) {
|
||||
serveLiveLeds(request);
|
||||
servingClient = false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
else if (url.indexOf("pal") > 0) {
|
||||
request->send_P(200, "application/json", JSON_palette_names);
|
||||
servingClient = false;
|
||||
return;
|
||||
}
|
||||
else if (url.indexOf("cfg") > 0 && handleFileRead(request, "/cfg.json")) {
|
||||
servingClient = false;
|
||||
return;
|
||||
}
|
||||
else if (url.length() > 6) { //not just /json
|
||||
serveJsonError(request, 501, ERR_NOT_IMPL);
|
||||
servingClient = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!requestJSONBufferLock(17)) {
|
||||
GlobalBufferAsyncJsonResponse *response = new GlobalBufferAsyncJsonResponse(subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
|
||||
if (!response->owns_lock()) {
|
||||
serveJsonError(request, 503, ERR_NOBUF);
|
||||
servingClient = false;
|
||||
delete response;
|
||||
return;
|
||||
}
|
||||
AsyncJsonResponse *response = new AsyncJsonResponse(&doc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
|
||||
|
||||
JsonVariant lDoc = response->getRoot();
|
||||
|
||||
@ -1110,8 +1119,6 @@ void serveJson(AsyncWebServerRequest* request)
|
||||
DEBUG_PRINT(F("JSON content length: ")); DEBUG_PRINTLN(len);
|
||||
|
||||
request->send(response);
|
||||
releaseJSONBufferLock();
|
||||
servingClient = false;
|
||||
}
|
||||
|
||||
#ifdef WLED_ENABLE_JSONLIVE
|
||||
|
@ -109,8 +109,8 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties
|
||||
return;
|
||||
}
|
||||
if (payloadStr[0] == '{') { //JSON API
|
||||
deserializeJson(doc, payloadStr);
|
||||
deserializeState(doc.as<JsonObject>());
|
||||
deserializeJson(*pDoc, payloadStr);
|
||||
deserializeState(pDoc->as<JsonObject>());
|
||||
} else { //HTTP API
|
||||
String apireq = "win"; apireq += '&'; // reduce flash string usage
|
||||
apireq += payloadStr;
|
||||
|
@ -15,11 +15,11 @@ void _overlayAnalogClock()
|
||||
float minuteP = ((float)minute(localTime))/60.0f;
|
||||
hourP = hourP + minuteP/12.0f;
|
||||
float secondP = ((float)second(localTime))/60.0f;
|
||||
int hourPixel = floorf(analogClock12pixel + overlaySize*hourP);
|
||||
unsigned hourPixel = floorf(analogClock12pixel + overlaySize*hourP);
|
||||
if (hourPixel > overlayMax) hourPixel = overlayMin -1 + hourPixel - overlayMax;
|
||||
int minutePixel = floorf(analogClock12pixel + overlaySize*minuteP);
|
||||
unsigned minutePixel = floorf(analogClock12pixel + overlaySize*minuteP);
|
||||
if (minutePixel > overlayMax) minutePixel = overlayMin -1 + minutePixel - overlayMax;
|
||||
int secondPixel = floorf(analogClock12pixel + overlaySize*secondP);
|
||||
unsigned secondPixel = floorf(analogClock12pixel + overlaySize*secondP);
|
||||
if (secondPixel > overlayMax) secondPixel = overlayMin -1 + secondPixel - overlayMax;
|
||||
if (analogClockSecondsTrail)
|
||||
{
|
||||
@ -36,7 +36,7 @@ void _overlayAnalogClock()
|
||||
{
|
||||
for (byte i = 0; i <= 12; i++)
|
||||
{
|
||||
int pix = analogClock12pixel + roundf((overlaySize / 12.0f) *i);
|
||||
unsigned pix = analogClock12pixel + roundf((overlaySize / 12.0f) *i);
|
||||
if (pix > overlayMax) pix -= overlaySize;
|
||||
strip.setPixelColor(pix, 0x00FFAA);
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag)
|
||||
// Check if supplied GPIO is ok to use
|
||||
bool PinManagerClass::isPinOk(byte gpio, bool output)
|
||||
{
|
||||
#ifdef ESP32
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
if (digitalPinIsValid(gpio)) {
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
// strapping pins: 2, 8, & 9
|
||||
@ -257,6 +257,9 @@ bool PinManagerClass::isPinOk(byte gpio, bool output)
|
||||
// GPIO46 is input only and pulled down
|
||||
#else
|
||||
if (gpio > 5 && gpio < 12) return false; //SPI flash pins
|
||||
#ifdef BOARD_HAS_PSRAM
|
||||
if (gpio == 16 || gpio == 17) return false; //PSRAM pins
|
||||
#endif
|
||||
#endif
|
||||
if (output) return digitalPinCanOutput(gpio);
|
||||
else return true;
|
||||
|
@ -41,7 +41,7 @@ enum struct PinOwner : uint8_t {
|
||||
UM_Temperature = USERMOD_ID_TEMPERATURE, // 0x03 // Usermod "usermod_temperature.h"
|
||||
// #define USERMOD_ID_FIXNETSERVICES // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins
|
||||
UM_PIR = USERMOD_ID_PIRSWITCH, // 0x05 // Usermod "usermod_PIR_sensor_switch.h"
|
||||
// #define USERMOD_ID_IMU // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" HW_I2C pins
|
||||
UM_IMU = USERMOD_ID_IMU, // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Interrupt pin
|
||||
UM_FourLineDisplay = USERMOD_ID_FOUR_LINE_DISP, // 0x07 // Usermod "usermod_v2_four_line_display.h -- May use "standard" HW_I2C pins
|
||||
UM_RotaryEncoderUI = USERMOD_ID_ROTARY_ENC_UI, // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h"
|
||||
// #define USERMOD_ID_AUTO_SAVE // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins
|
||||
|
@ -24,10 +24,12 @@ static void doSaveState() {
|
||||
bool persist = (presetToSave < 251);
|
||||
const char *filename = getFileName(persist);
|
||||
|
||||
unsigned long start = millis();
|
||||
while (strip.isUpdating() && millis()-start < (2*FRAMETIME_FIXED)+1) yield(); // wait 2 frames
|
||||
if (!requestJSONBufferLock(10)) return; // will set fileDoc
|
||||
|
||||
initPresetsFile(); // just in case if someone deleted presets.json using /edit
|
||||
JsonObject sObj = doc.to<JsonObject>();
|
||||
JsonObject sObj = pDoc->to<JsonObject>();
|
||||
|
||||
DEBUG_PRINTLN(F("Serialize current state"));
|
||||
if (playlistSave) {
|
||||
@ -42,7 +44,7 @@ static void doSaveState() {
|
||||
/*
|
||||
#ifdef WLED_DEBUG
|
||||
DEBUG_PRINTLN(F("Serialized preset"));
|
||||
serializeJson(doc,Serial);
|
||||
serializeJson(*pDoc,Serial);
|
||||
DEBUG_PRINTLN();
|
||||
#endif
|
||||
*/
|
||||
@ -83,9 +85,9 @@ bool getPresetName(byte index, String& name)
|
||||
{
|
||||
if (!requestJSONBufferLock(9)) return false;
|
||||
bool presetExists = false;
|
||||
if (readObjectFromFileUsingId(getFileName(), index, &doc))
|
||||
if (readObjectFromFileUsingId(getFileName(), index, pDoc))
|
||||
{
|
||||
JsonObject fdo = doc.as<JsonObject>();
|
||||
JsonObject fdo = pDoc->as<JsonObject>();
|
||||
if (fdo["n"]) {
|
||||
name = (const char*)(fdo["n"]);
|
||||
presetExists = true;
|
||||
@ -132,7 +134,9 @@ void applyPresetWithFallback(uint8_t index, uint8_t callMode, uint8_t effectID,
|
||||
void handlePresets()
|
||||
{
|
||||
if (presetToSave) {
|
||||
strip.suspend();
|
||||
doSaveState();
|
||||
strip.resume();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -123,8 +123,8 @@ static bool remoteJson(int button)
|
||||
sprintf_P(objKey, PSTR("\"%d\":"), button);
|
||||
|
||||
// attempt to read command from remote.json
|
||||
readObjectFromFile("/remote.json", objKey, &doc);
|
||||
JsonObject fdo = doc.as<JsonObject>();
|
||||
readObjectFromFile("/remote.json", objKey, pDoc);
|
||||
JsonObject fdo = pDoc->as<JsonObject>();
|
||||
if (fdo.isNull()) {
|
||||
// the received button does not exist
|
||||
if (!WLED_FS.exists("/remote.json")) errorFlag = ERR_FS_RMLOAD; //warn if file itself doesn't exist
|
||||
|
57
wled00/set.cpp
Normal file → Executable file
57
wled00/set.cpp
Normal file → Executable file
@ -46,6 +46,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
if (t != apChannel) forceReconnect = true;
|
||||
if (t > 0 && t < 14) apChannel = t;
|
||||
|
||||
force802_3g = request->hasArg(F("FG"));
|
||||
noWifiSleep = request->hasArg(F("WS"));
|
||||
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
@ -98,8 +99,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
uint16_t length, start, maMax;
|
||||
uint8_t pins[5] = {255, 255, 255, 255, 255};
|
||||
|
||||
strip.ablMilliampsMax = request->arg(F("MA")).toInt();
|
||||
//strip.milliampsPerLed = request->arg(F("LA")).toInt();
|
||||
uint16_t ablMilliampsMax = request->arg(F("MA")).toInt();
|
||||
BusManager::setMilliampsMax(ablMilliampsMax);
|
||||
|
||||
autoSegments = request->hasArg(F("MS"));
|
||||
correctWB = request->hasArg(F("CCT"));
|
||||
@ -145,30 +146,30 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
break; // no parameter
|
||||
}
|
||||
awmode = request->arg(aw).toInt();
|
||||
uint16_t freqHz = request->arg(sp).toInt();
|
||||
if (type > TYPE_ONOFF && type < 49) {
|
||||
switch (freqHz) {
|
||||
case 0 : freqHz = WLED_PWM_FREQ/3; break;
|
||||
case 1 : freqHz = WLED_PWM_FREQ/2; break;
|
||||
uint16_t freq = request->arg(sp).toInt();
|
||||
if (IS_PWM(type)) {
|
||||
switch (freq) {
|
||||
case 0 : freq = WLED_PWM_FREQ/3; break;
|
||||
case 1 : freq = WLED_PWM_FREQ/2; break;
|
||||
default:
|
||||
case 2 : freqHz = WLED_PWM_FREQ; break;
|
||||
case 3 : freqHz = WLED_PWM_FREQ*2; break;
|
||||
case 4 : freqHz = WLED_PWM_FREQ*3; break;
|
||||
case 2 : freq = WLED_PWM_FREQ; break;
|
||||
case 3 : freq = WLED_PWM_FREQ*4/3; break;
|
||||
case 4 : freq = WLED_PWM_FREQ*2; break;
|
||||
}
|
||||
} else if (type > 48 && type < 64) {
|
||||
switch (freqHz) {
|
||||
} else if (IS_DIGITAL(type) && IS_2PIN(type)) {
|
||||
switch (freq) {
|
||||
default:
|
||||
case 0 : freqHz = 1000; break;
|
||||
case 1 : freqHz = 2000; break;
|
||||
case 2 : freqHz = 5000; break;
|
||||
case 3 : freqHz = 10000; break;
|
||||
case 4 : freqHz = 20000; break;
|
||||
case 0 : freq = 1000; break;
|
||||
case 1 : freq = 2000; break;
|
||||
case 2 : freq = 5000; break;
|
||||
case 3 : freq = 10000; break;
|
||||
case 4 : freq = 20000; break;
|
||||
}
|
||||
} else {
|
||||
freqHz = 0;
|
||||
freq = 0;
|
||||
}
|
||||
channelSwap = Bus::hasWhite(type) ? request->arg(wo).toInt() : 0;
|
||||
if ((type > TYPE_TM1814 && type < TYPE_WS2801) || type >= TYPE_NET_DDP_RGB) { // analog and virtual
|
||||
if (type == TYPE_ONOFF || IS_PWM(type) || IS_VIRTUAL(type)) { // analog and virtual
|
||||
maPerLed = 0;
|
||||
maMax = 0;
|
||||
} else {
|
||||
@ -179,7 +180,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
// actual finalization is done in WLED::loop() (removing old busses and adding new)
|
||||
// this may happen even before this loop is finished so we do "doInitBusses" after the loop
|
||||
if (busConfigs[s] != nullptr) delete busConfigs[s];
|
||||
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freqHz, useGlobalLedBuffer, maPerLed, maMax);
|
||||
busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, useGlobalLedBuffer, maPerLed, maMax);
|
||||
busesChanged = true;
|
||||
}
|
||||
//doInitBusses = busesChanged; // we will do that below to ensure all input data is processed
|
||||
@ -189,14 +190,16 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
char xs[4] = "XS"; xs[2] = 48+s; xs[3] = 0; //start LED
|
||||
char xc[4] = "XC"; xc[2] = 48+s; xc[3] = 0; //strip length
|
||||
char xo[4] = "XO"; xo[2] = 48+s; xo[3] = 0; //color order
|
||||
char xw[4] = "XW"; xw[2] = 48+s; xw[3] = 0; //W swap
|
||||
if (request->hasArg(xs)) {
|
||||
start = request->arg(xs).toInt();
|
||||
length = request->arg(xc).toInt();
|
||||
colorOrder = request->arg(xo).toInt();
|
||||
colorOrder = request->arg(xo).toInt() & 0x0F;
|
||||
colorOrder |= (request->arg(xw).toInt() & 0x0F) << 4; // add W swap information
|
||||
com.add(start, length, colorOrder);
|
||||
}
|
||||
}
|
||||
busses.updateColorOrderMap(com);
|
||||
BusManager::updateColorOrderMap(com);
|
||||
|
||||
// upate other pins
|
||||
int hw_ir_pin = request->arg(F("IR")).toInt();
|
||||
@ -303,13 +306,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
{
|
||||
strlcpy(serverDescription, request->arg(F("DS")).c_str(), 33);
|
||||
//syncToggleReceive = request->hasArg(F("ST"));
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
if (simplifiedUI ^ request->hasArg(F("SU"))) {
|
||||
// UI selection changed, invalidate browser cache
|
||||
cacheInvalidate++;
|
||||
}
|
||||
simplifiedUI = request->hasArg(F("SU"));
|
||||
#endif
|
||||
DEBUG_PRINTLN(F("Enumerating ledmaps"));
|
||||
enumerateLedmaps();
|
||||
DEBUG_PRINTLN(F("Loading custom palettes"));
|
||||
@ -341,7 +338,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
notifyButton = request->hasArg(F("SB"));
|
||||
notifyAlexa = request->hasArg(F("SA"));
|
||||
notifyHue = request->hasArg(F("SH"));
|
||||
notifyMacro = request->hasArg(F("SM"));
|
||||
|
||||
t = request->arg(F("UR")).toInt();
|
||||
if ((t>=0) && (t<30)) udpNumRetries = t;
|
||||
@ -353,6 +349,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
|
||||
receiveDirect = request->hasArg(F("RD")); // UDP realtime
|
||||
useMainSegmentOnly = request->hasArg(F("MO"));
|
||||
realtimeRespectLedMaps = request->hasArg(F("RLM"));
|
||||
e131SkipOutOfSequence = request->hasArg(F("ES"));
|
||||
e131Multicast = request->hasArg(F("EM"));
|
||||
t = request->arg(F("EP")).toInt();
|
||||
@ -631,7 +628,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject um = doc.createNestedObject("um");
|
||||
JsonObject um = pDoc->createNestedObject("um");
|
||||
|
||||
size_t args = request->args();
|
||||
uint16_t j=0;
|
||||
|
@ -286,10 +286,10 @@ void parseNotifyPacket(uint8_t *udpIn) {
|
||||
uint16_t stopY = version > 11 ? (udpIn[34+ofs] << 8 | udpIn[35+ofs]) : 1;
|
||||
uint16_t offset = (udpIn[7+ofs] << 8 | udpIn[8+ofs]);
|
||||
if (!receiveSegmentOptions) {
|
||||
//selseg.setUp(start, stop, selseg.grouping, selseg.spacing, offset, startY, stopY);
|
||||
// we have to use strip.setSegment() instead of selseg.setUp() to prevent crash if segment would change during drawing
|
||||
DEBUG_PRINTF("Set segment w/o options: %d [%d,%d;%d,%d]\n", id, (int)start, (int)stop, (int)startY, (int)stopY);
|
||||
strip.setSegment(id, start, stop, selseg.grouping, selseg.spacing, offset, startY, stopY);
|
||||
strip.suspend(); //should not be needed as UDP handling is not done in ISR callbacks but still added "just in case"
|
||||
selseg.setUp(start, stop, selseg.grouping, selseg.spacing, offset, startY, stopY);
|
||||
strip.resume();
|
||||
continue; // we do receive bounds, but not options
|
||||
}
|
||||
selseg.options = (selseg.options & 0x0071U) | (udpIn[9 +ofs] & 0x0E); // ignore selected, freeze, reset & transitional
|
||||
@ -326,12 +326,14 @@ void parseNotifyPacket(uint8_t *udpIn) {
|
||||
}
|
||||
if (receiveSegmentBounds) {
|
||||
DEBUG_PRINTF("Set segment w/ options: %d [%d,%d;%d,%d]\n", id, (int)start, (int)stop, (int)startY, (int)stopY);
|
||||
// we have to use strip.setSegment() instead of selseg.setUp() to prevent crash if segment would change during drawing
|
||||
strip.setSegment(id, start, stop, udpIn[5+ofs], udpIn[6+ofs], offset, startY, stopY);
|
||||
strip.suspend(); //should not be needed as UDP handling is not done in ISR callbacks but still added "just in case"
|
||||
selseg.setUp(start, stop, udpIn[5+ofs], udpIn[6+ofs], offset, startY, stopY);
|
||||
strip.resume();
|
||||
} else {
|
||||
// we have to use strip.setSegment() instead of selseg.setUp() to prevent crash if segment would change during drawing
|
||||
DEBUG_PRINTF("Set segment grouping: %d [%d,%d]\n", id, (int)udpIn[5+ofs], (int)udpIn[6+ofs]);
|
||||
strip.setSegment(id, selseg.start, selseg.stop, udpIn[5+ofs], udpIn[6+ofs], selseg.offset, selseg.startY, selseg.stopY);
|
||||
strip.suspend(); //should not be needed as UDP handling is not done in ISR callbacks but still added "just in case"
|
||||
selseg.setUp(selseg.start, selseg.stop, udpIn[5+ofs], udpIn[6+ofs], selseg.offset, selseg.startY, selseg.stopY);
|
||||
strip.resume();
|
||||
}
|
||||
}
|
||||
stateChanged = true;
|
||||
@ -434,6 +436,8 @@ void exitRealtime() {
|
||||
realtimeIP[0] = 0;
|
||||
if (useMainSegmentOnly) { // unfreeze live segment again
|
||||
strip.getMainSegment().freeze = false;
|
||||
} else {
|
||||
strip.show(); // possible fix for #3589
|
||||
}
|
||||
updateInterfaces(CALL_MODE_WS_SEND);
|
||||
}
|
||||
@ -608,13 +612,13 @@ void handleNotifications()
|
||||
if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return;
|
||||
|
||||
uint16_t totalLen = strip.getLengthTotal();
|
||||
if (udpIn[0] == 1) //warls
|
||||
if (udpIn[0] == 1 && packetSize > 5) //warls
|
||||
{
|
||||
for (size_t i = 2; i < packetSize -3; i += 4)
|
||||
{
|
||||
setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0);
|
||||
}
|
||||
} else if (udpIn[0] == 2) //drgb
|
||||
} else if (udpIn[0] == 2 && packetSize > 4) //drgb
|
||||
{
|
||||
uint16_t id = 0;
|
||||
for (size_t i = 2; i < packetSize -2; i += 3)
|
||||
@ -623,7 +627,7 @@ void handleNotifications()
|
||||
|
||||
id++; if (id >= totalLen) break;
|
||||
}
|
||||
} else if (udpIn[0] == 3) //drgbw
|
||||
} else if (udpIn[0] == 3 && packetSize > 6) //drgbw
|
||||
{
|
||||
uint16_t id = 0;
|
||||
for (size_t i = 2; i < packetSize -3; i += 4)
|
||||
@ -632,7 +636,7 @@ void handleNotifications()
|
||||
|
||||
id++; if (id >= totalLen) break;
|
||||
}
|
||||
} else if (udpIn[0] == 4) //dnrgb
|
||||
} else if (udpIn[0] == 4 && packetSize > 7) //dnrgb
|
||||
{
|
||||
uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
||||
for (size_t i = 4; i < packetSize -2; i += 3)
|
||||
@ -641,7 +645,7 @@ void handleNotifications()
|
||||
setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0);
|
||||
id++;
|
||||
}
|
||||
} else if (udpIn[0] == 5) //dnrgbw
|
||||
} else if (udpIn[0] == 5 && packetSize > 8) //dnrgbw
|
||||
{
|
||||
uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00);
|
||||
for (size_t i = 4; i < packetSize -2; i += 4)
|
||||
@ -664,8 +668,8 @@ void handleNotifications()
|
||||
apireq += (char*)udpIn;
|
||||
handleSet(nullptr, apireq);
|
||||
} else if (udpIn[0] == '{') { //JSON API
|
||||
DeserializationError error = deserializeJson(doc, udpIn);
|
||||
JsonObject root = doc.as<JsonObject>();
|
||||
DeserializationError error = deserializeJson(*pDoc, udpIn);
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
if (!error && !root.isNull()) deserializeState(root);
|
||||
}
|
||||
releaseJSONBufferLock();
|
||||
|
@ -177,6 +177,10 @@
|
||||
#include "../usermods/boblight/boblight.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_ANIMARTRIX
|
||||
#include "../usermods/usermod_v2_animartrix/usermod_v2_animartrix.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_INTERNAL_TEMPERATURE
|
||||
#include "../usermods/Internal_Temperature_v2/usermod_internal_temperature.h"
|
||||
#endif
|
||||
@ -197,6 +201,13 @@
|
||||
#include "../usermods/pwm_outputs/usermod_pwm_outputs.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
#include "../usermods/mpu6050_imu/usermod_mpu6050_imu.h"
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
#include "../usermods/mpu6050_imu/usermod_gyro_surge.h"
|
||||
#endif
|
||||
|
||||
void registerUsermods()
|
||||
{
|
||||
@ -206,6 +217,7 @@ void registerUsermods()
|
||||
* \/ \/ \/
|
||||
*/
|
||||
//usermods.add(new MyExampleUsermod());
|
||||
|
||||
#ifdef USERMOD_BATTERY
|
||||
usermods.add(new UsermodBattery());
|
||||
#endif
|
||||
@ -370,7 +382,19 @@ void registerUsermods()
|
||||
usermods.add(new ShtUsermod());
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_ANIMARTRIX
|
||||
usermods.add(new AnimartrixUsermod("Animartrix", false));
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_INTERNAL_TEMPERATURE
|
||||
usermods.add(new InternalTemperatureUsermod());
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_MPU6050_IMU
|
||||
static MPU6050Driver mpu6050; usermods.add(&mpu6050);
|
||||
#endif
|
||||
|
||||
#ifdef USERMOD_GYRO_SURGE
|
||||
static GyroSurge gyro_surge; usermods.add(&gyro_surge);
|
||||
#endif
|
||||
}
|
||||
|
@ -209,6 +209,10 @@ bool isAsterisksOnly(const char* str, byte maxLen)
|
||||
//threading/network callback details: https://github.com/Aircoookie/WLED/pull/2336#discussion_r762276994
|
||||
bool requestJSONBufferLock(uint8_t module)
|
||||
{
|
||||
if (pDoc == nullptr) {
|
||||
DEBUG_PRINTLN(F("ERROR: JSON buffer not allocated!"));
|
||||
return false;
|
||||
}
|
||||
unsigned long now = millis();
|
||||
|
||||
while (jsonBufferLock && millis()-now < 1000) delay(1); // wait for a second for buffer lock
|
||||
@ -224,8 +228,8 @@ bool requestJSONBufferLock(uint8_t module)
|
||||
DEBUG_PRINT(F("JSON buffer locked. ("));
|
||||
DEBUG_PRINT(jsonBufferLock);
|
||||
DEBUG_PRINTLN(")");
|
||||
fileDoc = &doc; // used for applying presets (presets.cpp)
|
||||
doc.clear();
|
||||
fileDoc = pDoc; // used for applying presets (presets.cpp)
|
||||
pDoc->clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -556,11 +560,12 @@ void enumerateLedmaps() {
|
||||
|
||||
#ifndef ESP8266
|
||||
if (requestJSONBufferLock(21)) {
|
||||
if (readObjectFromFile(fileName, nullptr, &doc)) {
|
||||
if (readObjectFromFile(fileName, nullptr, pDoc)) {
|
||||
size_t len = 0;
|
||||
if (!doc["n"].isNull()) {
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
if (!root["n"].isNull()) {
|
||||
// name field exists
|
||||
const char *name = doc["n"].as<const char*>();
|
||||
const char *name = root["n"].as<const char*>();
|
||||
if (name != nullptr) len = strlen(name);
|
||||
if (len > 0 && len < 33) {
|
||||
ledmapNames[i-1] = new char[len+1];
|
||||
|
@ -110,7 +110,7 @@ void WLED::loop()
|
||||
handlePresets();
|
||||
yield();
|
||||
|
||||
if (!offMode || strip.isOffRefreshRequired())
|
||||
if (!offMode || strip.isOffRefreshRequired() || strip.needsUpdate())
|
||||
strip.service();
|
||||
#ifdef ESP8266
|
||||
else if (!noWifiSleep)
|
||||
@ -159,7 +159,7 @@ void WLED::loop()
|
||||
if (heap < MIN_HEAP_SIZE && lastHeap < MIN_HEAP_SIZE) {
|
||||
DEBUG_PRINT(F("Heap too low! ")); DEBUG_PRINTLN(heap);
|
||||
forceReconnect = true;
|
||||
strip.purgeSegments(true); // remove all but one segments from memory
|
||||
strip.resetSegments(); // remove all but one segments from memory
|
||||
} else if (heap < MIN_HEAP_SIZE) {
|
||||
DEBUG_PRINTLN(F("Heap low, purging segments."));
|
||||
strip.purgeSegments();
|
||||
@ -174,7 +174,7 @@ void WLED::loop()
|
||||
doInitBusses = false;
|
||||
DEBUG_PRINTLN(F("Re-init busses."));
|
||||
bool aligned = strip.checkSegmentAlignment(); //see if old segments match old bus(ses)
|
||||
busses.removeAll();
|
||||
BusManager::removeAll();
|
||||
uint32_t mem = 0, globalBufMem = 0;
|
||||
uint16_t maxlen = 0;
|
||||
for (uint8_t i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) {
|
||||
@ -185,7 +185,7 @@ void WLED::loop()
|
||||
globalBufMem = maxlen * 4;
|
||||
}
|
||||
if (mem + globalBufMem <= MAX_LED_MEMORY) {
|
||||
busses.add(*busConfigs[i]);
|
||||
BusManager::add(*busConfigs[i]);
|
||||
}
|
||||
delete busConfigs[i]; busConfigs[i] = nullptr;
|
||||
}
|
||||
@ -195,7 +195,7 @@ void WLED::loop()
|
||||
doSerializeConfig = true;
|
||||
}
|
||||
if (loadLedmap >= 0) {
|
||||
if (!strip.deserializeMap(loadLedmap) && strip.isMatrix && loadLedmap == 0) strip.setUpMatrix();
|
||||
strip.deserializeMap(loadLedmap);
|
||||
loadLedmap = -1;
|
||||
}
|
||||
yield();
|
||||
@ -363,6 +363,11 @@ void WLED::setup()
|
||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM)
|
||||
/*
|
||||
* The following code is obsolete as PinManager::isPinOK() will return false for reserved GPIO.
|
||||
* Additionally xml.cpp will inform UI about reserved GPIO.
|
||||
*
|
||||
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
// S3: reserve GPIO 33-37 for "octal" PSRAM
|
||||
managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} };
|
||||
@ -380,12 +385,17 @@ void WLED::setup()
|
||||
managed_pin_type pins[] = { {16, true}, {17, true} };
|
||||
pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM);
|
||||
#endif
|
||||
*/
|
||||
#if defined(WLED_USE_PSRAM)
|
||||
pDoc = new PSRAMDynamicJsonDocument(2*JSON_BUFFER_SIZE);
|
||||
if (!pDoc) pDoc = new PSRAMDynamicJsonDocument(JSON_BUFFER_SIZE); // falback if double sized buffer could not be allocated
|
||||
// if the above still fails requestJsonBufferLock() will always return false preventing crashes
|
||||
if (psramFound()) {
|
||||
DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB");
|
||||
DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB");
|
||||
}
|
||||
#else
|
||||
if (!pDoc) pDoc = &gDoc; // just in case ... (it should be globally assigned)
|
||||
DEBUG_PRINTLN(F("PSRAM not used."));
|
||||
#endif
|
||||
#endif
|
||||
@ -393,7 +403,7 @@ void WLED::setup()
|
||||
//DEBUG_PRINT(F("LEDs inited. heap usage ~"));
|
||||
//DEBUG_PRINTLN(heapPreAlloc - ESP.getFreeHeap());
|
||||
|
||||
#ifdef WLED_DEBUG
|
||||
#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
|
||||
pinManager.allocatePin(hardwareTX, true, PinOwner::DebugOut); // TX (GPIO1 on ESP32) reserved for debug output
|
||||
#endif
|
||||
#ifdef WLED_ENABLE_DMX //reserve GPIO2 as hardcoded DMX pin
|
||||
@ -544,6 +554,13 @@ void WLED::beginStrip()
|
||||
else if (bri == 0) bri = 128;
|
||||
} else {
|
||||
// fix for #3196
|
||||
if (bootPreset > 0) {
|
||||
bool oldTransition = fadeTransition; // workaround if transitions are enabled
|
||||
fadeTransition = false; // ignore transitions temporarily
|
||||
strip.setColor(0, BLACK); // set all segments black
|
||||
fadeTransition = oldTransition; // restore transitions
|
||||
col[0] = col[1] = col[2] = col[3] = 0; // needed for colorUpdated()
|
||||
}
|
||||
briLast = briS; bri = 0;
|
||||
strip.fill(BLACK);
|
||||
strip.show();
|
||||
@ -716,7 +733,7 @@ void WLED::initConnection()
|
||||
|
||||
WiFi.disconnect(true); // close old connections
|
||||
#ifdef ESP8266
|
||||
WiFi.setPhyMode(WIFI_PHY_MODE_11N);
|
||||
WiFi.setPhyMode(force802_3g ? WIFI_PHY_MODE_11G : WIFI_PHY_MODE_11N);
|
||||
#endif
|
||||
|
||||
if (staticIP[0] != 0 && staticGateway[0] != 0) {
|
||||
@ -740,9 +757,10 @@ void WLED::initConnection()
|
||||
WiFi.mode(WIFI_STA);
|
||||
}
|
||||
}
|
||||
showWelcomePage = false;
|
||||
|
||||
if (WLED_WIFI_CONFIGURED) {
|
||||
showWelcomePage = false;
|
||||
|
||||
DEBUG_PRINT(F("Connecting to "));
|
||||
DEBUG_PRINT(clientSSID);
|
||||
DEBUG_PRINTLN("...");
|
||||
@ -964,7 +982,7 @@ void WLED::handleStatusLED()
|
||||
#if STATUSLED>=0
|
||||
digitalWrite(STATUSLED, ledStatusState);
|
||||
#else
|
||||
busses.setStatusPixel(ledStatusState ? c : 0);
|
||||
BusManager::setStatusPixel(ledStatusState ? c : 0);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
@ -975,7 +993,7 @@ void WLED::handleStatusLED()
|
||||
digitalWrite(STATUSLED, LOW);
|
||||
#endif
|
||||
#else
|
||||
busses.setStatusPixel(0);
|
||||
BusManager::setStatusPixel(0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
48
wled00/wled.h
Normal file → Executable file
48
wled00/wled.h
Normal file → Executable file
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2312160
|
||||
#define VERSION 2401140
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
@ -30,8 +30,8 @@
|
||||
#ifndef WLED_DISABLE_MQTT
|
||||
#define WLED_ENABLE_MQTT // saves 12kb
|
||||
#endif
|
||||
#ifndef WLED_DISABLE_ADALIGHT // can be used to disable reading commands from serial RX pin (see issue #3128).
|
||||
#define WLED_ENABLE_ADALIGHT // disable saves 5Kb (uses GPIO3 (RX) for serial). Related serial protocols: Adalight/TPM2, Improv, Serial JSON, Continuous Serial Streaming
|
||||
#ifndef WLED_DISABLE_ADALIGHT // can be used to disable reading commands from serial RX pin (see issue #3128).
|
||||
#define WLED_ENABLE_ADALIGHT // disable saves 5Kb (uses GPIO3 (RX) for serial). Related serial protocols: Adalight/TPM2, Improv, Serial JSON, Continuous Serial Streaming
|
||||
#else
|
||||
#undef WLED_ENABLE_ADALIGHT // disable has priority over enable
|
||||
#endif
|
||||
@ -44,7 +44,7 @@
|
||||
#define WLED_ENABLE_WEBSOCKETS
|
||||
#endif
|
||||
|
||||
//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now
|
||||
//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now
|
||||
|
||||
#define WLED_ENABLE_FS_EDITOR // enable /edit page for editing FS content. Will also be disabled with OTA lock
|
||||
|
||||
@ -319,6 +319,7 @@ WLED_GLOBAL bool noWifiSleep _INIT(true); // disabling
|
||||
#else
|
||||
WLED_GLOBAL bool noWifiSleep _INIT(false);
|
||||
#endif
|
||||
WLED_GLOBAL bool force802_3g _INIT(false);
|
||||
|
||||
#ifdef WLED_USE_ETHERNET
|
||||
#ifdef WLED_ETH_DEFAULT // default ethernet board type if specified
|
||||
@ -363,9 +364,8 @@ WLED_GLOBAL char serverDescription[33] _INIT("WLED"); // Name of module - use d
|
||||
#else
|
||||
WLED_GLOBAL char serverDescription[33] _INIT(SERVERNAME); // use predefined name
|
||||
#endif
|
||||
//WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise
|
||||
WLED_GLOBAL bool simplifiedUI _INIT(false); // enable simplified UI
|
||||
WLED_GLOBAL byte cacheInvalidate _INIT(0); // used to invalidate browser cache when switching from regular to simplified UI
|
||||
WLED_GLOBAL byte cacheInvalidate _INIT(0); // used to invalidate browser cache
|
||||
|
||||
// Sync CONFIG
|
||||
WLED_GLOBAL NodesMap Nodes;
|
||||
@ -394,7 +394,6 @@ WLED_GLOBAL bool receiveSegmentBounds _INIT(false); // apply segme
|
||||
WLED_GLOBAL bool notifyDirect _INIT(false); // send notification if change via UI or HTTP API
|
||||
WLED_GLOBAL bool notifyButton _INIT(false); // send if updated by button or infrared remote
|
||||
WLED_GLOBAL bool notifyAlexa _INIT(false); // send notification if updated via Alexa
|
||||
WLED_GLOBAL bool notifyMacro _INIT(false); // send notification for macro
|
||||
WLED_GLOBAL bool notifyHue _INIT(true); // send notification if Hue light changes
|
||||
WLED_GLOBAL uint8_t udpNumRetries _INIT(0); // Number of times a UDP sync message is retransmitted. Increase to increase reliability
|
||||
|
||||
@ -475,10 +474,19 @@ WLED_GLOBAL char last_signal_src[13] _INIT(""); // last seen ESP-NOW sender
|
||||
#endif
|
||||
|
||||
// Time CONFIG
|
||||
WLED_GLOBAL bool ntpEnabled _INIT(false); // get internet time. Only required if you use clock overlays or time-activated macros
|
||||
WLED_GLOBAL bool useAMPM _INIT(false); // 12h/24h clock format
|
||||
WLED_GLOBAL byte currentTimezone _INIT(0); // Timezone ID. Refer to timezones array in wled10_ntp.ino
|
||||
WLED_GLOBAL int utcOffsetSecs _INIT(0); // Seconds to offset from UTC before timzone calculation
|
||||
#ifndef WLED_NTP_ENABLED
|
||||
#define WLED_NTP_ENABLED false
|
||||
#endif
|
||||
#ifndef WLED_TIMEZONE
|
||||
#define WLED_TIMEZONE 0
|
||||
#endif
|
||||
#ifndef WLED_UTC_OFFSET
|
||||
#define WLED_UTC_OFFSET 0
|
||||
#endif
|
||||
WLED_GLOBAL bool ntpEnabled _INIT(WLED_NTP_ENABLED); // get internet time. Only required if you use clock overlays or time-activated macros
|
||||
WLED_GLOBAL bool useAMPM _INIT(false); // 12h/24h clock format
|
||||
WLED_GLOBAL byte currentTimezone _INIT(WLED_TIMEZONE); // Timezone ID. Refer to timezones array in wled10_ntp.ino
|
||||
WLED_GLOBAL int utcOffsetSecs _INIT(WLED_UTC_OFFSET); // Seconds to offset from UTC before timzone calculation
|
||||
|
||||
WLED_GLOBAL byte overlayCurrent _INIT(0); // 0: no overlay 1: analog clock 2: was single-digit clock 3: was cronixie
|
||||
WLED_GLOBAL byte overlayMin _INIT(0), overlayMax _INIT(DEFAULT_LED_COUNT - 1); // boundaries of overlay mode
|
||||
@ -634,6 +642,7 @@ WLED_GLOBAL unsigned long realtimeTimeout _INIT(0);
|
||||
WLED_GLOBAL uint8_t tpmPacketCount _INIT(0);
|
||||
WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0);
|
||||
WLED_GLOBAL bool useMainSegmentOnly _INIT(false);
|
||||
WLED_GLOBAL bool realtimeRespectLedMaps _INIT(true); // Respect LED maps when receiving realtime data
|
||||
|
||||
WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0);
|
||||
WLED_GLOBAL byte interfaceUpdateCallMode _INIT(CALL_MODE_INIT);
|
||||
@ -649,6 +658,12 @@ WLED_GLOBAL String escapedMac;
|
||||
WLED_GLOBAL DNSServer dnsServer;
|
||||
|
||||
// network time
|
||||
#ifndef WLED_LAT
|
||||
#define WLED_LAT 0.0f
|
||||
#endif
|
||||
#ifndef WLED_LON
|
||||
#define WLED_LON 0.0f
|
||||
#endif
|
||||
WLED_GLOBAL bool ntpConnected _INIT(false);
|
||||
WLED_GLOBAL time_t localTime _INIT(0);
|
||||
WLED_GLOBAL unsigned long ntpLastSyncTime _INIT(999000000L);
|
||||
@ -656,8 +671,8 @@ WLED_GLOBAL unsigned long ntpPacketSentTime _INIT(999000000L);
|
||||
WLED_GLOBAL IPAddress ntpServerIP;
|
||||
WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390);
|
||||
WLED_GLOBAL uint16_t rolloverMillis _INIT(0);
|
||||
WLED_GLOBAL float longitude _INIT(0.0);
|
||||
WLED_GLOBAL float latitude _INIT(0.0);
|
||||
WLED_GLOBAL float longitude _INIT(WLED_LON);
|
||||
WLED_GLOBAL float latitude _INIT(WLED_LAT);
|
||||
WLED_GLOBAL time_t sunrise _INIT(0);
|
||||
WLED_GLOBAL time_t sunset _INIT(0);
|
||||
WLED_GLOBAL Toki toki _INIT(Toki());
|
||||
@ -758,7 +773,12 @@ WLED_GLOBAL int8_t spi_sclk _INIT(SPISCLKPIN);
|
||||
#endif
|
||||
|
||||
// global ArduinoJson buffer
|
||||
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> doc;
|
||||
#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM)
|
||||
WLED_GLOBAL JsonDocument *pDoc _INIT(nullptr);
|
||||
#else
|
||||
WLED_GLOBAL StaticJsonDocument<JSON_BUFFER_SIZE> gDoc;
|
||||
WLED_GLOBAL JsonDocument *pDoc _INIT(&gDoc);
|
||||
#endif
|
||||
WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0);
|
||||
|
||||
// enable additional debug output
|
||||
|
8
wled00/wled_eeprom.cpp
Normal file → Executable file
8
wled00/wled_eeprom.cpp
Normal file → Executable file
@ -99,7 +99,7 @@ void loadSettingsFromEEPROM()
|
||||
bool skipFirst = EEPROM.read(2204);
|
||||
bool reversed = EEPROM.read(252);
|
||||
BusConfig bc = BusConfig(EEPROM.read(372) ? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, 0, length, colorOrder, reversed, skipFirst);
|
||||
busses.add(bc);
|
||||
BusManager::add(bc);
|
||||
|
||||
notifyButton = EEPROM.read(230);
|
||||
if (EEPROM.read(231)) udpNumRetries = 1;
|
||||
@ -321,7 +321,7 @@ void loadSettingsFromEEPROM()
|
||||
}
|
||||
|
||||
receiveDirect = !EEPROM.read(2200);
|
||||
notifyMacro = EEPROM.read(2201);
|
||||
//notifyMacro = EEPROM.read(2201);
|
||||
|
||||
//strip.rgbwMode = EEPROM.read(2203);
|
||||
//skipFirstLed = EEPROM.read(2204);
|
||||
@ -371,7 +371,7 @@ void deEEP() {
|
||||
DEBUGFS_PRINTLN(F("Allocating saving buffer for dEEP"));
|
||||
if (!requestJSONBufferLock(8)) return;
|
||||
|
||||
JsonObject sObj = doc.to<JsonObject>();
|
||||
JsonObject sObj = pDoc->to<JsonObject>();
|
||||
sObj.createNestedObject("0");
|
||||
|
||||
EEPROM.begin(EEPSIZE);
|
||||
@ -448,7 +448,7 @@ void deEEP() {
|
||||
releaseJSONBufferLock();
|
||||
return;
|
||||
}
|
||||
serializeJson(doc, f);
|
||||
serializeJson(*pDoc, f);
|
||||
f.close();
|
||||
|
||||
releaseJSONBufferLock();
|
||||
|
@ -115,21 +115,21 @@ void handleSerial()
|
||||
bool verboseResponse = false;
|
||||
if (!requestJSONBufferLock(16)) return;
|
||||
Serial.setTimeout(100);
|
||||
DeserializationError error = deserializeJson(doc, Serial);
|
||||
DeserializationError error = deserializeJson(*pDoc, Serial);
|
||||
if (error) {
|
||||
releaseJSONBufferLock();
|
||||
return;
|
||||
}
|
||||
verboseResponse = deserializeState(doc.as<JsonObject>());
|
||||
verboseResponse = deserializeState(pDoc->as<JsonObject>());
|
||||
//only send response if TX pin is unused for other purposes
|
||||
if (verboseResponse && (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut)) {
|
||||
doc.clear();
|
||||
JsonObject state = doc.createNestedObject("state");
|
||||
pDoc->clear();
|
||||
JsonObject state = pDoc->createNestedObject("state");
|
||||
serializeState(state);
|
||||
JsonObject info = doc.createNestedObject("info");
|
||||
JsonObject info = pDoc->createNestedObject("info");
|
||||
serializeInfo(info);
|
||||
|
||||
serializeJson(doc, Serial);
|
||||
serializeJson(*pDoc, Serial);
|
||||
Serial.println();
|
||||
}
|
||||
releaseJSONBufferLock();
|
||||
|
@ -1,9 +1,6 @@
|
||||
#include "wled.h"
|
||||
|
||||
#include "html_ui.h"
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
#include "html_simple.h"
|
||||
#endif
|
||||
#include "html_settings.h"
|
||||
#include "html_other.h"
|
||||
#ifdef WLED_ENABLE_PIXART
|
||||
@ -18,8 +15,9 @@
|
||||
* Integrated HTTP web server page declarations
|
||||
*/
|
||||
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request);
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response);
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request, int code, uint16_t eTagSuffix = 0);
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix = 0);
|
||||
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip = true, uint16_t eTagSuffix = 0);
|
||||
|
||||
// define flash strings once (saves flash memory)
|
||||
static const char s_redirecting[] PROGMEM = "Redirecting...";
|
||||
@ -116,22 +114,14 @@ void initServer()
|
||||
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), "*");
|
||||
|
||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||
#ifndef WLED_DISABLE_2D
|
||||
server.on("/liveview2D", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveviewws2D, PAGE_liveviewws2D_length);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
#ifndef WLED_DISABLE_2D
|
||||
server.on("/liveview2D", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "", 200, "text/html", PAGE_liveviewws2D, PAGE_liveviewws2D_length);
|
||||
});
|
||||
#endif
|
||||
#endif
|
||||
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveview, PAGE_liveview_length);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "", 200, "text/html", PAGE_liveview, PAGE_liveview_length);
|
||||
});
|
||||
|
||||
//settings page
|
||||
@ -141,19 +131,18 @@ void initServer()
|
||||
|
||||
// "/settings/settings.js&p=x" request also handled by serveSettings()
|
||||
|
||||
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "/style.css", 200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length);
|
||||
});
|
||||
|
||||
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if(!handleFileRead(request, "/favicon.ico"))
|
||||
{
|
||||
request->send_P(200, "image/x-icon", favicon, 156);
|
||||
}
|
||||
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "/favicon.ico", 200, "image/x-icon", favicon, favicon_length, false);
|
||||
});
|
||||
|
||||
server.on("/skin.css", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (handleFileRead(request, "/skin.css")) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "text/css");
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server.on("/welcome", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
@ -179,8 +168,8 @@ void initServer()
|
||||
|
||||
if (!requestJSONBufferLock(14)) return;
|
||||
|
||||
DeserializationError error = deserializeJson(doc, (uint8_t*)(request->_tempObject));
|
||||
JsonObject root = doc.as<JsonObject>();
|
||||
DeserializationError error = deserializeJson(*pDoc, (uint8_t*)(request->_tempObject));
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
if (error || root.isNull()) {
|
||||
releaseJSONBufferLock();
|
||||
serveJsonError(request, 400, ERR_JSON);
|
||||
@ -235,12 +224,8 @@ void initServer()
|
||||
});
|
||||
|
||||
#ifdef WLED_ENABLE_USERMOD_PAGE
|
||||
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_usermod, PAGE_usermod_length);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "", 200, "text/html", PAGE_usermod, PAGE_usermod_length);
|
||||
});
|
||||
#endif
|
||||
|
||||
@ -253,31 +238,6 @@ void initServer()
|
||||
size_t len, bool final) {handleUpload(request, filename, index, data, len, final);}
|
||||
);
|
||||
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
server.on("/simple.htm", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleFileRead(request, "/simple.htm")) return;
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_simple, PAGE_simple_L);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
});
|
||||
#endif
|
||||
|
||||
server.on("/iro.js", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", iroJs, iroJs_length);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
server.on("/rangetouch.js", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", rangetouchJs, rangetouchJs_length);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
});
|
||||
|
||||
createEditHandler(correctPIN);
|
||||
|
||||
#ifndef WLED_DISABLE_OTA
|
||||
@ -313,8 +273,9 @@ void initServer()
|
||||
#endif
|
||||
usermods.onUpdateBegin(true); // notify usermods that update is about to begin (some may require task de-init)
|
||||
lastEditTime = millis(); // make sure PIN does not lock during update
|
||||
strip.suspend();
|
||||
#ifdef ESP8266
|
||||
strip.purgeSegments(true); // free as much memory as you can
|
||||
strip.resetSegments(); // free as much memory as you can
|
||||
Update.runAsync(true);
|
||||
#endif
|
||||
Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
||||
@ -325,6 +286,7 @@ void initServer()
|
||||
DEBUG_PRINTLN(F("Update Success"));
|
||||
} else {
|
||||
DEBUG_PRINTLN(F("Update Failed"));
|
||||
strip.resume();
|
||||
usermods.onUpdateBegin(false); // notify usermods that update has failed (some may require task init)
|
||||
#if WLED_WATCHDOG_TIMEOUT > 0
|
||||
WLED::instance().enableWatchdog();
|
||||
@ -349,44 +311,29 @@ void initServer()
|
||||
});
|
||||
#endif
|
||||
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
if (captivePortal(request)) return;
|
||||
if (!showWelcomePage || request->hasArg(F("sliders"))){
|
||||
serveIndex(request);
|
||||
if (!showWelcomePage || request->hasArg(F("sliders"))) {
|
||||
handleStaticContent(request, "/index.htm", 200, "text/html", PAGE_index, PAGE_index_L);
|
||||
} else {
|
||||
serveSettings(request);
|
||||
}
|
||||
});
|
||||
|
||||
#ifdef WLED_ENABLE_PIXART
|
||||
server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleFileRead(request, "/pixart.htm")) return;
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pixart, PAGE_pixart_L);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
#ifdef WLED_ENABLE_PIXART
|
||||
server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "/pixart.htm", 200, "text/html", PAGE_pixart, PAGE_pixart_L);
|
||||
});
|
||||
#endif
|
||||
|
||||
#ifndef WLED_DISABLE_PXMAGIC
|
||||
server.on("/pxmagic.htm", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleFileRead(request, "/pxmagic.htm")) return;
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pxmagic, PAGE_pxmagic_L);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
#ifndef WLED_DISABLE_PXMAGIC
|
||||
server.on("/pxmagic.htm", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "/pxmagic.htm", 200, "text/html", PAGE_pxmagic, PAGE_pxmagic_L);
|
||||
});
|
||||
#endif
|
||||
#endif
|
||||
|
||||
server.on("/cpal.htm", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||
if (handleFileRead(request, "/cpal.htm")) return;
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_cpal, PAGE_cpal_L);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
server.on("/cpal.htm", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
handleStaticContent(request, "/cpal.htm", 200, "text/html", PAGE_cpal, PAGE_cpal_L);
|
||||
});
|
||||
|
||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||
@ -412,59 +359,73 @@ void initServer()
|
||||
#ifndef WLED_DISABLE_ALEXA
|
||||
if(espalexa.handleAlexaApiCall(request)) return;
|
||||
#endif
|
||||
if(handleFileRead(request, request->url())) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(404, "text/html", PAGE_404, PAGE_404_length);
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
handleStaticContent(request, request->url(), 404, "text/html", PAGE_404, PAGE_404_length);
|
||||
});
|
||||
}
|
||||
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request)
|
||||
{
|
||||
AsyncWebHeader* header = request->getHeader("If-None-Match");
|
||||
if (header && header->value() == String(VERSION)) {
|
||||
request->send(304);
|
||||
void generateEtag(char *etag, uint16_t eTagSuffix) {
|
||||
sprintf_P(etag, PSTR("%7d-%02x-%04x"), VERSION, cacheInvalidate, eTagSuffix);
|
||||
}
|
||||
|
||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request, int code, uint16_t eTagSuffix) {
|
||||
// Only send 304 (Not Modified) if response code is 200 (OK)
|
||||
if (code != 200) return false;
|
||||
|
||||
AsyncWebHeader *header = request->getHeader("If-None-Match");
|
||||
char etag[14];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
if (header && header->value() == etag) {
|
||||
AsyncWebServerResponse *response = request->beginResponse(304);
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response)
|
||||
{
|
||||
char tmp[12];
|
||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix) {
|
||||
// Only send ETag for 200 (OK) responses
|
||||
if (code != 200) return;
|
||||
|
||||
// https://medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c
|
||||
#ifndef WLED_DEBUG
|
||||
//this header name is misleading, "no-cache" will not disable cache,
|
||||
//it just revalidates on every load using the "If-None-Match" header with the last ETag value
|
||||
response->addHeader(F("Cache-Control"),"no-cache");
|
||||
// this header name is misleading, "no-cache" will not disable cache,
|
||||
// it just revalidates on every load using the "If-None-Match" header with the last ETag value
|
||||
response->addHeader(F("Cache-Control"), "no-cache");
|
||||
#else
|
||||
response->addHeader(F("Cache-Control"),"no-store,max-age=0"); // prevent caching if debug build
|
||||
response->addHeader(F("Cache-Control"), "no-store,max-age=0"); // prevent caching if debug build
|
||||
#endif
|
||||
sprintf_P(tmp, PSTR("%8d-%02x"), VERSION, cacheInvalidate);
|
||||
response->addHeader(F("ETag"), tmp);
|
||||
char etag[14];
|
||||
generateEtag(etag, eTagSuffix);
|
||||
response->addHeader(F("ETag"), etag);
|
||||
}
|
||||
|
||||
void serveIndex(AsyncWebServerRequest* request)
|
||||
{
|
||||
if (handleFileRead(request, "/index.htm")) return;
|
||||
|
||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||
|
||||
AsyncWebServerResponse *response;
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
if (simplifiedUI)
|
||||
response = request->beginResponse_P(200, "text/html", PAGE_simple, PAGE_simple_L);
|
||||
else
|
||||
#endif
|
||||
response = request->beginResponse_P(200, "text/html", PAGE_index, PAGE_index_L);
|
||||
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
/**
|
||||
* Handels the request for a static file.
|
||||
* If the file was found in the filesystem, it will be sent to the client.
|
||||
* Otherwise it will be checked if the browser cached the file and if so, a 304 response will be sent.
|
||||
* If the file was not found in the filesystem and not in the browser cache, the request will be handled as a 200 response with the content of the page.
|
||||
*
|
||||
* @param request The request object
|
||||
* @param path If a file with this path exists in the filesystem, it will be sent to the client. Set to "" to skip this check.
|
||||
* @param code The HTTP status code
|
||||
* @param contentType The content type of the web page
|
||||
* @param content Content of the web page
|
||||
* @param len Length of the content
|
||||
* @param gzip Optional. Defaults to true. If false, the gzip header will not be added.
|
||||
* @param eTagSuffix Optional. Defaults to 0. A suffix that will be added to the ETag header. This can be used to invalidate the cache for a specific page.
|
||||
*/
|
||||
void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip, uint16_t eTagSuffix) {
|
||||
if (path != "" && handleFileRead(request, path)) return;
|
||||
if (handleIfNoneMatchCacheHeader(request, code, eTagSuffix)) return;
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(code, contentType, content, len);
|
||||
if (gzip) response->addHeader(FPSTR(s_content_enc), "gzip");
|
||||
setStaticContentCacheHeaders(response, code, eTagSuffix);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
String msgProcessor(const String& var)
|
||||
{
|
||||
if (var == "MSG") {
|
||||
@ -566,25 +527,23 @@ void serveSettingsJS(AsyncWebServerRequest* request)
|
||||
}
|
||||
|
||||
|
||||
void serveSettings(AsyncWebServerRequest* request, bool post)
|
||||
{
|
||||
void serveSettings(AsyncWebServerRequest* request, bool post) {
|
||||
byte subPage = 0, originalSubPage = 0;
|
||||
const String& url = request->url();
|
||||
|
||||
if (url.indexOf("sett") >= 0)
|
||||
{
|
||||
if (url.indexOf(".js") > 0) subPage = SUBPAGE_JS;
|
||||
else if (url.indexOf(".css") > 0) subPage = SUBPAGE_CSS;
|
||||
else if (url.indexOf("wifi") > 0) subPage = SUBPAGE_WIFI;
|
||||
else if (url.indexOf("leds") > 0) subPage = SUBPAGE_LEDS;
|
||||
else if (url.indexOf("ui") > 0) subPage = SUBPAGE_UI;
|
||||
else if (url.indexOf("sync") > 0) subPage = SUBPAGE_SYNC;
|
||||
else if (url.indexOf("time") > 0) subPage = SUBPAGE_TIME;
|
||||
else if (url.indexOf("sec") > 0) subPage = SUBPAGE_SEC;
|
||||
else if (url.indexOf("dmx") > 0) subPage = SUBPAGE_DMX;
|
||||
else if (url.indexOf("um") > 0) subPage = SUBPAGE_UM;
|
||||
else if (url.indexOf("2D") > 0) subPage = SUBPAGE_2D;
|
||||
else if (url.indexOf("lock") > 0) subPage = SUBPAGE_LOCK;
|
||||
if (url.indexOf("sett") >= 0) {
|
||||
if (url.indexOf(F(".js")) > 0) subPage = SUBPAGE_JS;
|
||||
else if (url.indexOf(F(".css")) > 0) subPage = SUBPAGE_CSS;
|
||||
else if (url.indexOf(F("wifi")) > 0) subPage = SUBPAGE_WIFI;
|
||||
else if (url.indexOf(F("leds")) > 0) subPage = SUBPAGE_LEDS;
|
||||
else if (url.indexOf(F("ui")) > 0) subPage = SUBPAGE_UI;
|
||||
else if (url.indexOf( "sync") > 0) subPage = SUBPAGE_SYNC;
|
||||
else if (url.indexOf( "time") > 0) subPage = SUBPAGE_TIME;
|
||||
else if (url.indexOf(F("sec")) > 0) subPage = SUBPAGE_SEC;
|
||||
else if (url.indexOf( "dmx") > 0) subPage = SUBPAGE_DMX;
|
||||
else if (url.indexOf( "um") > 0) subPage = SUBPAGE_UM;
|
||||
else if (url.indexOf( "2D") > 0) subPage = SUBPAGE_2D;
|
||||
else if (url.indexOf(F("lock")) > 0) subPage = SUBPAGE_LOCK;
|
||||
}
|
||||
else if (url.indexOf("/update") >= 0) subPage = SUBPAGE_UPDATE; // update page, for PIN check
|
||||
//else if (url.indexOf("/edit") >= 0) subPage = 10;
|
||||
@ -633,22 +592,25 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
|
||||
}
|
||||
}
|
||||
|
||||
AsyncWebServerResponse *response;
|
||||
switch (subPage)
|
||||
{
|
||||
case SUBPAGE_WIFI : response = request->beginResponse_P(200, "text/html", PAGE_settings_wifi, PAGE_settings_wifi_length); break;
|
||||
case SUBPAGE_LEDS : response = request->beginResponse_P(200, "text/html", PAGE_settings_leds, PAGE_settings_leds_length); break;
|
||||
case SUBPAGE_UI : response = request->beginResponse_P(200, "text/html", PAGE_settings_ui, PAGE_settings_ui_length); break;
|
||||
case SUBPAGE_SYNC : response = request->beginResponse_P(200, "text/html", PAGE_settings_sync, PAGE_settings_sync_length); break;
|
||||
case SUBPAGE_TIME : response = request->beginResponse_P(200, "text/html", PAGE_settings_time, PAGE_settings_time_length); break;
|
||||
case SUBPAGE_SEC : response = request->beginResponse_P(200, "text/html", PAGE_settings_sec, PAGE_settings_sec_length); break;
|
||||
int code = 200;
|
||||
String contentType = "text/html";
|
||||
const uint8_t* content;
|
||||
size_t len;
|
||||
|
||||
switch (subPage) {
|
||||
case SUBPAGE_WIFI : content = PAGE_settings_wifi; len = PAGE_settings_wifi_length; break;
|
||||
case SUBPAGE_LEDS : content = PAGE_settings_leds; len = PAGE_settings_leds_length; break;
|
||||
case SUBPAGE_UI : content = PAGE_settings_ui; len = PAGE_settings_ui_length; break;
|
||||
case SUBPAGE_SYNC : content = PAGE_settings_sync; len = PAGE_settings_sync_length; break;
|
||||
case SUBPAGE_TIME : content = PAGE_settings_time; len = PAGE_settings_time_length; break;
|
||||
case SUBPAGE_SEC : content = PAGE_settings_sec; len = PAGE_settings_sec_length; break;
|
||||
#ifdef WLED_ENABLE_DMX
|
||||
case SUBPAGE_DMX : response = request->beginResponse_P(200, "text/html", PAGE_settings_dmx, PAGE_settings_dmx_length); break;
|
||||
case SUBPAGE_DMX : content = PAGE_settings_dmx; len = PAGE_settings_dmx_length; break;
|
||||
#endif
|
||||
case SUBPAGE_UM : response = request->beginResponse_P(200, "text/html", PAGE_settings_um, PAGE_settings_um_length); break;
|
||||
case SUBPAGE_UPDATE : response = request->beginResponse_P(200, "text/html", PAGE_update, PAGE_update_length); break;
|
||||
case SUBPAGE_UM : content = PAGE_settings_um; len = PAGE_settings_um_length; break;
|
||||
case SUBPAGE_UPDATE : content = PAGE_update; len = PAGE_update_length; break;
|
||||
#ifndef WLED_DISABLE_2D
|
||||
case SUBPAGE_2D : response = request->beginResponse_P(200, "text/html", PAGE_settings_2D, PAGE_settings_2D_length); break;
|
||||
case SUBPAGE_2D : content = PAGE_settings_2D; len = PAGE_settings_2D_length; break;
|
||||
#endif
|
||||
case SUBPAGE_LOCK : {
|
||||
correctPIN = !strlen(settingsPIN); // lock if a pin is set
|
||||
@ -656,13 +618,11 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
|
||||
serveMessage(request, 200, strlen(settingsPIN) > 0 ? PSTR("Settings locked") : PSTR("No PIN set"), FPSTR(s_redirecting), 1);
|
||||
return;
|
||||
}
|
||||
case SUBPAGE_PINREQ : response = request->beginResponse_P(401, "text/html", PAGE_settings_pin, PAGE_settings_pin_length); break;
|
||||
case SUBPAGE_CSS : response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length); break;
|
||||
case SUBPAGE_JS : serveSettingsJS(request); return;
|
||||
case SUBPAGE_WELCOME : response = request->beginResponse_P(200, "text/html", PAGE_welcome, PAGE_welcome_length); break;
|
||||
default: response = request->beginResponse_P(200, "text/html", PAGE_settings, PAGE_settings_length); break;
|
||||
case SUBPAGE_PINREQ : content = PAGE_settings_pin; len = PAGE_settings_pin_length; code = 401; break;
|
||||
case SUBPAGE_CSS : content = PAGE_settingsCss; len = PAGE_settingsCss_length; contentType = "text/css"; break;
|
||||
case SUBPAGE_JS : serveSettingsJS(request); return;
|
||||
case SUBPAGE_WELCOME : content = PAGE_welcome; len = PAGE_welcome_length; break;
|
||||
default: content = PAGE_settings; len = PAGE_settings_length; break;
|
||||
}
|
||||
response->addHeader(FPSTR(s_content_enc),"gzip");
|
||||
setStaticContentCacheHeaders(response);
|
||||
request->send(response);
|
||||
handleStaticContent(request, "", code, contentType, content, len);
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
bool verboseResponse = false;
|
||||
if (!requestJSONBufferLock(11)) return;
|
||||
|
||||
DeserializationError error = deserializeJson(doc, data, len);
|
||||
JsonObject root = doc.as<JsonObject>();
|
||||
DeserializationError error = deserializeJson(*pDoc, data, len);
|
||||
JsonObject root = pDoc->as<JsonObject>();
|
||||
if (error || root.isNull()) {
|
||||
releaseJSONBufferLock();
|
||||
return;
|
||||
@ -103,13 +103,13 @@ void sendDataWs(AsyncWebSocketClient * client)
|
||||
|
||||
if (!requestJSONBufferLock(12)) return;
|
||||
|
||||
JsonObject state = doc.createNestedObject("state");
|
||||
JsonObject state = pDoc->createNestedObject("state");
|
||||
serializeState(state);
|
||||
JsonObject info = doc.createNestedObject("info");
|
||||
JsonObject info = pDoc->createNestedObject("info");
|
||||
serializeInfo(info);
|
||||
|
||||
size_t len = measureJson(doc);
|
||||
DEBUG_PRINTF("JSON buffer size: %u for WS request (%u).\n", doc.memoryUsage(), len);
|
||||
size_t len = measureJson(*pDoc);
|
||||
DEBUG_PRINTF("JSON buffer size: %u for WS request (%u).\n", pDoc->memoryUsage(), len);
|
||||
|
||||
size_t heap1 = ESP.getFreeHeap();
|
||||
DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap());
|
||||
@ -136,7 +136,7 @@ void sendDataWs(AsyncWebSocketClient * client)
|
||||
}
|
||||
|
||||
buffer->lock();
|
||||
serializeJson(doc, (char *)buffer->get(), len);
|
||||
serializeJson(*pDoc, (char *)buffer->get(), len);
|
||||
|
||||
DEBUG_PRINT(F("Sending WS data "));
|
||||
if (client) {
|
||||
|
59
wled00/xml.cpp
Normal file → Executable file
59
wled00/xml.cpp
Normal file → Executable file
@ -133,7 +133,7 @@ void appendGPIOinfo() {
|
||||
// usermod pin reservations will become unnecessary when settings pages will read cfg.json directly
|
||||
if (requestJSONBufferLock(6)) {
|
||||
// if we can't allocate JSON buffer ignore usermod pins
|
||||
JsonObject mods = doc.createNestedObject(F("um"));
|
||||
JsonObject mods = pDoc->createNestedObject(F("um"));
|
||||
usermods.addToConfig(mods);
|
||||
if (!mods.isNull()) fillUMPins(mods);
|
||||
releaseJSONBufferLock();
|
||||
@ -157,8 +157,8 @@ void appendGPIOinfo() {
|
||||
oappend(SET_F(",2")); // DMX hardcoded pin
|
||||
#endif
|
||||
|
||||
#ifdef WLED_DEBUG
|
||||
oappend(SET_F(",")); oappend(itoa(hardwareTX,nS,10));// debug output (TX) pin
|
||||
#if defined(WLED_DEBUG) && !defined(WLED_DEBUG_HOST)
|
||||
oappend(SET_F(",")); oappend(itoa(hardwareTX,nS,10)); // debug output (TX) pin
|
||||
#endif
|
||||
|
||||
//Note: Using pin 3 (RX) disables Adalight / Serial JSON
|
||||
@ -277,6 +277,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappends('s',SET_F("AP"),fapass);
|
||||
|
||||
sappend('v',SET_F("AC"),apChannel);
|
||||
sappend('c',SET_F("FG"),force802_3g);
|
||||
sappend('c',SET_F("WS"),noWifiSleep);
|
||||
|
||||
#ifndef WLED_DISABLE_ESPNOW
|
||||
@ -355,8 +356,8 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',SET_F("LD"),useGlobalLedBuffer);
|
||||
|
||||
uint16_t sumMa = 0;
|
||||
for (uint8_t s=0; s < busses.getNumBusses(); s++) {
|
||||
Bus* bus = busses.getBus(s);
|
||||
for (uint8_t s=0; s < BusManager::getNumBusses(); s++) {
|
||||
Bus* bus = BusManager::getBus(s);
|
||||
if (bus == nullptr) continue;
|
||||
char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin
|
||||
char lc[4] = "LC"; lc[2] = 48+s; lc[3] = 0; //strip length
|
||||
@ -376,7 +377,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
uint8_t nPins = bus->getPins(pins);
|
||||
for (uint8_t i = 0; i < nPins; i++) {
|
||||
lp[1] = 48+i;
|
||||
if (pinManager.isPinOk(pins[i]) || bus->getType()>=TYPE_NET_DDP_RGB) sappend('v',lp,pins[i]);
|
||||
if (pinManager.isPinOk(pins[i]) || IS_VIRTUAL(bus->getType())) sappend('v',lp,pins[i]);
|
||||
}
|
||||
sappend('v',lc,bus->getLength());
|
||||
sappend('v',lt,bus->getType());
|
||||
@ -388,16 +389,16 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('v',aw,bus->getAutoWhiteMode());
|
||||
sappend('v',wo,bus->getColorOrder() >> 4);
|
||||
uint16_t speed = bus->getFrequency();
|
||||
if (bus->getType() > TYPE_ONOFF && bus->getType() < 48) {
|
||||
if (IS_PWM(bus->getType())) {
|
||||
switch (speed) {
|
||||
case WLED_PWM_FREQ/3 : speed = 0; break;
|
||||
case WLED_PWM_FREQ/2 : speed = 1; break;
|
||||
case WLED_PWM_FREQ/3 : speed = 0; break;
|
||||
case WLED_PWM_FREQ/2 : speed = 1; break;
|
||||
default:
|
||||
case WLED_PWM_FREQ : speed = 2; break;
|
||||
case WLED_PWM_FREQ*2 : speed = 3; break;
|
||||
case WLED_PWM_FREQ*3 : speed = 4; break;
|
||||
case WLED_PWM_FREQ : speed = 2; break;
|
||||
case WLED_PWM_FREQ*4/3 : speed = 3; break;
|
||||
case WLED_PWM_FREQ*2 : speed = 4; break;
|
||||
}
|
||||
} else {
|
||||
} else if (IS_DIGITAL(bus->getType()) && IS_2PIN(bus->getType())) {
|
||||
switch (speed) {
|
||||
case 1000 : speed = 0; break;
|
||||
case 2000 : speed = 1; break;
|
||||
@ -412,29 +413,20 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('v',ma,bus->getMaxCurrent());
|
||||
sumMa += bus->getMaxCurrent();
|
||||
}
|
||||
sappend('c',SET_F("PPL"),(sumMa>0 && abs(sumMa - strip.ablMilliampsMax)>2)); // approxiamte detection if per-output limiter is enabled
|
||||
sappend('v',SET_F("MA"),strip.ablMilliampsMax);
|
||||
/*
|
||||
sappend('v',SET_F("LA"),strip.milliampsPerLed);
|
||||
if (strip.currentMilliamps)
|
||||
{
|
||||
sappends('m',SET_F("(\"pow\")[0]"),(char*)"");
|
||||
olen -= 2; //delete ";
|
||||
oappendi(strip.currentMilliamps);
|
||||
oappend(SET_F("mA\";"));
|
||||
}
|
||||
*/
|
||||
sappend('v',SET_F("MA"),BusManager::ablMilliampsMax() ? BusManager::ablMilliampsMax() : sumMa);
|
||||
sappend('c',SET_F("PPL"),!BusManager::ablMilliampsMax() && sumMa > 0);
|
||||
|
||||
oappend(SET_F("resetCOM("));
|
||||
oappend(itoa(WLED_MAX_COLOR_ORDER_MAPPINGS,nS,10));
|
||||
oappend(SET_F(");"));
|
||||
const ColorOrderMap& com = busses.getColorOrderMap();
|
||||
const ColorOrderMap& com = BusManager::getColorOrderMap();
|
||||
for (uint8_t s=0; s < com.count(); s++) {
|
||||
const ColorOrderMapEntry* entry = com.get(s);
|
||||
if (entry == nullptr) break;
|
||||
oappend(SET_F("addCOM("));
|
||||
oappend(itoa(entry->start,nS,10)); oappend(",");
|
||||
oappend(itoa(entry->len,nS,10)); oappend(",");
|
||||
oappend(itoa(entry->colorOrder,nS,10)); oappend(");");
|
||||
oappend(itoa(entry->start,nS,10)); oappend(",");
|
||||
oappend(itoa(entry->len,nS,10)); oappend(",");
|
||||
oappend(itoa(entry->colorOrder,nS,10)); oappend(");");
|
||||
}
|
||||
|
||||
sappend('v',SET_F("CA"),briS);
|
||||
@ -459,7 +451,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',SET_F("RM"),rlyMde);
|
||||
for (uint8_t i=0; i<WLED_MAX_BUTTONS; i++) {
|
||||
oappend(SET_F("addBtn("));
|
||||
oappend(itoa(i,nS,10)); oappend(",");
|
||||
oappend(itoa(i,nS,10)); oappend(",");
|
||||
oappend(itoa(btnPin[i],nS,10)); oappend(",");
|
||||
oappend(itoa(buttonType[i],nS,10));
|
||||
oappend(SET_F(");"));
|
||||
@ -474,12 +466,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
if (subPage == SUBPAGE_UI)
|
||||
{
|
||||
sappends('s',SET_F("DS"),serverDescription);
|
||||
//sappend('c',SET_F("ST"),syncToggleReceive);
|
||||
#ifdef WLED_ENABLE_SIMPLE_UI
|
||||
sappend('c',SET_F("SU"),simplifiedUI);
|
||||
#else
|
||||
oappend(SET_F("toggle('Simple');")); // hide Simplified UI settings
|
||||
#endif
|
||||
}
|
||||
|
||||
if (subPage == SUBPAGE_SYNC)
|
||||
@ -505,7 +492,6 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',SET_F("SD"),notifyDirect);
|
||||
sappend('c',SET_F("SB"),notifyButton);
|
||||
sappend('c',SET_F("SH"),notifyHue);
|
||||
// sappend('c',SET_F("SM"),notifyMacro);
|
||||
sappend('v',SET_F("UR"),udpNumRetries);
|
||||
|
||||
sappend('c',SET_F("NL"),nodeListEnabled);
|
||||
@ -513,6 +499,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
|
||||
sappend('c',SET_F("RD"),receiveDirect);
|
||||
sappend('c',SET_F("MO"),useMainSegmentOnly);
|
||||
sappend('c',SET_F("RLM"),realtimeRespectLedMaps);
|
||||
sappend('v',SET_F("EP"),e131Port);
|
||||
sappend('c',SET_F("ES"),e131SkipOutOfSequence);
|
||||
sappend('c',SET_F("EM"),e131Multicast);
|
||||
|
Loading…
x
Reference in New Issue
Block a user