Release of v0.8.2 (merge)

Release of v0.8.2 (PR)
This commit is contained in:
Aircoookie 2018-12-06 00:30:05 +01:00 committed by GitHub
commit 9ac609f846
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 3271 additions and 590 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.pioenvs
.piolibdeps
.vscode
!.vscode/extensions.json

35
.travis.yml Normal file
View File

@ -0,0 +1,35 @@
# Continuous Integration (CI) is the practice, in software
# engineering, of merging all developer working copies with a shared mainline
# several times a day < https://docs.platformio.org/page/ci/index.html >
#
# Documentation:
#
# * Travis CI Embedded Builds with PlatformIO
# < https://docs.travis-ci.com/user/integration/platformio/ >
#
# * PlatformIO integration with Travis CI
# < https://docs.platformio.org/page/ci/travis.html >
#
# * User Guide for `platformio ci` command
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
#
#
# Please choose one of the following templates (proposed below) and uncomment
# it (remove "# " before each line) or use own configuration according to the
# Travis CI documentation (see above).
#
language: python
python:
- "2.7"
sudo: false
cache:
directories:
- "~/.platformio"
env:
- PLATFORMIO_CI_SRC=wled00
install:
- pip install -U platformio
- platformio update
script:
- platformio ci --project-conf=./platformio.ini -v

7
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}

39
include/README Normal file
View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

121
platformio.ini Normal file
View File

@ -0,0 +1,121 @@
; PlatformIO Project Configuration File
; Please visit documentation: https://docs.platformio.org/page/projectconf.html
[platformio]
src_dir = ./wled00
data_dir = ./wled00/data
lib_extra_dirs = ./wled00/src
; env_default = nodemcuv2
env_default = esp01
; env_default = esp01_1m
; env_default = d1_mini
; env_default = esp32dev
[common]
framework = arduino
monitor_speed = 115200
board_build.flash_mode = dout
upload_speed = 921600
build_flags =
; -D VERSION=0.8.2-dev
; -D DEBUG
# TODO replace libs in /lib with managed libs in here if possible.
# If they are not changed it's just a metter of setting the correfct version and change the import statement
lib_deps_external =
#Blynk@0.5.4
#E131@1.0.0
#webserver
FastLED@3.2.1
NeoPixelBus@2.3.4
#PubSubClient@2.7
#Time@1.5
#Timezone@1.2.1
#WS2812FX@1.1.2
[common:esp8266]
platform = espressif8266@1.8.0
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
[common:esp8266_512k]
platform = espressif8266@1.7.0
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH
; -D WLED_DISABLE_MOBILE_UI
-D WLED_DISABLE_OTA
-D WLED_DISABLE_ALEXA
; -D WLED_DISABLE_BLYNK
; -D WLED_DISABLE_CRONIXIE
-D WLED_DISABLE_HUESYNC
[common:esp32]
platform = espressif32@1.5.0
build_flags =
-D PIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH
-D ARDUINO_ARCH_ESP32
-D WORKAROUND_ESP32_BITBANG
# see: http://docs.platformio.org/en/latest/platforms/espressif8266.html
[env:nodemcuv2]
board = nodemcuv2
platform = ${common:esp8266.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266.build_flags}
lib_deps =
${common.lib_deps_external}
[env:d1_mini]
board = d1_mini
platform = ${common:esp8266.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266.build_flags}
lib_deps =
${common.lib_deps_external}
[env:esp01_1m]
board = esp01_1m
platform = ${common:esp8266.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266.build_flags}
lib_deps =
${common.lib_deps_external}
[env:esp01]
board = esp01
platform = ${common:esp8266_512k.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp8266_512k.build_flags}
lib_deps =
${common.lib_deps_external}
# see: http://docs.platformio.org/en/latest/platforms/espressif32.html
[env:esp32dev]
board = esp32dev
platform = ${common:esp32.platform}
monitor_speed = ${common.monitor_speed}
upload_speed = ${common.upload_speed}
framework = ${common.framework}
build_flags =
${common.build_flags}
${common:esp32.build_flags}
lib_deps =
${common.lib_deps_external}

View File

@ -1,6 +1,6 @@
![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/development/wled_logo.png) ![WLED logo](https://raw.githubusercontent.com/Aircoookie/WLED/development/wled_logo.png)
## Welcome to my project WLED! (v0.8.1) ## Welcome to my project WLED! (v0.8.2-dev)
A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs! A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
@ -28,6 +28,7 @@ A fast and feature-rich implementation of an ESP8266/ESP32 webserver to control
- Sync to Philips hue lights - Sync to Philips hue lights
- Adalight (PC ambilight via serial) - Adalight (PC ambilight via serial)
- Sync color of multiple WLED devices (UDP notifier) - Sync color of multiple WLED devices (UDP notifier)
- Infrared remotes (24-key RGB, receiver required)
- Simple timers/schedules (time from NTP, timezones/DST supported) - Simple timers/schedules (time from NTP, timezones/DST supported)
### Quick start guide and documentation: ### Quick start guide and documentation:
@ -37,13 +38,13 @@ See the [wiki](https://github.com/Aircoookie/WLED/wiki)!
### Other ### Other
Licensed under the MIT license Licensed under the MIT license
Credits in About page! Credits [here](https://github.com/Aircoookie/WLED/wiki/Contributors-&-About)!
Uses Linearicons by Perxis! Uses Linearicons by Perxis!
Join the Discord [server](https://discord.gg/KuqP7NE) to discuss everything about WLED! Join the Discord [server](https://discord.gg/KuqP7NE) to discuss everything about WLED!
You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com). You can also send me mails to [dev.aircoookie@gmail.com](mailto:dev.aircoookie@gmail.com).
If you insist that you just love WLED too much, you can [send me a gift](https://paypal.me/aircoookie)! If WLED really brightens up your every day, you can [send me a small gift](https://paypal.me/aircoookie)!

11
test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html

View File

@ -5,10 +5,12 @@
#define WORKAROUND_ESP32_BITBANG #define WORKAROUND_ESP32_BITBANG
//see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support //see https://github.com/Aircoookie/WLED/issues/2 for flicker free ESP32 support
//PIN CONFIGURATION
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 is recommended for ESP8266 #define LEDPIN 2 //strip pin. Any for ESP32, gpio2 is recommended for ESP8266
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#define IR_PIN 4 //infrared pin.
#define AUXPIN 15 //unused auxiliary output pin
//uncomment this if red and green are swapped
//#define SWAPRG
//automatically uses the right driver method for each platform //automatically uses the right driver method for each platform
@ -31,14 +33,11 @@
#endif #endif
#endif #endif
//handle swapping Red and Green automatically
#ifdef SWAPRG //you can now change the color order in the web settings
#define PIXELFEATURE3 NeoRgbFeature #define PIXELFEATURE3 NeoGrbFeature
#define PIXELFEATURE4 NeoRgbwFeature #define PIXELFEATURE4 NeoGrbwFeature
#else
#define PIXELFEATURE3 NeoGrbFeature
#define PIXELFEATURE4 NeoGrbwFeature
#endif
#include <NeoPixelBrightnessBus.h> #include <NeoPixelBrightnessBus.h>

View File

@ -59,7 +59,6 @@ void WS2812FX::init(bool supportWhite, uint16_t countPixels, bool skipFirst)
_segments[0].stop = _length -1; _segments[0].stop = _length -1;
unlockAll(); unlockAll();
setBrightness(_brightness); setBrightness(_brightness);
show();
_running = true; _running = true;
} }
@ -93,7 +92,7 @@ void WS2812FX::clear()
bool WS2812FX::modeUsesLock(uint8_t m) bool WS2812FX::modeUsesLock(uint8_t m)
{ {
if (m == FX_MODE_FIRE_2012 || m == FX_MODE_COLORTWINKLE) return true; if (m == FX_MODE_FIRE_2012 || m == FX_MODE_COLORTWINKLE || m == FX_MODE_METEOR || m == FX_MODE_METEOR_SMOOTH) return true;
return false; return false;
} }
@ -110,6 +109,14 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
if (_locked[i] && !modeUsesLock(SEGMENT.mode)) return; if (_locked[i] && !modeUsesLock(SEGMENT.mode)) return;
if (_reverseMode) i = _length - 1 -i; if (_reverseMode) i = _length - 1 -i;
if (IS_REVERSE) i = SEGMENT.stop - (i - SEGMENT.start); //reverse just individual segment if (IS_REVERSE) i = SEGMENT.stop - (i - SEGMENT.start); //reverse just individual segment
byte tmpg = g;
switch (colorOrder) //0 = Grb, default
{
case 0: break; //0 = Grb, default
case 1: g = r; r = tmpg; break; //1 = Rgb, common for WS2811
case 2: g = b; b = tmpg; break; //2 = Brg
case 3: g = b; b = r; r = tmpg; //3 = Rbg
}
if (!_cronixieMode) if (!_cronixieMode)
{ {
if (_skipFirstMode) {i++;if(i==1)bus->SetPixelColor(i, RgbwColor(0,0,0,0));} if (_skipFirstMode) {i++;if(i==1)bus->SetPixelColor(i, RgbwColor(0,0,0,0));}
@ -119,13 +126,13 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
byte o = 10*i; byte o = 10*i;
if (_cronixieBacklightEnabled && _cronixieDigits[i] <11) if (_cronixieBacklightEnabled && _cronixieDigits[i] <11)
{ {
byte rCorr = (int)(((double)((_segments[0].colors[1]>>16) & 0xFF))*_cronixieSecMultiplier); byte r2 = (_segments[0].colors[1] >>16) & 0xFF;
byte gCorr = (int)(((double)((_segments[0].colors[1]>>8) & 0xFF))*_cronixieSecMultiplier); byte g2 = (_segments[0].colors[1] >> 8) & 0xFF;
byte bCorr = (int)(((double)((_segments[0].colors[1]) & 0xFF))*_cronixieSecMultiplier); byte b2 = (_segments[0].colors[1] ) & 0xFF;
byte wCorr = (int)(((double)((_segments[0].colors[1]>>24) & 0xFF))*_cronixieSecMultiplier); byte w2 = (_segments[0].colors[1] >>24) & 0xFF;
for (int j=o; j< o+19; j++) for (int j=o; j< o+19; j++)
{ {
bus->SetPixelColor((_skipFirstMode)?j+1:j,RgbwColor(rCorr,gCorr,bCorr,wCorr)); bus->SetPixelColor((_skipFirstMode)?j+1:j,RgbwColor(r2,g2,b2,w2));
} }
} else } else
{ {
@ -174,7 +181,75 @@ void WS2812FX::setCronixieDigits(byte d[])
} }
} }
//DISCLAIMER
//The following function attemps to calculate the current LED power usage,
//and will limit the brightness to stay below a set amperage threshold.
//It is NOT a measurement and NOT guaranteed to stay within the ablMilliampsMax margin.
//Stay safe with high amperage and have a reasonable safety margin!
//I am NOT to be held liable for burned down garages!
//fine tune power estimation constants for your setup
#define PU_PER_MA 3600 //power units per milliamperere for accurate power estimation
//formula: 195075 divided by mA per fully lit LED, here ~54mA)
//lowering the value increases the estimated usage and therefore makes the ABL more aggressive
#define MA_FOR_ESP 100 //how much mA does the ESP use (Wemos D1 about 80mA, ESP32 about 120mA)
//you can set it to 0 if the ESP is powered by USB and the LEDs by external
void WS2812FX::show(void) { void WS2812FX::show(void) {
//power limit calculation
//each LED can draw up 195075 "power units" (approx. 53mA)
//one PU is the power it takes to have 1 channel 1 step brighter per brightness step
//so A=2,R=255,G=0,B=0 would use 510 PU per LED (1mA is about 3700 PU)
if (ablMilliampsMax > 149 && ablMilliampsMax < 65000) //lower numbers and 65000 turn off calculation
{
uint32_t powerBudget = (ablMilliampsMax - MA_FOR_ESP) * PU_PER_MA; //100mA for ESP power
if (powerBudget > PU_PER_MA * _length) //each LED uses about 1mA in standby, exclude that from power budget
{
powerBudget -= PU_PER_MA * _length;
} else
{
powerBudget = 0;
}
uint32_t powerSum = 0;
for (uint16_t i = 0; i < _length; i++) //sum up the usage of each LED
{
RgbwColor c = bus->GetPixelColorRgbw(i);
powerSum += (c.R + c.G + c.B + c.W);
}
if (_rgbwMode) //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less
{
powerSum *= 3;
powerSum >> 2; //same as /= 4
}
uint32_t powerSum0 = powerSum;
powerSum *= _brightness;
if (powerSum > powerBudget) //scale brightness down to stay in current limit
{
float scale = (float)powerBudget / (float)powerSum;
uint16_t scaleI = scale * 255;
uint8_t scaleB = (scaleI > 255) ? 255 : scaleI;
uint8_t newBri = scale8(_brightness, scaleB);
bus->SetBrightness(newBri);
currentMilliamps = (powerSum0 * newBri) / PU_PER_MA;
} else
{
currentMilliamps = powerSum / PU_PER_MA;
bus->SetBrightness(_brightness);
}
currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate
currentMilliamps += _length; //add standby power back to estimate
} else {
currentMilliamps = 0;
}
bus->Show(); bus->Show();
} }
@ -185,7 +260,8 @@ void WS2812FX::trigger() {
void WS2812FX::setMode(uint8_t m) { void WS2812FX::setMode(uint8_t m) {
RESET_RUNTIME; RESET_RUNTIME;
bool ua = modeUsesLock(_segments[0].mode) && !modeUsesLock(m); bool ua = modeUsesLock(_segments[0].mode) && !modeUsesLock(m);
_segments[0].mode = constrain(m, 0, MODE_COUNT - 1); if (m > MODE_COUNT - 1) m = MODE_COUNT - 1;
_segments[0].mode = m;
if (ua) unlockAll(); if (ua) unlockAll();
setBrightness(_brightness); setBrightness(_brightness);
} }
@ -204,6 +280,16 @@ void WS2812FX::setPalette(uint8_t p) {
_segments[0].palette = p; _segments[0].palette = p;
} }
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p) {
bool changed = false;
m = constrain(m, 0, MODE_COUNT - 1);
if (m != _segments[0].mode) { setMode(m); changed = true; }
if (s != _segments[0].speed) { setSpeed(s); changed = true; }
if (i != _segments[0].intensity) { setIntensity(i); changed = true; }
if (p != _segments[0].palette) { setPalette(p); changed = true; }
return changed;
}
void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) { void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
setColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b); setColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
} }
@ -218,10 +304,10 @@ void WS2812FX::setColor(uint32_t c) {
void WS2812FX::setSecondaryColor(uint32_t c) { void WS2812FX::setSecondaryColor(uint32_t c) {
_segments[0].colors[1] = c; _segments[0].colors[1] = c;
if (_cronixieMode) _cronixieSecMultiplier = getSafePowerMultiplier(900, 100, c, _brightness);
} }
void WS2812FX::setBrightness(uint8_t b) { void WS2812FX::setBrightness(uint8_t b) {
if (_brightness == b) return;
_brightness = b; _brightness = b;
bus->SetBrightness(_brightness); bus->SetBrightness(_brightness);
show(); show();
@ -275,7 +361,15 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
} }
} }
RgbwColor lColor = bus->GetPixelColorRgbw(i); RgbwColor lColor = bus->GetPixelColorRgbw(i);
return lColor.W*16777216 + lColor.R*65536 + lColor.G*256 + lColor.B; byte r = lColor.R, g = lColor.G, b = lColor.B;
switch (colorOrder)
{
case 0: break; //0 = Grb
case 1: r = lColor.G; g = lColor.R; break; //1 = Rgb, common for WS2811
case 2: g = lColor.B; b = lColor.G; break; //2 = Brg
case 3: r = lColor.B; g = lColor.R; b = lColor.G; //3 = Rbg
}
return ( (lColor.W << 24) | (r << 16) | (g << 8) | (b) );
} }
WS2812FX::Segment WS2812FX::getSegment(void) { WS2812FX::Segment WS2812FX::getSegment(void) {
@ -414,33 +508,6 @@ uint32_t WS2812FX::color_blend(uint32_t color1, uint32_t color2, uint8_t blend)
} }
double WS2812FX::getPowerEstimate(uint16_t leds, uint32_t c, byte b)
{
double _mARequired = 100; //ESP power
double _mul = (double)b/255;
double _sum = ((c & 0xFF000000) >> 24) + ((c & 0x00FF0000) >> 16) + ((c & 0x0000FF00) >> 8) + ((c & 0x000000FF) >> 0);
_sum /= (_rgbwMode)?1024:768;
double _mAPerLed = 50*(_mul*_sum);
_mARequired += leds*_mAPerLed;
return _mARequired;
}
//DISCLAIMER
//This is just a helper function for huge amounts of LEDs.
//It is NOT guaranteed to stay within the safeAmps margin.
//Stay safe with high amperage and have a reasonable safety margin!
//I am NOT to be held liable for burned down garages!
double WS2812FX::getSafePowerMultiplier(double safeMilliAmps, uint16_t leds, uint32_t c, byte b)
{
double _mARequired = getPowerEstimate(leds,c,b);
if (_mARequired > safeMilliAmps)
{
return safeMilliAmps/_mARequired;
}
return 1.0;
}
/* ##################################################### /* #####################################################
# #
# Color and Blinken Functions # Color and Blinken Functions
@ -2139,7 +2206,10 @@ void WS2812FX::handle_palette(void)
bool singleSegmentMode = (_segment_index == _segment_index_palette_last); bool singleSegmentMode = (_segment_index == _segment_index_palette_last);
_segment_index_palette_last = _segment_index; _segment_index_palette_last = _segment_index;
switch (SEGMENT.palette) byte paletteIndex = SEGMENT.palette;
if ((SEGMENT.mode >= FX_MODE_METEOR) && SEGMENT.palette == 0) paletteIndex = 4;
switch (paletteIndex)
{ {
case 0: {//default palette. Differs depending on effect case 0: {//default palette. Differs depending on effect
switch (SEGMENT.mode) switch (SEGMENT.mode)
@ -2240,7 +2310,7 @@ uint16_t WS2812FX::mode_palette(void)
setPixelColor(i, color_from_palette(colorIndex, false, true, 255)); setPixelColor(i, color_from_palette(colorIndex, false, true, 255));
} }
SEGMENT_RUNTIME.counter_mode_step += SEGMENT.speed *2; SEGMENT_RUNTIME.counter_mode_step += SEGMENT.speed;
if (SEGMENT.speed == 0) SEGMENT_RUNTIME.counter_mode_step = 0; if (SEGMENT.speed == 0) SEGMENT_RUNTIME.counter_mode_step = 0;
return 20; return 20;
} }
@ -2430,8 +2500,6 @@ uint16_t WS2812FX::mode_noise16_2(void)
uint16_t shift_y = SEGMENT_RUNTIME.counter_mode_step/42; uint16_t shift_y = SEGMENT_RUNTIME.counter_mode_step/42;
uint32_t real_x = (i + shift_x) * scale; // calculate the coordinates within the noise field uint32_t real_x = (i + shift_x) * scale; // calculate the coordinates within the noise field
uint32_t real_y = (i + shift_y) * scale; // based on the precalculated positions
uint32_t real_z = 4223;
uint8_t noise = inoise16(real_x, 0, 4223) >> 8; // get the noise data and scale it down uint8_t noise = inoise16(real_x, 0, 4223) >> 8; // get the noise data and scale it down
@ -2548,3 +2616,116 @@ uint16_t WS2812FX::mode_lake() {
} }
return 33; return 33;
} }
// meteor effect
// send a meteor from begining to to the end of the strip with a trail that randomly decays.
// adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain
uint16_t WS2812FX::mode_meteor() {
byte meteorSize= 1+ SEGMENT_LENGTH / 10;
uint16_t in = SEGMENT.start + SEGMENT_RUNTIME.counter_mode_step;
byte decayProb = 255 - SEGMENT.intensity;
// fade all leds to colors[1] in LEDs one step
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) {
if (random8() <= decayProb)
{
byte meteorTrailDecay = 128 + random8(127);
_locked[i] = scale8(_locked[i], meteorTrailDecay);
setPixelColor(i, color_from_palette(_locked[i], false, true, 255));
}
}
// draw meteor
for(int j = 0; j < meteorSize; j++) {
uint16_t index = in + j;
if(in + j > SEGMENT.stop) {
index = SEGMENT.start + (in + j - SEGMENT.stop) -1;
}
_locked[index] = 240;
setPixelColor(index, color_from_palette(_locked[index], false, true, 255));
}
SEGMENT_RUNTIME.counter_mode_step = (SEGMENT_RUNTIME.counter_mode_step + 1) % (SEGMENT_LENGTH);
return SPEED_FORMULA_L;
}
//smooth
//front ramping (maybe from get color
//50fps
//fade each led by a certain range (even ramp possible for sparkling)
//maybe dim to color[1] at end?
//_locked 0-15 bg-last 15-240 last-first 240-255 first-bg
#define IS_PART_OF_METEOR 245
// smooth meteor effect
// send a meteor from begining to to the end of the strip with a trail that randomly decays.
// adapted from https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectMeteorRain
uint16_t WS2812FX::mode_meteor_smooth() {
byte meteorSize= 1+ SEGMENT_LENGTH / 10;
uint16_t in = map((SEGMENT_RUNTIME.counter_mode_step >> 6 & 0xFF), 0, 255, SEGMENT.start, SEGMENT.stop);
byte decayProb = 255 - SEGMENT.intensity;
// fade all leds to colors[1] in LEDs one step
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i++) {
if (_locked[i] != IS_PART_OF_METEOR && _locked[i] != 0 && random8() <= decayProb)
{
int change = 3 - random8(12); //change each time between -8 and +3
_locked[i] += change;
if (_locked[i] > 245) _locked[i] = 0;
if (_locked[i] > 240) _locked[i] = 240;
setPixelColor(i, color_from_palette(_locked[i], false, true, 255));
}
}
// draw meteor
for(int j = 0; j < meteorSize; j++) {
uint16_t index = in + j;
if(in + j > SEGMENT.stop) {
index = SEGMENT.start + (in + j - SEGMENT.stop) -1;
}
_locked[index] = IS_PART_OF_METEOR;
setPixelColor(index, color_blend(getPixelColor(index), color_from_palette(240, false, true, 255), 48));
if (j == 0) _locked[index] = 240;//last pixel of meteor
}
SEGMENT_RUNTIME.counter_mode_step += SEGMENT.speed +1;
return 20;
}
//Railway Crossing / Christmas Fairy lights
uint16_t WS2812FX::mode_railway()
{
uint16_t dur = 40 + (255 - SEGMENT.speed) * 10;
uint16_t rampdur = (dur * SEGMENT.intensity) >> 8;
if (SEGMENT_RUNTIME.counter_mode_step > dur)
{
//reverse direction
SEGMENT_RUNTIME.counter_mode_step = 0;
SEGMENT_RUNTIME.aux_param = !SEGMENT_RUNTIME.aux_param;
}
uint8_t pos = 255;
if (rampdur != 0)
{
uint16_t p0 = (SEGMENT_RUNTIME.counter_mode_step * 255) / rampdur;
if (p0 < 255) pos = p0;
}
if (SEGMENT_RUNTIME.aux_param) pos = 255 - pos;
for (uint16_t i = SEGMENT.start; i <= SEGMENT.stop; i += 2)
{
setPixelColor(i, color_from_palette(255 - pos, false, false, 255));
if (i != SEGMENT.stop)
{
setPixelColor(i + 1, color_from_palette(pos, false, false, 255));
}
}
SEGMENT_RUNTIME.counter_mode_step += 20;
return 20;
}

View File

@ -44,9 +44,9 @@
#define FASTLED_INTERNAL //remove annoying pragma messages #define FASTLED_INTERNAL //remove annoying pragma messages
#include "FastLED.h" #include "FastLED.h"
#define DEFAULT_BRIGHTNESS (uint8_t)50 #define DEFAULT_BRIGHTNESS (uint8_t)127
#define DEFAULT_MODE (uint8_t)0 #define DEFAULT_MODE (uint8_t)0
#define DEFAULT_SPEED (uint16_t)1000 #define DEFAULT_SPEED (uint8_t)128
#define DEFAULT_COLOR (uint32_t)0xFF0000 #define DEFAULT_COLOR (uint32_t)0xFF0000
#define min(a,b) ((a)<(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b))
@ -85,7 +85,7 @@
#define REVERSE (uint8_t)0x80 #define REVERSE (uint8_t)0x80
#define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE) #define IS_REVERSE ((SEGMENT.options & REVERSE) == REVERSE)
#define MODE_COUNT 76 #define MODE_COUNT 79
#define FX_MODE_STATIC 0 #define FX_MODE_STATIC 0
#define FX_MODE_BLINK 1 #define FX_MODE_BLINK 1
@ -164,6 +164,10 @@
#define FX_MODE_NOISE16_4 73 #define FX_MODE_NOISE16_4 73
#define FX_MODE_COLORTWINKLE 74 #define FX_MODE_COLORTWINKLE 74
#define FX_MODE_LAKE 75 #define FX_MODE_LAKE 75
#define FX_MODE_METEOR 76
#define FX_MODE_METEOR_SMOOTH 77
#define FX_MODE_RAILWAY 78
class WS2812FX { class WS2812FX {
typedef uint16_t (WS2812FX::*mode_ptr)(void); typedef uint16_t (WS2812FX::*mode_ptr)(void);
@ -268,6 +272,10 @@ class WS2812FX {
_mode[FX_MODE_NOISE16_4] = &WS2812FX::mode_noise16_4; _mode[FX_MODE_NOISE16_4] = &WS2812FX::mode_noise16_4;
_mode[FX_MODE_COLORTWINKLE] = &WS2812FX::mode_colortwinkle; _mode[FX_MODE_COLORTWINKLE] = &WS2812FX::mode_colortwinkle;
_mode[FX_MODE_LAKE] = &WS2812FX::mode_lake; _mode[FX_MODE_LAKE] = &WS2812FX::mode_lake;
_mode[FX_MODE_METEOR] = &WS2812FX::mode_meteor;
_mode[FX_MODE_METEOR_SMOOTH] = &WS2812FX::mode_meteor_smooth;
_mode[FX_MODE_RAILWAY] = &WS2812FX::mode_railway;
_brightness = DEFAULT_BRIGHTNESS; _brightness = DEFAULT_BRIGHTNESS;
_running = false; _running = false;
@ -278,8 +286,11 @@ class WS2812FX {
_segments[0].speed = DEFAULT_SPEED; _segments[0].speed = DEFAULT_SPEED;
_reverseMode = false; _reverseMode = false;
_skipFirstMode = false; _skipFirstMode = false;
colorOrder = 0;
paletteFade = 0; paletteFade = 0;
paletteBlend = 0; paletteBlend = 0;
ablMilliampsMax = 750;
currentMilliamps = 0;
_locked = NULL; _locked = NULL;
_cronixieDigits = new byte[6]; _cronixieDigits = new byte[6];
bus = new NeoPixelWrapper(); bus = new NeoPixelWrapper();
@ -323,9 +334,13 @@ class WS2812FX {
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0), setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
show(void); show(void);
bool
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);
uint8_t uint8_t
paletteFade, paletteFade,
paletteBlend, paletteBlend,
colorOrder,
getBrightness(void), getBrightness(void),
getMode(void), getMode(void),
getSpeed(void), getSpeed(void),
@ -339,10 +354,6 @@ class WS2812FX {
getPixelColor(uint16_t), getPixelColor(uint16_t),
getColor(void); getColor(void);
double
getPowerEstimate(uint16_t leds, uint32_t c, byte b),
getSafePowerMultiplier(double safeMilliAmps, uint16_t leds, uint32_t c, byte b);
WS2812FX::Segment WS2812FX::Segment
getSegment(void); getSegment(void);
@ -354,6 +365,8 @@ class WS2812FX {
// mode helper functions // mode helper functions
uint16_t uint16_t
ablMilliampsMax,
currentMilliamps,
blink(uint32_t, uint32_t, bool strobe, bool), blink(uint32_t, uint32_t, bool strobe, bool),
color_wipe(uint32_t, uint32_t, bool , bool), color_wipe(uint32_t, uint32_t, bool , bool),
scan(bool), scan(bool),
@ -443,6 +456,9 @@ class WS2812FX {
mode_noise16_4(void), mode_noise16_4(void),
mode_colortwinkle(void), mode_colortwinkle(void),
mode_lake(void), mode_lake(void),
mode_meteor(void),
mode_meteor_smooth(void),
mode_railway(void),
mode_lightning(void); mode_lightning(void);
private: private:
@ -457,9 +473,6 @@ class WS2812FX {
void handle_palette(void); void handle_palette(void);
bool modeUsesLock(uint8_t); bool modeUsesLock(uint8_t);
double
_cronixieSecMultiplier;
boolean boolean
_running, _running,
_rgbwMode, _rgbwMode,
@ -480,9 +493,9 @@ class WS2812FX {
uint8_t _segment_index = 0; uint8_t _segment_index = 0;
uint8_t _segment_index_palette_last = 99; uint8_t _segment_index_palette_last = 99;
uint8_t _num_segments = 1; uint8_t _num_segments = 1;
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 20 bytes per element segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 21 bytes per element
// start, stop, speed, intensity, mode, options, color[] // start, stop, speed, intensity, palette, mode, options, color[]
{ 0, 7, DEFAULT_SPEED, 128, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}} { 0, 7, DEFAULT_SPEED, 128, 0, FX_MODE_STATIC, NO_OPTIONS, {DEFAULT_COLOR}}
}; };
segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 17 bytes per element segment_runtime _segment_runtimes[MAX_NUM_SEGMENTS]; // SRAM footprint: 17 bytes per element
}; };

View File

@ -2,7 +2,7 @@
<html> <html>
<head><meta charset="utf-8"><meta name="theme-color" content="#fff"> <head><meta charset="utf-8"><meta name="theme-color" content="#fff">
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/> <link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/>
<title>WLED 0.8.1</title> <title>WLED 0.8.2</title>
<script> <script>
var d=document; var d=document;
var w=window.getComputedStyle(d.querySelector("html")); var w=window.getComputedStyle(d.querySelector("html"));
@ -26,14 +26,17 @@
{ {
return d.getElementById(s); return d.getElementById(s);
} }
function UCol()
function Startup()
{ {
var w=window.getComputedStyle(d.querySelector("html"));
aC = w.getPropertyValue("--aCol"); aC = w.getPropertyValue("--aCol");
bC = w.getPropertyValue("--bCol"); bC = w.getPropertyValue("--bCol");
dC = w.getPropertyValue("--dCol"); dC = w.getPropertyValue("--dCol");
d.querySelector("meta[name=theme-color]").setAttribute("content",bC); d.querySelector("meta[name=theme-color]").setAttribute("content",bC);
}
function Startup()
{
var w=window.getComputedStyle(d.querySelector("html"));
UCol();
CV(0); CV(0);
setInterval('GIO()', 5000); setInterval('GIO()', 5000);
GIO(); GIO();
@ -66,6 +69,14 @@
d.Cf.NC.checked = (this.responseXML.getElementsByTagName('nf')[0].innerHTML)!=0?true:false; d.Cf.NC.checked = (this.responseXML.getElementsByTagName('nf')[0].innerHTML)!=0?true:false;
d.Cf.SN.value = this.responseXML.getElementsByTagName('nd')[0].childNodes[0].nodeValue; d.Cf.SN.value = this.responseXML.getElementsByTagName('nd')[0].childNodes[0].nodeValue;
d.Cf.ST.value = this.responseXML.getElementsByTagName('nt')[0].childNodes[0].nodeValue; d.Cf.ST.value = this.responseXML.getElementsByTagName('nt')[0].childNodes[0].nodeValue;
d.documentElement.style.setProperty("--aCol",this.responseXML.getElementsByTagName('ca')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--bCol",this.responseXML.getElementsByTagName('cb')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--cCol",this.responseXML.getElementsByTagName('cc')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--dCol",this.responseXML.getElementsByTagName('cd')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--sCol",this.responseXML.getElementsByTagName('cs')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--tCol",this.responseXML.getElementsByTagName('ct')[0].childNodes[0].nodeValue);
d.documentElement.style.setProperty("--cFn",this.responseXML.getElementsByTagName('cf')[0].childNodes[0].nodeValue);
UCol();
CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue)); CV(parseInt(this.responseXML.getElementsByTagName('md')[0].childNodes[0].nodeValue));
}firstload=false; }firstload=false;
nState = 0; nState = 0;
@ -77,6 +88,7 @@
} }
} }
} }
if (firstload) resp+="&IT"
request.open("GET", "win" +resp +nocache, true); request.open("GET", "win" +resp +nocache, true);
request.send(null); request.send(null);
resp=""; resp="";
@ -192,10 +204,10 @@
function SwFX(s) function SwFX(s)
{ {
var n=Cf.TX.selectedIndex+s; var n=Cf.TX.selectedIndex+s;
if (n==-1||n==76) return; if (n==-1||n==79) return;
Cf.TX.selectedIndex =n; Cf.TX.selectedIndex =n;
if (n < 0) Cf.TX.selectedIndex = 0; if (n < 0) Cf.TX.selectedIndex = 0;
if (n > 75) Cf.TX.selectedIndex = 65; if (n > 78) Cf.TX.selectedIndex = 65;
GX(); GX();
} }
function TgHSB() function TgHSB()
@ -302,7 +314,6 @@
rr=diffc(r); rr=diffc(r);
gg=diffc(g); gg=diffc(g);
bb=diffc(b); bb=diffc(b);
if(r===v) { if(r===v) {
h=bb-gg; h=bb-gg;
}else if (g===v){ }else if (g===v){
@ -662,6 +673,9 @@
<option value="73">Noise 16 4 (73)</option> <option value="73">Noise 16 4 (73)</option>
<option value="74">Colortwinkle (74)</option> <option value="74">Colortwinkle (74)</option>
<option value="75">Lake (75)</option> <option value="75">Lake (75)</option>
<option value="76">Meteor (76)</option>
<option value="77">Smooth Meteor (77)</option>
<option value="78">Railway (78)</option>
</select><br><br> </select><br><br>
Set secondary color to Set secondary color to
<button type="button" onclick="CS(0)">White</button> <button type="button" onclick="CS(0)">White</button>
@ -734,14 +748,14 @@
<svg id="psn" onclick="SwitchPS(1)"><use xlink:href="#lnr-arrow-right-circle"></use></svg> <svg id="psn" onclick="SwitchPS(1)"><use xlink:href="#lnr-arrow-right-circle"></use></svg>
<svg id="pss" onclick="PSIO(true)"><use xlink:href="#lnr-arrow-down-circle"></use></svg> <svg id="pss" onclick="PSIO(true)"><use xlink:href="#lnr-arrow-down-circle"></use></svg>
<br><input id="psI" name = "FF" type="number" value="1" min="1" max="25" step="1"><br><br> <br><input id="psI" name = "FF" type="number" value="1" min="1" max="25" step="1"><br><br>
Click checkmark to apply <input type="checkbox" checked="true" name="BC"> brightness, <input type="checkbox" checked="true" name="CC"> color and <input type="checkbox" checked="true" name="FC"> effects.<br><br> Click checkmark to apply <input type="checkbox" checked name="CC"> color, <input type="checkbox" checked name="FC"> effects and <input type="checkbox" name="BC"> brightness.<br><br>
Cycle through presets <input id="cy1" name="P1" type="number" value="1" min="1" max="25" step="1"> to <input id="cy2" name="P2" type="number" value="5" min="1" max="25" step="1">, keep each for <input id="cyT" name="PT" type="number" value="1250" min="50" max="65501" step="1">ms: <input type="checkbox" name="CY" onclick="uCY()"><br><br> Cycle through presets <input id="cy1" name="P1" type="number" value="1" min="1" max="25" step="1"> to <input id="cy2" name="P2" type="number" value="5" min="1" max="25" step="1">, keep each for <input id="cyT" name="PT" type="number" value="1250" min="50" max="65501" step="1">ms: <input type="checkbox" name="CY" onclick="uCY()"><br><br>
<button type="button" onclick="R()">Apply boot config</button><br> <button type="button" onclick="R()">Apply boot config</button><br>
</div> </div>
<div id="tlN" class="tools"> <div id="tlN" class="tools">
Timed Light<br><br> Timed Light<br><br>
<svg id="ntb" onclick="TgNl()"><use xlink:href="#lnr-power-switch"></use></svg><br><br> <svg id="ntb" onclick="TgNl()"><use xlink:href="#lnr-power-switch"></use></svg><br><br>
Gradually dim down <input type="checkbox" checked="true" name="NC"><br> Gradually dim down <input type="checkbox" checked name="NC"><br>
1st slider sets duration (1-255min), 2nd sets target brightness. 1st slider sets duration (1-255min), 2nd sets target brightness.
<div id="slN" class="sl"> <div id="slN" class="sl">
<input type="range" title="Duration" class="sds" name="SN" value="60" min="1" max="255" step="1"></div> <input type="range" title="Duration" class="sds" name="SN" value="60" min="1" max="255" step="1"></div>

View File

@ -7,7 +7,7 @@
<meta name="theme-color" content="#333333"> <meta name="theme-color" content="#333333">
<meta content="yes" name="apple-mobile-web-app-capable"> <meta content="yes" name="apple-mobile-web-app-capable">
<link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/> <link rel="shortcut icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAGACGAAAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAQAAAAEAgGAAAAH/P/YQAAAE1JREFUOI1j/P//PwOxgNGeAUMxE9G6cQCKDWAhpADZ2f8PMjBS3QW08QK20KaZC2gfC9hCnqouoNgARgY7zMxAyNlUdQHlXiAlO2MDAD63EVqNHAe0AAAAAElFTkSuQmCC"/>
<title>WLED 0.8.1</title> <title>WLED 0.8.2</title>
<style> <style>
*{transition-duration: 0.5s;} *{transition-duration: 0.5s;}
body { body {
@ -434,7 +434,10 @@
<li onclick="X(72)">Noise 16 3</li> <li onclick="X(72)">Noise 16 3</li>
<li onclick="X(73)">Noise 16 4</li> <li onclick="X(73)">Noise 16 4</li>
<li onclick="X(74)">Colortwinkle</li> <li onclick="X(74)">Colortwinkle</li>
<li onclick="X(75)">Colortwinkle</li>&nbsp; <li onclick="X(75)">Lake</li>
<li onclick="X(76)">Meteor</li>
<li onclick="X(77)">Smooth Meteor</li>
<li onclick="X(78)">Railway</li>&nbsp;
<li><a href="#">Go to top</a></li>&nbsp; <li><a href="#">Go to top</a></li>&nbsp;
<p style="margin-left:-37px">FastLED Palette (Effects 56-73)</p> <p style="margin-left:-37px">FastLED Palette (Effects 56-73)</p>
<li onclick="P(0)">Default</li> <li onclick="P(0)">Default</li>

View File

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head>
<meta content='width=device-width' name='viewport'>
<title>WLED Message</title> <title>WLED Message</title>
<script> <script>
function B() { function B() {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,6 +1,7 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta content='width=device-width' name='viewport'>
<title>WLED Setup</title> <title>WLED Setup</title>
<style> <style>
:root { :root {
@ -14,9 +15,7 @@
font-family: Verdana, Helvetica, sans-serif; font-family: Verdana, Helvetica, sans-serif;
text-align: center; text-align: center;
background: linear-gradient(var(--bCol),black); background: linear-gradient(var(--bCol),black);
height: 100%;
margin: 0; margin: 0;
background-repeat: no-repeat;
background-attachment: fixed; background-attachment: fixed;
color: var(--dCol); color: var(--dCol);
} }

711
wled00/html_classic.h Normal file
View File

@ -0,0 +1,711 @@
/*
* Binary arrays for the classic desktop UI index page.
* gzip is used for smaller size and improved speeds.
*
* Workflow for creating them from HTML source:
* 1. Minify HTML (https://htmlcompressor.com/compressor/) (optional)
* 2. Compress with gzip (https://online-converting.com/archives/convert-to-gzip/)
* 3. Convert gzip binary to c array (https://sourceforge.net/projects/bin2header/)
* alternative: https://littlevgl.com/image-to-c-array (raw)
* 4. update length value
*/
const uint16_t PAGE_index0_L = 11122;
const char PAGE_index0[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x08, 0x8d, 0x45, 0x08, 0x5c, 0x00, 0x03, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65,
0x73, 0x73, 0x65, 0x64, 0x20, 0x28, 0x31, 0x30, 0x29, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x00, 0xcc,
0x5a, 0x09, 0x6f, 0xdb, 0xc6, 0xb6, 0xfe, 0x2b, 0xac, 0x82, 0xb6, 0x52, 0x2d, 0xd2, 0xe4, 0x70,
0x97, 0x4c, 0x17, 0x89, 0xdb, 0x2c, 0x40, 0xe2, 0x1a, 0xb1, 0x6f, 0x9b, 0xa2, 0x28, 0x02, 0x8a,
0xa4, 0x2c, 0xc6, 0x14, 0xa9, 0x4b, 0x52, 0x5e, 0xea, 0xfa, 0xbf, 0xbf, 0xef, 0xcc, 0x0c, 0x25,
0x52, 0xde, 0xa4, 0xdc, 0xbe, 0xfb, 0x5e, 0x80, 0x50, 0x9a, 0x39, 0x33, 0x73, 0x96, 0xef, 0x6c,
0x43, 0xf9, 0xe0, 0x9b, 0x9f, 0x7e, 0x39, 0x3a, 0xfb, 0xfd, 0xe4, 0x67, 0x65, 0x56, 0xcf, 0xb3,
0xc3, 0x03, 0xf9, 0x4c, 0xc2, 0xf8, 0xf0, 0x60, 0x9e, 0xd4, 0xa1, 0x12, 0xcd, 0xc2, 0xb2, 0x4a,
0xea, 0x60, 0x59, 0x4f, 0x55, 0x4f, 0xce, 0xe5, 0xe1, 0x3c, 0x09, 0xea, 0x59, 0x32, 0x4f, 0xd4,
0xa8, 0xc8, 0x8a, 0x52, 0x89, 0x8a, 0xbc, 0x4e, 0xf2, 0x3a, 0x78, 0x31, 0x9d, 0x4e, 0x0f, 0x0f,
0xb2, 0x34, 0xbf, 0x50, 0xca, 0x24, 0x0b, 0xbe, 0xaf, 0x66, 0x45, 0x59, 0x47, 0xcb, 0x5a, 0x49,
0xb1, 0xe2, 0x7b, 0xa5, 0xbe, 0x59, 0x24, 0x41, 0x3a, 0x0f, 0xcf, 0x93, 0xfd, 0x6b, 0x95, 0xa6,
0x94, 0x59, 0x99, 0x4c, 0x83, 0xef, 0xf7, 0xa7, 0xe1, 0x25, 0x0d, 0x35, 0x3c, 0xbe, 0xdf, 0x3f,
0x3c, 0xa8, 0xd3, 0x3a, 0x4b, 0x0e, 0x7f, 0x7b, 0xff, 0xf3, 0x4f, 0x8a, 0xae, 0x79, 0x1a, 0x3b,
0xd8, 0x17, 0x33, 0xca, 0x41, 0x15, 0x95, 0xe9, 0xa2, 0x3e, 0xbc, 0x0c, 0x4b, 0x25, 0x0e, 0xe2,
0x22, 0x5a, 0xce, 0xc1, 0x76, 0x4c, 0xc3, 0xab, 0xe0, 0x2a, 0xcd, 0xe3, 0xe2, 0x4a, 0x3b, 0x4f,
0xea, 0xa3, 0x62, 0xbe, 0x58, 0xd6, 0x49, 0x7c, 0x5a, 0xdf, 0x64, 0x49, 0x3f, 0xd6, 0xfe, 0xbd,
0x4c, 0xca, 0x9b, 0xd3, 0x24, 0x4b, 0xa2, 0xba, 0x28, 0xfb, 0x3d, 0xd2, 0xb1, 0x37, 0x18, 0x8c,
0xcb, 0xa4, 0x5a, 0x04, 0xbd, 0x1e, 0xdf, 0x9e, 0x67, 0x61, 0x30, 0x0d, 0xb3, 0x2a, 0x11, 0xa3,
0xb2, 0x33, 0xaa, 0xda, 0xa3, 0xaa, 0x2e, 0x5a, 0xa3, 0xe5, 0xd5, 0x65, 0x9b, 0x36, 0x99, 0x06,
0x75, 0xb9, 0x14, 0x83, 0x69, 0x5a, 0x56, 0x75, 0x56, 0x84, 0xf1, 0x7a, 0x2a, 0x0b, 0xab, 0xba,
0xba, 0x0e, 0x74, 0x71, 0xec, 0x69, 0x1d, 0xd6, 0x89, 0x1c, 0x44, 0x97, 0xf2, 0x4b, 0x36, 0xc7,
0x97, 0xf0, 0x88, 0xe4, 0x9a, 0xf0, 0x67, 0xcc, 0x9f, 0xd3, 0x65, 0x1e, 0xd5, 0x29, 0x2c, 0x76,
0xfe, 0x2e, 0xee, 0x87, 0x83, 0xdb, 0x32, 0xa9, 0x97, 0x65, 0xae, 0xc4, 0xa4, 0xee, 0xcf, 0x59,
0x42, 0x66, 0x78, 0x75, 0xc3, 0x49, 0x77, 0xab, 0xa5, 0xff, 0x3a, 0x2a, 0xb2, 0xfe, 0xe0, 0x16,
0x87, 0x71, 0xab, 0x9c, 0x94, 0xc5, 0x22, 0x29, 0xeb, 0x9b, 0x5f, 0xc3, 0x6c, 0x99, 0xf4, 0x7b,
0xaa, 0x1a, 0x82, 0xde, 0x1b, 0x10, 0x9b, 0x87, 0xe9, 0x13, 0x41, 0x8f, 0x1f, 0xa3, 0xc7, 0x92,
0xbe, 0x69, 0x5f, 0xf2, 0x91, 0x3f, 0x36, 0x7d, 0xe4, 0xcf, 0xde, 0x40, 0x83, 0x1f, 0xbd, 0xac,
0xeb, 0x32, 0x9d, 0x00, 0x9c, 0x7e, 0x4f, 0x3a, 0x4d, 0x6f, 0x38, 0x39, 0x6a, 0x09, 0x0d, 0xa3,
0x94, 0xf5, 0x72, 0x01, 0xb9, 0xc9, 0x1a, 0xe1, 0xee, 0xa8, 0x0a, 0xad, 0xc7, 0x47, 0xbf, 0xf6,
0xf5, 0xc1, 0x18, 0x1c, 0xdf, 0x81, 0x4b, 0x79, 0x19, 0x66, 0xfd, 0xde, 0x9b, 0x77, 0xbf, 0xf4,
0x07, 0xbd, 0xa1, 0xad, 0xeb, 0xa0, 0xf0, 0xc1, 0x9a, 0x2d, 0x1f, 0xde, 0xe6, 0x45, 0x14, 0x46,
0xb3, 0x24, 0xe8, 0x7d, 0xb7, 0xfa, 0xb6, 0xf7, 0x21, 0xac, 0x67, 0x5a, 0x19, 0x42, 0x8a, 0x79,
0x7f, 0xf0, 0x83, 0xa1, 0xf3, 0x7f, 0x63, 0x21, 0x5c, 0x9e, 0x5c, 0x29, 0x9f, 0x3e, 0xbc, 0x7f,
0x5b, 0xd7, 0x8b, 0x8f, 0x09, 0xe4, 0xa9, 0x6a, 0x70, 0x0e, 0xb5, 0x22, 0x2f, 0x11, 0x40, 0x37,
0x15, 0xe1, 0x8b, 0xf8, 0xc9, 0xcf, 0x93, 0xa0, 0x61, 0x04, 0x26, 0xe9, 0xb4, 0x5f, 0xcf, 0xd2,
0x4a, 0xe3, 0x6b, 0x84, 0x0f, 0x04, 0xd6, 0x7a, 0x9a, 0x76, 0x2d, 0xab, 0x20, 0x60, 0x90, 0xb2,
0xb5, 0xb6, 0x5a, 0x14, 0x79, 0x95, 0x80, 0xd9, 0x37, 0x41, 0xbe, 0xcc, 0xb2, 0xc1, 0x6d, 0xac,
0x1d, 0x4d, 0xb5, 0xd3, 0x97, 0xda, 0x25, 0xc1, 0x11, 0x6c, 0xae, 0x6a, 0xf9, 0x45, 0xf5, 0xea,
0xe6, 0x2c, 0x3c, 0x3f, 0x06, 0x1e, 0xfd, 0x5e, 0x18, 0xf5, 0x06, 0x7f, 0xe8, 0x7f, 0x6a, 0xd1,
0x2c, 0xcd, 0xe2, 0xe3, 0x22, 0x4e, 0x2a, 0x1a, 0xe5, 0xf8, 0xc2, 0x51, 0x1d, 0x8b, 0x43, 0x3f,
0xee, 0x76, 0x68, 0x94, 0x6d, 0x73, 0xe8, 0x9b, 0xaf, 0x38, 0xd4, 0x78, 0xee, 0xd0, 0x57, 0x5f,
0x71, 0x28, 0x7b, 0xfc, 0xd0, 0x07, 0xcc, 0xfd, 0xc8, 0x49, 0x57, 0x97, 0x4f, 0xea, 0x7c, 0x18,
0xe8, 0x0d, 0x42, 0xbf, 0xed, 0x26, 0xe2, 0x33, 0x07, 0x8f, 0x29, 0xe1, 0x50, 0x3e, 0xb9, 0x4b,
0x90, 0x74, 0x6e, 0x57, 0xe9, 0xe7, 0x0e, 0xac, 0xce, 0x3e, 0x21, 0xc2, 0x28, 0x1c, 0x92, 0xf8,
0x5d, 0x1e, 0x27, 0xd7, 0xdb, 0xb2, 0x9c, 0x5e, 0x3f, 0xcd, 0x12, 0x47, 0xbf, 0x3e, 0xf9, 0xca,
0xa3, 0x17, 0xdb, 0xb8, 0xc6, 0xa7, 0xdd, 0x4c, 0x54, 0x3d, 0x23, 0x2f, 0x3f, 0xf4, 0xdd, 0x8e,
0x87, 0xa6, 0xcf, 0x1c, 0x4a, 0x05, 0x62, 0x5b, 0xe7, 0xc8, 0x65, 0x40, 0xa4, 0x79, 0x9e, 0x94,
0x6f, 0xcf, 0x3e, 0xbc, 0x1f, 0x7c, 0x13, 0xe8, 0x3f, 0x12, 0x6a, 0x23, 0x51, 0x2b, 0xe0, 0x67,
0xab, 0xea, 0x20, 0xfd, 0xe4, 0xf8, 0x08, 0xac, 0x93, 0xe8, 0x22, 0x89, 0xb7, 0x67, 0x33, 0x7d,
0x86, 0x8d, 0xb0, 0xee, 0xf1, 0x6e, 0x86, 0xc8, 0xe3, 0x6d, 0x20, 0x3b, 0xdb, 0xf1, 0xd0, 0xfa,
0xb9, 0x43, 0x9b, 0x62, 0x2e, 0x37, 0x23, 0x0d, 0x22, 0xcb, 0x53, 0xc5, 0x68, 0xca, 0xce, 0xaa,
0x62, 0x0d, 0xb7, 0x0d, 0xf6, 0xf0, 0x49, 0x9e, 0x83, 0x6d, 0x99, 0x4e, 0x76, 0x62, 0x3a, 0xf9,
0x67, 0x98, 0x46, 0x3b, 0x31, 0x7d, 0x3a, 0xab, 0x6f, 0xcd, 0x34, 0xde, 0x89, 0xe9, 0xd3, 0x7e,
0xb2, 0x35, 0xd3, 0x6a, 0x27, 0xa6, 0xd5, 0x3f, 0xc3, 0xb4, 0xde, 0x89, 0xe9, 0xd3, 0xce, 0xbb,
0x3d, 0xa6, 0xaf, 0xf3, 0xed, 0x79, 0x4e, 0x9f, 0xe1, 0xb9, 0x6e, 0x73, 0x16, 0xd4, 0xa0, 0xa3,
0xcb, 0xd9, 0x36, 0x6d, 0xcc, 0x9f, 0x01, 0x0e, 0x5d, 0xd1, 0xaa, 0x73, 0x15, 0x79, 0x64, 0xd5,
0xa9, 0xca, 0x2f, 0x5b, 0x27, 0xa8, 0xf2, 0xa1, 0x04, 0x65, 0x8c, 0x9a, 0x83, 0xf6, 0xb6, 0x3f,
0xa9, 0x7a, 0xe8, 0x24, 0x86, 0x93, 0xe2, 0xee, 0x8e, 0x23, 0xb4, 0xd8, 0x95, 0xd8, 0x03, 0xc5,
0xa2, 0x8d, 0x5d, 0xdb, 0xa6, 0xab, 0x78, 0x93, 0xdd, 0xf8, 0x5f, 0xbf, 0xa2, 0x5b, 0xc4, 0xbf,
0x8d, 0xd4, 0x4d, 0x47, 0xed, 0xa1, 0x5d, 0x7c, 0x77, 0xd6, 0xbb, 0x43, 0xdf, 0xb7, 0x48, 0x72,
0xb4, 0x99, 0x3f, 0x9f, 0xf5, 0x86, 0x3d, 0xf4, 0xad, 0xbd, 0x3d, 0x4e, 0x96, 0xad, 0xe4, 0x90,
0x12, 0x33, 0x75, 0x87, 0x55, 0x92, 0xc7, 0x7d, 0xde, 0xc3, 0x35, 0x37, 0x90, 0x56, 0x1b, 0x7a,
0xd4, 0x5f, 0x1f, 0xfa, 0x12, 0xdd, 0x67, 0xab, 0xc7, 0x1b, 0x37, 0xf3, 0x1f, 0xe5, 0xfc, 0xc7,
0x8d, 0xf9, 0x37, 0x72, 0xfe, 0xcd, 0xc6, 0xfc, 0x2b, 0x39, 0x2f, 0x9b, 0x25, 0x52, 0x01, 0x7d,
0xc3, 0x9a, 0xcf, 0x6f, 0x92, 0x2e, 0x3b, 0x95, 0x3b, 0xd2, 0xf5, 0x5e, 0x7f, 0xfc, 0xa9, 0x25,
0xd8, 0xeb, 0x4f, 0x62, 0xc7, 0x66, 0xc3, 0xb1, 0xe2, 0x78, 0x2a, 0x17, 0x34, 0x95, 0x7d, 0x45,
0x78, 0x27, 0x09, 0x4d, 0x75, 0x1e, 0x3f, 0xc8, 0x2b, 0xa9, 0x3f, 0xbe, 0x79, 0xd5, 0xdc, 0x00,
0x86, 0xd9, 0x30, 0x1f, 0x7e, 0x19, 0xce, 0x87, 0xc9, 0x30, 0x1a, 0x2e, 0x79, 0xe3, 0x7d, 0x11,
0x88, 0x22, 0xf4, 0x56, 0x1c, 0x32, 0xbc, 0x96, 0xe3, 0x53, 0x39, 0x2e, 0x02, 0x66, 0xdb, 0xe3,
0x2f, 0x01, 0x6f, 0xdd, 0xa7, 0x59, 0x81, 0xeb, 0xc1, 0xc5, 0x0f, 0xce, 0x60, 0x3c, 0x0f, 0xf0,
0xa1, 0x7e, 0x19, 0x27, 0x41, 0xf1, 0x43, 0xdf, 0x50, 0xaf, 0x07, 0xe3, 0x48, 0x7c, 0x9b, 0xff,
0x80, 0xef, 0x4b, 0xf1, 0x9d, 0x86, 0x03, 0x1a, 0x57, 0x57, 0x69, 0x1d, 0xcd, 0xfa, 0x5f, 0xbe,
0x75, 0x06, 0xb7, 0x51, 0x58, 0x25, 0x8a, 0x3e, 0x0a, 0x83, 0x62, 0x98, 0x05, 0xcb, 0x61, 0x1e,
0x24, 0xe3, 0x09, 0xfa, 0xf7, 0x8b, 0x31, 0x27, 0x18, 0x20, 0x44, 0x20, 0x14, 0x9b, 0x04, 0x06,
0x42, 0x22, 0x09, 0xcb, 0x36, 0xc1, 0x94, 0x84, 0x08, 0x84, 0xa2, 0x4d, 0xb0, 0x40, 0x58, 0x82,
0x90, 0x6c, 0x12, 0x6c, 0xc9, 0x9c, 0x08, 0xd1, 0x5d, 0xb7, 0x4f, 0x0f, 0x37, 0x5a, 0xec, 0x6c,
0xa3, 0x3b, 0xce, 0xc7, 0xe4, 0x57, 0x2d, 0x03, 0x9f, 0xb4, 0xc1, 0x3c, 0x11, 0x90, 0x6c, 0xb6,
0x78, 0x9b, 0xa8, 0x20, 0xd3, 0x84, 0xfc, 0x42, 0x82, 0x0b, 0xf0, 0xe0, 0xf6, 0x28, 0x2b, 0xaa,
0xe4, 0x34, 0xa9, 0xeb, 0x34, 0x3f, 0xaf, 0xb0, 0x8c, 0xae, 0xa5, 0xbd, 0x2a, 0x7b, 0x49, 0xb7,
0x3c, 0x9e, 0xfb, 0xe2, 0xb4, 0x5a, 0x64, 0xe1, 0x4d, 0xd0, 0xcb, 0x8b, 0x3c, 0xe9, 0x8d, 0x05,
0xbd, 0x3c, 0x9f, 0x3c, 0xbd, 0x60, 0x56, 0x3d, 0x4d, 0xcf, 0x7e, 0x7b, 0x92, 0x5e, 0x67, 0x9f,
0x9e, 0xa1, 0x9f, 0x3c, 0x43, 0x3f, 0x7e, 0x8c, 0x0e, 0xc5, 0xc3, 0x03, 0xc6, 0x0d, 0xc0, 0x83,
0xe7, 0x71, 0x79, 0x26, 0x59, 0x11, 0x5d, 0xf4, 0x9e, 0xb0, 0x88, 0x5c, 0x20, 0xfd, 0x2b, 0x5c,
0x79, 0xd7, 0x13, 0x36, 0x12, 0x5b, 0xc6, 0xfc, 0xe5, 0x40, 0xc7, 0xf1, 0x1e, 0x37, 0xdb, 0x7a,
0x8b, 0xd1, 0x75, 0xc9, 0xc7, 0x2d, 0x21, 0xb7, 0x74, 0xfc, 0xf4, 0x71, 0xbb, 0xde, 0x5f, 0x6d,
0x8d, 0x1e, 0xb7, 0xa2, 0x54, 0x3a, 0xba, 0x84, 0xb7, 0xce, 0xe3, 0x89, 0x24, 0x4f, 0xd3, 0x2c,
0x0b, 0xfa, 0xd9, 0xfc, 0x50, 0x1f, 0xfc, 0x18, 0x1e, 0x8d, 0xe2, 0xa3, 0xb5, 0xbf, 0xc1, 0x0e,
0x6c, 0x96, 0x5c, 0xf7, 0x29, 0xec, 0x43, 0x91, 0x0b, 0x26, 0x41, 0xf8, 0x77, 0x3f, 0x3a, 0x38,
0xf0, 0x06, 0x7f, 0xf7, 0x93, 0x83, 0x03, 0xc3, 0xa1, 0x0c, 0x4a, 0xef, 0x41, 0x7a, 0x2f, 0x7a,
0x7b, 0x7d, 0xc3, 0x71, 0x5d, 0x97, 0x19, 0xce, 0xde, 0x64, 0xa0, 0xd5, 0xc5, 0x69, 0x5d, 0xc2,
0x35, 0x31, 0x09, 0x49, 0xb2, 0x34, 0x4a, 0xfa, 0x46, 0xcb, 0x97, 0x33, 0x90, 0xca, 0x30, 0x6e,
0xce, 0x96, 0x87, 0x60, 0x36, 0x09, 0x4b, 0x95, 0x28, 0x29, 0x0a, 0x42, 0xbf, 0xb7, 0x37, 0x39,
0xda, 0x43, 0x2a, 0xdf, 0xeb, 0x8a, 0xb2, 0xd7, 0x1b, 0xb4, 0x32, 0x36, 0x25, 0x30, 0x74, 0xf0,
0x93, 0x22, 0xbe, 0x91, 0x3a, 0x4d, 0xc2, 0xe8, 0xe2, 0xbc, 0x2c, 0x96, 0x79, 0x1c, 0x34, 0x7c,
0x5a, 0xc1, 0x3a, 0x6c, 0x05, 0xea, 0xb0, 0x15, 0xa4, 0xfc, 0x5d, 0xc5, 0xdb, 0xd3, 0xed, 0x96,
0x4e, 0xaf, 0xbb, 0x06, 0xe4, 0xe1, 0xbe, 0x99, 0x8d, 0x57, 0x36, 0xc5, 0xdd, 0xa5, 0xbb, 0x1c,
0x77, 0x99, 0x15, 0xa9, 0x7e, 0x94, 0x24, 0xfd, 0x53, 0x94, 0xea, 0xae, 0x93, 0x2e, 0x90, 0x58,
0x8d, 0x15, 0xc6, 0x7c, 0x27, 0x36, 0xac, 0x48, 0xec, 0x1e, 0xe9, 0xbe, 0xcf, 0x3e, 0x70, 0x44,
0xb8, 0xed, 0x11, 0xec, 0x6b, 0xa4, 0x08, 0x8f, 0x1e, 0x70, 0xec, 0xdd, 0xa4, 0x08, 0x8f, 0xee,
0xea, 0xf3, 0xae, 0xbd, 0x5a, 0xf5, 0x79, 0x6d, 0xef, 0xe9, 0xe2, 0xd3, 0x86, 0xfb, 0xf7, 0x1f,
0xc1, 0x47, 0x86, 0xc5, 0x48, 0x26, 0x99, 0x69, 0x31, 0xdd, 0x3c, 0xfd, 0xde, 0x2e, 0xc7, 0x5a,
0xb1, 0x99, 0x97, 0xcf, 0xad, 0x3e, 0x30, 0xee, 0xc5, 0xd5, 0xd9, 0xf9, 0x99, 0x78, 0x09, 0xd5,
0x15, 0x7d, 0x55, 0x0f, 0xce, 0x02, 0xbd, 0x37, 0x6e, 0xbf, 0x5a, 0xd2, 0xc5, 0xab, 0x86, 0x35,
0x9d, 0xf5, 0x1e, 0x6c, 0x11, 0x4e, 0xaf, 0x5e, 0x7f, 0xea, 0xaf, 0x22, 0xf5, 0x01, 0x61, 0xf6,
0x42, 0xca, 0xa2, 0x93, 0x20, 0x50, 0x8d, 0xbf, 0xff, 0xc6, 0x87, 0xeb, 0x37, 0xa1, 0xf7, 0xe0,
0xdb, 0x8b, 0x09, 0x5f, 0x7d, 0x00, 0xd1, 0x1e, 0xa2, 0xea, 0x77, 0x44, 0x3d, 0x74, 0xbd, 0x87,
0xc9, 0x8e, 0x7d, 0x47, 0x2d, 0x4b, 0x5b, 0xed, 0xb7, 0xa7, 0xaf, 0x84, 0xe2, 0xd1, 0x25, 0x25,
0x72, 0x7c, 0x0c, 0x7e, 0xe4, 0x6f, 0x09, 0x47, 0x78, 0x22, 0x3b, 0x70, 0x2d, 0xf1, 0x35, 0x9b,
0xa3, 0xd3, 0x6b, 0x69, 0x45, 0x51, 0x70, 0x72, 0x4a, 0x9a, 0xf1, 0x30, 0x7b, 0xfd, 0x5a, 0xda,
0x65, 0xd5, 0x77, 0x77, 0xa6, 0x07, 0x42, 0xcb, 0xce, 0x1c, 0x50, 0xd8, 0xd8, 0x6b, 0xdc, 0x6d,
0xae, 0x39, 0x64, 0xf6, 0xe6, 0x22, 0x66, 0xb7, 0xe4, 0x38, 0x79, 0x59, 0xaf, 0x8a, 0xb6, 0xd8,
0xf9, 0x6a, 0xf5, 0xc6, 0x00, 0x7e, 0xf4, 0xdd, 0xc9, 0xcb, 0xc0, 0x80, 0x1f, 0xd1, 0x27, 0xf0,
0x6b, 0xaf, 0x3b, 0xea, 0xae, 0x3b, 0x92, 0xeb, 0x8e, 0x36, 0xd7, 0xbd, 0xee, 0xae, 0xfb, 0x24,
0xd7, 0x7d, 0xc2, 0xba, 0x96, 0x18, 0xa7, 0x00, 0x1d, 0xa6, 0xe0, 0xe2, 0xf0, 0xa2, 0xb8, 0xf6,
0x9c, 0x93, 0xd3, 0xa0, 0x39, 0xb1, 0xa3, 0x48, 0xd7, 0x7f, 0x4e, 0xde, 0x3f, 0xb2, 0x6a, 0xc3,
0x9d, 0x7e, 0x41, 0x33, 0xbd, 0x6e, 0x30, 0x6e, 0xe9, 0xb5, 0x3b, 0x7f, 0x8f, 0x5e, 0x75, 0x33,
0x16, 0xc2, 0x35, 0x8a, 0x5f, 0x3d, 0x5c, 0xb3, 0xab, 0x7a, 0xba, 0x49, 0x48, 0x73, 0xca, 0xf2,
0xbc, 0x9c, 0x57, 0x93, 0x29, 0x1d, 0x8b, 0x25, 0x65, 0x14, 0xf4, 0xf6, 0x2b, 0xc9, 0x0b, 0x85,
0x79, 0x32, 0x95, 0x2f, 0xd5, 0xd6, 0xcd, 0x4f, 0xb7, 0xdd, 0xb9, 0x5d, 0xff, 0x08, 0xb0, 0x21,
0x4e, 0xfc, 0xa0, 0x38, 0x0d, 0xd7, 0x07, 0x04, 0xe2, 0x92, 0xb6, 0xdd, 0xf4, 0xb4, 0xff, 0x78,
0x97, 0xc5, 0x0d, 0xd9, 0x35, 0xcc, 0x5d, 0x7b, 0xef, 0x31, 0xbd, 0xef, 0xa7, 0x37, 0x55, 0xdf,
0xe0, 0x41, 0x3a, 0x52, 0x3a, 0x5f, 0x59, 0xfe, 0x18, 0x96, 0xdf, 0xeb, 0xbc, 0x13, 0x5a, 0xf5,
0xe5, 0xc7, 0x67, 0x2b, 0xd2, 0x59, 0x87, 0xd4, 0xdf, 0x78, 0x39, 0x45, 0xae, 0x71, 0xfc, 0x5a,
0xb8, 0x06, 0x3e, 0xe1, 0x1a, 0x1d, 0x70, 0xc1, 0x42, 0x7f, 0x38, 0x3b, 0x40, 0x38, 0x92, 0x4d,
0xdc, 0xfb, 0xf6, 0xb8, 0x6c, 0xfc, 0xfb, 0xa1, 0xd9, 0xcc, 0x22, 0xa4, 0x1f, 0x2e, 0x39, 0xab,
0x5b, 0xc5, 0x71, 0xa0, 0x7f, 0xf7, 0xf1, 0x98, 0xfc, 0xb6, 0x53, 0x4f, 0x36, 0xe9, 0x46, 0xaf,
0x5b, 0x2c, 0x5a, 0x74, 0xe3, 0xfe, 0x7e, 0xf3, 0x1e, 0xdd, 0x78, 0x58, 0x03, 0x51, 0x9f, 0x45,
0x7e, 0x4b, 0x86, 0x17, 0xb8, 0x93, 0x84, 0x41, 0x58, 0x9e, 0xf3, 0x7b, 0x3f, 0x5d, 0xa1, 0xf7,
0x71, 0xe9, 0x18, 0xa6, 0xad, 0x29, 0x43, 0x4c, 0x65, 0xad, 0x29, 0x26, 0xa6, 0xa6, 0x43, 0xba,
0x11, 0xf0, 0xeb, 0xc9, 0x3c, 0xbc, 0xee, 0x87, 0xc3, 0x74, 0x98, 0x0d, 0x86, 0xf3, 0x20, 0x57,
0xc5, 0x5c, 0x9a, 0x37, 0x73, 0xd1, 0xfa, 0x97, 0x83, 0x49, 0x93, 0x2d, 0xfb, 0xb9, 0x3a, 0x19,
0xec, 0x3b, 0xfb, 0xf3, 0x3d, 0x63, 0x9f, 0xf1, 0x1b, 0xe9, 0x3c, 0xa0, 0xf7, 0xcd, 0xd3, 0xa0,
0x68, 0x92, 0x75, 0x11, 0xcc, 0xf7, 0x73, 0xdc, 0x73, 0x22, 0xc4, 0xe7, 0xf8, 0x02, 0x1f, 0xe9,
0x00, 0xf7, 0xa1, 0xa8, 0x9f, 0x89, 0x98, 0x0d, 0x82, 0x20, 0xa7, 0xf5, 0x5f, 0xd4, 0x0b, 0xb1,
0x1e, 0x93, 0x69, 0x33, 0xd9, 0x37, 0xf6, 0xcd, 0xc1, 0x5e, 0xa2, 0x7e, 0x59, 0x91, 0xb2, 0x15,
0x89, 0x11, 0xe9, 0x42, 0x4d, 0x70, 0x13, 0xa6, 0x8b, 0x30, 0x25, 0xe7, 0xe9, 0x1e, 0xb2, 0x59,
0xb3, 0x72, 0x7a, 0x88, 0x54, 0x37, 0x55, 0x31, 0xc3, 0x17, 0x14, 0x87, 0xab, 0xd7, 0xe0, 0xf2,
0xae, 0x16, 0x4c, 0xef, 0x3a, 0x77, 0xb5, 0xa0, 0x68, 0x05, 0x19, 0x4f, 0xb2, 0xf7, 0xda, 0xe2,
0x15, 0x3c, 0xbf, 0x3d, 0x86, 0xfb, 0xab, 0xc7, 0x00, 0xff, 0xb8, 0xe1, 0x0b, 0x2d, 0xac, 0x4f,
0x36, 0x3a, 0xd7, 0x15, 0xe1, 0xa8, 0xd7, 0xbd, 0x76, 0xb5, 0x0e, 0x83, 0x6b, 0x6f, 0xf8, 0xc4,
0xf2, 0xe8, 0xf7, 0x7e, 0x93, 0x0c, 0x3b, 0x39, 0xf7, 0xf7, 0x76, 0xc0, 0x1c, 0xfd, 0x2e, 0x02,
0x06, 0x9f, 0xab, 0x9c, 0x8b, 0x44, 0x68, 0x88, 0x8b, 0xd7, 0x89, 0xb1, 0x11, 0x8c, 0x27, 0x4c,
0x12, 0xd8, 0x26, 0xe1, 0x4c, 0x12, 0x9a, 0x18, 0xdd, 0x90, 0xe6, 0x63, 0xeb, 0x5a, 0x77, 0x42,
0x91, 0x28, 0x17, 0x8c, 0x0f, 0xf6, 0xe5, 0x0f, 0xa7, 0xca, 0x01, 0x4f, 0x3f, 0x87, 0xa3, 0xb2,
0x28, 0xea, 0x5b, 0xf1, 0x42, 0x75, 0xf4, 0x22, 0xf6, 0x27, 0xa6, 0xa1, 0x8f, 0xc5, 0xab, 0xce,
0xd1, 0x0b, 0x7d, 0x62, 0x46, 0x76, 0x3c, 0x16, 0x2f, 0x21, 0x47, 0x2f, 0x8c, 0x98, 0xb9, 0xa6,
0x31, 0x16, 0xaf, 0x07, 0x47, 0x2f, 0x4c, 0xe6, 0x45, 0x11, 0x0d, 0x2b, 0xb1, 0x58, 0xa7, 0x8d,
0x75, 0x97, 0x14, 0xbd, 0xce, 0x47, 0xbf, 0x26, 0x65, 0x1c, 0xe6, 0xe1, 0x9d, 0x16, 0xd5, 0x65,
0xf6, 0x79, 0x52, 0x5c, 0xdf, 0xce, 0x11, 0x07, 0x69, 0x3e, 0x0a, 0x97, 0x75, 0x31, 0xbe, 0x4a,
0xe3, 0x7a, 0x36, 0xf2, 0xf4, 0xcb, 0xab, 0xf1, 0xba, 0x5f, 0x16, 0xbf, 0x14, 0x8e, 0x10, 0x60,
0x7d, 0xc1, 0x7c, 0x30, 0x5e, 0x14, 0x55, 0x4a, 0xba, 0x8d, 0xc2, 0x49, 0x55, 0x64, 0xcb, 0x3a,
0x19, 0xd7, 0xc5, 0x62, 0x64, 0xdb, 0xdf, 0x8e, 0xb3, 0x64, 0x5a, 0x8f, 0x6c, 0xfd, 0xdb, 0x71,
0x5d, 0x86, 0x79, 0x35, 0x2d, 0xca, 0xf9, 0x88, 0x7f, 0xcb, 0x90, 0x3a, 0xfa, 0x2a, 0x08, 0x43,
0x7a, 0xa0, 0x57, 0x4e, 0xb3, 0x3a, 0x29, 0x47, 0x71, 0x59, 0x2c, 0xd4, 0x6a, 0x16, 0xc6, 0xc5,
0x15, 0xa8, 0x8b, 0x6b, 0x85, 0x3f, 0xe8, 0xbf, 0x60, 0x47, 0xda, 0x0c, 0x06, 0x77, 0x5a, 0x15,
0x57, 0xb7, 0x42, 0x38, 0x43, 0xc7, 0xe1, 0xb3, 0x24, 0x3d, 0x9f, 0xd5, 0x23, 0x83, 0x5d, 0xce,
0xc6, 0x42, 0x7e, 0x95, 0x04, 0xc0, 0x10, 0x4b, 0x33, 0xa9, 0x92, 0xca, 0x65, 0xe1, 0x7a, 0xc9,
0x89, 0x92, 0xef, 0x6a, 0xcf, 0xc8, 0x5d, 0x52, 0x71, 0xd7, 0xbd, 0xbc, 0xba, 0x7b, 0x81, 0xdb,
0xe1, 0x6d, 0x8b, 0xac, 0x83, 0xbc, 0x36, 0xc6, 0x68, 0xf3, 0x3a, 0x52, 0x17, 0x0a, 0x3f, 0x76,
0x38, 0xc9, 0xb0, 0x68, 0x78, 0x93, 0x64, 0x59, 0x71, 0x35, 0xa0, 0x53, 0x3e, 0xde, 0x6e, 0xbf,
0xad, 0x84, 0x4b, 0xd2, 0x9e, 0x37, 0x3b, 0xec, 0x39, 0x2f, 0x93, 0x24, 0xe7, 0xbb, 0x5e, 0xed,
0xb0, 0x6b, 0x42, 0xdd, 0x10, 0x6d, 0xfa, 0x6d, 0x87, 0x4d, 0x57, 0xb3, 0xb4, 0x16, 0xbb, 0xde,
0x6e, 0xb5, 0x0b, 0xea, 0x0c, 0x8b, 0x92, 0x7e, 0x62, 0x95, 0x06, 0x11, 0xc2, 0x0e, 0xa3, 0x9b,
0x30, 0xe7, 0x12, 0x0c, 0x2f, 0xd3, 0x22, 0x4b, 0xea, 0x95, 0xde, 0xa7, 0x5b, 0x1d, 0x8b, 0x43,
0x6e, 0x5a, 0x6a, 0x1f, 0xef, 0xa0, 0x01, 0x32, 0xf4, 0xbf, 0x97, 0x45, 0x5a, 0x09, 0x2d, 0xce,
0x76, 0xd8, 0xd9, 0x20, 0x8a, 0xdb, 0x6b, 0x91, 0x55, 0xff, 0xb1, 0x6f, 0x7d, 0xfa, 0x2a, 0xb3,
0xbf, 0xdb, 0xd5, 0x97, 0xe8, 0xe6, 0x7b, 0x3b, 0x2d, 0xf2, 0x5a, 0x9d, 0x86, 0xf3, 0x34, 0xbb,
0x69, 0xc2, 0xf7, 0x75, 0x3e, 0x18, 0xbe, 0x4d, 0xb2, 0xcb, 0xa4, 0x4e, 0xa3, 0x70, 0x58, 0x21,
0x32, 0xd5, 0x2a, 0x29, 0xd3, 0xe9, 0xb8, 0x4e, 0xae, 0x6b, 0x35, 0xcc, 0xd2, 0xf3, 0x7c, 0x14,
0x25, 0xf4, 0xe3, 0xfc, 0x53, 0x4e, 0x2f, 0x0e, 0xa3, 0xbc, 0x34, 0x10, 0x4c, 0x07, 0xab, 0x90,
0xa4, 0xf0, 0x94, 0x29, 0x45, 0x6f, 0x27, 0x91, 0x32, 0x59, 0x24, 0x61, 0x3d, 0xca, 0x0b, 0xf9,
0xad, 0x4d, 0x0b, 0xeb, 0x3a, 0x8c, 0x66, 0x54, 0x8b, 0x47, 0xd3, 0xf4, 0x3a, 0x89, 0xc7, 0xed,
0x8c, 0x43, 0x49, 0x6c, 0x70, 0x47, 0x7f, 0x47, 0x70, 0xdb, 0xe2, 0x81, 0x3a, 0x56, 0x86, 0xf3,
0xe4, 0x56, 0x76, 0x6c, 0x23, 0x6a, 0xd8, 0xc6, 0x93, 0xa2, 0x8c, 0x91, 0x54, 0xf4, 0xdd, 0xb2,
0xcb, 0xf8, 0x91, 0x0c, 0x28, 0xb9, 0x39, 0x94, 0x00, 0xfe, 0xe3, 0x84, 0x77, 0x57, 0x5d, 0x9e,
0xdf, 0x52, 0x2f, 0x2a, 0xb5, 0x8a, 0x79, 0x1e, 0x95, 0x29, 0x8d, 0xad, 0xb9, 0x19, 0xfa, 0x25,
0xfa, 0x8c, 0x1d, 0xd3, 0x63, 0x9a, 0x2f, 0x96, 0xf5, 0xed, 0x6e, 0x4a, 0x3f, 0xe2, 0x1b, 0x6b,
0x8f, 0xb8, 0x9b, 0x2c, 0xeb, 0xba, 0xc8, 0xdb, 0x8e, 0xd7, 0x82, 0xbd, 0x03, 0x91, 0x50, 0x46,
0x5a, 0x5f, 0xb3, 0xa3, 0x99, 0x02, 0x23, 0xa5, 0xb1, 0xd2, 0x5e, 0x2f, 0x83, 0x62, 0x52, 0xe0,
0xd0, 0xf9, 0xc8, 0x80, 0x4d, 0xff, 0x69, 0x79, 0xc5, 0x55, 0x73, 0x1b, 0x79, 0xeb, 0x2d, 0xe4,
0xfd, 0xa7, 0xa5, 0xe3, 0x18, 0xfd, 0xc1, 0xff, 0xd6, 0x2a, 0x5f, 0xce, 0x27, 0x49, 0xf9, 0xe7,
0x3f, 0x25, 0xa9, 0x70, 0x22, 0x33, 0x99, 0xb7, 0x79, 0xf0, 0xe4, 0xfb, 0xe7, 0xad, 0x7a, 0x95,
0x4c, 0x2e, 0x52, 0x04, 0xf6, 0x02, 0x31, 0x87, 0xb9, 0x28, 0x11, 0x91, 0x22, 0x5d, 0x5e, 0xb5,
0xa0, 0x88, 0x7e, 0x7f, 0xdf, 0x68, 0x5a, 0x44, 0xcb, 0xea, 0xb6, 0x58, 0xd6, 0x14, 0xf9, 0xa3,
0x87, 0x56, 0x8c, 0x9a, 0xa3, 0x2b, 0xc8, 0x93, 0x94, 0x6a, 0xb9, 0xcc, 0xf3, 0x70, 0x92, 0x25,
0x2a, 0xbc, 0x3f, 0xba, 0x78, 0xac, 0x58, 0x47, 0xcb, 0xb2, 0x82, 0x72, 0x8b, 0x22, 0xdd, 0x4c,
0x31, 0x2d, 0x8d, 0xb6, 0xe0, 0x56, 0xcf, 0x60, 0xc3, 0x1d, 0x3d, 0x7e, 0x1d, 0x61, 0x4d, 0x4e,
0x36, 0x36, 0x6a, 0xbb, 0x58, 0x1e, 0x0a, 0x14, 0xba, 0x92, 0x3e, 0x6d, 0x48, 0x9e, 0xeb, 0xe1,
0xd3, 0x0f, 0x4a, 0x3e, 0x2f, 0xfe, 0x52, 0xf9, 0xe0, 0x7f, 0xcb, 0x34, 0x2d, 0x06, 0xff, 0x6d,
0xb3, 0x6c, 0xa3, 0x7e, 0xf5, 0xb5, 0x7a, 0xf3, 0x3c, 0xba, 0x08, 0x4b, 0xfa, 0x63, 0x42, 0x11,
0x02, 0xb2, 0x15, 0x6d, 0x13, 0xee, 0xcd, 0x3c, 0x26, 0x04, 0x25, 0x5f, 0x15, 0x95, 0x3c, 0x29,
0xdb, 0x81, 0xf7, 0xe2, 0x59, 0xe3, 0xca, 0x9d, 0x4b, 0x00, 0xbf, 0xf3, 0x4e, 0x81, 0xc7, 0xce,
0x56, 0x6d, 0x41, 0x72, 0x87, 0x4b, 0x02, 0xbf, 0x1b, 0xc8, 0x3b, 0x82, 0x92, 0xc6, 0xc1, 0xac,
0xc8, 0x60, 0x8b, 0x2f, 0xc8, 0x2c, 0x7c, 0x86, 0x73, 0xa5, 0xf2, 0xbd, 0x1f, 0x55, 0xd5, 0x61,
0xb3, 0xfe, 0x60, 0x5f, 0xfc, 0xb9, 0x28, 0x35, 0x02, 0x4a, 0x91, 0xf3, 0xdf, 0x8d, 0x57, 0x7f,
0xc5, 0xa7, 0x44, 0xf4, 0x83, 0x6c, 0xf0, 0xf9, 0x33, 0x6a, 0x67, 0x9a, 0x7f, 0xa6, 0xcd, 0x9f,
0x3f, 0xfe, 0xfc, 0xf2, 0xa7, 0xdf, 0x3f, 0x7f, 0x26, 0x46, 0x8b, 0x30, 0x97, 0x2b, 0xe8, 0xd7,
0xda, 0xc3, 0xf7, 0xd8, 0x9b, 0xe6, 0xe7, 0x9a, 0xa6, 0xe1, 0x70, 0xd0, 0x68, 0xc9, 0xe5, 0xb9,
0xc2, 0xf9, 0x04, 0xf7, 0x2b, 0xa3, 0x50, 0x57, 0x6f, 0xb4, 0xd0, 0xc7, 0xc5, 0x65, 0x52, 0x4e,
0x61, 0xf9, 0xd1, 0x2c, 0x8d, 0xe3, 0x24, 0x57, 0x30, 0xac, 0xb0, 0x23, 0x30, 0x34, 0x43, 0xb9,
0x9e, 0x67, 0x79, 0x15, 0xcc, 0xea, 0x7a, 0x31, 0xda, 0xdf, 0xbf, 0xba, 0xba, 0xd2, 0xae, 0x4c,
0xad, 0x28, 0xcf, 0xf7, 0x19, 0x6e, 0x30, 0xfb, 0xe0, 0x02, 0x5e, 0x71, 0x32, 0xad, 0x0e, 0x95,
0xfd, 0xfd, 0xf7, 0xbc, 0x09, 0xa1, 0xbf, 0x48, 0xad, 0xb4, 0xa8, 0x98, 0xef, 0x4f, 0xd1, 0x08,
0x42, 0x92, 0x9b, 0xf9, 0xa4, 0xc8, 0xc8, 0x2c, 0x59, 0x5e, 0xaa, 0x0b, 0xc2, 0x57, 0x15, 0x97,
0x55, 0xe5, 0x32, 0x4d, 0xae, 0x5e, 0x15, 0xd7, 0x41, 0x4f, 0x57, 0x74, 0xc5, 0xd0, 0x99, 0xc5,
0x1f, 0xbd, 0xc3, 0x03, 0x7a, 0x89, 0xac, 0xc4, 0x41, 0xef, 0x83, 0xe5, 0x39, 0x9a, 0xa5, 0x38,
0x86, 0xa5, 0x59, 0x91, 0x8a, 0xa7, 0x61, 0x7a, 0x8a, 0xae, 0x32, 0x5b, 0x73, 0x54, 0xc3, 0xd0,
0x2c, 0xc7, 0x10, 0xdf, 0xe9, 0x71, 0xa9, 0x5a, 0x8e, 0xae, 0x79, 0x91, 0xde, 0xac, 0xe3, 0x0b,
0x18, 0xa7, 0x29, 0xab, 0x55, 0x15, 0x1f, 0x0a, 0x92, 0xb2, 0x22, 0x5d, 0xca, 0xad, 0x0a, 0xdf,
0xea, 0xab, 0x2d, 0xfa, 0x7a, 0xff, 0x5f, 0x10, 0x6c, 0x9f, 0x24, 0xbb, 0x27, 0x9f, 0xef, 0x32,
0xec, 0x56, 0x21, 0xbc, 0x66, 0xbb, 0x90, 0xcf, 0xf0, 0x7d, 0xd5, 0xf4, 0x35, 0xdf, 0xb2, 0x54,
0xe6, 0x1a, 0x9a, 0x6d, 0xe2, 0x40, 0xa6, 0x59, 0xae, 0x8a, 0x75, 0x36, 0xf3, 0x9a, 0x0f, 0x39,
0x69, 0x38, 0x9e, 0xe6, 0x3b, 0xcd, 0x48, 0x6c, 0xc0, 0x21, 0x9e, 0xa5, 0x99, 0xbe, 0xad, 0x30,
0x47, 0xf3, 0x6c, 0x48, 0xe4, 0xc0, 0x04, 0xae, 0xa7, 0xb8, 0xae, 0xe6, 0xb8, 0x38, 0xd6, 0xc4,
0x2a, 0xdf, 0x52, 0x2c, 0x5f, 0x33, 0x6c, 0x15, 0x34, 0xdf, 0xb0, 0xa1, 0x15, 0x0e, 0x72, 0x49,
0x7a, 0x13, 0x5b, 0x61, 0x4c, 0xdf, 0xd1, 0x1c, 0x66, 0xa9, 0x86, 0xe9, 0x68, 0xb6, 0x6e, 0x28,
0x98, 0xb6, 0x6d, 0xd5, 0xd2, 0x74, 0xd3, 0x52, 0x98, 0xab, 0x79, 0xba, 0xad, 0x98, 0x9a, 0xe3,
0x99, 0x0a, 0x0e, 0xf3, 0xc8, 0x60, 0xae, 0xc6, 0x4c, 0xab, 0x52, 0xc5, 0xa4, 0x58, 0xa1, 0x8a,
0x49, 0xb9, 0x04, 0x3a, 0x92, 0x5e, 0xb6, 0xad, 0x58, 0x86, 0xe6, 0xd8, 0x24, 0x87, 0xab, 0xb9,
0x3a, 0xc3, 0x56, 0x58, 0x60, 0x3d, 0x34, 0x0d, 0x5f, 0xd3, 0x19, 0x23, 0x54, 0x3d, 0x30, 0xd5,
0x61, 0x71, 0x48, 0xca, 0x20, 0x93, 0x69, 0x62, 0x61, 0xfb, 0x59, 0xf1, 0xa7, 0xda, 0xa1, 0xab,
0xfc, 0xc9, 0x91, 0x74, 0x34, 0xc3, 0x73, 0x55, 0x1f, 0xc7, 0xda, 0x30, 0x8d, 0xab, 0x99, 0xae,
0xe4, 0x62, 0xa8, 0x82, 0x09, 0xa9, 0x07, 0xb5, 0x98, 0xd0, 0x4b, 0x65, 0x86, 0xc6, 0x1c, 0xd8,
0xd4, 0xd3, 0x98, 0xe7, 0x49, 0xe1, 0x55, 0xa9, 0x1f, 0xad, 0x60, 0x72, 0xb9, 0x42, 0x2b, 0x7c,
0xb9, 0x5c, 0x68, 0xe7, 0x8a, 0xe5, 0x36, 0xb7, 0xb1, 0x05, 0xcc, 0x4d, 0xcd, 0xe0, 0x92, 0xbb,
0x9a, 0x05, 0xc3, 0xc3, 0xe0, 0x1e, 0x13, 0x36, 0x35, 0xf1, 0x09, 0x9b, 0x5a, 0xbe, 0xaf, 0xd8,
0xf0, 0x1b, 0xc3, 0x51, 0x1c, 0x57, 0x33, 0x0c, 0xb1, 0xd3, 0xb5, 0xf9, 0x16, 0x06, 0x33, 0xc8,
0xa1, 0x00, 0xcb, 0x13, 0x3e, 0x0e, 0x0f, 0x11, 0xbe, 0x41, 0x67, 0x41, 0x01, 0x9d, 0x49, 0xe4,
0x15, 0xe9, 0x2a, 0xc2, 0x39, 0x14, 0xfe, 0xe1, 0x48, 0xe7, 0x50, 0xba, 0xce, 0x21, 0x46, 0x2d,
0x7f, 0xdc, 0x17, 0x41, 0x76, 0xb8, 0x19, 0x6d, 0x59, 0x5a, 0xd5, 0x5b, 0x44, 0x99, 0xef, 0x7b,
0xf0, 0x62, 0x0f, 0xf6, 0x64, 0x33, 0xd5, 0x75, 0xbc, 0xe7, 0x42, 0xad, 0x7a, 0x30, 0xb4, 0x66,
0xb4, 0x53, 0x04, 0x10, 0x18, 0xad, 0xe3, 0xcc, 0x58, 0xc7, 0x59, 0xa5, 0xb6, 0x66, 0x9e, 0x8e,
0x2c, 0x21, 0x93, 0xed, 0x98, 0xff, 0xef, 0x64, 0x32, 0x75, 0xf7, 0x29, 0x99, 0xd8, 0xd7, 0xca,
0xc4, 0xbe, 0x4a, 0x26, 0xd7, 0xa1, 0x48, 0xb2, 0x3d, 0x4a, 0x90, 0x16, 0xd3, 0x4c, 0x8b, 0x12,
0x10, 0x4d, 0xaa, 0x26, 0x32, 0x06, 0xf9, 0x13, 0x7d, 0xa7, 0x47, 0xd5, 0x9a, 0x50, 0x56, 0xb3,
0x8a, 0x38, 0x80, 0x93, 0x94, 0x35, 0xa9, 0x35, 0xb1, 0x5e, 0xf6, 0x97, 0xe0, 0xc6, 0x6c, 0x47,
0x68, 0x0e, 0x8f, 0x17, 0x9a, 0x73, 0x05, 0x3c, 0x7b, 0x2d, 0x69, 0x25, 0x26, 0xd6, 0x1a, 0xad,
0x1f, 0x6a, 0x8b, 0xa4, 0xb6, 0x26, 0xd6, 0x66, 0x53, 0x9f, 0xd4, 0x55, 0x16, 0x83, 0x07, 0x74,
0x35, 0xd6, 0xba, 0x62, 0x5e, 0x2e, 0x78, 0x50, 0xe9, 0xea, 0x41, 0xa5, 0x91, 0xff, 0xf9, 0x26,
0xff, 0x49, 0xed, 0x6d, 0x83, 0xfd, 0x1f, 0x6a, 0xef, 0xb9, 0xfa, 0xf3, 0xda, 0x3f, 0x8b, 0xb4,
0xb1, 0x25, 0xd2, 0x2b, 0x1f, 0xff, 0x2f, 0xe9, 0xfa, 0x58, 0x1e, 0x9b, 0x17, 0x45, 0xbe, 0x45,
0x1e, 0xb3, 0x99, 0x05, 0xa1, 0x69, 0x96, 0xa4, 0xd6, 0x35, 0xc3, 0xf5, 0x49, 0x6c, 0x24, 0x4d,
0xdf, 0xf1, 0x54, 0xdb, 0x42, 0x06, 0x07, 0xb6, 0x18, 0xea, 0x3e, 0x6a, 0x8b, 0x6d, 0xa2, 0x8a,
0x54, 0xf2, 0x13, 0x45, 0x45, 0x47, 0x11, 0x6d, 0x46, 0x72, 0x11, 0x95, 0x20, 0xc3, 0xd6, 0x18,
0x92, 0x35, 0xca, 0x03, 0xc3, 0xf1, 0xba, 0x41, 0xbc, 0x1d, 0xcd, 0xf7, 0x91, 0xc6, 0x61, 0x19,
0x1b, 0x85, 0xc2, 0x34, 0x79, 0x39, 0xb7, 0x50, 0x75, 0x1d, 0xd4, 0x00, 0x93, 0x57, 0x68, 0x0f,
0xcd, 0x93, 0x4d, 0x35, 0xd9, 0xd7, 0x4c, 0x66, 0xf3, 0x1c, 0x6f, 0x32, 0x53, 0x41, 0x41, 0xd3,
0x6d, 0x9d, 0x2a, 0x92, 0x85, 0xbe, 0x01, 0xb5, 0xc4, 0xb1, 0x54, 0xdb, 0xd6, 0x2c, 0xd2, 0x06,
0xb5, 0xc4, 0x02, 0x1b, 0xb0, 0x66, 0xb0, 0x9a, 0x8f, 0xc2, 0x82, 0x02, 0xa5, 0xf9, 0xa8, 0xdc,
0x4c, 0xe7, 0x2b, 0x74, 0xcd, 0x34, 0x1d, 0xea, 0x08, 0x7c, 0xb4, 0x19, 0xa8, 0x5f, 0x8c, 0x55,
0xa8, 0x84, 0x54, 0xb9, 0x51, 0x24, 0x50, 0xaa, 0x4c, 0x4d, 0x77, 0x50, 0xda, 0x3d, 0x48, 0x89,
0x08, 0x85, 0x58, 0x3a, 0x26, 0xd1, 0x1c, 0x98, 0x68, 0x69, 0x2c, 0x0f, 0xb5, 0xd3, 0x57, 0x0c,
0x58, 0x1c, 0x15, 0x7a, 0x35, 0xf4, 0x4d, 0x01, 0x2e, 0x8a, 0x14, 0x8a, 0x92, 0x8b, 0x09, 0xa8,
0x0b, 0x31, 0x4d, 0x7c, 0x74, 0x9e, 0xa8, 0x70, 0x96, 0x61, 0x91, 0xe5, 0x71, 0xbe, 0xeb, 0x02,
0x4b, 0x1b, 0x27, 0x18, 0xcd, 0x09, 0xe2, 0x40, 0x0f, 0x52, 0x1b, 0xba, 0x8b, 0x5a, 0x0c, 0x13,
0x90, 0xd4, 0x86, 0x89, 0x6e, 0xc2, 0x72, 0x7c, 0x29, 0x94, 0x90, 0x90, 0x5c, 0xc6, 0xa0, 0x9e,
0x01, 0x64, 0x8b, 0xeb, 0x61, 0x49, 0xa5, 0x22, 0x3a, 0xd5, 0x43, 0xde, 0x23, 0x14, 0x5c, 0x93,
0x0a, 0xa5, 0x67, 0xc1, 0x88, 0x3a, 0x74, 0xf0, 0xa4, 0x65, 0x1c, 0x69, 0x28, 0x9b, 0x8c, 0x68,
0x38, 0x8e, 0x62, 0xc1, 0x87, 0xd0, 0x03, 0xc1, 0x04, 0x36, 0xe2, 0x03, 0xea, 0x01, 0x9a, 0xc6,
0xdc, 0x8d, 0xf9, 0x7d, 0x1d, 0x75, 0x13, 0xb6, 0x80, 0x8e, 0xbe, 0x47, 0xfd, 0x99, 0x66, 0x52,
0x69, 0xdf, 0x00, 0x52, 0x8e, 0xff, 0xfa, 0x00, 0x33, 0xa3, 0x83, 0x72, 0x69, 0xbd, 0xe7, 0x53,
0xb2, 0x43, 0x35, 0x76, 0x2d, 0x83, 0xb0, 0xf5, 0x3d, 0xe4, 0x73, 0x70, 0x31, 0x40, 0x66, 0xf0,
0x31, 0x1d, 0xcd, 0x59, 0x33, 0xb6, 0x18, 0x9d, 0x4b, 0x46, 0x62, 0x0e, 0x64, 0x03, 0xc2, 0x8c,
0x2a, 0xb5, 0x0d, 0x19, 0xc9, 0x2b, 0x3a, 0x4f, 0xc3, 0xf3, 0x79, 0x63, 0xa5, 0x23, 0x79, 0xc3,
0x92, 0x86, 0x25, 0xdb, 0x00, 0xbb, 0x39, 0xa5, 0x39, 0x55, 0xb5, 0x31, 0x4d, 0xc2, 0xfa, 0xd4,
0x44, 0xa0, 0xc9, 0x24, 0xbb, 0xa3, 0x3d, 0xf3, 0x39, 0xd1, 0x40, 0xe3, 0x6a, 0x83, 0x65, 0x33,
0xc4, 0xa7, 0x4f, 0x8d, 0x17, 0x22, 0x8b, 0xc1, 0xd6, 0xd8, 0xad, 0x53, 0xa3, 0x88, 0x28, 0x87,
0xe8, 0x26, 0x50, 0x43, 0xe6, 0xa0, 0x92, 0xe4, 0xa3, 0xe3, 0x71, 0x7c, 0xfe, 0xe1, 0xca, 0x49,
0x6a, 0x9e, 0xc8, 0xc1, 0x9d, 0xd5, 0x58, 0x6c, 0xa2, 0x64, 0x0a, 0x11, 0x0d, 0xd3, 0x00, 0xba,
0x20, 0xea, 0x80, 0x12, 0xdd, 0x4c, 0x57, 0x80, 0x2d, 0x82, 0x38, 0x2a, 0xce, 0xb7, 0x88, 0x61,
0x13, 0x50, 0x91, 0x5b, 0xe9, 0x60, 0xe3, 0xda, 0x76, 0x84, 0x08, 0x30, 0x74, 0x0a, 0x63, 0x0b,
0x61, 0xe8, 0xa9, 0x3a, 0xfa, 0x35, 0xa6, 0x3a, 0xe4, 0x6b, 0x2a, 0xb5, 0x5e, 0x2a, 0xd0, 0xf7,
0x5d, 0x9e, 0x59, 0x3c, 0xdd, 0x24, 0x9c, 0x0d, 0xca, 0xdf, 0xc0, 0xc5, 0xa2, 0x56, 0x0f, 0x0e,
0x83, 0xa0, 0x46, 0xe4, 0x33, 0x83, 0x96, 0xf8, 0x0c, 0x49, 0x11, 0x51, 0x81, 0x86, 0xdc, 0x21,
0xdf, 0x64, 0x8c, 0x08, 0x3e, 0x75, 0xc7, 0x94, 0x07, 0x4d, 0x8b, 0xdc, 0x11, 0xce, 0x0c, 0x3b,
0xf8, 0x0c, 0x7e, 0x47, 0xe0, 0xf9, 0xbc, 0x7d, 0x84, 0x9f, 0xc9, 0x11, 0x1c, 0xdd, 0xf7, 0xc9,
0xc2, 0xb6, 0xc3, 0x8d, 0x44, 0x02, 0x90, 0x61, 0xd1, 0xda, 0x59, 0xdd, 0x27, 0xfc, 0x9b, 0x51,
0xde, 0xc4, 0xc9, 0x3a, 0xf9, 0x29, 0x50, 0x5d, 0x6d, 0x97, 0x87, 0xe1, 0xc3, 0x30, 0x4d, 0x85,
0xfa, 0x74, 0xea, 0xee, 0x28, 0x52, 0x15, 0x50, 0x98, 0x14, 0x87, 0x49, 0xd9, 0x90, 0x78, 0x0c,
0x44, 0x15, 0xf9, 0x14, 0xa3, 0xdc, 0x6f, 0xe9, 0x9e, 0xea, 0x91, 0xd7, 0xd8, 0x42, 0x37, 0x43,
0xaa, 0x4a, 0xd1, 0x66, 0x9a, 0x26, 0x1d, 0xeb, 0x7b, 0x3e, 0xa2, 0xcd, 0x87, 0xb3, 0x3a, 0x54,
0xd2, 0x14, 0x83, 0x78, 0x70, 0xcb, 0xe0, 0x83, 0xb7, 0xef, 0xb8, 0xa4, 0x10, 0xde, 0x26, 0x77,
0x73, 0x17, 0xe7, 0x23, 0xe8, 0xe8, 0x6a, 0x20, 0x47, 0xe8, 0xb9, 0x41, 0xab, 0x54, 0x1e, 0xb9,
0x60, 0x67, 0xaa, 0x9c, 0xe0, 0x71, 0x82, 0xa5, 0x47, 0xc4, 0xc4, 0xe5, 0xb1, 0xce, 0x5c, 0x0a,
0x29, 0xe4, 0x58, 0x46, 0x3a, 0x3b, 0xa6, 0xa7, 0x1a, 0x42, 0x21, 0xce, 0xcc, 0x55, 0x24, 0x36,
0x02, 0x29, 0x45, 0x62, 0x23, 0x90, 0x52, 0x3a, 0xe2, 0x23, 0xc0, 0x04, 0x38, 0x1c, 0x29, 0x45,
0xa0, 0xc3, 0x91, 0x52, 0x04, 0x3a, 0xc2, 0x1c, 0x0a, 0x87, 0xc7, 0xe4, 0x50, 0xf1, 0xd6, 0x1d,
0x49, 0x4f, 0xd8, 0x53, 0xe1, 0xd6, 0x6d, 0x06, 0x02, 0x20, 0xd9, 0x76, 0x37, 0x40, 0x29, 0x2d,
0x88, 0xe8, 0xaa, 0x46, 0x20, 0x39, 0xaa, 0xc0, 0x86, 0x03, 0x45, 0x41, 0xb4, 0x06, 0x5a, 0x15,
0x66, 0xe3, 0x38, 0x21, 0x40, 0x00, 0x0d, 0xe3, 0x38, 0x59, 0x14, 0x0c, 0x2d, 0xb7, 0xe1, 0xd8,
0x08, 0xa0, 0x1c, 0x9e, 0x85, 0x28, 0xa2, 0x05, 0x52, 0x4a, 0xc7, 0x0d, 0x0d, 0x92, 0xce, 0xa7,
0x88, 0x04, 0x52, 0x3c, 0xef, 0x11, 0x3a, 0x84, 0x94, 0xd2, 0x98, 0xcb, 0x11, 0x1f, 0x16, 0x99,
0x99, 0x0e, 0x76, 0x75, 0x9e, 0x10, 0x57, 0x48, 0x21, 0xcb, 0x72, 0x08, 0xe4, 0xa8, 0x02, 0x34,
0x02, 0x24, 0x3e, 0x0f, 0xf3, 0x0b, 0x04, 0x23, 0xb0, 0xf3, 0x38, 0x4a, 0x06, 0xe5, 0x5a, 0xc7,
0xb2, 0x05, 0x4a, 0xb6, 0x60, 0xe4, 0x0b, 0x94, 0x7c, 0x45, 0xe2, 0xc2, 0x51, 0x62, 0x0a, 0xe1,
0x62, 0x4b, 0x90, 0xa4, 0xe4, 0xa6, 0xd2, 0x48, 0x6e, 0xf0, 0xe4, 0xc2, 0x41, 0x22, 0x31, 0x51,
0x0a, 0x38, 0x48, 0xba, 0x27, 0x8c, 0xa1, 0x48, 0xa7, 0x25, 0x60, 0x98, 0x40, 0xc9, 0xe1, 0xd6,
0x44, 0x46, 0xe7, 0x38, 0xb9, 0xcd, 0xa8, 0x09, 0xa2, 0x06, 0xa3, 0x36, 0x36, 0xdd, 0x27, 0xc7,
0x87, 0xb2, 0xa4, 0xc0, 0x86, 0x03, 0x25, 0xb7, 0x4b, 0xa0, 0x14, 0x0e, 0x8e, 0x27, 0x90, 0x52,
0x04, 0x38, 0x1c, 0x29, 0x29, 0x8f, 0x25, 0x85, 0xe3, 0xd8, 0x38, 0x12, 0x29, 0xc5, 0x12, 0x59,
0x55, 0x20, 0x25, 0x14, 0x6c, 0x80, 0x52, 0x04, 0x34, 0x22, 0x88, 0x80, 0x93, 0x0f, 0xcb, 0x0a,
0x9c, 0xa4, 0x63, 0x4b, 0xa4, 0x54, 0x89, 0x8d, 0x40, 0x4a, 0x86, 0x87, 0x44, 0x4a, 0xed, 0x20,
0x55, 0x49, 0x7c, 0x70, 0xad, 0x6e, 0xcd, 0xe3, 0x3e, 0x2d, 0x62, 0x48, 0x21, 0xa4, 0x14, 0x11,
0x42, 0x8a, 0x08, 0x21, 0xa5, 0xcd, 0xc9, 0x97, 0xe9, 0x4d, 0x42, 0x25, 0xd3, 0x9b, 0x80, 0x4a,
0xed, 0x88, 0xce, 0xb3, 0x9b, 0x2d, 0x80, 0xb2, 0x55, 0x89, 0x8d, 0x40, 0x4a, 0x6d, 0x19, 0x83,
0xa9, 0x12, 0x1c, 0x8e, 0x94, 0xda, 0xc1, 0x46, 0x6d, 0x19, 0x17, 0xa3, 0x26, 0x88, 0x64, 0xc4,
0xb4, 0xb3, 0x9d, 0x84, 0x48, 0x57, 0x64, 0xa6, 0x13, 0xd8, 0xc8, 0x6c, 0xd7, 0x05, 0x5a, 0xba,
0x34, 0x01, 0xe5, 0x88, 0x04, 0xd7, 0x00, 0xc5, 0xc5, 0x69, 0xc2, 0x5b, 0x62, 0x23, 0x90, 0x52,
0x25, 0x36, 0x02, 0xa9, 0x55, 0x8a, 0x90, 0xc9, 0x9c, 0xf1, 0x73, 0x09, 0x29, 0x47, 0xa6, 0x38,
0x81, 0x94, 0xda, 0x76, 0x6e, 0x57, 0x64, 0x38, 0x4f, 0x22, 0x25, 0x32, 0x9c, 0xdd, 0x4e, 0x64,
0x4d, 0xb4, 0x78, 0x95, 0x4a, 0xef, 0x3c, 0x44, 0xae, 0xeb, 0x84, 0x17, 0x1a, 0x29, 0xdc, 0xd9,
0xa9, 0xad, 0x94, 0x2f, 0x53, 0xb8, 0xc0, 0x50, 0x99, 0x7a, 0x35, 0x48, 0x4a, 0x75, 0x82, 0x0f,
0xfe, 0xfa, 0x80, 0xab, 0x81, 0x6c, 0xd0, 0x6d, 0x7a, 0x43, 0x61, 0xf3, 0xd4, 0x83, 0x9a, 0x89,
0x08, 0x32, 0x99, 0x78, 0x27, 0x85, 0x5e, 0xca, 0x37, 0xd0, 0xbc, 0xa1, 0x38, 0x93, 0xb3, 0xd2,
0xcb, 0x04, 0x17, 0x28, 0x30, 0x72, 0x1c, 0xdc, 0xf8, 0x75, 0xfe, 0xea, 0xc2, 0x73, 0xf9, 0xab,
0x04, 0xe6, 0x8b, 0xda, 0x63, 0x39, 0xaa, 0x8d, 0xfe, 0x84, 0xa7, 0x42, 0xdd, 0xa5, 0xe5, 0x16,
0x8a, 0x34, 0xb5, 0x77, 0xae, 0x2d, 0x07, 0xa8, 0xf2, 0x86, 0xc7, 0xc4, 0x5b, 0x23, 0xc7, 0x47,
0xa3, 0x43, 0x0d, 0xa1, 0xc5, 0xbb, 0x59, 0xea, 0x97, 0x4c, 0xaa, 0xdb, 0xe2, 0xbb, 0x4b, 0x0d,
0x9a, 0x88, 0x27, 0x7a, 0xbb, 0xc1, 0x38, 0x33, 0xbe, 0xdd, 0x50, 0xe8, 0x2c, 0x8f, 0xfb, 0xbd,
0xcb, 0x53, 0x99, 0x0b, 0x0b, 0x33, 0xec, 0x32, 0xe9, 0x7c, 0xc7, 0x61, 0x8a, 0x94, 0x46, 0xca,
0x66, 0x51, 0x77, 0x44, 0xc6, 0x67, 0xe4, 0x49, 0xa4, 0x11, 0x5a, 0x34, 0xe8, 0x82, 0x0c, 0x2e,
0x47, 0x42, 0x5d, 0xdc, 0x47, 0x44, 0x84, 0x0a, 0x63, 0x18, 0x52, 0xfb, 0x86, 0x1a, 0x09, 0xfd,
0x55, 0x69, 0x0c, 0xa1, 0xbf, 0xca, 0xad, 0xe1, 0xa8, 0x5d, 0x8e, 0xc2, 0x00, 0x0a, 0x59, 0x83,
0x09, 0x03, 0x58, 0x42, 0xe8, 0xc6, 0x00, 0x62, 0x20, 0x8d, 0x20, 0x7a, 0x7c, 0x47, 0x6d, 0x1b,
0x43, 0x9a, 0x41, 0x24, 0x7e, 0x18, 0x82, 0xeb, 0xaf, 0x4a, 0x63, 0xb4, 0x8e, 0x6a, 0xf4, 0x57,
0xa5, 0x35, 0x84, 0x01, 0x54, 0x61, 0x8d, 0x2e, 0x36, 0xc2, 0x00, 0x8a, 0xb0, 0x86, 0xd0, 0x5f,
0xe9, 0xea, 0x2f, 0x87, 0x55, 0x63, 0x00, 0xb5, 0xb1, 0x87, 0xf0, 0x06, 0x69, 0xad, 0x48, 0x5a,
0x80, 0x3a, 0x62, 0x82, 0x94, 0xbb, 0x83, 0xc2, 0xcd, 0x61, 0x49, 0x96, 0x12, 0x00, 0x61, 0x00,
0x85, 0x5b, 0xc3, 0xe6, 0x52, 0xf3, 0x4b, 0x88, 0xee, 0x32, 0x39, 0x90, 0x78, 0xea, 0x8a, 0xb0,
0x84, 0xb4, 0x40, 0xd7, 0x11, 0xc4, 0x77, 0x57, 0x76, 0x57, 0xc2, 0x02, 0x2a, 0xe3, 0xcc, 0xa4,
0x05, 0x84, 0x39, 0xb8, 0x01, 0xfe, 0xa7, 0xb4, 0x2b, 0xec, 0x8d, 0xdb, 0x56, 0xb6, 0x7f, 0x85,
0xb8, 0x0f, 0xb8, 0x70, 0xf1, 0x2a, 0x47, 0x24, 0x45, 0x4a, 0x2a, 0x52, 0x01, 0xb1, 0xfb, 0xd2,
0xe6, 0xa2, 0x49, 0x0c, 0xdb, 0xef, 0x36, 0xf7, 0xd3, 0x83, 0x2c, 0xcb, 0xce, 0x22, 0xf2, 0xae,
0xb1, 0x5a, 0x27, 0x75, 0x7e, 0xfd, 0x9b, 0x33, 0x43, 0xed, 0x4a, 0xf2, 0xd2, 0xd9, 0xa6, 0x1f,
0xbc, 0x6b, 0xad, 0xa8, 0x21, 0x39, 0xc3, 0x19, 0xce, 0x9c, 0x19, 0x49, 0x56, 0x31, 0x3b, 0x32,
0x61, 0x80, 0x0a, 0xdc, 0x08, 0xa3, 0x09, 0x63, 0x63, 0x06, 0x28, 0xe6, 0x46, 0x58, 0xe0, 0xb9,
0x9a, 0xb0, 0x43, 0x0d, 0xcb, 0x21, 0x19, 0xb4, 0x41, 0x94, 0x23, 0x99, 0x9c, 0xce, 0x1b, 0x9e,
0x7f, 0xd0, 0x0d, 0x15, 0xd4, 0x21, 0x70, 0x63, 0xda, 0xa3, 0x30, 0x40, 0x94, 0x43, 0x18, 0x90,
0x25, 0x63, 0x06, 0x84, 0x83, 0x61, 0x39, 0xc8, 0x9c, 0xd5, 0x98, 0x19, 0xe1, 0x53, 0x4c, 0x58,
0x5a, 0x26, 0xa2, 0x0e, 0x81, 0x19, 0xa2, 0x0e, 0x81, 0x97, 0x32, 0xff, 0xa0, 0x1c, 0x81, 0x01,
0xa2, 0x1c, 0x6a, 0x2a, 0x1b, 0x61, 0x80, 0x28, 0x87, 0x9a, 0xa8, 0xc3, 0x30, 0xff, 0x70, 0xb8,
0x2f, 0xc6, 0x87, 0x05, 0xf1, 0x9e, 0x02, 0x9a, 0xe6, 0xdb, 0x8b, 0xb8, 0x8f, 0x2b, 0x79, 0x64,
0x9e, 0xd1, 0x75, 0x20, 0xa6, 0x2b, 0x83, 0x38, 0x9a, 0x6f, 0x5b, 0xfc, 0x3e, 0xb6, 0x5b, 0x37,
0xdf, 0xf4, 0xb8, 0xfa, 0xa8, 0xbb, 0x7c, 0x40, 0x00, 0xf1, 0xb1, 0xad, 0xd7, 0x87, 0xc0, 0x99,
0x13, 0x50, 0x1e, 0x5b, 0x2b, 0xc3, 0xe9, 0xc7, 0x8e, 0xb6, 0x14, 0xcd, 0x6b, 0x04, 0x7b, 0x13,
0x60, 0x61, 0x44, 0xd0, 0xd4, 0xa0, 0x20, 0x6f, 0xda, 0x1c, 0x63, 0x03, 0x04, 0xa2, 0x5c, 0xd0,
0x8e, 0x20, 0xb8, 0xb9, 0x21, 0x71, 0x69, 0x03, 0xa7, 0x56, 0x53, 0xbc, 0xc1, 0xdc, 0xf3, 0x19,
0xb9, 0xc1, 0xb4, 0xb9, 0x62, 0xb3, 0x44, 0x60, 0x8b, 0x6f, 0xda, 0xa5, 0x3c, 0x02, 0x0a, 0xc3,
0x80, 0xbf, 0x2e, 0xb6, 0x56, 0xc4, 0x52, 0x58, 0x5a, 0xd0, 0x6e, 0x40, 0xd7, 0xe4, 0x0e, 0x71,
0x3c, 0x07, 0x4b, 0xb4, 0x2f, 0x0c, 0x87, 0xc6, 0xd2, 0xa8, 0x0a, 0x66, 0x75, 0x26, 0x7b, 0x80,
0xa6, 0x98, 0xd9, 0x21, 0xc2, 0xa4, 0xbe, 0xe0, 0x74, 0xd0, 0x67, 0xf8, 0x1f, 0xcb, 0x90, 0xd4,
0x10, 0x53, 0xb6, 0x0c, 0x16, 0x42, 0x31, 0xb0, 0xd5, 0x3b, 0xc4, 0xa0, 0x1a, 0x0a, 0x52, 0x92,
0xd3, 0x45, 0xbb, 0xaa, 0x71, 0x9a, 0x7d, 0x89, 0x9c, 0xf5, 0x34, 0x23, 0x43, 0x91, 0xc1, 0x41,
0xb1, 0x08, 0xe1, 0x1d, 0xf9, 0x9a, 0xb4, 0xad, 0xf9, 0x74, 0xd8, 0x09, 0x80, 0xc0, 0x38, 0x72,
0x09, 0x29, 0x92, 0x0d, 0x26, 0xdd, 0x23, 0x04, 0xc8, 0x91, 0x29, 0x08, 0x0d, 0x33, 0x2f, 0xb8,
0x09, 0x29, 0x45, 0x96, 0x2b, 0x0a, 0x9d, 0x0b, 0xf2, 0xf7, 0x43, 0x77, 0xd2, 0x7b, 0xba, 0x3d,
0x0c, 0xd3, 0x48, 0x65, 0xe8, 0xc3, 0x74, 0xd4, 0x68, 0x3a, 0x74, 0x8e, 0xf4, 0x05, 0xb1, 0x27,
0x7a, 0x86, 0x11, 0x70, 0x05, 0xbb, 0xce, 0xc2, 0x13, 0x15, 0x78, 0x82, 0xd0, 0x1f, 0xf9, 0x0e,
0x4f, 0x5a, 0xed, 0xc8, 0xef, 0x87, 0x6f, 0x01, 0xd7, 0x99, 0x24, 0x9b, 0xf9, 0x81, 0xd9, 0x6a,
0x60, 0xb6, 0x86, 0x25, 0x80, 0xcb, 0x96, 0x92, 0x96, 0x72, 0x5a, 0x22, 0x65, 0xd7, 0x01, 0xe8,
0x79, 0x0e, 0xb3, 0x26, 0x92, 0x54, 0x83, 0x24, 0x2d, 0xfc, 0x1d, 0xb2, 0xfd, 0x88, 0x15, 0x25,
0x8a, 0xe0, 0xa5, 0x20, 0xeb, 0x42, 0x0e, 0xbe, 0xbe, 0x0d, 0x53, 0x80, 0x7e, 0x34, 0xbc, 0x34,
0xca, 0x02, 0xea, 0x68, 0xe0, 0xa0, 0xc1, 0x7f, 0xf3, 0x3a, 0x0b, 0x07, 0xf2, 0x09, 0xfb, 0xe2,
0xb0, 0x70, 0x78, 0xda, 0x96, 0x9c, 0x04, 0x03, 0x47, 0x82, 0xf6, 0x2b, 0x83, 0x34, 0x03, 0xfd,
0x6e, 0x69, 0xb8, 0x96, 0xa6, 0x0c, 0xc7, 0x8d, 0xa2, 0xe9, 0x42, 0x73, 0xe8, 0x4e, 0xd6, 0x05,
0x60, 0x10, 0x19, 0xc4, 0x63, 0xef, 0x88, 0x4b, 0xe4, 0x61, 0xb0, 0x3f, 0x4e, 0x7c, 0x81, 0x97,
0x47, 0xb6, 0xd2, 0x41, 0x61, 0xca, 0x63, 0x5b, 0x80, 0xb4, 0x05, 0x24, 0x02, 0xa4, 0x0e, 0xcc,
0x0b, 0x8d, 0x93, 0xa1, 0x31, 0x85, 0xcd, 0x70, 0xd1, 0x11, 0xd7, 0x1b, 0xc0, 0xc7, 0xd2, 0x31,
0xcd, 0x1f, 0x51, 0x40, 0xb6, 0x3d, 0x1e, 0x06, 0x92, 0x0e, 0xf3, 0x4a, 0x78, 0x3e, 0x5e, 0xe6,
0x33, 0xf9, 0x2c, 0x72, 0x64, 0x60, 0x78, 0xc3, 0x24, 0xfb, 0xe6, 0x3c, 0x12, 0x21, 0x39, 0x00,
0xad, 0xd2, 0x0a, 0x8b, 0x2d, 0xb1, 0xbe, 0x04, 0x4b, 0x01, 0xf5, 0x91, 0x93, 0x04, 0xe0, 0x91,
0x46, 0x85, 0xb4, 0x0a, 0x11, 0x70, 0x00, 0x32, 0x32, 0x81, 0x6d, 0xf8, 0x88, 0x02, 0xca, 0x14,
0x81, 0x06, 0x3c, 0x55, 0xa7, 0xc3, 0xb9, 0x44, 0xce, 0x35, 0xc8, 0xc7, 0x64, 0xce, 0x23, 0xa1,
0x65, 0x69, 0xd3, 0x05, 0x1e, 0xa3, 0xd1, 0x57, 0xe8, 0x23, 0xf4, 0x39, 0x1c, 0x1f, 0x60, 0x32,
0xfa, 0x4d, 0xbd, 0x3e, 0xc0, 0x62, 0xe4, 0x44, 0x18, 0x19, 0x9a, 0x9d, 0xcd, 0x48, 0x1d, 0xdb,
0x0c, 0x84, 0x7b, 0x9a, 0x13, 0x4b, 0xb4, 0x36, 0x8c, 0x23, 0xef, 0x12, 0xe1, 0x48, 0x47, 0x3a,
0x59, 0xb2, 0xf7, 0x8a, 0x04, 0x55, 0xa9, 0xcd, 0x70, 0xac, 0xc2, 0x31, 0x5c, 0x1a, 0xd0, 0xcb,
0x78, 0xb7, 0x27, 0x16, 0x6b, 0xcd, 0xe9, 0x27, 0x24, 0x2c, 0x72, 0xa0, 0x27, 0x44, 0xd4, 0x6b,
0x60, 0x11, 0x25, 0xed, 0x52, 0xb4, 0x68, 0x72, 0xf6, 0xbe, 0x53, 0xf4, 0xe6, 0x8e, 0x41, 0x97,
0xf8, 0x08, 0x7c, 0xc2, 0xd1, 0x35, 0x65, 0x47, 0x5a, 0xc9, 0xb9, 0xad, 0x12, 0x03, 0x03, 0x1b,
0xa8, 0x0d, 0x05, 0x7d, 0xf2, 0xed, 0x1a, 0x8a, 0x7c, 0x72, 0x22, 0x23, 0x9f, 0x25, 0x6f, 0x38,
0x1a, 0x07, 0xc0, 0x49, 0x4c, 0xce, 0x2a, 0x5e, 0xea, 0xac, 0xd7, 0xb0, 0x3d, 0x46, 0x10, 0x36,
0xc3, 0xe0, 0x1c, 0x67, 0xbc, 0x32, 0x5b, 0x74, 0xa0, 0x8c, 0xe9, 0xa0, 0x23, 0x07, 0xb5, 0x35,
0x38, 0x69, 0x32, 0x86, 0x0e, 0x9b, 0x8c, 0x9d, 0xec, 0x82, 0x31, 0x3d, 0x48, 0x96, 0x11, 0x61,
0xd8, 0x1a, 0x62, 0x16, 0xa6, 0xc2, 0x47, 0xbd, 0x86, 0x85, 0x35, 0xe4, 0x9a, 0x40, 0x6d, 0xe5,
0x94, 0x92, 0x53, 0x9d, 0xd0, 0x53, 0x81, 0x9e, 0x0a, 0xbd, 0x29, 0xe9, 0xad, 0x29, 0x25, 0x88,
0x23, 0x27, 0x9b, 0xd7, 0x88, 0xc9, 0x10, 0xd9, 0x5b, 0xf8, 0x66, 0x18, 0xa2, 0x38, 0xd7, 0x45,
0x2f, 0x30, 0x17, 0x58, 0x69, 0xad, 0xcc, 0x4b, 0xc9, 0xbc, 0xba, 0x81, 0x1f, 0x2a, 0xf0, 0x43,
0x09, 0xbb, 0x54, 0x60, 0x57, 0x03, 0x56, 0x03, 0xb9, 0x02, 0x50, 0xc7, 0xfa, 0x0d, 0x55, 0x82,
0x67, 0xc7, 0x3c, 0x56, 0xc2, 0x63, 0x92, 0x79, 0xa6, 0x11, 0x87, 0x6b, 0x46, 0x19, 0x3c, 0x05,
0x28, 0x64, 0x4a, 0x2c, 0x43, 0x24, 0xa4, 0x76, 0xfc, 0xbf, 0xec, 0x92, 0xc0, 0xc4, 0x11, 0x82,
0x20, 0x79, 0x53, 0xc0, 0xef, 0xa7, 0xa1, 0xb3, 0xea, 0x61, 0x81, 0x30, 0x05, 0x5a, 0x20, 0x30,
0x38, 0x19, 0x90, 0x4b, 0x83, 0x35, 0xe4, 0x81, 0x04, 0x38, 0x07, 0x49, 0x38, 0xc4, 0x39, 0x64,
0x4e, 0x8e, 0xad, 0x04, 0x5f, 0xd4, 0x04, 0xa6, 0x02, 0x02, 0xc3, 0xce, 0x99, 0x23, 0xa2, 0x23,
0x6e, 0x51, 0x20, 0xd5, 0x69, 0xd8, 0x5f, 0x4e, 0x01, 0xca, 0xb7, 0x81, 0xa1, 0xb4, 0x1a, 0x38,
0x33, 0x2d, 0x14, 0x2c, 0xb1, 0xb4, 0x48, 0x41, 0x29, 0x63, 0x30, 0x16, 0xfe, 0x26, 0x11, 0xc9,
0xd9, 0x83, 0xf6, 0xf0, 0xae, 0x11, 0x32, 0x76, 0x0c, 0x18, 0xd2, 0x7a, 0x27, 0xd5, 0x4a, 0xb1,
0xac, 0x87, 0x63, 0x15, 0x8e, 0x11, 0xde, 0x78, 0xee, 0xd9, 0xa2, 0xaf, 0x14, 0xcc, 0xe2, 0xb8,
0xba, 0x10, 0x3a, 0x6a, 0xa0, 0x13, 0xba, 0x57, 0xd2, 0xbd, 0x92, 0x51, 0x65, 0xe1, 0xdb, 0x37,
0x2e, 0x38, 0xa6, 0xc0, 0x6b, 0x69, 0x25, 0x90, 0x53, 0xc9, 0xc2, 0x77, 0x3c, 0x25, 0x15, 0xa6,
0x14, 0xf8, 0xa0, 0x02, 0x1f, 0x94, 0xb0, 0x09, 0x18, 0x01, 0xb3, 0xa9, 0xa1, 0xae, 0x0c, 0x62,
0xf7, 0xb4, 0x00, 0x11, 0x04, 0xd5, 0xcc, 0xce, 0xc0, 0x5b, 0x39, 0x38, 0x04, 0x69, 0x5c, 0xaf,
0xfa, 0xfe, 0x90, 0x7c, 0x41, 0x26, 0xee, 0xa9, 0xb3, 0x64, 0xe9, 0x3a, 0x53, 0xd0, 0xba, 0x29,
0x81, 0xe6, 0xe2, 0x1b, 0xeb, 0x12, 0x58, 0x31, 0x7f, 0x2a, 0xf9, 0x1f, 0xae, 0x5d, 0x8a, 0x3d,
0xc0, 0x7a, 0x66, 0x65, 0xc9, 0xe8, 0xb1, 0x7c, 0xca, 0xb9, 0x70, 0xc0, 0xe7, 0x69, 0xb3, 0xee,
0x02, 0x31, 0xe0, 0xdf, 0x13, 0xe2, 0xc3, 0xef, 0x4d, 0xb2, 0xeb, 0x65, 0x1f, 0x0d, 0x58, 0x21,
0x3e, 0x54, 0xa3, 0x76, 0x6a, 0x18, 0x87, 0x92, 0x36, 0xdd, 0xb4, 0x93, 0x62, 0xde, 0x69, 0x33,
0x22, 0x91, 0xef, 0x25, 0x41, 0x2c, 0xa0, 0x25, 0x8e, 0x89, 0x6a, 0xd2, 0x43, 0xc8, 0x2c, 0x2b,
0x39, 0xab, 0x80, 0x85, 0xc2, 0x07, 0xbd, 0xb6, 0xb2, 0x8a, 0x38, 0xeb, 0x2d, 0x67, 0x12, 0x9c,
0x29, 0xbb, 0x69, 0xaf, 0x85, 0x9a, 0xf7, 0x2e, 0x84, 0x77, 0xe4, 0xc9, 0x05, 0x19, 0xd1, 0xd7,
0x51, 0xfa, 0x5a, 0xe8, 0x37, 0xe3, 0x99, 0xef, 0x93, 0x83, 0xed, 0x66, 0x5c, 0x2d, 0x0e, 0x58,
0x22, 0xf5, 0x7a, 0xbd, 0xfa, 0xc2, 0x45, 0xc2, 0x49, 0xb3, 0x58, 0x37, 0x5d, 0x7b, 0xc0, 0x72,
0x09, 0xd8, 0x39, 0xa7, 0x3c, 0x48, 0x65, 0x9a, 0x11, 0x86, 0x8e, 0x0c, 0xc7, 0x14, 0x3c, 0x57,
0x01, 0x3c, 0x1f, 0x8e, 0xfb, 0x00, 0xc8, 0x2b, 0x06, 0xe4, 0x5d, 0x38, 0x8d, 0xf2, 0x02, 0x69,
0x3e, 0x7c, 0x0b, 0x99, 0xdd, 0xf1, 0x00, 0xdc, 0x87, 0xcb, 0x84, 0x4a, 0xf9, 0xa4, 0x97, 0xe9,
0x65, 0x26, 0x99, 0x92, 0x37, 0xc9, 0x70, 0xdd, 0x24, 0x1d, 0x50, 0x6c, 0xd3, 0x01, 0xdb, 0x66,
0x93, 0x49, 0x98, 0x6d, 0x06, 0x20, 0x5c, 0x36, 0xcc, 0x61, 0xd6, 0xcb, 0xd7, 0x89, 0xcb, 0x1d,
0x32, 0x49, 0xa9, 0x24, 0x8e, 0x92, 0x71, 0x46, 0x29, 0xe1, 0xcf, 0x3e, 0xfc, 0x96, 0x8c, 0x7e,
0x93, 0x4f, 0x72, 0x00, 0xc2, 0xc5, 0x72, 0xac, 0xc6, 0x0d, 0x85, 0x44, 0x1f, 0xcb, 0x50, 0xed,
0x0b, 0xa7, 0x34, 0x0d, 0x8b, 0xd1, 0x53, 0xcd, 0x10, 0x60, 0x67, 0xc8, 0x3f, 0x24, 0x5e, 0xe1,
0x93, 0x97, 0x95, 0x0b, 0xea, 0x3d, 0x52, 0xbc, 0x62, 0xd0, 0x88, 0x54, 0xed, 0x54, 0x3f, 0x2c,
0xbc, 0xb9, 0xd6, 0x90, 0x71, 0x45, 0x9e, 0x07, 0x8e, 0xa9, 0x47, 0xbe, 0xd0, 0x7f, 0x74, 0x86,
0x33, 0x48, 0xcd, 0x50, 0x17, 0xf0, 0x6c, 0xc9, 0xc1, 0xbc, 0xc0, 0xe8, 0x63, 0x12, 0x2e, 0xef,
0x02, 0x39, 0x15, 0xc8, 0x37, 0xbb, 0x91, 0xb8, 0xfd, 0x23, 0x49, 0x32, 0x1e, 0x25, 0x7f, 0x26,
0xac, 0x64, 0x39, 0xeb, 0x95, 0x87, 0x11, 0x87, 0x32, 0xf2, 0x41, 0x9f, 0x8c, 0xb5, 0x2c, 0x9c,
0x4a, 0x72, 0x66, 0x4d, 0x32, 0xe6, 0x0d, 0xed, 0x03, 0xc1, 0x0a, 0xd1, 0x3f, 0xdc, 0x95, 0x11,
0x6d, 0xd3, 0x7f, 0x41, 0xb9, 0xb8, 0xe4, 0xfd, 0x70, 0xed, 0x2a, 0xe0, 0xb3, 0x23, 0x1e, 0x08,
0xda, 0x95, 0x4c, 0xd4, 0x2b, 0x96, 0x9b, 0xda, 0xaa, 0x57, 0x32, 0xd5, 0xaf, 0x99, 0x02, 0x64,
0xc9, 0x4c, 0xbf, 0x66, 0x0a, 0xe4, 0xd5, 0x54, 0xbf, 0x66, 0xea, 0x57, 0xcc, 0xd4, 0xd2, 0xcc,
0xd4, 0xd7, 0xa8, 0xa9, 0x7e, 0xcd, 0x94, 0xdf, 0xa8, 0x99, 0x7e, 0xcd, 0x14, 0xa8, 0x48, 0xa6,
0xfa, 0x95, 0x3c, 0xab, 0x5f, 0x33, 0x1d, 0xd9, 0xa3, 0x4c, 0xfd, 0x53, 0xb5, 0x09, 0xfa, 0x35,
0xd5, 0xcd, 0x3d, 0xd9, 0xde, 0x7e, 0x8f, 0xbe, 0xc6, 0xf5, 0x2b, 0x2f, 0x3c, 0xaf, 0xae, 0x41,
0xbf, 0xa6, 0x8b, 0x68, 0xa4, 0x61, 0xe3, 0xad, 0xad, 0xd8, 0x6e, 0x8f, 0xa3, 0xcd, 0x35, 0x4f,
0xf6, 0x6b, 0xd8, 0x5c, 0xc1, 0x06, 0x15, 0x99, 0x95, 0xde, 0xa8, 0x51, 0x39, 0xd0, 0xae, 0x2c,
0x61, 0x5c, 0x52, 0x23, 0x1a, 0x36, 0x28, 0x58, 0x32, 0xd7, 0xb0, 0xd1, 0x50, 0xdc, 0xfe, 0xa1,
0xa8, 0x91, 0x8a, 0xa9, 0xb1, 0x8a, 0xa9, 0x89, 0x8a, 0xcd, 0xf7, 0xb1, 0x9d, 0x86, 0x8d, 0x79,
0x33, 0xe8, 0x97, 0xfa, 0x2e, 0xfd, 0x5a, 0xaf, 0x9a, 0x4f, 0xed, 0x21, 0x48, 0x88, 0x47, 0x1c,
0xa8, 0xa4, 0xb8, 0x31, 0xc9, 0x69, 0x8d, 0x71, 0x41, 0x04, 0x92, 0x01, 0x2e, 0xe7, 0x2c, 0xa3,
0xe6, 0x0c, 0x51, 0xd1, 0xef, 0x0e, 0x55, 0xf8, 0x09, 0xdf, 0x4a, 0x7e, 0x56, 0xc3, 0xcf, 0xbb,
0xc3, 0xa1, 0xc5, 0xd7, 0xd0, 0x05, 0x97, 0x04, 0x4d, 0x8a, 0x52, 0x9e, 0x14, 0xde, 0xf4, 0xf3,
0x72, 0x9b, 0x67, 0x6a, 0x50, 0x9e, 0xd4, 0x2e, 0xf1, 0xc7, 0xbe, 0x15, 0x08, 0xa9, 0x22, 0x19,
0xc5, 0x35, 0x1f, 0x9e, 0xcb, 0xed, 0x52, 0x0e, 0x3f, 0xb9, 0x76, 0x02, 0x31, 0x16, 0xfb, 0x12,
0x5e, 0x7c, 0x09, 0x04, 0x9d, 0x14, 0x48, 0xc9, 0x27, 0x45, 0x01, 0xce, 0x49, 0xe4, 0x69, 0x28,
0x06, 0x2b, 0x1d, 0x3b, 0x60, 0xe4, 0x79, 0xe6, 0x05, 0x47, 0x52, 0x06, 0x29, 0x84, 0xac, 0xe0,
0x25, 0x02, 0x42, 0xd6, 0x48, 0xc9, 0x9f, 0x41, 0x51, 0x22, 0x2c, 0xcc, 0x70, 0x9c, 0x1f, 0x17,
0x80, 0x98, 0x90, 0xf9, 0x29, 0x51, 0x53, 0x81, 0x72, 0x13, 0x80, 0x1c, 0xce, 0x7b, 0x65, 0x9d,
0x94, 0x88, 0xe4, 0x0c, 0x43, 0x0d, 0x5f, 0xe4, 0x58, 0x6b, 0x72, 0x7c, 0x32, 0x2e, 0xd3, 0xb4,
0xb4, 0x62, 0x68, 0xa5, 0x96, 0x52, 0x05, 0x2a, 0xa9, 0x94, 0x9c, 0xa3, 0xee, 0x04, 0x78, 0x87,
0x46, 0xfa, 0x8e, 0xec, 0x42, 0x41, 0xc1, 0xa1, 0x35, 0x52, 0x8b, 0x83, 0x4a, 0x94, 0x82, 0x57,
0x59, 0x81, 0x72, 0x40, 0x4e, 0x63, 0x90, 0xeb, 0xad, 0xf1, 0x3f, 0x12, 0x05, 0x34, 0x01, 0x94,
0x33, 0xe0, 0xff, 0xaf, 0x6f, 0x4d, 0x86, 0x22, 0x11, 0x04, 0xee, 0xd4, 0x9f, 0x43, 0x90, 0xed,
0xf0, 0x1d, 0xb2, 0xfa, 0xa5, 0xa4, 0x59, 0xb3, 0x84, 0x54, 0xd9, 0x14, 0x06, 0xe5, 0x22, 0xc6,
0x72, 0xea, 0x16, 0x49, 0x8f, 0x8c, 0xc2, 0x0b, 0x46, 0xbc, 0x0c, 0x62, 0xbf, 0x54, 0x22, 0x08,
0x92, 0xb8, 0xe3, 0xac, 0x07, 0x62, 0xbd, 0x1c, 0x38, 0xa3, 0x75, 0x9c, 0x15, 0x45, 0xe4, 0x07,
0x80, 0x02, 0x01, 0x0d, 0x3c, 0x7c, 0x30, 0xc3, 0x23, 0x7c, 0xa0, 0x58, 0xc7, 0xb2, 0x37, 0xeb,
0x32, 0xb0, 0x34, 0xb1, 0x39, 0x03, 0xd8, 0x79, 0xca, 0xd8, 0x9b, 0xf7, 0x1c, 0x39, 0x12, 0x3b,
0x72, 0x24, 0x0f, 0x33, 0x29, 0x04, 0x15, 0x34, 0x8d, 0x86, 0x9e, 0x43, 0x92, 0x96, 0x4d, 0xfa,
0xb1, 0x2f, 0x8c, 0x20, 0x21, 0xd4, 0x01, 0x49, 0x05, 0xa6, 0x12, 0x31, 0x83, 0x1f, 0xbe, 0x90,
0x54, 0x02, 0xfe, 0x93, 0x42, 0x3d, 0x91, 0xf5, 0x41, 0x76, 0x88, 0x0f, 0xe2, 0xf5, 0x7c, 0x48,
0x65, 0xa3, 0xde, 0x34, 0x13, 0x63, 0x42, 0x73, 0x75, 0x1e, 0x4c, 0x71, 0x80, 0x08, 0xe9, 0xb0,
0xa4, 0x90, 0x95, 0x86, 0x88, 0x48, 0xbd, 0x30, 0xac, 0xb4, 0xd6, 0x4b, 0x96, 0x9b, 0x66, 0xc3,
0x00, 0x7c, 0xc1, 0x30, 0xb4, 0xd1, 0xb8, 0xb4, 0x10, 0x61, 0x15, 0x1c, 0x5f, 0x72, 0xc4, 0x6c,
0xc4, 0x35, 0x4d, 0xb9, 0xec, 0xd4, 0x20, 0x04, 0x46, 0x28, 0xcf, 0x89, 0x10, 0x14, 0xe6, 0x16,
0x14, 0x1d, 0x02, 0x5a, 0xa3, 0x73, 0xa8, 0x0a, 0x4d, 0x50, 0x17, 0x82, 0xa2, 0xd1, 0x94, 0x6b,
0x83, 0x91, 0x18, 0x43, 0x54, 0x4d, 0x32, 0x42, 0x51, 0x00, 0x42, 0x30, 0x29, 0x09, 0xe6, 0x72,
0x2f, 0x04, 0xce, 0x3e, 0xec, 0x67, 0x40, 0x82, 0xb8, 0xe2, 0x25, 0xe5, 0xe0, 0x0d, 0x08, 0x99,
0xe7, 0xb5, 0x0c, 0xfc, 0x8c, 0x4c, 0x1c, 0x80, 0x30, 0x85, 0x21, 0x97, 0x58, 0x58, 0xa9, 0x45,
0x5d, 0x0c, 0x83, 0x4c, 0xc8, 0xde, 0x40, 0x8b, 0x38, 0x6d, 0x88, 0x64, 0x3c, 0x82, 0x2d, 0x0c,
0xb4, 0xd0, 0x08, 0x0b, 0x01, 0x18, 0x03, 0xaf, 0xe7, 0x0a, 0x06, 0x4e, 0xf2, 0xf2, 0x2c, 0xcb,
0xe3, 0xdc, 0xc1, 0xab, 0x07, 0x24, 0x84, 0x64, 0x62, 0x69, 0xc2, 0x01, 0x4d, 0x49, 0x70, 0x4a,
0x1b, 0x10, 0x75, 0x29, 0xb6, 0x4d, 0x3d, 0xf4, 0x0e, 0xe1, 0x77, 0x8a, 0x10, 0x1f, 0x85, 0x1c,
0x19, 0x83, 0xea, 0x5a, 0x00, 0xa2, 0x92, 0x99, 0x9c, 0x21, 0x12, 0xcf, 0x91, 0x9a, 0x64, 0xfb,
0xc1, 0xd8, 0x49, 0x86, 0x24, 0x4f, 0x2e, 0xa9, 0x49, 0xc3, 0x15, 0x50, 0xda, 0x89, 0x46, 0x92,
0x22, 0x32, 0x26, 0xe6, 0x39, 0x1c, 0xcf, 0x78, 0xbd, 0x2b, 0x9a, 0x38, 0xa0, 0x79, 0x5a, 0xa4,
0x9c, 0xd2, 0xa2, 0xa1, 0xd1, 0x5a, 0x07, 0x77, 0x50, 0x62, 0x6b, 0x38, 0x85, 0x18, 0xbe, 0x50,
0x17, 0x46, 0x01, 0x2d, 0x30, 0x42, 0x3b, 0x34, 0x31, 0x72, 0x05, 0x97, 0x49, 0x67, 0x5c, 0x3c,
0x85, 0x04, 0x29, 0x76, 0x0d, 0xa4, 0xbf, 0xb9, 0xac, 0x57, 0xba, 0x35, 0x61, 0x14, 0x9a, 0x53,
0x22, 0x52, 0x52, 0x91, 0x93, 0x09, 0xa1, 0xd1, 0xfb, 0xc2, 0x63, 0x2e, 0x9c, 0x05, 0xc8, 0x91,
0x05, 0xc0, 0xc4, 0x2c, 0xd2, 0xe2, 0x05, 0x29, 0x08, 0x7f, 0x62, 0x71, 0xa0, 0x38, 0x0b, 0x38,
0x09, 0x0a, 0xe2, 0x68, 0xc8, 0x21, 0x85, 0x93, 0x62, 0x87, 0x71, 0xc8, 0x98, 0x16, 0x9c, 0x30,
0xcd, 0x73, 0xce, 0x3c, 0x5a, 0x2e, 0xa7, 0xca, 0xd1, 0xad, 0x1c, 0x09, 0x84, 0x99, 0x2a, 0x51,
0x10, 0x52, 0xa4, 0x9c, 0x77, 0xa5, 0x8c, 0xab, 0x14, 0xf2, 0x94, 0x51, 0x4c, 0x64, 0xd3, 0x68,
0x88, 0xa5, 0x2a, 0x18, 0xec, 0xc9, 0x00, 0x49, 0x6f, 0x45, 0x3e, 0x2c, 0x81, 0xcc, 0x33, 0x42,
0x6d, 0x73, 0xf6, 0x77, 0x48, 0x4f, 0x3d, 0xac, 0xa5, 0x93, 0x6c, 0x47, 0x58, 0x4c, 0xb2, 0xb8,
0x38, 0xff, 0x47, 0x0b, 0x3d, 0x73, 0x40, 0xc9, 0x01, 0xb3, 0xa0, 0xf2, 0xa3, 0x4c, 0xb1, 0x34,
0x87, 0x15, 0x2a, 0x0b, 0xd6, 0x4a, 0xc4, 0x0e, 0x34, 0x0a, 0x55, 0xae, 0x24, 0x5f, 0xe4, 0xce,
0x29, 0x36, 0x03, 0xc4, 0x22, 0x6b, 0xde, 0x48, 0x5e, 0xd4, 0x67, 0x6c, 0x1e, 0x5c, 0xce, 0xd2,
0x02, 0x8e, 0x8b, 0xc5, 0x01, 0x3c, 0x00, 0x60, 0x8a, 0xa8, 0x92, 0xdd, 0xaa, 0x16, 0x29, 0x0a,
0xc6, 0x0a, 0x43, 0xe4, 0x61, 0xab, 0x3c, 0xd7, 0xbb, 0x1b, 0x50, 0x26, 0xf9, 0x84, 0xc3, 0xa0,
0xb3, 0x9f, 0xa5, 0xd8, 0x56, 0x4a, 0x0c, 0xdf, 0x6a, 0x57, 0x72, 0x30, 0x4b, 0xb6, 0x1e, 0x96,
0xb5, 0xa1, 0xc8, 0x1f, 0x75, 0x62, 0xb0, 0x40, 0x62, 0xb2, 0x8a, 0x8c, 0x41, 0x54, 0xf6, 0x01,
0xd3, 0x5c, 0x50, 0x09, 0x98, 0x44, 0xcb, 0x89, 0x46, 0x43, 0x93, 0x77, 0x92, 0xcb, 0x01, 0xa6,
0x0e, 0xfc, 0x43, 0x6b, 0x06, 0xf7, 0x9c, 0x67, 0x5b, 0xae, 0x89, 0x29, 0x8e, 0x96, 0x8d, 0x2b,
0xb9, 0xee, 0xcc, 0x0a, 0x72, 0x03, 0xf6, 0x79, 0x06, 0xb2, 0x0a, 0x9a, 0x3f, 0x6a, 0xc5, 0x2d,
0x43, 0xed, 0x3e, 0x47, 0xb6, 0xd8, 0xa0, 0xf8, 0x4a, 0x15, 0xc4, 0x02, 0xda, 0x6e, 0x1a, 0x9a,
0x44, 0x4e, 0x2e, 0x1f, 0x84, 0xe4, 0xc0, 0x24, 0x76, 0x44, 0x34, 0xef, 0x8b, 0xb8, 0x42, 0x0b,
0x01, 0xd4, 0x0e, 0xd0, 0x78, 0x70, 0x4b, 0x00, 0x97, 0xc6, 0x43, 0x33, 0x38, 0x05, 0x6e, 0x45,
0x15, 0x30, 0x0c, 0xec, 0xd4, 0xc4, 0xe4, 0x92, 0x2b, 0x8a, 0x00, 0x29, 0x17, 0x5c, 0x08, 0x84,
0x4a, 0x46, 0x0b, 0x26, 0xa3, 0x58, 0xb8, 0xe4, 0xd9, 0x01, 0xd0, 0xc7, 0x6c, 0xad, 0x76, 0x5f,
0xdf, 0xe6, 0x39, 0x17, 0x57, 0x29, 0x87, 0x19, 0x02, 0x18, 0x02, 0xfc, 0x4a, 0x46, 0x91, 0xfc,
0xf1, 0x12, 0x3a, 0x00, 0x4c, 0x91, 0xd7, 0x84, 0xe3, 0xed, 0x0f, 0x98, 0x32, 0x14, 0x6d, 0x38,
0x4e, 0x99, 0xbf, 0xc8, 0x1a, 0x91, 0x7c, 0x35, 0xf4, 0xdb, 0xc2, 0x5e, 0xa1, 0xb0, 0x80, 0x0b,
0x01, 0x19, 0xc2, 0xce, 0xe1, 0x3a, 0x58, 0x96, 0x29, 0xe9, 0x32, 0xac, 0x39, 0x4d, 0xc6, 0xeb,
0x02, 0x88, 0x2f, 0xd2, 0xcc, 0x8e, 0xb3, 0x34, 0xc4, 0x18, 0x74, 0xc0, 0x9f, 0xa8, 0x54, 0x42,
0x6b, 0xd2, 0x0a, 0xd9, 0x55, 0xd0, 0x80, 0x5b, 0xf3, 0x4e, 0x50, 0x02, 0xdd, 0x47, 0xb1, 0xbf,
0x1b, 0x7a, 0xa1, 0x3e, 0x73, 0x22, 0xb5, 0x3b, 0x42, 0xed, 0x56, 0x2a, 0xb0, 0x27, 0xa2, 0xf4,
0xb0, 0xc0, 0x3c, 0xe7, 0x8b, 0x65, 0xf0, 0xf9, 0x68, 0x32, 0x86, 0xf3, 0xe9, 0x1a, 0xbb, 0x19,
0xf4, 0x93, 0xac, 0x81, 0x43, 0x41, 0x15, 0x90, 0x7c, 0xd4, 0x17, 0xd1, 0x8e, 0x51, 0xc0, 0x51,
0x4f, 0x0d, 0xeb, 0xb7, 0x63, 0x5c, 0x93, 0x37, 0x56, 0xf2, 0x51, 0x32, 0x6c, 0xd2, 0xb4, 0xbb,
0x0b, 0x0c, 0x27, 0x6d, 0xb6, 0xd7, 0x1c, 0x82, 0x56, 0x3f, 0x2e, 0x9b, 0x6f, 0x78, 0x75, 0xd4,
0x92, 0x1f, 0xbe, 0x24, 0xe1, 0x2d, 0x85, 0x12, 0x6c, 0x92, 0x33, 0x30, 0xb3, 0x0c, 0x2e, 0xf7,
0x37, 0x10, 0x29, 0x92, 0x7e, 0x61, 0x79, 0x35, 0xd3, 0x17, 0xca, 0xeb, 0x90, 0xbc, 0x4a, 0x81,
0x9c, 0xf2, 0x46, 0x54, 0xe2, 0x36, 0x83, 0x14, 0x45, 0x5d, 0x9c, 0x1b, 0xa0, 0x05, 0x4b, 0xab,
0x88, 0x74, 0x87, 0x73, 0xf0, 0xb4, 0x15, 0xc9, 0x17, 0xf9, 0x4d, 0x45, 0x2a, 0x39, 0x13, 0x4e,
0x35, 0x31, 0xf2, 0x02, 0x42, 0x72, 0x04, 0xbd, 0x35, 0xbc, 0x9d, 0xc2, 0x0c, 0x13, 0x4f, 0x60,
0x56, 0x90, 0x31, 0xf7, 0x70, 0x11, 0x81, 0x3d, 0x16, 0x5c, 0xc1, 0xe9, 0x25, 0x13, 0x15, 0xc2,
0xd1, 0x63, 0xb9, 0xeb, 0x04, 0x95, 0x6b, 0x30, 0x72, 0x9e, 0x6b, 0x49, 0x5c, 0x99, 0x4b, 0x83,
0x42, 0x49, 0xeb, 0xa1, 0x05, 0x5a, 0xcb, 0xf9, 0x24, 0xb4, 0x06, 0x71, 0x0c, 0x21, 0x07, 0x2c,
0xcc, 0x77, 0x9e, 0xb0, 0x67, 0x80, 0x21, 0x78, 0xdc, 0xe4, 0xc2, 0xc9, 0x98, 0xed, 0xb1, 0x2e,
0x25, 0xa2, 0x43, 0x01, 0xa6, 0x91, 0xb2, 0x32, 0x6c, 0x8e, 0xec, 0xb3, 0x49, 0x4d, 0xaa, 0x85,
0x2d, 0xd7, 0x25, 0xb3, 0xcc, 0xd1, 0x54, 0xe5, 0xeb, 0x00, 0x26, 0x4f, 0x40, 0xc3, 0x7d, 0xc1,
0x84, 0xeb, 0xc6, 0x59, 0xd3, 0xbf, 0x09, 0x90, 0x75, 0xa3, 0x2c, 0x6a, 0x0c, 0x2c, 0x73, 0x5b,
0xb0, 0x6c, 0xee, 0x07, 0x85, 0x05, 0x65, 0x24, 0x06, 0xf7, 0x5c, 0xbc, 0x4c, 0x96, 0x94, 0xd3,
0xa5, 0x5c, 0xe3, 0x07, 0xef, 0x18, 0x9c, 0xb7, 0xb0, 0x26, 0x41, 0x4c, 0x88, 0x4c, 0x45, 0x32,
0xcc, 0x79, 0x38, 0x1b, 0x16, 0x01, 0x01, 0xb3, 0x1e, 0x6b, 0x83, 0x59, 0xaf, 0x84, 0xd5, 0x28,
0xd4, 0x95, 0x3c, 0xd8, 0x70, 0x2c, 0xac, 0x67, 0x00, 0xcf, 0x49, 0x07, 0x81, 0xf5, 0x49, 0x60,
0x7d, 0xc2, 0xac, 0x37, 0xba, 0x13, 0x96, 0xab, 0xc0, 0x79, 0xf2, 0x1f, 0x47, 0x00, 0x65, 0x39,
0x06, 0x28, 0xcb, 0x38, 0x40, 0xd9, 0x8c, 0x71, 0xcf, 0xb1, 0xd4, 0x46, 0x00, 0xe2, 0x98, 0x85,
0xdf, 0x86, 0x64, 0xbb, 0x71, 0x36, 0xfc, 0x00, 0x74, 0xb5, 0x0f, 0xc7, 0xe5, 0xe0, 0x3d, 0x0a,
0x15, 0x56, 0xc1, 0xa0, 0x8f, 0x0d, 0xf4, 0x50, 0x89, 0x1e, 0xf2, 0x3e, 0x57, 0xa2, 0x94, 0x80,
0xf5, 0xd0, 0xa8, 0xa0, 0x88, 0x4a, 0x14, 0x91, 0xef, 0x2b, 0xe2, 0x4a, 0xf3, 0x5c, 0xb6, 0x5a,
0xd6, 0xc4, 0x4c, 0x89, 0xee, 0x29, 0xd1, 0x44, 0x33, 0x1c, 0x0e, 0xaa, 0xa8, 0x44, 0x15, 0x13,
0xd1, 0x44, 0x15, 0x34, 0x31, 0x09, 0x9a, 0xc8, 0xba, 0x55, 0x88, 0xb8, 0x35, 0x74, 0x0b, 0xf7,
0x46, 0x89, 0xb8, 0x45, 0xc2, 0x2c, 0xef, 0x43, 0x62, 0x53, 0x7e, 0x7e, 0xcb, 0x5d, 0xbd, 0xfe,
0x74, 0x38, 0xf2, 0x23, 0xe0, 0x46, 0x28, 0xdb, 0x3f, 0xac, 0x80, 0x39, 0xeb, 0x67, 0x45, 0xcb,
0xd9, 0x0c, 0x18, 0xf2, 0x28, 0xdd, 0x67, 0x5a, 0x76, 0x40, 0x84, 0xa6, 0xe0, 0xe5, 0xb6, 0x61,
0x2f, 0x04, 0xec, 0x1c, 0x11, 0x1a, 0x8e, 0x9b, 0xed, 0x90, 0xd4, 0xf3, 0x10, 0x6e, 0x7f, 0x10,
0x84, 0x9b, 0xa9, 0x29, 0xc8, 0xb3, 0x3d, 0x3d, 0x00, 0x5e, 0x4a, 0x6a, 0xb2, 0x67, 0x44, 0xe6,
0x78, 0xd6, 0xd7, 0x1d, 0xd7, 0xb0, 0x04, 0xbf, 0x1f, 0x36, 0x8d, 0xa2, 0xb4, 0x51, 0x90, 0x76,
0x5f, 0x24, 0x05, 0xdf, 0x23, 0xcf, 0x78, 0x28, 0x9e, 0xe3, 0x9c, 0xf4, 0x09, 0xd4, 0xb8, 0x4b,
0x18, 0x8c, 0x8b, 0x58, 0xa6, 0xd6, 0x74, 0xaf, 0x76, 0xee, 0x49, 0x7d, 0x24, 0x33, 0x4d, 0x42,
0x61, 0x0d, 0x1b, 0xcc, 0xf0, 0x6d, 0x43, 0x39, 0x83, 0x7c, 0x17, 0xcd, 0x53, 0xdd, 0x1c, 0x53,
0x98, 0x62, 0xbd, 0xc5, 0x5e, 0x84, 0xd5, 0x75, 0x6c, 0x9b, 0xb2, 0xe1, 0x56, 0xab, 0x90, 0x2f,
0x49, 0x46, 0xf9, 0x92, 0x64, 0x9c, 0x2f, 0x39, 0x18, 0x25, 0xbd, 0x5e, 0x7d, 0x59, 0xfe, 0x55,
0x90, 0xd4, 0x53, 0xc8, 0x89, 0x1b, 0x01, 0x8b, 0x59, 0x0a, 0x62, 0x56, 0xc7, 0x3f, 0x5b, 0x3b,
0x45, 0x9f, 0x4c, 0x35, 0x61, 0xae, 0x32, 0x31, 0x55, 0xda, 0xa9, 0x5a, 0x00, 0x47, 0x27, 0x10,
0x6b, 0x31, 0x83, 0x58, 0xcd, 0x0c, 0x62, 0x35, 0x53, 0x88, 0x35, 0x9b, 0x41, 0xac, 0x66, 0x06,
0xb1, 0xfa, 0x27, 0xbf, 0x4f, 0x21, 0xd6, 0x7c, 0x0a, 0xb1, 0x6e, 0x53, 0x15, 0x48, 0xce, 0xd2,
0x6a, 0xe6, 0x54, 0x1e, 0xe9, 0xfe, 0xe4, 0x76, 0x96, 0xa7, 0x40, 0x68, 0x1f, 0xc3, 0x3f, 0x9b,
0xe1, 0x4e, 0x98, 0x28, 0x0e, 0xda, 0x47, 0xd5, 0x63, 0x6f, 0x41, 0x57, 0x9a, 0xf1, 0x86, 0x54,
0x58, 0x2e, 0x12, 0x7b, 0x92, 0x81, 0x90, 0x75, 0xed, 0xf6, 0x27, 0xb6, 0x46, 0x5a, 0x11, 0x41,
0x50, 0x9f, 0x00, 0x99, 0x9f, 0xb7, 0x00, 0xe9, 0x70, 0x1f, 0xf4, 0x93, 0x3b, 0x25, 0xe5, 0xd6,
0xc4, 0x11, 0x6c, 0x3a, 0xba, 0x41, 0xf1, 0xf3, 0x04, 0x20, 0xd5, 0x5c, 0xb2, 0xc4, 0xf4, 0x0f,
0x41, 0x73, 0xc7, 0x39, 0x88, 0x80, 0x8c, 0x32, 0x4c, 0x9a, 0x8c, 0x61, 0xd2, 0x3e, 0x6c, 0xd0,
0x36, 0xe8, 0x0a, 0xef, 0x37, 0x7c, 0x46, 0x78, 0xa3, 0x76, 0xbc, 0x81, 0x7b, 0xa1, 0x02, 0x3a,
0xaa, 0x59, 0x0f, 0x35, 0xee, 0xa2, 0xdd, 0xab, 0x5a, 0x2f, 0xe4, 0x26, 0xf4, 0x97, 0x7c, 0x4b,
0xfa, 0xcb, 0xeb, 0xc5, 0x67, 0x68, 0xd9, 0xe6, 0xea, 0x24, 0xdc, 0x26, 0x8f, 0x47, 0x03, 0xe1,
0x61, 0x5a, 0xe1, 0xce, 0x78, 0x9c, 0xbb, 0xbd, 0x52, 0xab, 0x65, 0xd3, 0x2d, 0x9a, 0x4f, 0x3f,
0xf3, 0xb3, 0x3d, 0xab, 0x97, 0x0f, 0x7d, 0xab, 0xfe, 0xc4, 0x5b, 0x98, 0x7e, 0xe2, 0xf7, 0x2b,
0xfd, 0xd7, 0xfc, 0x7e, 0x75, 0xea, 0x8f, 0x9a, 0x54, 0x2f, 0xc3, 0x6d, 0xef, 0x81, 0xd0, 0xdd,
0xf5, 0x98, 0x10, 0x3f, 0x2d, 0x73, 0x3f, 0x29, 0xdc, 0x8c, 0xbb, 0x9f, 0xc4, 0x7d, 0xbf, 0x23,
0x71, 0xfa, 0xef, 0x23, 0x13, 0x21, 0xc0, 0xf5, 0x6f, 0xfb, 0x29, 0xdc, 0xfc, 0x39, 0xa1, 0x60,
0x23, 0x14, 0x50, 0x0e, 0xb3, 0x9f, 0xc0, 0xb2, 0x9b, 0x10, 0xc8, 0x22, 0x04, 0x70, 0x23, 0x5e,
0x84, 0x40, 0x3f, 0x66, 0xc3, 0xbb, 0x18, 0x13, 0x10, 0xe2, 0xec, 0x27, 0xd0, 0x6f, 0xc6, 0x04,
0x2e, 0x62, 0x04, 0x9a, 0xd5, 0xed, 0xe4, 0x7a, 0x92, 0xfc, 0xe2, 0xf3, 0x56, 0xe2, 0xcd, 0xf5,
0x20, 0xf1, 0xe1, 0xf1, 0x69, 0xd5, 0x4b, 0x3c, 0xf2, 0x87, 0x79, 0x44, 0xdf, 0xff, 0xd7, 0xc8,
0x5b, 0xb8, 0x4e, 0x6f, 0xa8, 0xe3, 0xab, 0xf5, 0xf6, 0xba, 0xbe, 0x7b, 0x15, 0xae, 0xeb, 0xb1,
0x9a, 0xf8, 0x69, 0x11, 0x6a, 0xf7, 0xb4, 0x08, 0xc5, 0x2f, 0xd2, 0xfa, 0xf9, 0x84, 0x53, 0x5a,
0xcb, 0xb6, 0xef, 0x87, 0xc6, 0xd7, 0xbd, 0xd0, 0xbb, 0x78, 0xa5, 0xc2, 0x53, 0x5f, 0xd5, 0xdd,
0x62, 0x89, 0xcf, 0xfa, 0x4f, 0x3c, 0x4d, 0x5d, 0xf5, 0x9b, 0xf6, 0xfe, 0x67, 0x8d, 0x89, 0xc9,
0x0b, 0x8d, 0xf0, 0x44, 0xf1, 0xd9, 0x98, 0xf1, 0xe8, 0xea, 0xd1, 0x40, 0xce, 0x0f, 0x18, 0xc8,
0x3f, 0xce, 0xdb, 0x6b, 0xc5, 0xaf, 0x1d, 0xf8, 0xc7, 0x93, 0x91, 0x9c, 0xff, 0x8d, 0x91, 0x74,
0xbf, 0x1e, 0xd2, 0xf9, 0xaf, 0x78, 0xc0, 0x57, 0xac, 0xfb, 0x5f, 0xff, 0x4e, 0xf7, 0x27, 0x87,
0x74, 0x7f, 0x42, 0xe4, 0x63, 0xbd, 0x9f, 0x7c, 0x47, 0xef, 0xd3, 0x31, 0x7c, 0xec, 0x47, 0xe3,
0xf9, 0xed, 0x80, 0xf1, 0xfc, 0x46, 0xa3, 0x99, 0x0f, 0xe3, 0xb7, 0x3d, 0xc3, 0xd0, 0x32, 0x88,
0xf4, 0x38, 0x35, 0x6e, 0x34, 0x90, 0xf0, 0xd0, 0xfe, 0x27, 0xac, 0xb8, 0x38, 0xa0, 0xeb, 0x8b,
0x7a, 0xf3, 0xb0, 0xae, 0xf9, 0x19, 0x86, 0xf3, 0x11, 0x5c, 0x7c, 0xf7, 0x08, 0x66, 0xe3, 0xf8,
0xe3, 0x10, 0x91, 0xfc, 0x81, 0xe7, 0xa0, 0xc5, 0x64, 0xf2, 0xc7, 0xf7, 0xaf, 0x88, 0x4d, 0xf7,
0x61, 0x64, 0xc0, 0xc9, 0xbe, 0xff, 0xcf, 0xcd, 0x4d, 0xdb, 0x6c, 0xd4, 0x59, 0xbd, 0x6c, 0x3b,
0xd6, 0x5f, 0xfa, 0xdb, 0x19, 0xc1, 0xbb, 0xf5, 0xd6, 0x82, 0xf0, 0x53, 0x95, 0x93, 0xb2, 0x8c,
0x59, 0x11, 0x54, 0x08, 0x45, 0x4c, 0xe9, 0x6a, 0x4e, 0x45, 0x47, 0x88, 0x3c, 0xa9, 0x21, 0x89,
0x10, 0xbc, 0xbb, 0x99, 0x12, 0x7c, 0x9e, 0xde, 0x38, 0x6d, 0x1e, 0x1b, 0xe1, 0x8c, 0x60, 0x74,
0x9a, 0x92, 0x28, 0x9c, 0xda, 0xcb, 0x1d, 0xd7, 0xf8, 0x71, 0x5c, 0x22, 0xa4, 0xcb, 0x0f, 0x23,
0x39, 0x7c, 0x80, 0x1c, 0x56, 0xf7, 0xbc, 0xae, 0x06, 0xd1, 0x0d, 0x8f, 0x89, 0xae, 0x2e, 0xf8,
0xf1, 0x56, 0x47, 0xe9, 0x0f, 0x2f, 0x5f, 0x48, 0x93, 0x59, 0x53, 0x5d, 0x9d, 0xf0, 0x8b, 0x0c,
0x69, 0x96, 0x91, 0x16, 0xa6, 0x3a, 0x59, 0xb7, 0xf0, 0x8f, 0x68, 0xa3, 0x8b, 0x34, 0xb1, 0xd5,
0x1f, 0x8b, 0xfb, 0x56, 0xd1, 0x3e, 0x16, 0x69, 0x90, 0x49, 0x83, 0x73, 0x7e, 0xbf, 0x9c, 0xa2,
0xed, 0x2a, 0xd2, 0xce, 0x55, 0xa7, 0xfc, 0xa6, 0xc5, 0x73, 0x75, 0xe4, 0x62, 0x6d, 0x7c, 0x75,
0xf1, 0xa5, 0x6d, 0xef, 0xd5, 0x91, 0x8f, 0xb5, 0xc8, 0xab, 0x5f, 0x1e, 0x89, 0x4d, 0x8b, 0x46,
0x1d, 0xe5, 0xb1, 0x36, 0x85, 0xf4, 0xd4, 0xad, 0x56, 0x44, 0xa9, 0x88, 0xb5, 0x2a, 0xab, 0xf3,
0x7a, 0xb1, 0xbc, 0x5a, 0x7d, 0x51, 0x47, 0x65, 0x94, 0x83, 0x69, 0x75, 0xd1, 0xd4, 0x4b, 0xe2,
0x60, 0x9c, 0xc9, 0x5a, 0x9a, 0xfc, 0x69, 0xa8, 0x55, 0x94, 0xd1, 0xda, 0x54, 0xaf, 0xeb, 0x6b,
0x62, 0xa3, 0x8e, 0x32, 0x5a, 0xdb, 0xea, 0xf4, 0x23, 0x1e, 0xd8, 0x7a, 0xa4, 0xa3, 0xbc, 0xd6,
0x59, 0x68, 0x73, 0xda, 0x51, 0xb3, 0x28, 0xab, 0xb5, 0xab, 0xce, 0x1f, 0x96, 0xcb, 0xc5, 0xf2,
0x96, 0x5a, 0x45, 0x99, 0xad, 0x7d, 0x75, 0xf9, 0x85, 0xd6, 0x47, 0x87, 0x2e, 0xa3, 0x0c, 0xd7,
0xf9, 0xb6, 0x15, 0x49, 0x4e, 0x47, 0x99, 0xae, 0x8b, 0x6d, 0xbb, 0x30, 0xd3, 0x28, 0xe7, 0x75,
0xb9, 0x23, 0xf9, 0x9a, 0x1a, 0x46, 0xd9, 0x6f, 0x88, 0xfd, 0xf7, 0xf5, 0x9a, 0x47, 0x68, 0xa2,
0x12, 0x30, 0x7a, 0xdb, 0xea, 0xcd, 0xf2, 0x33, 0xb5, 0x8c, 0x2f, 0x77, 0x33, 0x6e, 0xf9, 0xdf,
0xd4, 0x34, 0x2a, 0x0d, 0x63, 0xab, 0x8b, 0xcd, 0x7a, 0x75, 0x85, 0x9e, 0xa3, 0xe2, 0x30, 0xd9,
0xd0, 0x08, 0xf2, 0x30, 0x51, 0x79, 0x18, 0x37, 0xb4, 0x43, 0x9f, 0x51, 0x81, 0x18, 0x1f, 0x14,
0x96, 0xa9, 0x45, 0x25, 0x62, 0xf2, 0xea, 0xd5, 0xf2, 0x7a, 0xbd, 0x82, 0xee, 0x9b, 0xa8, 0x3c,
0x4c, 0x31, 0x2c, 0x27, 0x13, 0x15, 0x84, 0x29, 0x43, 0x1b, 0x92, 0xac, 0x89, 0x4a, 0xc1, 0xa6,
0x43, 0xab, 0x41, 0x5f, 0x6c, 0x54, 0x16, 0x56, 0x87, 0xb6, 0xaf, 0x69, 0xab, 0x20, 0xb3, 0x62,
0xa3, 0xb2, 0xb0, 0x66, 0xa0, 0x4a, 0x4b, 0xc0, 0xc6, 0xcd, 0x8f, 0xdd, 0xad, 0x78, 0x96, 0xae,
0x8d, 0x4a, 0xc3, 0x66, 0xa2, 0xf7, 0x37, 0x0f, 0xc4, 0x3e, 0x1b, 0x15, 0x86, 0x75, 0xd5, 0xe5,
0xba, 0xbe, 0xb9, 0x21, 0x13, 0xf2, 0x3b, 0xec, 0x3b, 0xb5, 0x8d, 0x4a, 0xc4, 0x0e, 0x06, 0xe9,
0xfc, 0xc8, 0x46, 0xe5, 0x61, 0xf3, 0xad, 0xb6, 0x91, 0x0d, 0xb0, 0x51, 0x89, 0xd8, 0xa2, 0x22,
0x5f, 0xf1, 0x05, 0xfb, 0x4c, 0x47, 0x36, 0x2a, 0x14, 0x5b, 0x6e, 0xc9, 0x91, 0x58, 0x6c, 0x54,
0x2c, 0x99, 0xd8, 0xa6, 0x65, 0xbb, 0x26, 0xa3, 0x1b, 0x15, 0x48, 0xa6, 0x2b, 0x9e, 0xe5, 0xc7,
0x15, 0x36, 0xa5, 0xa3, 0x2c, 0x2a, 0x8f, 0x8c, 0x2c, 0xd4, 0x62, 0xdd, 0x7e, 0x59, 0xad, 0x3f,
0xf5, 0xd4, 0x2e, 0x2a, 0x90, 0xcc, 0x8e, 0xda, 0xd1, 0x00, 0xb3, 0xf8, 0xc6, 0x00, 0x63, 0xb5,
0xa6, 0x48, 0xeb, 0xae, 0x06, 0xc5, 0xa8, 0x40, 0x32, 0xc7, 0x14, 0x69, 0xc9, 0xd0, 0x2e, 0xca,
0xb3, 0x89, 0xca, 0x23, 0xf3, 0xd5, 0xaf, 0xe1, 0xb9, 0xaa, 0xd4, 0x2c, 0x2a, 0x91, 0x2c, 0x1f,
0x9e, 0xc3, 0x46, 0xad, 0xa2, 0xf2, 0xc8, 0x0a, 0xd9, 0xb9, 0xde, 0xbc, 0xa7, 0x56, 0x51, 0x71,
0x64, 0x65, 0x68, 0xf5, 0x86, 0x5a, 0x45, 0x85, 0xe1, 0x52, 0x69, 0xf5, 0x9e, 0x68, 0xb9, 0xa8,
0x30, 0x9c, 0x0e, 0xad, 0x88, 0x96, 0x8b, 0x4a, 0xc2, 0x91, 0x66, 0x90, 0xcb, 0xf1, 0x40, 0x4c,
0x73, 0x51, 0x31, 0x38, 0x5b, 0xfd, 0x56, 0xe3, 0x61, 0xbb, 0xf0, 0xff, 0x8f, 0x5c, 0x54, 0x08,
0x2e, 0xa3, 0xd5, 0xbe, 0x90, 0x77, 0x1c, 0x07, 0x7b, 0xe0, 0xe2, 0x5b, 0xb4, 0xdb, 0x35, 0x96,
0x5d, 0xdf, 0x45, 0x45, 0xe1, 0xfc, 0xae, 0xad, 0x18, 0x7c, 0x17, 0x95, 0x87, 0xcb, 0x65, 0x11,
0xb2, 0x40, 0x5c, 0x54, 0x20, 0xae, 0xa8, 0xde, 0x9c, 0xfe, 0x2f, 0xb5, 0x88, 0x0a, 0xc3, 0x95,
0xd5, 0xdb, 0x87, 0x6e, 0xb3, 0x50, 0xa7, 0xab, 0xbb, 0x96, 0x96, 0x80, 0x8b, 0x0a, 0xc4, 0xef,
0xb4, 0x03, 0x3b, 0xb3, 0x8f, 0xca, 0xc4, 0xeb, 0x2a, 0xb8, 0x2e, 0x81, 0x3d, 0x3e, 0x2a, 0x18,
0x6f, 0xaa, 0xf7, 0x7d, 0xb3, 0xe8, 0xf0, 0xb8, 0x5a, 0x6a, 0x17, 0x95, 0x8d, 0xb7, 0xd5, 0xd9,
0x7a, 0x41, 0x2c, 0x31, 0xa9, 0x76, 0xd4, 0x30, 0x2a, 0x1c, 0x9f, 0x55, 0xff, 0x7a, 0xb8, 0xbd,
0xc5, 0xf6, 0xe6, 0xa3, 0x42, 0xf1, 0xae, 0x3a, 0xab, 0xbb, 0x76, 0xc3, 0x7d, 0xc6, 0x3d, 0x27,
0x2f, 0x4a, 0x44, 0x5d, 0x62, 0xba, 0x51, 0x51, 0xf8, 0x5c, 0x8c, 0xe4, 0x97, 0xfa, 0x73, 0x4b,
0x0b, 0xcc, 0x47, 0x85, 0xe1, 0x8b, 0xea, 0xe4, 0xec, 0x2d, 0xb5, 0x88, 0x0a, 0xc3, 0x97, 0xd4,
0x65, 0xd7, 0xa9, 0x77, 0x78, 0x54, 0xb4, 0x2a, 0xa8, 0x69, 0x54, 0x1a, 0x79, 0x5a, 0x49, 0x2b,
0x60, 0x8a, 0xe4, 0xb9, 0x45, 0xa5, 0x91, 0xeb, 0x5d, 0x43, 0x9a, 0x47, 0x1e, 0x95, 0x45, 0x6e,
0x76, 0x0d, 0x2d, 0x35, 0x8c, 0x0a, 0x23, 0xb7, 0xbb, 0x86, 0x19, 0x35, 0x8c, 0x0a, 0x23, 0x0f,
0xdb, 0xc7, 0x66, 0xf0, 0x89, 0xf2, 0xa8, 0x48, 0x72, 0x57, 0xfd, 0x5e, 0x7f, 0x42, 0x93, 0xa8,
0x3c, 0x72, 0x5f, 0xbd, 0x6d, 0x37, 0x2d, 0x29, 0xc7, 0x51, 0x1e, 0x77, 0x66, 0xf3, 0xea, 0xe2,
0x6e, 0xb5, 0x22, 0xff, 0x7b, 0xdb, 0x36, 0x2a, 0x8f, 0xbc, 0x80, 0xbf, 0xda, 0x7d, 0xa9, 0x1f,
0xa9, 0xd5, 0x48, 0x26, 0xc0, 0xd9, 0x38, 0x20, 0xd8, 0x85, 0x13, 0x17, 0xa4, 0x1a, 0x7d, 0xdb,
0xac, 0x96, 0xd7, 0xf5, 0xfa, 0x51, 0x89, 0x8a, 0x6e, 0x56, 0xea, 0xa5, 0x3c, 0xa4, 0x58, 0x62,
0xc6, 0xf0, 0xff, 0x16, 0x67, 0xba, 0xa0, 0x30, 0xa2, 0xe2, 0xd8, 0xf1, 0xe5, 0x0b, 0x39, 0x57,
0x7d, 0xeb, 0x02, 0x8a, 0x9d, 0x4e, 0xf0, 0x3c, 0xeb, 0x83, 0x2f, 0x30, 0x3f, 0x04, 0x55, 0x3b,
0xf8, 0x0a, 0xfb, 0x03, 0x34, 0xe9, 0x8e, 0xa6, 0x71, 0xf0, 0x25, 0xd9, 0x0f, 0xb4, 0x65, 0xd7,
0xf7, 0xea, 0xec, 0xc5, 0xc5, 0xee, 0x1a, 0x62, 0xc0, 0x37, 0x2e, 0x73, 0x74, 0x19, 0xb1, 0x2d,
0xf4, 0x06, 0x76, 0xcd, 0x86, 0x3a, 0xc4, 0xc1, 0x37, 0xf7, 0x1f, 0x04, 0xaf, 0x7a, 0x5d, 0xf7,
0x1b, 0xbc, 0xdf, 0x3d, 0x28, 0xe7, 0xfe, 0x60, 0xee, 0xf5, 0xd9, 0x28, 0x98, 0x3b, 0x7b, 0x2e,
0x98, 0xfb, 0xa5, 0xbd, 0xa9, 0xc9, 0xb4, 0x45, 0x43, 0xb9, 0xc1, 0x48, 0x3d, 0x52, 0x2c, 0x1a,
0x8d, 0xe6, 0x86, 0xe1, 0x4b, 0xa4, 0xf5, 0x7e, 0xd9, 0x3d, 0x46, 0xa3, 0xba, 0x13, 0x32, 0x76,
0xd7, 0x0a, 0xef, 0xc3, 0x19, 0x18, 0xbc, 0x7f, 0xfb, 0x63, 0xb6, 0x30, 0xbd, 0xfe, 0x39, 0x82,
0x6e, 0x47, 0x70, 0x77, 0x41, 0x34, 0xca, 0x3b, 0xab, 0xd7, 0x9b, 0x18, 0x25, 0x32, 0x50, 0xdd,
0xea, 0xe1, 0x3a, 0x1a, 0xdb, 0xfd, 0x5e, 0x7f, 0xae, 0xa3, 0x21, 0xdd, 0xfb, 0xa6, 0xad, 0x97,
0xf1, 0x60, 0xee, 0xf5, 0x6a, 0xdd, 0xf6, 0x51, 0x1e, 0xeb, 0x21, 0x22, 0x8c, 0x07, 0x71, 0x83,
0x0b, 0x8c, 0x77, 0xb3, 0xdd, 0xc7, 0xe4, 0x40, 0x91, 0xdc, 0xc5, 0xc3, 0xb2, 0x6f, 0xa3, 0x1d,
0x65, 0xd5, 0xf9, 0xe2, 0x73, 0xbb, 0xbc, 0x6e, 0xbb, 0x2e, 0x1e, 0xc1, 0x51, 0x64, 0xde, 0x7e,
0x8d, 0x76, 0xe1, 0xe1, 0x4b, 0xaa, 0x7f, 0x2a, 0x78, 0x93, 0xf1, 0xc8, 0xed, 0x3f, 0xfc, 0x3c,
0xfe, 0xd5, 0x43, 0x74, 0x24, 0x05, 0x85, 0x12, 0x75, 0xb7, 0xba, 0x25, 0xef, 0x30, 0x1e, 0xac,
0x5d, 0xdc, 0xc3, 0x99, 0x8f, 0xc7, 0x68, 0x67, 0xa4, 0x09, 0x6d, 0x6c, 0x26, 0x88, 0xce, 0x98,
0x19, 0x26, 0x1e, 0x94, 0x9d, 0xb4, 0x6d, 0x13, 0xa5, 0x6f, 0xab, 0x7f, 0x2f, 0x96, 0x9b, 0xfa,
0x36, 0xba, 0xea, 0x33, 0xd2, 0x9d, 0x7b, 0x3c, 0xac, 0x77, 0x1d, 0x6d, 0x02, 0x7b, 0xbd, 0xbc,
0xee, 0x9b, 0x3a, 0x2a, 0x33, 0xc4, 0x5e, 0x6d, 0x1d, 0x1f, 0x05, 0x59, 0xea, 0x8f, 0xed, 0xfa,
0x2a, 0x2a, 0x53, 0x0a, 0xb7, 0x7e, 0x8b, 0xab, 0x2f, 0x05, 0x5a, 0x38, 0xeb, 0xb3, 0x78, 0x88,
0xf5, 0xcb, 0xfa, 0xf1, 0x4b, 0x94, 0x3a, 0x85, 0x55, 0xff, 0x7a, 0x88, 0x71, 0x98, 0x22, 0xa9,
0x5f, 0xd7, 0xcf, 0xb2, 0x88, 0x82, 0xa8, 0xf3, 0xf6, 0xcb, 0xc7, 0x45, 0x3c, 0x70, 0xba, 0x6c,
0xd7, 0x9b, 0x45, 0xdc, 0x0a, 0x58, 0x71, 0xd1, 0xe3, 0x51, 0xd2, 0x9b, 0xa6, 0xbd, 0x79, 0xa6,
0x01, 0xe9, 0xf4, 0x63, 0xbd, 0x8c, 0x9e, 0x2e, 0xc4, 0x3d, 0x54, 0x67, 0xb4, 0xf3, 0xc6, 0xa3,
0xa2, 0x57, 0x0f, 0x9b, 0x87, 0xbb, 0x98, 0x72, 0x53, 0x34, 0xf4, 0x96, 0x18, 0x40, 0x5c, 0x88,
0x07, 0x42, 0xd4, 0x60, 0xdd, 0xc6, 0x0c, 0x0b, 0xc5, 0x3f, 0xa4, 0x2d, 0x77, 0xf5, 0x6d, 0x3c,
0xee, 0xa1, 0xf3, 0x57, 0xdd, 0x43, 0x3c, 0xda, 0x79, 0x2f, 0x40, 0xec, 0x3f, 0xd5, 0x65, 0x5b,
0xc7, 0x84, 0x45, 0x64, 0x2e, 0x17, 0xf5, 0x5d, 0x1d, 0x93, 0x34, 0x91, 0x79, 0x75, 0xbf, 0x5e,
0x90, 0x57, 0x05, 0x8e, 0xec, 0xdb, 0xe5, 0x67, 0xa0, 0xf0, 0x87, 0x43, 0x40, 0xe1, 0x80, 0xd5,
0x5e, 0xdc, 0xb7, 0xed, 0xf5, 0x53, 0x54, 0xf8, 0xc3, 0xa1, 0xa8, 0xf0, 0x87, 0x3d, 0xe0, 0xf8,
0x9b, 0xbf, 0xd0, 0xff, 0x9b, 0xe5, 0xa6, 0x5d, 0xf6, 0x8b, 0xcd, 0xe3, 0x93, 0x31, 0xbc, 0xf9,
0x9e, 0x31, 0xcc, 0xf0, 0xe9, 0xb3, 0x29, 0x3e, 0xfd, 0xba, 0xfe, 0xbc, 0x5a, 0x03, 0x0b, 0x3f,
0x23, 0x9b, 0xdf, 0x6e, 0xfa, 0x27, 0x18, 0xf5, 0x7d, 0xdf, 0x6d, 0x3d, 0x00, 0x7e, 0x29, 0x1c,
0xbf, 0x0e, 0x2d, 0x86, 0x52, 0xcf, 0x6a, 0x69, 0x62, 0xd9, 0xc3, 0xfb, 0x11, 0x1c, 0x1c, 0x5e,
0xbb, 0xf7, 0x77, 0x41, 0xeb, 0xfb, 0x7e, 0xf9, 0x94, 0xe8, 0xdf, 0x05, 0xae, 0xef, 0xfb, 0x7e,
0x3a, 0x79, 0x7e, 0xb7, 0xf3, 0x73, 0x34, 0x47, 0xd5, 0x11, 0x33, 0x92, 0x60, 0xac, 0x48, 0x9e,
0x09, 0xbf, 0x09, 0xae, 0xcf, 0x6b, 0x35, 0x7a, 0x83, 0xc3, 0xb0, 0x9b, 0xb0, 0x78, 0x75, 0x10,
0x6f, 0x90, 0xee, 0xce, 0x73, 0x3d, 0xc5, 0x78, 0xd4, 0x96, 0xd7, 0x70, 0xc3, 0xea, 0xfb, 0xfb,
0xee, 0x71, 0xb2, 0xb2, 0xf8, 0xf4, 0xd5, 0xea, 0x4f, 0x15, 0xde, 0x4f, 0x15, 0xd2, 0x88, 0xa7,
0x95, 0xb8, 0xba, 0x3f, 0x1e, 0xd0, 0xf8, 0x35, 0x35, 0x6e, 0x79, 0x4d, 0xf6, 0x8a, 0x36, 0x86,
0xfd, 0x57, 0x70, 0xcb, 0x13, 0x6a, 0x79, 0xb5, 0xcd, 0x35, 0x1e, 0xef, 0x46, 0x0a, 0x3f, 0x4c,
0x6d, 0x3e, 0xae, 0x57, 0x0f, 0xb7, 0x1f, 0xd5, 0xbd, 0x2c, 0x31, 0xb5, 0x63, 0x43, 0xf3, 0xa8,
0x85, 0xc0, 0x99, 0x3e, 0x98, 0x0d, 0xec, 0xa4, 0x8f, 0x28, 0x98, 0x40, 0xc1, 0xec, 0xa1, 0xe0,
0xf6, 0x52, 0xf8, 0x51, 0x7d, 0x02, 0x5a, 0x85, 0x8d, 0x4c, 0x21, 0x79, 0x32, 0xa6, 0x76, 0x19,
0xa8, 0x5d, 0xee, 0x1b, 0x8f, 0x71, 0xa2, 0x78, 0x4e, 0x34, 0xcf, 0x3b, 0xd4, 0x02, 0x04, 0xa2,
0x77, 0xfd, 0x4f, 0xcf, 0x30, 0xe8, 0xf4, 0x3f, 0xdb, 0x75, 0xc4, 0xaf, 0x12, 0x1b, 0x65, 0x35,
0x9e, 0xf1, 0xb8, 0xcf, 0xa9, 0xe1, 0x2b, 0x96, 0xec, 0x15, 0xc5, 0x3f, 0x24, 0xb8, 0xe5, 0xcd,
0xe2, 0x76, 0xe7, 0x6b, 0x83, 0xc4, 0x4c, 0xbb, 0xdf, 0x4d, 0xb5, 0xfb, 0x72, 0x71, 0x47, 0xc2,
0xe4, 0x6d, 0xe3, 0x89, 0x62, 0x2f, 0x27, 0xe9, 0x6b, 0xbc, 0x51, 0xf0, 0x2f, 0x16, 0x14, 0x6c,
0x29, 0x02, 0x6c, 0x7a, 0xa8, 0x3b, 0x1a, 0xe6, 0xf5, 0xe2, 0x4e, 0x41, 0x03, 0x0e, 0x58, 0x5c,
0xef, 0x4e, 0xe5, 0x62, 0xdd, 0x53, 0x18, 0xc6, 0xaf, 0xe0, 0x50, 0xbc, 0x38, 0xae, 0x87, 0x04,
0xe1, 0x11, 0x2a, 0x40, 0x1c, 0xb1, 0xfb, 0x87, 0x1f, 0x95, 0xa1, 0xd5, 0xc7, 0x67, 0x37, 0xf5,
0xfa, 0x96, 0x1c, 0xe7, 0xf1, 0x5a, 0xdb, 0xda, 0xd8, 0x77, 0x07, 0xd8, 0xd8, 0x5f, 0x62, 0xe9,
0xc7, 0x77, 0x5b, 0x44, 0x64, 0xb2, 0x64, 0x76, 0xca, 0x37, 0x33, 0xe8, 0x97, 0x87, 0x18, 0xf4,
0x4b, 0x19, 0xed, 0x2e, 0x0b, 0xff, 0x74, 0x57, 0xb9, 0x7c, 0xd6, 0xa2, 0x4f, 0x6c, 0xb8, 0x98,
0x90, 0x17, 0xa8, 0x0a, 0xd8, 0xfe, 0x22, 0xef, 0x2c, 0x92, 0x6a, 0x84, 0x1b, 0x85, 0x17, 0x5c,
0xd6, 0x57, 0xe4, 0xc8, 0xfe, 0x74, 0xd5, 0xd5, 0xcb, 0x4f, 0xd4, 0x4a, 0xce, 0xd3, 0x3f, 0x78,
0x69, 0x03, 0xde, 0xe0, 0xb0, 0xb9, 0xeb, 0xaa, 0xff, 0x07, 0x89, 0xc6, 0x88, 0x77, 0x0c, 0x8c,
};

1286
wled00/html_mobile.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@ const char PAGE_usermod[] PROGMEM = R"=====(
//server message //server message
const char PAGE_msg0[] PROGMEM = R"=====( const char PAGE_msg0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head><meta content='width=device-width' name='viewport'>
<title>WLED Message</title> <title>WLED Message</title>
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script> <script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script>
)====="; )=====";
@ -27,12 +27,12 @@ button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-seri
#ifndef WLED_DISABLE_MOBILE_UI #ifndef WLED_DISABLE_MOBILE_UI
const char PAGE_welcome0[] PROGMEM = R"=====( const char PAGE_welcome0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head><meta content='width=device-width' name='viewport'>
<title>WLED Welcome!</title> <title>WLED Welcome!</title>
)====="; )=====";
const char PAGE_welcome1[] PROGMEM = R"=====( const char PAGE_welcome1[] PROGMEM = R"=====(
body{font-family:var(--cFn),sans-serif;text-align:center;background:linear-gradient(var(--bCol),black);height:100%;margin:0;background-repeat:no-repeat;background-attachment: fixed;color: var(--tCol);}svg {fill: var(--dCol);} body{font-family:var(--cFn),sans-serif;text-align:center;background:linear-gradient(var(--bCol),black);margin:0;background-attachment: fixed;color: var(--tCol);}svg {fill: var(--dCol);}
</style></head> </style></head>
<body> <body>
<svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg"> <svg style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg">

View File

@ -4,7 +4,7 @@
//common CSS of settings pages //common CSS of settings pages
const char PAGE_settingsCss[] PROGMEM = R"=====( const char PAGE_settingsCss[] PROGMEM = R"=====(
body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:3em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}</style> body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}hr{border-color:var(--dCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}.helpB{text-align:left;position:absolute;width:60px}input{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.5ch solid var(--bCol);filter:drop-shadow(-5px -5px 5px var(--sCol))}input[type=number]{width:4em}select{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:0.5ch solid var(--bCol);filter:drop-shadow( -5px -5px 5px var(--sCol) );}</style>
)====="; )=====";
@ -34,7 +34,7 @@ body{text-align:center;background:var(--cCol);height:100%;margin:0;background-at
//wifi settings //wifi settings
const char PAGE_settings_wifi0[] PROGMEM = R"=====( const char PAGE_settings_wifi0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head><meta name="viewport" content="width=500">
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d = document; <title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d = document;
)====="; )=====";
@ -83,44 +83,63 @@ AP IP: <span class="sip"> Not active </span><hr>
//LED settings //LED settings
const char PAGE_settings_leds0[] PROGMEM = R"=====( const char PAGE_settings_leds0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head><meta name="viewport" content="width=500">
<title>LED Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}function B(){window.history.back();}function GetV(){var d = document; <title>LED Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#led-settings");}function B(){window.history.back();}function S(){GetV();UI();}function UI(){
var myC=document.querySelectorAll('.wc'),l=myC.length;
for (i = 0; i < l; i++){myC[i].style.display=(document.getElementById('rgbw').checked)?'inline':'none';}
var val=Math.ceil((100+document.Sf.LC.value*55)/500)/2;
val=(val>5)?Math.ceil(val):val;var s="";
if (val<1.1){s="ESP 5V pin with 1A USB supply";}else{s="External 5V ";s+=val;s+="A supply connected to LEDs";}
document.getElementById('psu').innerHTML=s;document.getElementById('ps2').innerHTML=val+"A = "+val*1000;
}function GetV(){var d = document;
)====="; )=====";
const char PAGE_settings_leds1[] PROGMEM = R"=====( const char PAGE_settings_leds1[] PROGMEM = R"=====(
</head> </head>
<body onload="GetV()"> <body onload="S()">
<form id="form_s" name="Sf" method="post"> <form id="form_s" name="Sf" method="post">
<div class="helpB"><button type="button" onclick="H()">?</button></div> <div class="helpB"><button type="button" onclick="H()">?</button></div>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr> <button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>LED setup</h2> <h2>LED setup</h2>
LED count: <input name="LC" type="number" min="1" max="1200" required><br> LED count: <input name="LC" type="number" min="1" max="1200" oninput=UI() required><br>
LEDs are 4-channel type (RGBW): <input type="checkbox" name="EW"><br> <i>Recommended power supply for brightest white:</i><br>
<br> <b><span id="psu">?</span></b><br><br>
Apply preset <input name="BP" type="number" min="0" max="25" required> at boot (0 uses defaults)<br> Maximum Current: <input name="MA" type="number" min="250" max="65000" required> mA<br>
Turn on after power up/reset: <input type="checkbox" name="BO"><br> <i>Automatically limits brightness to stay close to the limit.<br>
<br> Keep at &lt;1A if powering LEDs directly from the ESP 5V pin!<br>
If you are using an external 5V supply, enter its rating.<br>
"65000" completely diasbles the power calculation.<br>
(Current estimated usage: <span class="pow">unknown</span>)</i><br><br>
LEDs are 4-channel type (RGBW): <input type="checkbox" name="EW" onchange=UI() id="rgbw"><br>
Color order:
<select name="CO">
<option value="0">GRB</option>
<option value="1">RGB</option>
<option value="2">BRG</option>
<option value="3">RBG</option></select>
<h3>Defaults</h3>
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br><br>
Default RGB color: Default RGB color:
<input name="CR" type="number" min="0" max="255" required> <input name="CR" type="number" min="0" max="255" required>
<input name="CG" type="number" min="0" max="255" required> <input name="CG" type="number" min="0" max="255" required>
<input name="CB" type="number" min="0" max="255" required><br> <input name="CB" type="number" min="0" max="255" required><br>
Default white value (only RGBW): <input name="CW" type="number" min="0" max="255" required><br> <span class="wc">Default white value: <input name="CW" type="number" min="0" max="255" required><br>
Auto-calculate white from RGB instead: <input type="checkbox" name="AW"><br> Auto-calculate white from RGB instead: <input type="checkbox" name="AW"><br></span>
Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br> Default brightness: <input name="CA" type="number" min="0" max="255" required> (0-255)<br>
Default effect ID: <input name="FX" type="number" min="0" max="57" required><br> Default effect ID: <input name="FX" type="number" min="0" max="57" required><br>
Default effect speed: <input name="SX" type="number" min="0" max="255" required><br> Default effect speed: <input name="SX" type="number" min="0" max="255" required><br>
Default effect intensity: <input name="IX" type="number" min="0" max="255" required><br> Default effect intensity: <input name="IX" type="number" min="0" max="255" required><br>
Default effect palette: <input name="FP" type="number" min="0" max="255" required><br> Default effect palette: <input name="FP" type="number" min="0" max="255" required><br>
Default secondary RGB(W):<br> Default secondary RGB<span class="wc">W</span>:<br>
<input name="SR" type="number" min="0" max="255" required> <input name="SR" type="number" min="0" max="255" required>
<input name="SG" type="number" min="0" max="255" required> <input name="SG" type="number" min="0" max="255" required>
<input name="SB" type="number" min="0" max="255" required> <input name="SB" type="number" min="0" max="255" required>
<input name="SW" type="number" min="0" max="255" required><br> <span class="wc"><input name="SW" type="number" min="0" max="255" required></span><br>
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br> Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br><br>
Save current preset cycle configuration as boot default: <input type="checkbox" name="PC"><br> Apply preset <input name="BP" type="number" min="0" max="25" required> at boot (0 uses defaults)<br>
<br> Save current preset cycle configuration as boot default: <input type="checkbox" name="PC"><br><br>
Use Gamma correction for color: <input type="checkbox" name="GC"> (strongly recommended)<br> Use Gamma correction for color: <input type="checkbox" name="GC"> (strongly recommended)<br>
Use Gamma correction for brightness: <input type="checkbox" name="GB"> (not recommended)<br> Use Gamma correction for brightness: <input type="checkbox" name="GB"> (not recommended)<br><br>
Brightness factor: <input name="BF" type="number" min="0" max="255" required> % Brightness factor: <input name="BF" type="number" min="0" max="255" required> %
<h3>Transitions</h3> <h3>Transitions</h3>
Crossfade: <input type="checkbox" name="TF"><br> Crossfade: <input type="checkbox" name="TF"><br>
@ -152,7 +171,7 @@ Skip first LED: <input type="checkbox" name="SL"><hr>
//User Interface settings //User Interface settings
const char PAGE_settings_ui0[] PROGMEM = R"=====( const char PAGE_settings_ui0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head><meta name="viewport" content="width=500">
<title>UI Settings</title><script> <title>UI Settings</title><script>
function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d = document; function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d = document;
)====="; )=====";
@ -188,7 +207,7 @@ Color Theme:
<option value="10">Terminal</option> <option value="10">Terminal</option>
<option value="11">C64</option> <option value="11">C64</option>
<option value="12">Easter</option> <option value="12">Easter</option>
<option value="13">Placeholder</option> <option value="13">Christmas</option>
<option value="14">The End</option> <option value="14">The End</option>
<option value="15" id="co">Custom</option> <option value="15" id="co">Custom</option>
</select><br> </select><br>
@ -212,7 +231,7 @@ Make sure the font you use is installed on your system!<br>
//sync settings //sync settings
const char PAGE_settings_sync0[] PROGMEM = R"=====( const char PAGE_settings_sync0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head><title>Sync Settings</title> <html><head><meta name="viewport" content="width=500"><title>Sync Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d = document; <script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}function GetV(){var d = document;
)====="; )=====";
@ -224,7 +243,9 @@ const char PAGE_settings_sync1[] PROGMEM = R"=====(
<button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr> <button type="button" onclick="B()">Back</button><button type="submit">Save</button><hr>
<h2>Sync setup</h2> <h2>Sync setup</h2>
<h3>Button setup</h3> <h3>Button setup</h3>
On/Off button enabled: <input type="checkbox" name="BT"> On/Off button enabled: <input type="checkbox" name="BT"><br>
Infrared receiver enabled: <input type="checkbox" name="IR"><br>
<a href="https://github.com/Aircoookie/WLED/wiki/Infrared-Control" target="_blank">IR info</a>
<h3>WLED Broadcast</h3> <h3>WLED Broadcast</h3>
UDP Port: <input name="UP" maxlength="5" size="4"><br> UDP Port: <input name="UP" maxlength="5" size="4"><br>
Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br> Receive <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
@ -248,6 +269,10 @@ Enable UI access during realtime: <input type="checkbox" name="RU"> (can cause i
Emulate Alexa device: <input type="checkbox" name="AL"><br> Emulate Alexa device: <input type="checkbox" name="AL"><br>
Alexa invocation name: <input name="AI" maxlength="32"> Alexa invocation name: <input name="AI" maxlength="32">
<h3>Blynk</h3> <h3>Blynk</h3>
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
This impacts the responsiveness of the ESP8266.</b><br>
For best results, only use one of these services at a time.<br>
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
Device Auth token: <input name="BK" maxlength="33"><br> Device Auth token: <input name="BK" maxlength="33"><br>
<i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a> <i>Clear the token field to disable. </i><a href="https://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
<h3>MQTT</h3> <h3>MQTT</h3>
@ -277,7 +302,7 @@ Hue status: <span class="hms"> Internal ESP Error! </span><hr>
//time and macro settings //time and macro settings
const char PAGE_settings_time0[] PROGMEM = R"=====( const char PAGE_settings_time0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head><title>Time Settings</title> <html><head><meta name="viewport" content="width=500"><title>Time Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){GetV();Cs();}function gId(s){return document.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}function GetV(){var d = document; <script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings");}function B(){window.open("/settings","_self");}function S(){GetV();Cs();}function gId(s){return document.getElementById(s);}function Cs(){gId("cac").style.display="none";gId("coc").style.display="block";gId("ccc").style.display="none";if (gId("ca").selected){gId("cac").style.display="block";}if (gId("cc").selected){gId("coc").style.display="none";gId("ccc").style.display="block";}if (gId("cn").selected){gId("coc").style.display="none";}}function GetV(){var d = document;
)====="; )=====";
@ -329,7 +354,8 @@ Cronixie Display: <input name="CX" maxlength="6"><br>
Cronixie Backlight: <input type="checkbox" name="CB"><br> Cronixie Backlight: <input type="checkbox" name="CB"><br>
</div> </div>
Countdown Mode: <input type="checkbox" name="CE"><br> Countdown Mode: <input type="checkbox" name="CE"><br>
Countdown Goal: Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br> Countdown Goal:<br>
Year: 20 <input name="CY" type="number" min="0" max="99" required> Month: <input name="CI" type="number" min="1" max="12" required> Day: <input name="CD" type="number" min="1" max="31" required><br>
Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br> Hour: <input name="CH" type="number" min="0" max="23" required> Minute: <input name="CM" type="number" min="0" max="59" required> Second: <input name="CS" type="number" min="0" max="59" required><br>
<h3>Advanced Macros</h3> <h3>Advanced Macros</h3>
Define API macros here:<br> Define API macros here:<br>
@ -382,7 +408,7 @@ Time-Controlled Macros (Hours/Minutes &gt; Macro):<br>
//security settings and about //security settings and about
const char PAGE_settings_sec0[] PROGMEM = R"=====( const char PAGE_settings_sec0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head><meta name="viewport" content="width=500">
<title>Misc Settings</title> <title>Misc Settings</title>
<script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings");}function B(){window.open("/settings","_self");}function U(){window.open("/update","_self");}function GetV(){var d = document; <script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings");}function B(){window.open("/settings","_self");}function U(){window.open("/update","_self");}function GetV(){var d = document;
)====="; )=====";
@ -411,24 +437,11 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
<button type="button" onclick="U()">Manual OTA Update</button><br> <button type="button" onclick="U()">Manual OTA Update</button><br>
Enable ArduinoOTA: <input type="checkbox" name="AO"><br> Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
<h3>About</h3> <h3>About</h3>
<a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.1<br><br> <a href="https://github.com/Aircoookie/WLED" target="_blank">WLED</a> version 0.8.2<br><br>
<b>Contributors:</b><br> <a href="https://github.com/Aircoookie/WLED/wiki/Contributors-&-About" target="_blank">Contributors, dependencies and special thanks</a><br>
StormPie <i>(Mobile HTML UI)</i><br><br> A huge thank you to everyone who helped me create WLED!<br><br>
Thank you so much!<br><br>
(c) 2016-2018 Christian Schwinne <br> (c) 2016-2018 Christian Schwinne <br>
<i>Licensed under the MIT license</i><br><br> <i>Licensed under the MIT license</i><br><br>
<b>Uses libraries:</b><br>
<i>ESP8266/ESP32 Arduino Core</i><br>
<i><a href="https://github.com/svenihoney/NeoPixelBus" target="_blank">NeoPixelBus</a> by Makuna (svenihoney fork)</i><br>
<i><a href="https://github.com/FastLED/FastLED/" target="_blank">FastLED</a> library</i><br>
<i>(ESP32) <a href="https://github.com/bbx10/WebServer_tng" target="_blank">WebServer_tng</a> by bbx10</i><br>
<i><a href="https://github.com/kitesurfer1404/WS2812FX" target="_blank">WS2812FX</a> by kitesurfer1404 (modified)</i><br>
<i><a href="https://github.com/JChristensen/Timezone" target="_blank">Timezone</a> library by JChristensen</i><br>
<i><a href="https://github.com/blynkkk/blynk-library" target="_blank">Blynk</a> library (compacted)</i><br>
<i><a href="https://github.com/forkineye/E131" target="_blank">E1.31</a> library by forkineye (modified)</i><br>
<i><a href="https://github.com/knolleary/pubsubclient" target="_blank">PubSubClient</a> by knolleary (modified)</i><br>
<i><a href="https://github.com/Aircoookie/Espalexa" target="_blank">Espalexa</a> by Aircoookie (modified)</i><br><br>
<i>UI icons by <a href="https://linearicons.com" target="_blank">Linearicons</a> created by <a href="https://perxis.com" target="_blank">Perxis</a>! (CC-BY-SA 4.0)</i> <br><br>
Server message: <span class="msg"> Response error! </span><hr> Server message: <span class="msg"> Response error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button> <button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
</form> </form>

File diff suppressed because one or more lines are too long

95
wled00/ir_codes.h Normal file
View File

@ -0,0 +1,95 @@
//Infrared codes
//Add your custom codes here
#define IRCUSTOM_ONOFF 0xA55AEA15 //Pioneer RC-975R "+FAV" button (example)
#define IRCUSTOM_MACRO1 0xFFFFFFFF //placeholder, will never be checked for
//Infrared codes for 24-key remote from http://woodsgood.ca/projects/2015/02/13/rgb-led-strip-controllers-ir-codes/
#define IR24_BRIGHTER 0xF700FF
#define IR24_DARKER 0xF7807F
#define IR24_OFF 0xF740BF
#define IR24_ON 0xF7C03F
#define IR24_RED 0xF720DF
#define IR24_REDDISH 0xF710EF
#define IR24_ORANGE 0xF730CF
#define IR24_YELLOWISH 0xF708F7
#define IR24_YELLOW 0xF728D7
#define IR24_GREEN 0xF7A05F
#define IR24_GREENISH 0xF7906F
#define IR24_TURQUOISE 0xF7B04F
#define IR24_CYAN 0xF78877
#define IR24_AQUA 0xF7A857
#define IR24_BLUE 0xF7609F
#define IR24_DEEPBLUE 0xF750AF
#define IR24_PURPLE 0xF7708F
#define IR24_MAGENTA 0xF748B7
#define IR24_PINK 0xF76897
#define IR24_WHITE 0xF7E01F
#define IR24_FLASH 0xF7D02F
#define IR24_STROBE 0xF7F00F
#define IR24_FADE 0xF7C837
#define IR24_SMOOTH 0xF7E817
/* 44-key defs, to be done later
#define IR44_BPlus 0xFF3AC5 //
#define IR44_BMinus 0xFFBA45 //
#define IR44_ON 0xFF827D //
#define IR44_OFF 0xFF02FD //
#define IR44_R 0xFF1AE5 //
#define IR44_G 0xFF9A65 //
#define IR44_B 0xFFA25D //
#define IR44_W 0xFF22DD //
#define IR44_B1 0xFF2AD5 //
#define IR44_B2 0xFFAA55 //
#define IR44_B3 0xFF926D //
#define IR44_B4 0xFF12ED //
#define IR44_B5 0xFF0AF5 //
#define IR44_B6 0xFF8A75 //
#define IR44_B7 0xFFB24D //
#define IR44_B8 0xFF32CD //
#define IR44_B9 0xFF38C7 //
#define IR44_B10 0xFFB847 //
#define IR44_B11 0xFF7887 //
#define IR44_B12 0xFFF807 //
#define IR44_B13 0xFF18E7 //
#define IR44_B14 0xFF9867 //
#define IR44_B15 0xFF58A7 //
#define IR44_B16 0xFFD827 //
#define IR44_UPR 0xFF28D7 //
#define IR44_UPG 0xFFA857 //
#define IR44_UPB 0xFF6897 //
#define IR44_QUICK 0xFFE817 //
#define IR44_DOWNR 0xFF08F7 //
#define IR44_DOWNG 0xFF8877 //
#define IR44_DOWNB 0xFF48B7 //
#define IR44_SLOW 0xFFC837 //
#define IR44_DIY1 0xFF30CF //
#define IR44_DIY2 0xFFB04F //
#define IR44_DIY3 0xFF708F //
#define IR44_AUTO 0xFFF00F //
#define IR44_DIY4 0xFF10EF //
#define IR44_DIY5 0xFF906F //
#define IR44_DIY6 0xFF50AF //
#define IR44_FLASH 0xFFD02F //
#define IR44_JUMP3 0xFF20DF //
#define IR44_JUMP7 0xFFA05F //
#define IR44_FADE3 0xFF609F //
#define IR44_FADE7 0xFFE01F //
*/
#define COLOR_RED 0xFF0000
#define COLOR_REDDISH 0xFF7800
#define COLOR_ORANGE 0xFFA000
#define COLOR_YELLOWISH 0xFFC800
#define COLOR_YELLOW 0xFFFF00
#define COLOR_GREEN 0x00FF00
#define COLOR_GREENISH 0x00FF78
#define COLOR_TURQUOISE 0x00FFA0
#define COLOR_CYAN 0x00FFDC
#define COLOR_AQUA 0x00C8FF
#define COLOR_BLUE 0x00A0FF
#define COLOR_DEEPBLUE 0x0000FF
#define COLOR_PURPLE 0xAA00FF
#define COLOR_MAGENTA 0xFF00DC
#define COLOR_PINK 0xFF00A0
#define COLOR_WHITE 0xFFFFDC

View File

@ -3,7 +3,7 @@
*/ */
/* /*
* @title WLED project sketch * @title WLED project sketch
* @version 0.8.1 * @version 0.8.2
* @author Christian Schwinne * @author Christian Schwinne
*/ */
@ -11,21 +11,22 @@
//ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS). //ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS).
//ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS). //ESP8266-01 (black) has 1MB flash and can thus fit the whole program. Use 1M(64K SPIFFS).
//If you want the OTA update function though, you need to make sure the sketch is smaller than 479kB.
//Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB): //Uncomment some of the following lines to disable features to compile for ESP8266-01 (max flash size 434kB):
//You are required to disable these two features: //You are required to disable over-the-air updates:
//#define WLED_DISABLE_MOBILE_UI #define WLED_DISABLE_OTA
//#define WLED_DISABLE_OTA
//You need to choose 1-2 of these features to disable: //You need to choose 1-2 of these features to disable:
//#define WLED_DISABLE_ALEXA //#define WLED_DISABLE_ALEXA
//#define WLED_DISABLE_BLYNK //#define WLED_DISABLE_BLYNK
//#define WLED_DISABLE_CRONIXIE //#define WLED_DISABLE_CRONIXIE
//#define WLED_DISABLE_HUESYNC #define WLED_DISABLE_HUESYNC
#define WLED_DISABLE_INFRARED //there is no pin left for this on ESP8266-01
//#define WLED_DISABLE_MOBILE_UI
//to toggle usb serial debug (un)comment following line(s) //to toggle usb serial debug (un)comment following line(s)
//#define DEBUG //#define WLED_DEBUG
//library inclusions //library inclusions
#include <Arduino.h> #include <Arduino.h>
@ -34,11 +35,19 @@
#include <ESPmDNS.h> #include <ESPmDNS.h>
#include "src/dependencies/webserver/WebServer.h" #include "src/dependencies/webserver/WebServer.h"
#include <HTTPClient.h> #include <HTTPClient.h>
/*#ifndef WLED_DISABLE_INFRARED
#include <IRremote.h>
#endif*/ //there are issues with ESP32 infrared, so it is disabled for now
#else #else
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESP8266mDNS.h> #include <ESP8266mDNS.h>
#include <ESP8266WebServer.h> #include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h> #include <ESP8266HTTPClient.h>
#ifndef WLED_DISABLE_INFRARED
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#endif
#endif #endif
#include <EEPROM.h> #include <EEPROM.h>
@ -56,15 +65,17 @@
#endif #endif
#include "src/dependencies/e131/E131.h" #include "src/dependencies/e131/E131.h"
#include "src/dependencies/pubsubclient/PubSubClient.h" #include "src/dependencies/pubsubclient/PubSubClient.h"
#include "htmls00.h" #include "html_classic.h"
#include "htmls01.h" #include "html_mobile.h"
#include "htmls02.h" #include "html_settings.h"
#include "html_other.h"
#include "WS2812FX.h" #include "WS2812FX.h"
#include "ir_codes.h"
//version code in format yymmddb (b = daily build) //version code in format yymmddb (b = daily build)
#define VERSION 1811091 #define VERSION 1812052
char versionString[] = "0.8.1"; char versionString[] = "0.8.2";
//AP and OTA default passwords (for maximum change them!) //AP and OTA default passwords (for maximum change them!)
@ -77,9 +88,8 @@ char otaPass[33] = "wledota";
//Hardware CONFIG (only changeble HERE, not at runtime) //Hardware CONFIG (only changeble HERE, not at runtime)
//LED strip pin changeable in NpbWrapper.h. Only change for ESP32 //LED strip pin, button pin and IR pin changeable in NpbWrapper.h!
byte buttonPin = 0; //needs pull-up
byte auxPin = 15; //debug feature, use e.g. for external relay with API call AX=
byte auxDefaultState = 0; //0: input 1: high 2: low byte auxDefaultState = 0; //0: input 1: high 2: low
byte auxTriggeredState = 0; //0: input 1: high 2: low byte auxTriggeredState = 0; //0: input 1: high 2: low
char ntpServerName[] = "0.wled.pool.ntp.org"; //NTP server to use char ntpServerName[] = "0.wled.pool.ntp.org"; //NTP server to use
@ -101,9 +111,10 @@ IPAddress staticDNS(8, 8, 8, 8); //only for NTP, google DNS server
//LED CONFIG //LED CONFIG
uint16_t ledCount = 10; //lowered to prevent accidental overcurrent uint16_t ledCount = 30; //overcurrent prevented by ABL
bool useRGBW = false; //SK6812 strips can contain an extra White channel bool useRGBW = false; //SK6812 strips can contain an extra White channel
bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White channel from RGB bool autoRGBtoRGBW = false; //if RGBW enabled, calculate White channel from RGB
#define ABL_MILLIAMPS_DEFAULT 850; //auto lower brightness to stay close to milliampere limit
bool turnOnAtBoot = true; //turn on LEDs at power-up bool turnOnAtBoot = true; //turn on LEDs at power-up
byte bootPreset = 0; //save preset to load after power-up byte bootPreset = 0; //save preset to load after power-up
@ -145,6 +156,7 @@ bool useHSBDefault = useHSB;
//Sync CONFIG //Sync CONFIG
bool buttonEnabled = true; bool buttonEnabled = true;
bool irEnabled = false; //Infrared receiver
uint16_t udpPort = 21324; //WLED notifier default port uint16_t udpPort = 21324; //WLED notifier default port
uint16_t udpRgbPort = 19446; //Hyperion port uint16_t udpRgbPort = 19446; //Hyperion port
@ -153,7 +165,7 @@ bool receiveNotificationBrightness = true; //apply brightness from incoming n
bool receiveNotificationColor = true; //apply color bool receiveNotificationColor = true; //apply color
bool receiveNotificationEffects = true; //apply effects setup bool receiveNotificationEffects = true; //apply effects setup
bool notifyDirect = true; //send notification if change via UI or HTTP API bool notifyDirect = true; //send notification if change via UI or HTTP API
bool notifyButton = true; bool notifyButton = true; //send if updated by button or infrared remote
bool notifyAlexa = false; //send notification if updated via Alexa bool notifyAlexa = false; //send notification if updated via Alexa
bool notifyMacro = false; //send notification for macro bool notifyMacro = false; //send notification for macro
bool notifyHue = true; //send notification if Hue light changes bool notifyHue = true; //send notification if Hue light changes
@ -254,6 +266,7 @@ float tperLast = 0; //crossfade transition progress, 0
bool nightlightActive = false; bool nightlightActive = false;
bool nightlightActiveOld = false; bool nightlightActiveOld = false;
uint32_t nightlightDelayMs = 10; uint32_t nightlightDelayMs = 10;
uint8_t nightlightDelayMinsDefault = nightlightDelayMins;
unsigned long nightlightStartTime; unsigned long nightlightStartTime;
byte briNlT = 0; //current nightlight brightness byte briNlT = 0; //current nightlight brightness
@ -287,7 +300,6 @@ bool udpConnected = false, udpRgbConnected = false;
//ui style //ui style
char cssCol[6][9]={"","","","","",""}; char cssCol[6][9]={"","","","","",""};
String cssColorString="";
bool showWelcomePage = false; bool showWelcomePage = false;
//hue //hue
@ -335,7 +347,7 @@ bool presetCyclingEnabled = false;
byte presetCycleMin = 1, presetCycleMax = 5; byte presetCycleMin = 1, presetCycleMax = 5;
uint16_t presetCycleTime = 1250; uint16_t presetCycleTime = 1250;
unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin;
bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true; bool presetApplyBri = false, presetApplyCol = true, presetApplyFx = true;
bool saveCurrPresetCycConf = false; bool saveCurrPresetCycConf = false;
//realtime //realtime
@ -376,7 +388,7 @@ unsigned int ntpLocalPort = 2390;
#define NTP_PACKET_SIZE 48 #define NTP_PACKET_SIZE 48
//string temp buffer //string temp buffer
#define OMAX 1750 #define OMAX 2000
char obuf[OMAX]; char obuf[OMAX];
uint16_t olen = 0; uint16_t olen = 0;
@ -403,7 +415,7 @@ E131* e131;
WS2812FX strip = WS2812FX(); WS2812FX strip = WS2812FX();
//debug macros //debug macros
#ifdef DEBUG #ifdef WLED_DEBUG
#define DEBUG_PRINT(x) Serial.print (x) #define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTLN(x) Serial.println (x) #define DEBUG_PRINTLN(x) Serial.println (x)
#define DEBUG_PRINTF(x) Serial.printf (x) #define DEBUG_PRINTF(x) Serial.printf (x)
@ -493,6 +505,7 @@ void loop() {
yield(); yield();
handleButton(); handleButton();
handleIR();
handleNetworkTime(); handleNetworkTime();
if (!onlyAP) if (!onlyAP)
{ {
@ -519,7 +532,7 @@ void loop() {
} }
//DEBUG serial logging //DEBUG serial logging
#ifdef DEBUG #ifdef WLED_DEBUG
if (millis() - debugTime > 5000) if (millis() - debugTime > 5000)
{ {
DEBUG_PRINTLN("---MODULE DEBUG INFO---"); DEBUG_PRINTLN("---MODULE DEBUG INFO---");

View File

@ -6,7 +6,7 @@
#define EEPSIZE 3072 #define EEPSIZE 3072
//eeprom Version code, enables default settings instead of 0 init on update //eeprom Version code, enables default settings instead of 0 init on update
#define EEPVER 9 #define EEPVER 10
//0 -> old version, default //0 -> old version, default
//1 -> 0.4p 1711272 and up //1 -> 0.4p 1711272 and up
//2 -> 0.4p 1711302 and up //2 -> 0.4p 1711302 and up
@ -17,6 +17,8 @@
//7 -> 0.7.1 and up //7 -> 0.7.1 and up
//8 -> 0.8.0-a and up //8 -> 0.8.0-a and up
//9 -> 0.8.0 //9 -> 0.8.0
//10-> 0.8.2
/* /*
* Erase all configuration data * Erase all configuration data
@ -30,6 +32,7 @@ void clearEEPROM()
EEPROM.commit(); EEPROM.commit();
} }
void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len) void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len)
{ {
for (int i = 0; i < len; ++i) for (int i = 0; i < len; ++i)
@ -39,6 +42,7 @@ void writeStringToEEPROM(uint16_t pos, char* str, uint16_t len)
} }
} }
void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len) void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len)
{ {
for (int i = 0; i < len; ++i) for (int i = 0; i < len; ++i)
@ -49,6 +53,7 @@ void readStringFromEEPROM(uint16_t pos, char* str, uint16_t len)
str[len] = 0; //make sure every string is properly terminated. str must be at least len +1 big. str[len] = 0; //make sure every string is properly terminated. str must be at least len +1 big.
} }
/* /*
* Write configuration to flash * Write configuration to flash
*/ */
@ -66,12 +71,12 @@ void saveSettingsToEEPROM()
writeStringToEEPROM(128, apSSID, 32); writeStringToEEPROM(128, apSSID, 32);
writeStringToEEPROM(160, apPass, 64); writeStringToEEPROM(160, apPass, 64);
EEPROM.write(224, nightlightDelayMins); EEPROM.write(224, nightlightDelayMinsDefault);
EEPROM.write(225, nightlightFade); EEPROM.write(225, nightlightFade);
EEPROM.write(226, notifyDirectDefault); EEPROM.write(226, notifyDirectDefault);
EEPROM.write(227, apChannel); EEPROM.write(227, apChannel);
EEPROM.write(228, apHide); EEPROM.write(228, apHide);
EEPROM.write(229, (ledCount >> 0) & 0xFF); EEPROM.write(229, ledCount & 0xFF);
EEPROM.write(230, notifyButton); EEPROM.write(230, notifyButton);
EEPROM.write(231, notifyTwice); EEPROM.write(231, notifyTwice);
EEPROM.write(232, buttonEnabled); EEPROM.write(232, buttonEnabled);
@ -92,7 +97,7 @@ void saveSettingsToEEPROM()
EEPROM.write(250, receiveNotificationBrightness); EEPROM.write(250, receiveNotificationBrightness);
EEPROM.write(251, fadeTransition); EEPROM.write(251, fadeTransition);
EEPROM.write(252, reverseMode); EEPROM.write(252, reverseMode);
EEPROM.write(253, (transitionDelayDefault >> 0) & 0xFF); EEPROM.write(253, transitionDelayDefault & 0xFF);
EEPROM.write(254, (transitionDelayDefault >> 8) & 0xFF); EEPROM.write(254, (transitionDelayDefault >> 8) & 0xFF);
EEPROM.write(255, briMultiplier); EEPROM.write(255, briMultiplier);
@ -101,7 +106,7 @@ void saveSettingsToEEPROM()
EEPROM.write(288, nightlightTargetBri); EEPROM.write(288, nightlightTargetBri);
EEPROM.write(289, otaLock); EEPROM.write(289, otaLock);
EEPROM.write(290, (udpPort >> 0) & 0xFF); EEPROM.write(290, udpPort & 0xFF);
EEPROM.write(291, (udpPort >> 8) & 0xFF); EEPROM.write(291, (udpPort >> 8) & 0xFF);
writeStringToEEPROM(292, serverDescription, 32); writeStringToEEPROM(292, serverDescription, 32);
@ -138,14 +143,19 @@ void saveSettingsToEEPROM()
EEPROM.write(380, colSecS[2]); EEPROM.write(380, colSecS[2]);
EEPROM.write(381, whiteSecS); EEPROM.write(381, whiteSecS);
EEPROM.write(382, strip.paletteBlend); EEPROM.write(382, strip.paletteBlend);
EEPROM.write(383, strip.colorOrder);
EEPROM.write(385, irEnabled);
EEPROM.write(387, strip.ablMilliampsMax & 0xFF);
EEPROM.write(388, (strip.ablMilliampsMax >> 8) & 0xFF);
EEPROM.write(389, bootPreset); EEPROM.write(389, bootPreset);
EEPROM.write(390, aOtaEnabled); EEPROM.write(390, aOtaEnabled);
EEPROM.write(391, receiveNotificationColor); EEPROM.write(391, receiveNotificationColor);
EEPROM.write(392, receiveNotificationEffects); EEPROM.write(392, receiveNotificationEffects);
EEPROM.write(393, wifiLock); EEPROM.write(393, wifiLock);
EEPROM.write(394, (abs(utcOffsetSecs) >> 0) & 0xFF); EEPROM.write(394, abs(utcOffsetSecs) & 0xFF);
EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF); EEPROM.write(395, (abs(utcOffsetSecs) >> 8) & 0xFF);
EEPROM.write(396, (utcOffsetSecs<0)); //is negative EEPROM.write(396, (utcOffsetSecs<0)); //is negative
EEPROM.write(397, initLedsLast); EEPROM.write(397, initLedsLast);
@ -170,7 +180,7 @@ void saveSettingsToEEPROM()
EEPROM.write(i, hueIP[i-2050]); EEPROM.write(i, hueIP[i-2050]);
} }
writeStringToEEPROM(2054, hueApiKey, 46); writeStringToEEPROM(2054, hueApiKey, 46);
EEPROM.write(2100, (huePollIntervalMs >> 0) & 0xFF); EEPROM.write(2100, huePollIntervalMs & 0xFF);
EEPROM.write(2101, (huePollIntervalMs >> 8) & 0xFF); EEPROM.write(2101, (huePollIntervalMs >> 8) & 0xFF);
EEPROM.write(2102, notifyHue); EEPROM.write(2102, notifyHue);
EEPROM.write(2103, hueApplyOnOff); EEPROM.write(2103, hueApplyOnOff);
@ -205,10 +215,10 @@ void saveSettingsToEEPROM()
EEPROM.write(2180, macroCountdown); EEPROM.write(2180, macroCountdown);
EEPROM.write(2181, macroNl); EEPROM.write(2181, macroNl);
EEPROM.write(2190, (e131Universe >> 0) & 0xFF); EEPROM.write(2190, e131Universe & 0xFF);
EEPROM.write(2191, (e131Universe >> 8) & 0xFF); EEPROM.write(2191, (e131Universe >> 8) & 0xFF);
EEPROM.write(2192, e131Multicast); EEPROM.write(2192, e131Multicast);
EEPROM.write(2193, (realtimeTimeoutMs >> 0) & 0xFF); EEPROM.write(2193, realtimeTimeoutMs & 0xFF);
EEPROM.write(2194, (realtimeTimeoutMs >> 8) & 0xFF); EEPROM.write(2194, (realtimeTimeoutMs >> 8) & 0xFF);
EEPROM.write(2195, arlsForceMaxBri); EEPROM.write(2195, arlsForceMaxBri);
EEPROM.write(2196, arlsDisableGammaCorrection); EEPROM.write(2196, arlsDisableGammaCorrection);
@ -222,7 +232,7 @@ void saveSettingsToEEPROM()
if (saveCurrPresetCycConf) if (saveCurrPresetCycConf)
{ {
EEPROM.write(2205, presetCyclingEnabled); EEPROM.write(2205, presetCyclingEnabled);
EEPROM.write(2206, (presetCycleTime >> 0) & 0xFF); EEPROM.write(2206, presetCycleTime & 0xFF);
EEPROM.write(2207, (presetCycleTime >> 8) & 0xFF); EEPROM.write(2207, (presetCycleTime >> 8) & 0xFF);
EEPROM.write(2208, presetCycleMin); EEPROM.write(2208, presetCycleMin);
EEPROM.write(2209, presetCycleMax); EEPROM.write(2209, presetCycleMax);
@ -246,9 +256,10 @@ void saveSettingsToEEPROM()
writeStringToEEPROM(2333, mqttDeviceTopic, 32); writeStringToEEPROM(2333, mqttDeviceTopic, 32);
writeStringToEEPROM(2366, mqttGroupTopic, 32); writeStringToEEPROM(2366, mqttGroupTopic, 32);
EEPROM.commit(); commit();
} }
/* /*
* Read all configuration from flash * Read all configuration from flash
*/ */
@ -256,7 +267,9 @@ void loadSettingsFromEEPROM(bool first)
{ {
if (EEPROM.read(233) != 233) //first boot/reset to default if (EEPROM.read(233) != 233) //first boot/reset to default
{ {
DEBUG_PRINT("Settings invalid, restoring defaults...");
saveSettingsToEEPROM(); saveSettingsToEEPROM();
DEBUG_PRINTLN("done");
return; return;
} }
int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update int lastEEPROMversion = EEPROM.read(377); //last EEPROM version before update
@ -268,7 +281,8 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(128, apSSID, 32); readStringFromEEPROM(128, apSSID, 32);
readStringFromEEPROM(160, apPass, 64); readStringFromEEPROM(160, apPass, 64);
nightlightDelayMins = EEPROM.read(224); nightlightDelayMinsDefault = EEPROM.read(224);
nightlightDelayMins = nightlightDelayMinsDefault;
nightlightFade = EEPROM.read(225); nightlightFade = EEPROM.read(225);
notifyDirectDefault = EEPROM.read(226); notifyDirectDefault = EEPROM.read(226);
notifyDirect = notifyDirectDefault; notifyDirect = notifyDirectDefault;
@ -277,7 +291,7 @@ void loadSettingsFromEEPROM(bool first)
if (apChannel > 13 || apChannel < 1) apChannel = 1; if (apChannel > 13 || apChannel < 1) apChannel = 1;
apHide = EEPROM.read(228); apHide = EEPROM.read(228);
if (apHide > 1) apHide = 1; if (apHide > 1) apHide = 1;
ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10; ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 30;
notifyButton = EEPROM.read(230); notifyButton = EEPROM.read(230);
notifyTwice = EEPROM.read(231); notifyTwice = EEPROM.read(231);
@ -307,7 +321,7 @@ void loadSettingsFromEEPROM(bool first)
receiveNotificationBrightness = EEPROM.read(250); receiveNotificationBrightness = EEPROM.read(250);
fadeTransition = EEPROM.read(251); fadeTransition = EEPROM.read(251);
reverseMode = EEPROM.read(252); reverseMode = EEPROM.read(252);
transitionDelayDefault = ((EEPROM.read(253) << 0) & 0xFF) + ((EEPROM.read(254) << 8) & 0xFF00); transitionDelayDefault = EEPROM.read(253) + ((EEPROM.read(254) << 8) & 0xFF00);
transitionDelay = transitionDelayDefault; transitionDelay = transitionDelayDefault;
briMultiplier = EEPROM.read(255); briMultiplier = EEPROM.read(255);
@ -315,7 +329,7 @@ void loadSettingsFromEEPROM(bool first)
nightlightTargetBri = EEPROM.read(288); nightlightTargetBri = EEPROM.read(288);
otaLock = EEPROM.read(289); otaLock = EEPROM.read(289);
udpPort = ((EEPROM.read(290) << 0) & 0xFF) + ((EEPROM.read(291) << 8) & 0xFF00); udpPort = EEPROM.read(290) + ((EEPROM.read(291) << 8) & 0xFF00);
readStringFromEEPROM(292, serverDescription, 32); readStringFromEEPROM(292, serverDescription, 32);
@ -377,7 +391,7 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(2054, hueApiKey, 46); readStringFromEEPROM(2054, hueApiKey, 46);
huePollIntervalMs = ((EEPROM.read(2100) << 0) & 0xFF) + ((EEPROM.read(2101) << 8) & 0xFF00); huePollIntervalMs = EEPROM.read(2100) + ((EEPROM.read(2101) << 8) & 0xFF00);
notifyHue = EEPROM.read(2102); notifyHue = EEPROM.read(2102);
hueApplyOnOff = EEPROM.read(2103); hueApplyOnOff = EEPROM.read(2103);
hueApplyBri = EEPROM.read(2104); hueApplyBri = EEPROM.read(2104);
@ -413,9 +427,9 @@ void loadSettingsFromEEPROM(bool first)
if (lastEEPROMversion > 6) if (lastEEPROMversion > 6)
{ {
e131Universe = ((EEPROM.read(2190) << 0) & 0xFF) + ((EEPROM.read(2191) << 8) & 0xFF00); e131Universe = EEPROM.read(2190) + ((EEPROM.read(2191) << 8) & 0xFF00);
e131Multicast = EEPROM.read(2192); e131Multicast = EEPROM.read(2192);
realtimeTimeoutMs = ((EEPROM.read(2193) << 0) & 0xFF) + ((EEPROM.read(2194) << 8) & 0xFF00); realtimeTimeoutMs = EEPROM.read(2193) + ((EEPROM.read(2194) << 8) & 0xFF00);
arlsForceMaxBri = EEPROM.read(2195); arlsForceMaxBri = EEPROM.read(2195);
arlsDisableGammaCorrection = EEPROM.read(2196); arlsDisableGammaCorrection = EEPROM.read(2196);
} }
@ -430,8 +444,8 @@ void loadSettingsFromEEPROM(bool first)
timerHours[i] = EEPROM.read(2260 + i); timerHours[i] = EEPROM.read(2260 + i);
timerMinutes[i] = EEPROM.read(2270 + i); timerMinutes[i] = EEPROM.read(2270 + i);
timerWeekday[i] = EEPROM.read(2280 + i); timerWeekday[i] = EEPROM.read(2280 + i);
if (timerWeekday[i] == 0) timerWeekday[i] = 255;
timerMacro[i] = EEPROM.read(2290 + i); timerMacro[i] = EEPROM.read(2290 + i);
if (timerWeekday[i] == 0) timerWeekday[i] = 255;
} }
} }
@ -442,6 +456,18 @@ void loadSettingsFromEEPROM(bool first)
readStringFromEEPROM(2366, mqttGroupTopic, 32); readStringFromEEPROM(2366, mqttGroupTopic, 32);
} }
if (lastEEPROMversion > 9)
{
strip.colorOrder = EEPROM.read(383);
irEnabled = EEPROM.read(385);
strip.ablMilliampsMax = EEPROM.read(387) + ((EEPROM.read(388) << 8) & 0xFF00);
} else if (lastEEPROMversion > 1) //ABL is off by default when updating from version older than 0.8.2
{
strip.ablMilliampsMax = 65000;
} else {
strip.ablMilliampsMax = ABL_MILLIAMPS_DEFAULT;
}
receiveDirect = !EEPROM.read(2200); receiveDirect = !EEPROM.read(2200);
enableRealtimeUI = EEPROM.read(2201); enableRealtimeUI = EEPROM.read(2201);
uiConfiguration = EEPROM.read(2202); uiConfiguration = EEPROM.read(2202);
@ -457,7 +483,7 @@ void loadSettingsFromEEPROM(bool first)
if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212)) if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212))
{ {
presetCyclingEnabled = EEPROM.read(2205); presetCyclingEnabled = EEPROM.read(2205);
presetCycleTime = ((EEPROM.read(2206) << 0) & 0xFF) + ((EEPROM.read(2207) << 8) & 0xFF00); presetCycleTime = EEPROM.read(2206) + ((EEPROM.read(2207) << 8) & 0xFF00);
presetCycleMin = EEPROM.read(2208); presetCycleMin = EEPROM.read(2208);
presetCycleMax = EEPROM.read(2209); presetCycleMax = EEPROM.read(2209);
presetApplyBri = EEPROM.read(2210); presetApplyBri = EEPROM.read(2210);
@ -467,7 +493,7 @@ void loadSettingsFromEEPROM(bool first)
bootPreset = EEPROM.read(389); bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393); wifiLock = EEPROM.read(393);
utcOffsetSecs = ((EEPROM.read(394) << 0) & 0xFF) + ((EEPROM.read(395) << 8) & 0xFF00); utcOffsetSecs = EEPROM.read(394) + ((EEPROM.read(395) << 8) & 0xFF00);
if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative if (EEPROM.read(396)) utcOffsetSecs = -utcOffsetSecs; //negative
initLedsLast = EEPROM.read(397); initLedsLast = EEPROM.read(397);
enableSecTransition = !EEPROM.read(399); enableSecTransition = !EEPROM.read(399);
@ -491,23 +517,24 @@ void loadSettingsFromEEPROM(bool first)
useHSB = useHSBDefault; useHSB = useHSBDefault;
strip.setMode(effectCurrent);
strip.setSpeed(effectSpeed);
strip.setIntensity(effectIntensity);
strip.setPalette(effectPalette);
overlayCurrent = overlayDefault; overlayCurrent = overlayDefault;
} }
//PRESET PROTOCOL 20 bytes //PRESET PROTOCOL 20 bytes
//0: preset purpose byte 0:invalid 1:valid preset 1.0 //0: preset purpose byte 0:invalid 1:valid preset 1.0
//1:a 2:r 3:g 4:b 5:w 6:er 7:eg 8:eb 9:ew 10:fx 11:sx | custom chase 12:numP 13:numS 14:(0:fs 1:both 2:fe) 15:step 16:ix 17: fp 18-19:Zeros //1:a 2:r 3:g 4:b 5:w 6:er 7:eg 8:eb 9:ew 10:fx 11:sx | custom chase 12:numP 13:numS 14:(0:fs 1:both 2:fe) 15:step 16:ix 17: fp 18-19:Zeros
void applyPreset(byte index, bool loadBri, bool loadCol, bool loadFX) bool applyPreset(byte index, bool loadBri = true, bool loadCol = true, bool loadFX = true)
{ {
if (index == 255 || index == 0) loadSettingsFromEEPROM(false);//load boot defaults if (index == 255 || index == 0)
if (index > 25 || index < 1) return; {
loadSettingsFromEEPROM(false);//load boot defaults
return true;
}
if (index > 25 || index < 1) return false;
uint16_t i = 380 + index*20; uint16_t i = 380 + index*20;
if (EEPROM.read(i) == 0) return; if (EEPROM.read(i) == 0) return false;
if (loadBri) bri = EEPROM.read(i+1); if (loadBri) bri = EEPROM.read(i+1);
if (loadCol) if (loadCol)
{ {
@ -522,16 +549,12 @@ void applyPreset(byte index, bool loadBri, bool loadCol, bool loadFX)
} }
if (loadFX) if (loadFX)
{ {
byte lastfx = effectCurrent;
effectCurrent = EEPROM.read(i+10); effectCurrent = EEPROM.read(i+10);
effectSpeed = EEPROM.read(i+11); effectSpeed = EEPROM.read(i+11);
effectIntensity = EEPROM.read(i+16); effectIntensity = EEPROM.read(i+16);
effectPalette = EEPROM.read(i+17); effectPalette = EEPROM.read(i+17);
if (lastfx != effectCurrent) strip.setMode(effectCurrent);
strip.setSpeed(effectSpeed);
strip.setIntensity(effectIntensity);
strip.setPalette(effectPalette);
} }
return true;
} }
void savePreset(byte index) void savePreset(byte index)
@ -554,9 +577,10 @@ void savePreset(byte index)
EEPROM.write(i+16, effectIntensity); EEPROM.write(i+16, effectIntensity);
EEPROM.write(i+17, effectPalette); EEPROM.write(i+17, effectPalette);
EEPROM.commit(); commit();
} }
String loadMacro(byte index) String loadMacro(byte index)
{ {
index-=1; index-=1;
@ -570,6 +594,7 @@ String loadMacro(byte index)
return m; return m;
} }
void applyMacro(byte index) void applyMacro(byte index)
{ {
index-=1; index-=1;
@ -588,6 +613,7 @@ void applyMacro(byte index)
handleSet(mc); handleSet(mc);
} }
void saveMacro(byte index, String mc, bool sing=true) //only commit on single save, not in settings void saveMacro(byte index, String mc, bool sing=true) //only commit on single save, not in settings
{ {
index-=1; index-=1;
@ -597,5 +623,23 @@ void saveMacro(byte index, String mc, bool sing=true) //only commit on single sa
{ {
EEPROM.write(i, mc.charAt(i-s)); EEPROM.write(i, mc.charAt(i-s));
} }
if (sing) EEPROM.commit(); if (sing) commit();
}
void commit()
{
DEBUG_PRINT("s");
//this is to support IR on ESP32, needs work
/*#ifdef ARDUINO_ARCH_ESP32
portMUX_TYPE mMux = portMUX_INITIALIZER_UNLOCKED;
portENTER_CRITICAL(&mMux);
#endif*/
EEPROM.commit();
/*#ifdef ARDUINO_ARCH_ESP32
portEXIT_CRITICAL(&mMux);
#endif*/
DEBUG_PRINT(".");
} }

View File

@ -3,7 +3,7 @@
*/ */
//build XML response to HTTP /win API request //build XML response to HTTP /win API request
void XML_response(bool isHTTP) void XML_response(bool isHTTP, bool includeTheme)
{ {
olen = 0; olen = 0;
oappend("<?xml version = \"1.0\" ?><vs><ac>"); oappend("<?xml version = \"1.0\" ?><vs><ac>");
@ -47,7 +47,28 @@ void XML_response(bool isHTTP)
oappendi(useHSB); oappendi(useHSB);
oappend("</md><ds>"); oappend("</md><ds>");
oappend(serverDescription); oappend(serverDescription);
oappend("</ds></vs>"); oappend("</ds>");
if (includeTheme)
{
char cs[6][9];
getThemeColors(cs);
oappend("<th><ca>#");
oappend(cs[0]);
oappend("</ca><cb>#");
oappend(cs[1]);
oappend("</cb><cc>#");
oappend(cs[2]);
oappend("</cc><cd>#");
oappend(cs[3]);
oappend("</cd><cs>#");
oappend(cs[4]);
oappend("</cs><ct>#");
oappend(cs[5]);
oappend("</ct><cf>");
oappend(cssFont);
oappend("</cf></th>");
}
oappend("</vs>");
if (isHTTP) server.send(200, "text/xml", obuf); if (isHTTP) server.send(200, "text/xml", obuf);
} }
@ -170,11 +191,20 @@ void getSettingsJS(byte subPage)
if (subPage == 2) { if (subPage == 2) {
sappend('v',"LC",ledCount); sappend('v',"LC",ledCount);
sappend('v',"MA",strip.ablMilliampsMax);
if (strip.currentMilliamps)
{
sappends('m',"(\"pow\")[0]","");
olen -= 2; //delete ";
oappendi(strip.currentMilliamps);
oappend("mA\";");
}
sappend('v',"CR",colS[0]); sappend('v',"CR",colS[0]);
sappend('v',"CG",colS[1]); sappend('v',"CG",colS[1]);
sappend('v',"CB",colS[2]); sappend('v',"CB",colS[2]);
sappend('v',"CA",briS); sappend('v',"CA",briS);
sappend('c',"EW",useRGBW); sappend('c',"EW",useRGBW);
sappend('i',"CO",strip.colorOrder);
sappend('c',"AW",autoRGBtoRGBW); sappend('c',"AW",autoRGBtoRGBW);
sappend('v',"CW",whiteS); sappend('v',"CW",whiteS);
sappend('v',"SR",colSecS[0]); sappend('v',"SR",colSecS[0]);
@ -195,7 +225,7 @@ void getSettingsJS(byte subPage)
sappend('c',"T2",enableSecTransition); sappend('c',"T2",enableSecTransition);
sappend('v',"BF",briMultiplier); sappend('v',"BF",briMultiplier);
sappend('v',"TB",nightlightTargetBri); sappend('v',"TB",nightlightTargetBri);
sappend('v',"TL",nightlightDelayMins); sappend('v',"TL",nightlightDelayMinsDefault);
sappend('c',"TW",nightlightFade); sappend('c',"TW",nightlightFade);
sappend('i',"PB",strip.paletteBlend); sappend('i',"PB",strip.paletteBlend);
sappend('c',"RV",reverseMode); sappend('c',"RV",reverseMode);
@ -221,6 +251,7 @@ void getSettingsJS(byte subPage)
if (subPage == 4) if (subPage == 4)
{ {
sappend('c',"BT",buttonEnabled); sappend('c',"BT",buttonEnabled);
sappend('c',"IR",irEnabled);
sappend('v',"UP",udpPort); sappend('v',"UP",udpPort);
sappend('c',"RB",receiveNotificationBrightness); sappend('c',"RB",receiveNotificationBrightness);
sappend('c',"RC",receiveNotificationColor); sappend('c',"RC",receiveNotificationColor);
@ -320,3 +351,29 @@ void getSettingsJS(byte subPage)
} }
oappend("}</script>"); oappend("}</script>");
} }
//get colors from current theme as c strings
void getThemeColors(char o[][9])
{
switch (currentTheme)
{
// accent color (aCol) background (bCol) panel (cCol) controls (dCol) shadows (sCol) text (tCol)
default: strcpy(o[0], "D9B310"); strcpy(o[1], "0B3C5D"); strcpy(o[2], "1D2731"); strcpy(o[3], "328CC1"); strcpy(o[4], "000"); strcpy(o[5], "328CC1"); break; //night
case 1: strcpy(o[0], "eee"); strcpy(o[1], "ddd"); strcpy(o[2], "b9b9b9"); strcpy(o[3], "049"); strcpy(o[4], "777"); strcpy(o[5], "049"); break; //modern
case 2: strcpy(o[0], "abc"); strcpy(o[1], "fff"); strcpy(o[2], "ddd"); strcpy(o[3], "000"); strcpy(o[4], "0004"); strcpy(o[5], "000"); break; //bright
case 3: strcpy(o[0], "c09f80"); strcpy(o[1], "d7cec7"); strcpy(o[2], "76323f"); strcpy(o[3], "888"); strcpy(o[4], "3334"); strcpy(o[5], "888"); break; //wine
case 4: strcpy(o[0], "3cc47c"); strcpy(o[1], "828081"); strcpy(o[2], "d9a803"); strcpy(o[3], "1e392a"); strcpy(o[4], "000a"); strcpy(o[5], "1e392a"); break; //electric
case 5: strcpy(o[0], "57bc90"); strcpy(o[1], "a5a5af"); strcpy(o[2], "015249"); strcpy(o[3], "88c9d4"); strcpy(o[4], "0004"); strcpy(o[5], "88c9d4"); break; //mint
case 6: strcpy(o[0], "f7c331"); strcpy(o[1], "dcc7aa"); strcpy(o[2], "6b7a8f"); strcpy(o[3], "f7882f"); strcpy(o[4], "0007"); strcpy(o[5], "f7882f"); break; //amber
case 7: strcpy(o[0], "fc3"); strcpy(o[1], "124"); strcpy(o[2], "334"); strcpy(o[3], "f1d"); strcpy(o[4], "f00"); strcpy(o[5], "f1d"); break; //club
case 8: strcpy(o[0], "0ac"); strcpy(o[1], "124"); strcpy(o[2], "224"); strcpy(o[3], "003eff"); strcpy(o[4], "003eff"); strcpy(o[5], "003eff"); break; //air
case 9: strcpy(o[0], "f70"); strcpy(o[1], "421"); strcpy(o[2], "221"); strcpy(o[3], "a50"); strcpy(o[4], "f70"); strcpy(o[5], "f70"); break; //nixie
case 10: strcpy(o[0], "2d2"); strcpy(o[1], "010"); strcpy(o[2], "121"); strcpy(o[3], "060"); strcpy(o[4], "040"); strcpy(o[5], "3f3"); break; //terminal
case 11: strcpy(o[0], "867ADE"); strcpy(o[1], "4033A3"); strcpy(o[2], "483AAA"); strcpy(o[3], "483AAA"); strcpy(o[4], ""); strcpy(o[5], "867ADE"); break; //c64
case 12: strcpy(o[0], "fbe8a6"); strcpy(o[1], "d2fdff"); strcpy(o[2], "b4dfe5"); strcpy(o[3], "f4976c"); strcpy(o[4], ""); strcpy(o[5], "303c6c"); break; //easter
case 13: strcpy(o[0], "d4af37"); strcpy(o[1], "173305"); strcpy(o[2], "308505"); strcpy(o[3], "f21313"); strcpy(o[4], "f002"); strcpy(o[5], "d4af37"); break; //christmas
case 14: strcpy(o[0], "fc7"); strcpy(o[1], "49274a"); strcpy(o[2], "94618e"); strcpy(o[3], "f4decb"); strcpy(o[4], "0008"); strcpy(o[5], "f4decb"); break; //end
case 15: for (int i=0;i<6;i++) strcpy(o[i], cssCol[i]); //custom
}
}

View File

@ -59,7 +59,9 @@ void handleSettingsSet(byte subPage)
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
if (ledCount > 600) ledCount = 600; if (ledCount > 600) ledCount = 600;
#endif #endif
strip.ablMilliampsMax = server.arg("MA").toInt();
useRGBW = server.hasArg("EW"); useRGBW = server.hasArg("EW");
strip.colorOrder = server.arg("CO").toInt();
autoRGBtoRGBW = server.hasArg("AW"); autoRGBtoRGBW = server.hasArg("AW");
//ignore settings and save current brightness, colors and fx as default //ignore settings and save current brightness, colors and fx as default
@ -109,7 +111,7 @@ void handleSettingsSet(byte subPage)
nightlightTargetBri = server.arg("TB").toInt(); nightlightTargetBri = server.arg("TB").toInt();
t = server.arg("TL").toInt(); t = server.arg("TL").toInt();
if (t > 0) nightlightDelayMins = t; if (t > 0) nightlightDelayMinsDefault = t;
nightlightFade = server.hasArg("TW"); nightlightFade = server.hasArg("TW");
t = server.arg("PB").toInt(); t = server.arg("PB").toInt();
@ -138,13 +140,13 @@ void handleSettingsSet(byte subPage)
strcpy(cssCol[i],server.arg(k).c_str()); strcpy(cssCol[i],server.arg(k).c_str());
} }
strcpy(cssFont,server.arg("CF").c_str()); strcpy(cssFont,server.arg("CF").c_str());
buildCssColorString();
} }
//SYNC //SYNC
if (subPage == 4) if (subPage == 4)
{ {
buttonEnabled = server.hasArg("BT"); buttonEnabled = server.hasArg("BT");
irEnabled = server.hasArg("IR");
int t = server.arg("UP").toInt(); int t = server.arg("UP").toInt();
if (t > 0) udpPort = t; if (t > 0) udpPort = t;
receiveNotificationBrightness = server.hasArg("RB"); receiveNotificationBrightness = server.hasArg("RB");
@ -280,7 +282,7 @@ void handleSettingsSet(byte subPage)
if (server.hasArg("RS")) //complete factory reset if (server.hasArg("RS")) //complete factory reset
{ {
clearEEPROM(); clearEEPROM();
serveMessage(200, "All Settings erased.", "Connect to WLED-AP to setup again...",255); serveMessage(200, "All Settings erased.", "Connect to WLED-AP to setup again",255);
reset(); reset();
} }
@ -309,9 +311,17 @@ void handleSettingsSet(byte subPage)
if (subPage == 2) strip.init(useRGBW,ledCount,skipFirstLed); if (subPage == 2) strip.init(useRGBW,ledCount,skipFirstLed);
} }
//helper to get int value at a position in string
int getNumVal(String* req, uint16_t pos)
{
return req->substring(pos + 3).toInt();
}
//HTTP API request parser
bool handleSet(String req) bool handleSet(String req)
{ {
bool effectUpdated = false;
if (!(req.indexOf("win") >= 0)) return false; if (!(req.indexOf("win") >= 0)) return false;
int pos = 0; int pos = 0;
@ -331,7 +341,7 @@ bool handleSet(String req)
} }
pos = req.indexOf("IN"); pos = req.indexOf("IN");
if (pos < 1) XML_response(true); if (pos < 1) XML_response(true, false);
return true; return true;
//if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise //if you save a macro in one request, other commands in that request are ignored due to unwanted behavior otherwise
} }
@ -339,17 +349,17 @@ bool handleSet(String req)
//set brigthness //set brigthness
pos = req.indexOf("&A="); pos = req.indexOf("&A=");
if (pos > 0) { if (pos > 0) {
bri = req.substring(pos + 3).toInt(); bri = getNumVal(&req, pos);
} }
//set hue //set hue
pos = req.indexOf("HU="); pos = req.indexOf("HU=");
if (pos > 0) { if (pos > 0) {
uint16_t temphue = req.substring(pos + 3).toInt(); uint16_t temphue = getNumVal(&req, pos);
byte tempsat = 255; byte tempsat = 255;
pos = req.indexOf("SA="); pos = req.indexOf("SA=");
if (pos > 0) { if (pos > 0) {
tempsat = req.substring(pos + 3).toInt(); tempsat = getNumVal(&req, pos);
} }
colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col); colorHStoRGB(temphue,tempsat,(req.indexOf("H2")>0)? colSec:col);
} }
@ -357,43 +367,43 @@ bool handleSet(String req)
//set red value //set red value
pos = req.indexOf("&R="); pos = req.indexOf("&R=");
if (pos > 0) { if (pos > 0) {
col[0] = req.substring(pos + 3).toInt(); col[0] = getNumVal(&req, pos);
} }
//set green value //set green value
pos = req.indexOf("&G="); pos = req.indexOf("&G=");
if (pos > 0) { if (pos > 0) {
col[1] = req.substring(pos + 3).toInt(); col[1] = getNumVal(&req, pos);
} }
//set blue value //set blue value
pos = req.indexOf("&B="); pos = req.indexOf("&B=");
if (pos > 0) { if (pos > 0) {
col[2] = req.substring(pos + 3).toInt(); col[2] = getNumVal(&req, pos);
} }
//set white value //set white value
pos = req.indexOf("&W="); pos = req.indexOf("&W=");
if (pos > 0) { if (pos > 0) {
white = req.substring(pos + 3).toInt(); white = getNumVal(&req, pos);
} }
//set 2nd red value //set 2nd red value
pos = req.indexOf("R2="); pos = req.indexOf("R2=");
if (pos > 0) { if (pos > 0) {
colSec[0] = req.substring(pos + 3).toInt(); colSec[0] = getNumVal(&req, pos);
} }
//set 2nd green value //set 2nd green value
pos = req.indexOf("G2="); pos = req.indexOf("G2=");
if (pos > 0) { if (pos > 0) {
colSec[1] = req.substring(pos + 3).toInt(); colSec[1] = getNumVal(&req, pos);
} }
//set 2nd blue value //set 2nd blue value
pos = req.indexOf("B2="); pos = req.indexOf("B2=");
if (pos > 0) { if (pos > 0) {
colSec[2] = req.substring(pos + 3).toInt(); colSec[2] = getNumVal(&req, pos);
} }
//set 2nd white value //set 2nd white value
pos = req.indexOf("W2="); pos = req.indexOf("W2=");
if (pos > 0) { if (pos > 0) {
whiteSec = req.substring(pos + 3).toInt(); whiteSec = getNumVal(&req, pos);
} }
//set color from HEX or 32bit DEC //set color from HEX or 32bit DEC
@ -433,7 +443,7 @@ bool handleSet(String req)
//set to random hue SR=0->1st SR=1->2nd //set to random hue SR=0->1st SR=1->2nd
pos = req.indexOf("SR"); pos = req.indexOf("SR");
if (pos > 0) { if (pos > 0) {
_setRandomColor(req.substring(pos + 3).toInt()); _setRandomColor(getNumVal(&req, pos));
} }
//set 2nd to 1st //set 2nd to 1st
pos = req.indexOf("SP"); pos = req.indexOf("SP");
@ -461,48 +471,28 @@ bool handleSet(String req)
//set current effect index //set current effect index
pos = req.indexOf("FX="); pos = req.indexOf("FX=");
if (pos > 0) { if (pos > 0) {
if (effectCurrent != req.substring(pos + 3).toInt()) effectCurrent = getNumVal(&req, pos);
{
effectCurrent = req.substring(pos + 3).toInt();
strip.setMode(effectCurrent);
effectUpdated = true;
}
} }
//set effect speed //set effect speed
pos = req.indexOf("SX="); pos = req.indexOf("SX=");
if (pos > 0) { if (pos > 0) {
if (effectSpeed != req.substring(pos + 3).toInt()) effectSpeed = getNumVal(&req, pos);
{
effectSpeed = req.substring(pos + 3).toInt();
strip.setSpeed(effectSpeed);
effectUpdated = true;
}
} }
//set effect intensity //set effect intensity
pos = req.indexOf("IX="); pos = req.indexOf("IX=");
if (pos > 0) { if (pos > 0) {
if (effectIntensity != req.substring(pos + 3).toInt())
{
effectIntensity = req.substring(pos + 3).toInt(); effectIntensity = req.substring(pos + 3).toInt();
strip.setIntensity(effectIntensity);
effectUpdated = true;
}
} }
//set effect palette (only for FastLED effects) //set effect palette (only for FastLED effects)
pos = req.indexOf("FP="); pos = req.indexOf("FP=");
if (pos > 0) { if (pos > 0) {
if (effectPalette != req.substring(pos + 3).toInt())
{
effectPalette = req.substring(pos + 3).toInt(); effectPalette = req.substring(pos + 3).toInt();
strip.setPalette(effectPalette);
effectUpdated = true;
}
} }
//set hue polling light: 0 -off //set hue polling light: 0 -off
pos = req.indexOf("HP="); pos = req.indexOf("HP=");
if (pos > 0) { if (pos > 0) {
int id = req.substring(pos + 3).toInt(); int id = getNumVal(&req, pos);
if (id > 0) if (id > 0)
{ {
if (id < 100) huePollLightId = id; if (id < 100) huePollLightId = id;
@ -515,21 +505,21 @@ bool handleSet(String req)
//set default control mode (0 - RGB, 1 - HSB) //set default control mode (0 - RGB, 1 - HSB)
pos = req.indexOf("MD="); pos = req.indexOf("MD=");
if (pos > 0) { if (pos > 0) {
useHSB = req.substring(pos + 3).toInt(); useHSB = getNumVal(&req, pos);
} }
//set advanced overlay //set advanced overlay
pos = req.indexOf("OL="); pos = req.indexOf("OL=");
if (pos > 0) { if (pos > 0) {
overlayCurrent = req.substring(pos + 3).toInt(); overlayCurrent = getNumVal(&req, pos);
strip.unlockAll(); strip.unlockAll();
} }
//(un)lock pixel (ranges) //(un)lock pixel (ranges)
pos = req.indexOf("&L="); pos = req.indexOf("&L=");
if (pos > 0){ if (pos > 0){
int index = req.substring(pos + 3).toInt(); int index = getNumVal(&req, pos);
pos = req.indexOf("L2="); pos = req.indexOf("L2=");
if (pos > 0){ if (pos > 0){
int index2 = req.substring(pos + 3).toInt(); int index2 = getNumVal(&req, pos);
if (req.indexOf("UL") > 0) if (req.indexOf("UL") > 0)
{ {
strip.unlockRange(index, index2); strip.unlockRange(index, index2);
@ -552,7 +542,7 @@ bool handleSet(String req)
//apply macro //apply macro
pos = req.indexOf("&M="); pos = req.indexOf("&M=");
if (pos > 0) { if (pos > 0) {
applyMacro(req.substring(pos + 3).toInt()); applyMacro(getNumVal(&req, pos));
} }
//toggle send UDP direct notifications //toggle send UDP direct notifications
if (req.indexOf("SN=") > 0) if (req.indexOf("SN=") > 0)
@ -586,7 +576,7 @@ bool handleSet(String req)
bri = briT; bri = briT;
} else { } else {
nightlightActive = true; nightlightActive = true;
if (!aNlDef) nightlightDelayMins = req.substring(pos + 3).toInt(); if (!aNlDef) nightlightDelayMins = getNumVal(&req, pos);
nightlightStartTime = millis(); nightlightStartTime = millis();
} }
} else if (aNlDef) } else if (aNlDef)
@ -598,7 +588,7 @@ bool handleSet(String req)
//set nightlight target brightness //set nightlight target brightness
pos = req.indexOf("NT="); pos = req.indexOf("NT=");
if (pos > 0) { if (pos > 0) {
nightlightTargetBri = req.substring(pos + 3).toInt(); nightlightTargetBri = getNumVal(&req, pos);
nightlightActiveOld = false; //re-init nightlightActiveOld = false; //re-init
} }
@ -617,31 +607,24 @@ bool handleSet(String req)
//toggle general purpose output //toggle general purpose output
pos = req.indexOf("AX="); pos = req.indexOf("AX=");
if (pos > 0) { if (pos > 0) {
auxTime = req.substring(pos + 3).toInt(); auxTime = getNumVal(&req, pos);
auxActive = true; auxActive = true;
if (auxTime == 0) auxActive = false; if (auxTime == 0) auxActive = false;
} }
pos = req.indexOf("TT="); pos = req.indexOf("TT=");
if (pos > 0) { if (pos > 0) {
transitionDelay = req.substring(pos + 3).toInt(); transitionDelay = getNumVal(&req, pos);
} }
//main toggle on/off //main toggle on/off
pos = req.indexOf("&T="); pos = req.indexOf("&T=");
if (pos > 0) { if (pos > 0) {
nightlightActive = false; //always disable nightlight when toggling nightlightActive = false; //always disable nightlight when toggling
switch (req.substring(pos + 3).toInt()) switch (getNumVal(&req, pos))
{ {
case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off case 0: if (bri != 0){briLast = bri; bri = 0;} break; //off
case 1: bri = briLast; break; //on case 1: bri = briLast; break; //on
default: if (bri == 0) //toggle default: toggleOnOff(); //toggle
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
} }
} }
@ -650,22 +633,22 @@ bool handleSet(String req)
//set time (unix timestamp) //set time (unix timestamp)
pos = req.indexOf("ST="); pos = req.indexOf("ST=");
if (pos > 0) { if (pos > 0) {
setTime(req.substring(pos+3).toInt()); setTime(getNumVal(&req, pos));
} }
//set countdown goal (unix timestamp) //set countdown goal (unix timestamp)
pos = req.indexOf("CT="); pos = req.indexOf("CT=");
if (pos > 0) { if (pos > 0) {
countdownTime = req.substring(pos+3).toInt(); countdownTime = getNumVal(&req, pos);
if (countdownTime - now() > 0) countdownOverTriggered = false; if (countdownTime - now() > 0) countdownOverTriggered = false;
} }
//set presets //set presets
pos = req.indexOf("P1="); //sets first preset for cycle pos = req.indexOf("P1="); //sets first preset for cycle
if (pos > 0) presetCycleMin = req.substring(pos + 3).toInt(); if (pos > 0) presetCycleMin = getNumVal(&req, pos);
pos = req.indexOf("P2="); //sets last preset for cycle pos = req.indexOf("P2="); //sets last preset for cycle
if (pos > 0) presetCycleMax = req.substring(pos + 3).toInt(); if (pos > 0) presetCycleMax = getNumVal(&req, pos);
if (req.indexOf("CY=") > 0) //preset cycle if (req.indexOf("CY=") > 0) //preset cycle
{ {
@ -678,7 +661,7 @@ bool handleSet(String req)
} }
pos = req.indexOf("PT="); //sets cycle time in ms pos = req.indexOf("PT="); //sets cycle time in ms
if (pos > 0) { if (pos > 0) {
int v = req.substring(pos + 3).toInt(); int v = getNumVal(&req, pos);
if (v > 49) presetCycleTime = v; if (v > 49) presetCycleTime = v;
} }
if (req.indexOf("PA=") > 0) //apply brightness from preset if (req.indexOf("PA=") > 0) //apply brightness from preset
@ -699,12 +682,11 @@ bool handleSet(String req)
pos = req.indexOf("PS="); //saves current in preset pos = req.indexOf("PS="); //saves current in preset
if (pos > 0) { if (pos > 0) {
savePreset(req.substring(pos + 3).toInt()); savePreset(getNumVal(&req, pos));
} }
pos = req.indexOf("PL="); //applies entire preset pos = req.indexOf("PL="); //applies entire preset
if (pos > 0) { if (pos > 0) {
applyPreset(req.substring(pos + 3).toInt(), presetApplyBri, presetApplyCol, presetApplyFx); applyPreset(getNumVal(&req, pos), presetApplyBri, presetApplyCol, presetApplyFx);
if (presetApplyFx) effectUpdated = true;
} }
//cronixie //cronixie
@ -734,30 +716,20 @@ bool handleSet(String req)
pos = req.indexOf("U0="); //user var 0 pos = req.indexOf("U0="); //user var 0
if (pos > 0) { if (pos > 0) {
userVar0 = req.substring(pos + 3).toInt(); userVar0 = getNumVal(&req, pos);
} }
pos = req.indexOf("U1="); //user var 1 pos = req.indexOf("U1="); //user var 1
if (pos > 0) { if (pos > 0) {
userVar1 = req.substring(pos + 3).toInt(); userVar1 = getNumVal(&req, pos);
} }
//you can add more if you need //you can add more if you need
//internal call, does not send XML response //internal call, does not send XML response
pos = req.indexOf("IN"); pos = req.indexOf("IN");
if (pos < 1) XML_response(true); if (pos < 1) XML_response(true, (req.indexOf("IT") > 0)); //include theme if firstload
//do not send UDP notifications this time
pos = req.indexOf("NN"); pos = req.indexOf("NN"); //do not send UDP notifications this time
if (pos > 0) colorUpdated((pos > 0) ? 5:1);
{
colorUpdated(5);
return true;
}
if (effectUpdated)
{
colorUpdated(6);
} else
{
colorUpdated(1);
}
return true; return true;
} }

View File

@ -5,7 +5,8 @@
void wledInit() void wledInit()
{ {
EEPROM.begin(EEPSIZE); EEPROM.begin(EEPSIZE);
ledCount = ((EEPROM.read(229) << 0) & 0xFF) + ((EEPROM.read(398) << 8) & 0xFF00); if (ledCount > 1200 || ledCount == 0) ledCount = 10; ledCount = EEPROM.read(229) + ((EEPROM.read(398) << 8) & 0xFF00);
if (ledCount > 1200 || ledCount == 0) ledCount = 30;
//RMT eats up too much RAM //RMT eats up too much RAM
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
if (ledCount > 600) ledCount = 600; if (ledCount > 600) ledCount = 600;
@ -24,7 +25,6 @@ void wledInit()
if (!initLedsLast) initStrip(); if (!initLedsLast) initStrip();
DEBUG_PRINT("CSSID: "); DEBUG_PRINT("CSSID: ");
DEBUG_PRINT(clientSSID); DEBUG_PRINT(clientSSID);
buildCssColorString();
userBeginPreConnection(); userBeginPreConnection();
if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true; if (strcmp(clientSSID,"Your_Network") == 0) showWelcomePage = true;
@ -121,10 +121,12 @@ void wledInit()
if (initLedsLast) initStrip(); if (initLedsLast) initStrip();
userBegin(); userBegin();
if (macroBoot>0) applyMacro(macroBoot); if (macroBoot>0) applyMacro(macroBoot);
Serial.println("Ada"); Serial.println("Ada");
} }
void initStrip() void initStrip()
{ {
// Initialize NeoPixel Strip and button // Initialize NeoPixel Strip and button
@ -133,18 +135,16 @@ void initStrip()
strip.setColor(0); strip.setColor(0);
strip.setBrightness(255); strip.setBrightness(255);
pinMode(buttonPin, INPUT_PULLUP); pinMode(BTNPIN, INPUT_PULLUP);
pinMode(4,OUTPUT); //this is only needed in special cases
digitalWrite(4,LOW);
if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true); if (bootPreset>0) applyPreset(bootPreset, turnOnAtBoot, true, true);
colorUpdated(0); colorUpdated(0);
//disable button if it is "pressed" unintentionally //disable button if it is "pressed" unintentionally
if(digitalRead(buttonPin) == LOW) buttonEnabled = false; if(digitalRead(BTNPIN) == LOW) buttonEnabled = false;
} }
void initAP(){ void initAP(){
bool set = apSSID[0]; bool set = apSSID[0];
if (!set) strcpy(apSSID,"WLED-AP"); if (!set) strcpy(apSSID,"WLED-AP");
@ -152,6 +152,7 @@ void initAP(){
if (!set) apSSID[0] = 0; if (!set) apSSID[0] = 0;
} }
void initCon() void initCon()
{ {
WiFi.disconnect(); //close old connections WiFi.disconnect(); //close old connections
@ -230,6 +231,12 @@ void getBuildInfo()
oappendi(VERSION); oappendi(VERSION);
oappend("\r\neepver: "); oappend("\r\neepver: ");
oappendi(EEPVER); oappendi(EEPVER);
oappend("\r\nesp-core: ");
#ifdef ARDUINO_ARCH_ESP32
oappend((char*)ESP.getSdkVersion());
#else
oappend((char*)ESP.getCoreVersion().c_str());
#endif
oappend("\r\nopt: "); oappend("\r\nopt: ");
#ifndef WLED_DISABLE_ALEXA #ifndef WLED_DISABLE_ALEXA
oappend("alexa "); oappend("alexa ");
@ -254,16 +261,16 @@ void getBuildInfo()
#else #else
oappend("\r\nspiffs: false\r\n"); oappend("\r\nspiffs: false\r\n");
#endif #endif
#ifdef DEBUG #ifdef WLED_DEBUG
oappend("debug: true\r\n"); oappend("debug: true\r\n");
#else #else
oappend("debug: false\r\n"); oappend("debug: false\r\n");
#endif #endif
oappend("button-pin: gpio"); oappend("button-pin: gpio");
oappendi(buttonPin); oappendi(BTNPIN);
oappend("\r\nstrip-pin: gpio"); oappend("\r\nstrip-pin: gpio");
oappendi(LEDPIN); oappendi(LEDPIN);
oappend("\r\nbrand: wled\r\n"); oappend("\r\nbrand: wled");
oappend("\r\nbuild-type: src\r\n"); oappend("\r\nbuild-type: src\r\n");
} }

View File

@ -5,6 +5,7 @@
#define WLEDPACKETSIZE 24 #define WLEDPACKETSIZE 24
#define UDP_IN_MAXSIZE 1472 #define UDP_IN_MAXSIZE 1472
void notify(byte callMode, bool followUp=false) void notify(byte callMode, bool followUp=false)
{ {
if (!udpConnected) return; if (!udpConnected) return;
@ -53,6 +54,7 @@ void notify(byte callMode, bool followUp=false)
notificationTwoRequired = (followUp)? false:notifyTwice; notificationTwoRequired = (followUp)? false:notifyTwice;
} }
void arlsLock(uint32_t timeoutMs) void arlsLock(uint32_t timeoutMs)
{ {
if (!realtimeActive){ if (!realtimeActive){
@ -60,13 +62,14 @@ void arlsLock(uint32_t timeoutMs)
{ {
strip.setPixelColor(i,0,0,0,0); strip.setPixelColor(i,0,0,0,0);
} }
strip.setMode(0); strip.unlockAll();
} }
realtimeActive = true; realtimeActive = true;
realtimeTimeout = millis() + timeoutMs; realtimeTimeout = millis() + timeoutMs;
if (arlsForceMaxBri) strip.setBrightness(255); if (arlsForceMaxBri) strip.setBrightness(255);
} }
void initE131(){ void initE131(){
if (WiFi.status() == WL_CONNECTED && e131Enabled) if (WiFi.status() == WL_CONNECTED && e131Enabled)
{ {
@ -77,6 +80,7 @@ void initE131(){
} }
} }
void handleE131(){ void handleE131(){
//E1.31 protocol support //E1.31 protocol support
if(e131Enabled) { if(e131Enabled) {
@ -98,6 +102,7 @@ void handleE131(){
} }
} }
void handleNotifications() void handleNotifications()
{ {
//send second notification if enabled //send second notification if enabled
@ -110,10 +115,10 @@ void handleNotifications()
//unlock strip when realtime UDP times out //unlock strip when realtime UDP times out
if (realtimeActive && millis() > realtimeTimeout) if (realtimeActive && millis() > realtimeTimeout)
{ {
strip.unlockAll(); //strip.unlockAll();
strip.setBrightness(bri); strip.setBrightness(bri);
realtimeActive = false; realtimeActive = false;
strip.setMode(effectCurrent); //strip.setMode(effectCurrent);
realtimeIP[0] = 0; realtimeIP[0] = 0;
} }
@ -151,18 +156,19 @@ void handleNotifications()
notifierUdp.read(obuf, packetSize); notifierUdp.read(obuf, packetSize);
char* udpIn = obuf; char* udpIn = obuf;
if (udpIn[0] == 0 && !realtimeActive && receiveNotifications) //wled notifier, block if realtime packets active //wled notifier, block if realtime packets active
if (udpIn[0] == 0 && !realtimeActive && receiveNotifications)
{ {
//apply colors from notification
if (receiveNotificationColor) if (receiveNotificationColor)
{ {
col[0] = udpIn[3]; col[0] = udpIn[3];
col[1] = udpIn[4]; col[1] = udpIn[4];
col[2] = udpIn[5]; col[2] = udpIn[5];
} if (udpIn[11] > 0) //check if sending modules white val is inteded
if (udpIn[11] > 0 && receiveNotificationColor) //check if sending modules white val is inteded
{ {
white = udpIn[10]; white = udpIn[10];
if (udpIn[11] > 1 ) if (udpIn[11] > 1)
{ {
colSec[0] = udpIn[12]; colSec[0] = udpIn[12];
colSec[1] = udpIn[13]; colSec[1] = udpIn[13];
@ -170,36 +176,28 @@ void handleNotifications()
whiteSec = udpIn[15]; whiteSec = udpIn[15];
} }
} }
if (udpIn[8] != effectCurrent && receiveNotificationEffects) }
//apply effects from notification
if (receiveNotificationEffects)
{ {
effectCurrent = udpIn[8]; effectCurrent = udpIn[8];
strip.setMode(effectCurrent);
}
if (udpIn[9] != effectSpeed && receiveNotificationEffects)
{
effectSpeed = udpIn[9]; effectSpeed = udpIn[9];
strip.setSpeed(effectSpeed); if (udpIn[11] > 2) effectIntensity = udpIn[16];
} if (udpIn[11] > 4) effectPalette = udpIn[19];
if (udpIn[11] > 2 && udpIn[16] != effectIntensity && receiveNotificationEffects)
{
effectIntensity = udpIn[16];
strip.setIntensity(effectIntensity);
} }
if (udpIn[11] > 3) if (udpIn[11] > 3)
{ {
transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00); transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00);
} }
if (udpIn[11] > 4 && udpIn[19] != effectPalette && receiveNotificationEffects)
{
effectPalette = udpIn[19];
strip.setPalette(effectPalette);
}
nightlightActive = udpIn[6]; nightlightActive = udpIn[6];
if (!nightlightActive) if (nightlightActive) nightlightDelayMins = udpIn[7];
{
if (receiveNotificationBrightness) bri = udpIn[2]; if (receiveNotificationBrightness) bri = udpIn[2];
colorUpdated(3); colorUpdated(3);
}
} else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw } else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw
{ {
realtimeIP = notifierUdp.remoteIP(); realtimeIP = notifierUdp.remoteIP();
@ -252,6 +250,7 @@ void handleNotifications()
} }
} }
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w) void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w)
{ {
uint16_t pix = i + arlsOffset; uint16_t pix = i + arlsOffset;

View File

@ -2,6 +2,19 @@
* LED methods * LED methods
*/ */
void toggleOnOff()
{
if (bri == 0)
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
}
void setAllLeds() { void setAllLeds() {
if (!realtimeActive || !arlsForceMaxBri) if (!realtimeActive || !arlsForceMaxBri)
{ {
@ -38,6 +51,7 @@ void setAllLeds() {
} }
} }
void setLedsStandard() void setLedsStandard()
{ {
for (byte i = 0; i<3; i++) for (byte i = 0; i<3; i++)
@ -56,6 +70,7 @@ void setLedsStandard()
setAllLeds(); setAllLeds();
} }
bool colorChanged() bool colorChanged()
{ {
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
@ -68,12 +83,19 @@ bool colorChanged()
return false; return false;
} }
void colorUpdated(int callMode) void colorUpdated(int callMode)
{ {
//call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (NN)6: fx changed 7: hue 8: preset cycle 9: blynk //call for notifier -> 0: init 1: direct change 2: button 3: notification 4: nightlight 5: other (No notification)
// 6: fx changed 7: hue 8: preset cycle 9: blynk
bool fxChanged = strip.setEffectConfig(effectCurrent, effectSpeed, effectIntensity, effectPalette);
if (!colorChanged()) if (!colorChanged())
{ {
if (callMode == 6) notify(6); if (nightlightActive && !nightlightActiveOld && callMode != 3 && callMode != 5)
{
notify(4); return;
}
else if (fxChanged) notify(6);
return; //no change return; //no change
} }
if (callMode != 5 && nightlightActive && nightlightFade) if (callMode != 5 && nightlightActive && nightlightFade)
@ -133,6 +155,7 @@ void colorUpdated(int callMode)
updateInterfaces(callMode); updateInterfaces(callMode);
} }
void updateInterfaces(uint8_t callMode) void updateInterfaces(uint8_t callMode)
{ {
if (callMode != 9 && callMode != 5) updateBlynk(); if (callMode != 9 && callMode != 5) updateBlynk();
@ -140,6 +163,7 @@ void updateInterfaces(uint8_t callMode)
lastInterfaceUpdate = millis(); lastInterfaceUpdate = millis();
} }
void handleTransitions() void handleTransitions()
{ {
//handle still pending interface update //handle still pending interface update
@ -180,6 +204,7 @@ void handleTransitions()
} }
} }
void handleNightlight() void handleNightlight()
{ {
if (nightlightActive) if (nightlightActive)
@ -187,7 +212,6 @@ void handleNightlight()
if (!nightlightActiveOld) //init if (!nightlightActiveOld) //init
{ {
nightlightStartTime = millis(); nightlightStartTime = millis();
notify(4);
nightlightDelayMs = (int)(nightlightDelayMins*60000); nightlightDelayMs = (int)(nightlightDelayMins*60000);
nightlightActiveOld = true; nightlightActiveOld = true;
briNlT = bri; briNlT = bri;

View File

@ -6,15 +6,15 @@ void handleButton()
{ {
if (buttonEnabled) if (buttonEnabled)
{ {
if (digitalRead(buttonPin) == LOW && !buttonPressedBefore) if (digitalRead(BTNPIN) == LOW && !buttonPressedBefore)
{ {
buttonPressedTime = millis(); buttonPressedTime = millis();
buttonPressedBefore = true; buttonPressedBefore = true;
} }
else if (digitalRead(buttonPin) == HIGH && buttonPressedBefore) else if (digitalRead(BTNPIN) == HIGH && buttonPressedBefore)
{ {
delay(15); //debounce delay(15); //debounce
if (digitalRead(buttonPin) == HIGH) if (digitalRead(BTNPIN) == HIGH)
{ {
if (millis() - buttonPressedTime > 7000) {initAP();} if (millis() - buttonPressedTime > 7000) {initAP();}
else if (millis() - buttonPressedTime > 700) else if (millis() - buttonPressedTime > 700)
@ -25,14 +25,7 @@ void handleButton()
else { else {
if (macroButton == 0) if (macroButton == 0)
{ {
if (bri == 0) toggleOnOff();
{
bri = briLast;
} else
{
briLast = bri;
bri = 0;
}
colorUpdated(2); colorUpdated(2);
} else { } else {
applyMacro(macroButton); applyMacro(macroButton);
@ -51,9 +44,9 @@ void handleButton()
auxActiveBefore = true; auxActiveBefore = true;
switch (auxTriggeredState) switch (auxTriggeredState)
{ {
case 0: pinMode(auxPin, INPUT); break; case 0: pinMode(AUXPIN, INPUT); break;
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break; case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break; case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
} }
auxStartTime = millis(); auxStartTime = millis();
} }
@ -63,9 +56,9 @@ void handleButton()
auxActiveBefore = false; auxActiveBefore = false;
switch (auxDefaultState) switch (auxDefaultState)
{ {
case 0: pinMode(auxPin, INPUT); break; case 0: pinMode(AUXPIN, INPUT); break;
case 1: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, HIGH); break; case 1: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, HIGH); break;
case 2: pinMode(auxPin, OUTPUT); digitalWrite(auxPin, LOW); break; case 2: pinMode(AUXPIN, OUTPUT); digitalWrite(AUXPIN, LOW); break;
} }
} }
} }

View File

@ -2,6 +2,14 @@
* Color conversion methods * Color conversion methods
*/ */
void colorFromUint32(uint32_t in)
{
white = in >> 24 & 0xFF;
col[0] = in >> 16 & 0xFF;
col[1] = in >> 8 & 0xFF;
col[2] = in & 0xFF;
}
void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb void colorHStoRGB(uint16_t hue, byte sat, byte* rgb) //hue, sat to rgb
{ {
float h = ((float)hue)/65535.0; float h = ((float)hue)/65535.0;

View File

@ -66,22 +66,19 @@ BLYNK_WRITE(V3)
BLYNK_WRITE(V4) BLYNK_WRITE(V4)
{ {
effectCurrent = param.asInt()-1;//fx effectCurrent = param.asInt()-1;//fx
strip.setMode(effectCurrent); colorUpdated(9);
colorUpdated(6);
} }
BLYNK_WRITE(V5) BLYNK_WRITE(V5)
{ {
effectSpeed = param.asInt();//sx effectSpeed = param.asInt();//sx
strip.setSpeed(effectSpeed); colorUpdated(9);
colorUpdated(6);
} }
BLYNK_WRITE(V6) BLYNK_WRITE(V6)
{ {
effectIntensity = param.asInt();//ix effectIntensity = param.asInt();//ix
strip.setIntensity(effectIntensity); colorUpdated(9);
colorUpdated(6);
} }
BLYNK_WRITE(V7) BLYNK_WRITE(V7)

View File

@ -5,7 +5,7 @@
void parseMQTTBriPayload(char* payload) void parseMQTTBriPayload(char* payload)
{ {
if (strcmp(payload, "ON") == 0) {bri = briLast; colorUpdated(1);} if (strcmp(payload, "ON") == 0) {bri = briLast; colorUpdated(1);}
else if (strcmp(payload, "T" ) == 0) {handleSet("win&T=2");} else if (strcmp(payload, "T" ) == 0) {toggleOnOff(); colorUpdated(1);}
else { else {
uint8_t in = strtoul(payload, NULL, 10); uint8_t in = strtoul(payload, NULL, 10);
if (in == 0 && bri > 0) briLast = bri; if (in == 0 && bri > 0) briLast = bri;
@ -60,7 +60,7 @@ void publishMQTT()
//if you want to use this, increase the MQTT buffer in PubSubClient.h to 350+ //if you want to use this, increase the MQTT buffer in PubSubClient.h to 350+
//it will publish the API response to MQTT //it will publish the API response to MQTT
/*XML_response(false); /*XML_response(false, false);
strcpy(subuf, mqttDeviceTopic); strcpy(subuf, mqttDeviceTopic);
strcat(subuf, "/v"); strcat(subuf, "/v");
mqtt->publish(subuf, obuf);*/ mqtt->publish(subuf, obuf);*/

View File

@ -101,9 +101,16 @@ void initServer()
}); });
server.on("/power", HTTP_GET, [](){ server.on("/power", HTTP_GET, [](){
String val = (String)(int)strip.getPowerEstimate(ledCount,strip.getColor(),strip.getBrightness()); String val = "";
if (strip.currentMilliamps == 0)
{
val = "Power calculation disabled";
} else
{
val += (String)strip.currentMilliamps;
val += "mA currently"; val += "mA currently";
serveMessage(200,val,"This is just an estimate (does not take into account several factors like effects and wire resistance). It is NOT an accurate measurement!",254); }
serveMessage(200, val, "This is just an estimate (does not account for factors like wire resistance). It is NOT a measurement!", 254);
}); });
server.on("/u", HTTP_GET, [](){ server.on("/u", HTTP_GET, [](){
@ -113,7 +120,7 @@ void initServer()
}); });
server.on("/teapot", HTTP_GET, [](){ server.on("/teapot", HTTP_GET, [](){
serveMessage(418, "418. I'm a teapot.","(Tangible Embedded Advanced Project Of Twinkling)",254); serveMessage(418, "418. I'm a teapot.", "(Tangible Embedded Advanced Project Of Twinkling)", 254);
}); });
server.on("/build", HTTP_GET, [](){ server.on("/build", HTTP_GET, [](){
@ -136,7 +143,7 @@ void initServer()
httpUpdater.setup(&server); httpUpdater.setup(&server);
#else #else
server.on("/update", HTTP_GET, [](){ server.on("/update", HTTP_GET, [](){
serveMessage(500, "Not implemented", "OTA updates are not supported in this build.", 254); serveMessage(500, "Not implemented", "OTA updates are unsupported in this build.", 254);
}); });
#endif #endif
} else } else
@ -185,43 +192,6 @@ void initServer()
#endif #endif
} }
void buildCssColorString()
{
String cs[]={"","","","","",""};
switch (currentTheme)
{
default: cs[0]="D9B310"; cs[1]="0B3C5D"; cs[2]="1D2731"; cs[3]="328CC1"; cs[4]="000"; cs[5]="328CC1"; break; //night
case 1: cs[0]="eee"; cs[1]="ddd"; cs[2]="b9b9b9"; cs[3]="049"; cs[4]="777"; cs[5]="049"; break; //modern
case 2: cs[0]="abc"; cs[1]="fff"; cs[2]="ddd"; cs[3]="000"; cs[4]="0004"; cs[5]="000"; break; //bright
case 3: cs[0]="c09f80"; cs[1]="d7cec7"; cs[2]="76323f"; cs[3]="888"; cs[4]="3334"; cs[5]="888"; break; //wine
case 4: cs[0]="3cc47c"; cs[1]="828081"; cs[2]="d9a803"; cs[3]="1e392a"; cs[4]="000a"; cs[5]="1e392a"; break; //electric
case 5: cs[0]="57bc90"; cs[1]="a5a5af"; cs[2]="015249"; cs[3]="88c9d4"; cs[4]="0004"; cs[5]="88c9d4"; break; //mint
case 6: cs[0]="f7c331"; cs[1]="dcc7aa"; cs[2]="6b7a8f"; cs[3]="f7882f"; cs[4]="0007"; cs[5]="f7882f"; break; //amber
case 7: cs[0]="fc3"; cs[1]="124"; cs[2]="334"; cs[3]="f1d"; cs[4]="f00"; cs[5]="f1d"; break;//club
case 8: cs[0]="0ac"; cs[1]="124"; cs[2]="224"; cs[3]="003eff"; cs[4]="003eff"; cs[5]="003eff"; break;//air
case 9: cs[0]="f70"; cs[1]="421"; cs[2]="221"; cs[3]="a50"; cs[4]="f70"; cs[5]="f70"; break;//nixie
case 10: cs[0]="2d2"; cs[1]="010"; cs[2]="121"; cs[3]="060"; cs[4]="040"; cs[5]="3f3"; break; //terminal
case 11: cs[0]="867ADE"; cs[1]="4033A3"; cs[2]="483AAA"; cs[3]="483AAA"; cs[4]=""; cs[5]="867ADE"; break; //c64
case 12: cs[0]="fbe8a6"; cs[1]="d2fdff"; cs[2]="b4dfe5"; cs[3]="f4976c"; cs[4]=""; cs[5]="303c6c"; break; //c64
case 14: cs[0]="fc7"; cs[1]="49274a"; cs[2]="94618e"; cs[3]="f4decb"; cs[4]="0008"; cs[5]="f4decb"; break; //end
case 15: for (int i=0;i<6;i++)cs[i]=cssCol[i];//custom
}
cssColorString="<style>:root{--aCol:#";
cssColorString+=cs[0];
cssColorString+=";--bCol:#";
cssColorString+=cs[1];
cssColorString+=";--cCol:#";
cssColorString+=cs[2];
cssColorString+=";--dCol:#";
cssColorString+=cs[3];
cssColorString+=";--sCol:#";
cssColorString+=cs[4];
cssColorString+=";--tCol:#";
cssColorString+=cs[5];
cssColorString+=";--cFn:";
cssColorString+=cssFont;
cssColorString+=";}";
}
void serveIndexOrWelcome() void serveIndexOrWelcome()
{ {
@ -253,6 +223,22 @@ void serveRealtimeError(bool settings)
server.send(200, "text/plain", mesg); server.send(200, "text/plain", mesg);
} }
void getCSSColors()
{
char cs[6][9];
getThemeColors(cs);
oappend("<style>:root{--aCol:#"); oappend(cs[0]);
oappend(";--bCol:#"); oappend(cs[1]);
oappend(";--cCol:#"); oappend(cs[2]);
oappend(";--dCol:#"); oappend(cs[3]);
oappend(";--sCol:#"); oappend(cs[4]);
oappend(";--tCol:#"); oappend(cs[5]);
oappend(";--cFn:"); oappend(cssFont);
oappend(";}");
}
void serveIndex() void serveIndex()
{ {
bool serveMobile = false; bool serveMobile = false;
@ -265,25 +251,24 @@ void serveIndex()
return; return;
} }
if (serveMobile) //error message is not gzipped
{ #ifdef WLED_DISABLE_MOBILE_UI
server.setContentLength(strlen_P(PAGE_indexM)); if (!serveMobile) server.sendHeader("Content-Encoding","gzip");
server.send(200, "text/html", ""); #else
server.sendContent_P(PAGE_indexM); server.sendHeader("Content-Encoding","gzip");
} else #endif
{
server.setContentLength(strlen_P(PAGE_index0) + cssColorString.length() + strlen_P(PAGE_index1) + strlen_P(PAGE_index2) + strlen_P(PAGE_index3)); server.send_P(200, "text/html",
server.send(200, "text/html", ""); (serveMobile) ? PAGE_indexM : PAGE_index0,
server.sendContent_P(PAGE_index0); (serveMobile) ? PAGE_indexM_L : PAGE_index0_L);
server.sendContent(cssColorString);
server.sendContent_P(PAGE_index1);
server.sendContent_P(PAGE_index2);
server.sendContent_P(PAGE_index3);
}
} }
void serveMessage(int code, String headl, String subl="", int optionType) void serveMessage(int code, String headl, String subl="", int optionType)
{ {
olen = 0;
getCSSColors();
String messageBody = "<h2>"; String messageBody = "<h2>";
messageBody += headl; messageBody += headl;
messageBody += "</h2>"; messageBody += "</h2>";
@ -305,14 +290,15 @@ void serveMessage(int code, String headl, String subl="", int optionType)
messageBody += "<script>setTimeout(RP," + String((optionType-120)*1000) + ")</script>"; messageBody += "<script>setTimeout(RP," + String((optionType-120)*1000) + ")</script>";
} }
messageBody += "</body></html>"; messageBody += "</body></html>";
server.setContentLength(strlen_P(PAGE_msg0) + cssColorString.length() + strlen_P(PAGE_msg1) + messageBody.length()); server.setContentLength(strlen_P(PAGE_msg0) + olen + strlen_P(PAGE_msg1) + messageBody.length());
server.send(code, "text/html", ""); server.send(code, "text/html", "");
server.sendContent_P(PAGE_msg0); server.sendContent_P(PAGE_msg0);
server.sendContent(cssColorString); server.sendContent(obuf);
server.sendContent_P(PAGE_msg1); server.sendContent_P(PAGE_msg1);
server.sendContent(messageBody); server.sendContent(messageBody);
} }
void serveSettings(byte subPage) void serveSettings(byte subPage)
{ {
if (realtimeActive && !enableRealtimeUI) //do not serve while receiving realtime if (realtimeActive && !enableRealtimeUI) //do not serve while receiving realtime
@ -338,35 +324,38 @@ void serveSettings(byte subPage)
default: pl0 = strlen_P(PAGE_settings0); pl1 = strlen_P(PAGE_settings1); default: pl0 = strlen_P(PAGE_settings0); pl1 = strlen_P(PAGE_settings1);
} }
getSettingsJS(subPage); uint16_t sCssLength = (subPage >0 && subPage <7)?strlen_P(PAGE_settingsCss):0;
int sCssLength = (subPage >0 && subPage <7)?strlen_P(PAGE_settingsCss):0;
server.setContentLength(pl0 + cssColorString.length() + olen + sCssLength + pl1); getSettingsJS(subPage);
getCSSColors();
server.setContentLength(pl0 + olen + sCssLength + pl1);
server.send(200, "text/html", ""); server.send(200, "text/html", "");
switch (subPage) switch (subPage)
{ {
case 1: server.sendContent_P(PAGE_settings_wifi0); break; case 1: server.sendContent_P(PAGE_settings_wifi0); break;
case 2: server.sendContent_P(PAGE_settings_leds0); break; case 2: server.sendContent_P(PAGE_settings_leds0); break;
case 3: server.sendContent_P(PAGE_settings_ui0); break; case 3: server.sendContent_P(PAGE_settings_ui0 ); break;
case 4: server.sendContent_P(PAGE_settings_sync0); break; case 4: server.sendContent_P(PAGE_settings_sync0); break;
case 5: server.sendContent_P(PAGE_settings_time0); break; case 5: server.sendContent_P(PAGE_settings_time0); break;
case 6: server.sendContent_P(PAGE_settings_sec0); break; case 6: server.sendContent_P(PAGE_settings_sec0 ); break;
case 255: server.sendContent_P(PAGE_welcome0); break; case 255: server.sendContent_P(PAGE_welcome0 ); break;
default: server.sendContent_P(PAGE_settings0); default: server.sendContent_P(PAGE_settings0 );
} }
server.sendContent(obuf); server.sendContent(obuf);
server.sendContent(cssColorString);
if (subPage >0 && subPage <7) server.sendContent_P(PAGE_settingsCss); if (subPage >0 && subPage <7) server.sendContent_P(PAGE_settingsCss);
switch (subPage) switch (subPage)
{ {
case 1: server.sendContent_P(PAGE_settings_wifi1); break; case 1: server.sendContent_P(PAGE_settings_wifi1); break;
case 2: server.sendContent_P(PAGE_settings_leds1); break; case 2: server.sendContent_P(PAGE_settings_leds1); break;
case 3: server.sendContent_P(PAGE_settings_ui1); break; case 3: server.sendContent_P(PAGE_settings_ui1 ); break;
case 4: server.sendContent_P(PAGE_settings_sync1); break; case 4: server.sendContent_P(PAGE_settings_sync1); break;
case 5: server.sendContent_P(PAGE_settings_time1); break; case 5: server.sendContent_P(PAGE_settings_time1); break;
case 6: server.sendContent_P(PAGE_settings_sec1); break; case 6: server.sendContent_P(PAGE_settings_sec1 ); break;
case 255: server.sendContent_P(PAGE_welcome1); break; case 255: server.sendContent_P(PAGE_welcome1 ); break;
default: server.sendContent_P(PAGE_settings1); default: server.sendContent_P(PAGE_settings1 );
} }
} }

155
wled00/wled19_ir.ino Normal file
View File

@ -0,0 +1,155 @@
/*
* Infrared sensor support for generic 24 key RGB remote
*/
#if defined(WLED_DISABLE_INFRARED) || defined(ARDUINO_ARCH_ESP32)
void handleIR(){}
#else
IRrecv* irrecv;
//change pin in NpbWrapper.h
decode_results results;
unsigned long irCheckedTime = 0;
uint32_t lastValidCode = 0;
uint16_t irTimesRepeated = 0;
//Add what your custom IR codes should trigger here. Guide: https://github.com/Aircoookie/WLED/wiki/Infrared-Control
//IR codes themselves can be defined directly after "case" or in "ir_codes.h"
bool decodeIRCustom(uint32_t code)
{
switch (code)
{
//just examples, feel free to modify or remove
case IRCUSTOM_ONOFF : toggleOnOff(); break;
case IRCUSTOM_MACRO1 : applyMacro(1); break;
default: return false;
}
if (code != IRCUSTOM_MACRO1) colorUpdated(2); //don't update color again if we apply macro, it already does it
return true;
}
//relatively change brightness, minumum A=5
void relativeChange(byte* property, int8_t amount, byte lowerBoundary =0)
{
int16_t new_val = (int16_t) *property + amount;
if (new_val > 0xFF) new_val = 0xFF;
else if (new_val < lowerBoundary) new_val = lowerBoundary;
*property = new_val;
}
void decodeIR(uint32_t code)
{
if (code == 0xFFFFFFFF) //repeated code, continue brightness up/down
{
irTimesRepeated++;
if (lastValidCode == IR24_BRIGHTER)
{
relativeChange(&bri, 10); colorUpdated(2);
}
else if (lastValidCode == IR24_DARKER)
{
relativeChange(&bri, -10, 5); colorUpdated(2);
}
else if (lastValidCode == IR24_ON && irTimesRepeated > 7)
{
nightlightActive = true;
nightlightStartTime = millis();
colorUpdated(2);
}
return;
}
lastValidCode = 0; irTimesRepeated = 0;
if (decodeIRCustom(code)) return;
if (code > 0xFFFFFF) return; //invalid code
else if (code > 0xFF0000) decodeIR44(code); //is in 44-key remote range
else if (code > 0xF70000 && code < 0xF80000) decodeIR24(code); //is in 24-key remote range
//code <= 0xF70000 also invalid
}
void decodeIR24(uint32_t code)
{
switch (code) {
case IR24_BRIGHTER : relativeChange(&bri, 10); break;
case IR24_DARKER : relativeChange(&bri, -10, 5); break;
case IR24_OFF : briLast = bri; bri = 0; break;
case IR24_ON : bri = briLast; break;
case IR24_RED : colorFromUint32(COLOR_RED); break;
case IR24_REDDISH : colorFromUint32(COLOR_REDDISH); break;
case IR24_ORANGE : colorFromUint32(COLOR_ORANGE); break;
case IR24_YELLOWISH : colorFromUint32(COLOR_YELLOWISH); break;
case IR24_YELLOW : colorFromUint32(COLOR_YELLOW); break;
case IR24_GREEN : colorFromUint32(COLOR_GREEN); break;
case IR24_GREENISH : colorFromUint32(COLOR_GREENISH); break;
case IR24_TURQUOISE : colorFromUint32(COLOR_TURQUOISE); break;
case IR24_CYAN : colorFromUint32(COLOR_CYAN); break;
case IR24_AQUA : colorFromUint32(COLOR_AQUA); break;
case IR24_BLUE : colorFromUint32(COLOR_BLUE); break;
case IR24_DEEPBLUE : colorFromUint32(COLOR_DEEPBLUE); break;
case IR24_PURPLE : colorFromUint32(COLOR_PURPLE); break;
case IR24_MAGENTA : colorFromUint32(COLOR_MAGENTA); break;
case IR24_PINK : colorFromUint32(COLOR_PINK); break;
case IR24_WHITE : colorFromUint32(COLOR_WHITE); effectCurrent = 0; break;
case IR24_FLASH : if (!applyPreset(1)) effectCurrent = FX_MODE_COLORTWINKLE; break;
case IR24_STROBE : if (!applyPreset(2)) effectCurrent = FX_MODE_RAINBOW_CYCLE; break;
case IR24_FADE : if (!applyPreset(3)) effectCurrent = FX_MODE_BREATH; break;
case IR24_SMOOTH : if (!applyPreset(4)) effectCurrent = FX_MODE_RAINBOW; break;
default: return;
}
lastValidCode = code;
colorUpdated(2); //for notifier, IR is considered a button input
}
void decodeIR44(uint32_t code)
{
//not implemented for now
}
void initIR()
{
if (irEnabled)
{
irrecv = new IRrecv(IR_PIN);
irrecv->enableIRIn();
}
}
void handleIR()
{
if (irEnabled && millis() - irCheckedTime > 120)
{
irCheckedTime = millis();
if (irEnabled)
{
if (irrecv == NULL)
{
initIR(); return;
}
if (irrecv->decode(&results))
{
Serial.print("IR recv\r\n0x");
Serial.println((uint32_t)results.value, HEX);
Serial.println();
decodeIR(results.value);
irrecv->resume();
}
} else if (irrecv != NULL)
{
irrecv->disableIRIn();
delete irrecv; irrecv = NULL;
}
}
}
#endif