Compare commits

...

46 Commits

Author SHA1 Message Date
Blaz Kristan
2f6f0d2f3e WLED 0.14.4 2024-05-18 15:17:08 +02:00
Blaz Kristan
2aec21a6d0 Palette loading optimisation
- fixes #3978
- FX: Firenoise can use selected palette
2024-05-16 06:23:15 +02:00
Frank
ecc9443677 (0_14 branch only) adding compatibility for building with upstream arduinoFFT 2.xx
support compilation with new arduinoFFT versions 2.x
2024-05-11 14:45:42 +02:00
Blaž Kristan
197f47befe Merge pull request #3905 from w00000dy/main
Set stale lable to 'stale' and increase operations-per-run in stale.yml
2024-04-16 20:31:16 +02:00
Woody
6272969983 Set stale-pr-label & stale-issue-label to 'stale' in stale.yml
Hopefully this fixes the error messages that were thrown the last time the action was executed
2024-04-16 15:07:12 +02:00
Woody
b2e68db380 Increase operations-per-run in stale.yml again 2024-04-15 22:56:38 +02:00
Blaž Kristan
80ebcb2c28 Merge pull request #3901 from w00000dy/main
Increase operations-per-run in stale.yml
2024-04-14 15:47:31 +02:00
Woody
cd928bc586 Increase operations-per-run in stale.yml
Because of this we don't need to run this action 3 times a day
2024-04-14 13:14:03 +02:00
dependabot[bot]
d2b4d25317 Bump idna from 3.4 to 3.7 (#3895)
Bumps [idna](https://github.com/kjd/idna) from 3.4 to 3.7.
- [Release notes](https://github.com/kjd/idna/releases)
- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst)
- [Commits](https://github.com/kjd/idna/compare/v3.4...v3.7)

---
updated-dependencies:
- dependency-name: idna
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-13 19:38:03 +02:00
Woody
a418cd2a2a Activate stale (#3898)
* Update stale.yml

Update pr text
Schedule action 3 times a day

* Delete old .github/stale.yml

* Set exempt-all-milestones to true in stale.yml
2024-04-13 19:37:49 +02:00
Blaž Kristan
8358272b9a Merge pull request #3876 from w00000dy/main
Create new stale.yml
2024-04-10 19:42:52 +02:00
Blaz Kristan
00f5471270 Build bump, changelog udate 2024-04-04 21:59:41 +02:00
Will Miles
bff6697690 Update to AsyncWebServer v2.2.1 2024-04-03 18:23:50 +02:00
Woody
02405b4856 Create stale.yml 2024-04-03 12:32:18 +02:00
Blaz Kristan
6d278994ec WLED 0.14.3 release
- Fix for transition 0 (#3854, #3832, #3720)
- copyright year update
- updated AsyncWebServer to v2.2.0
2024-03-29 20:05:56 +01:00
Blaz Kristan
acf6736afd WLED 0.14.2 release 2024-03-17 11:52:09 +01:00
Frank
a42f78b08b Update CONTRIBUTING.md
Trying to explain why any PR should have a`description`
2024-03-14 20:27:03 +01:00
Blaz Kristan
9d70ec56f2 Distinguish 160MHz binaries 2024-03-11 23:22:14 +01:00
Blaz Kristan
7f8ec59939 Changelog update 2024-03-11 23:08:50 +01:00
Blaz Kristan
0398ec40b7 Merge branch 'main' into v0142-beta2 2024-03-11 23:00:17 +01:00
Blaz Kristan
f55465f8b8 Fix AsyncWebServer library 2024-03-11 18:02:03 +01:00
Christian Schwinne
6322ab9f07 . 2024-03-09 22:00:18 +01:00
Christian Schwinne
21d0f10dd7 Fix AR compilation 2024-03-09 21:59:45 +01:00
Christian Schwinne
91c11a18e0 Update CONTRIBUTING.md 2024-03-09 21:31:53 +01:00
Will Miles
d9b0df94e2 LockedJsonResponse: Release early if possible
Release the json buffer lock as soon as we've finished serializing.
This should slightly reduce the number of lock collisions as the
response class isn't destructed until after the last packet is ack'd.
2024-03-03 10:58:40 +01:00
Blaz Kristan
1fc0680c71 160MHz clock & alternate AWS 2024-03-02 14:12:57 +01:00
Will Miles
c8c394b4e9 TZ_TABLE: Add missing const 2024-02-20 18:33:18 +01:00
Will Miles
59886a1528 Move timezone table to PROGMEM 2024-02-20 18:33:09 +01:00
Blaz Kristan
a4733b4d91 Move strings into flash 2024-02-18 14:25:07 +01:00
Blaz Kristan
c932621b5d string fix 2024-02-17 15:00:47 +01:00
Frank
8422ffcd19 Fixing a potential array bounds violation in ESPDMX
DMXESPSerial::write and DMXESPSerial::read could access DMXDataStore[512] -   one more than the allocated number of elements (i.e. 0...511].
2024-02-15 00:53:00 +01:00
Blaž Kristan
0a815179a2 Merge pull request #3758 from lost-hope/main
Fixing stairway usermod and adding buildflags
2024-02-14 09:45:52 +01:00
lost-hope
23aad24027 Fixing stairway usermod and adding buildflags
Fixing Stairway:
missing setup function

Adding builflags:
USERMOD_STAIRCASE_WIPE to install the usermod
2024-02-12 22:41:13 +01:00
Blaz Kristan
7ae5459fe7 0.14.2-b1 2024-02-12 13:29:08 +01:00
Blaz Kristan
0a8a88421e Possible fix for #3589 & partial fix for #3605 2024-02-12 13:20:47 +01:00
Blaz Kristan
4f42a176ef Prevent JSON buffer clear after failed lock attempt
(alternative to #3743)
2024-02-11 20:12:54 +01:00
Blaz Kristan
4457067045 Multiple analog button fix for #3549 2024-02-10 11:47:40 +01:00
Blaž Kristan
3d6f25a9d3 Merge pull request #3732 from wled-install/patch-1
UM Audioreactive: add two compiler options
2024-02-01 17:07:00 +01:00
wled-install
917a981096 Update audio_reactive.h 2024-01-31 06:34:15 +01:00
wled-install
89f8b6060f Update readme.md 2024-01-31 06:33:48 +01:00
wled-install
345346315a Update readme.md 2024-01-30 22:59:29 +01:00
wled-install
f1c27e1798 Update readme.md 2024-01-30 22:56:09 +01:00
wled-install
4316024dc7 Update audio_reactive.h 2024-01-30 22:51:18 +01:00
Frank
2b0fad87d2 Merge pull request #3722 from lost-hope/main
Usermod Klipper Percentage: Fix for include paths (windows backslash vs. linux slash)
2024-01-26 11:41:02 +01:00
lost-hope
7afa550ba4 Usermod Klipper Percentage: fix error with slashes on non windows devices 2024-01-25 17:55:41 +01:00
Blaz Kristan
74fed5695f Fix for #3693 2024-01-16 19:34:23 +01:00
30 changed files with 1571 additions and 1067 deletions

20
.github/stale.yml vendored
View File

@@ -1,20 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 120
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- pinned
- keep
- enhancement
- confirmed
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
Hey! This issue has been open for quite some time without any new comments now.
It will be closed automatically in a week if no further activity occurs.
Thank you for using WLED!
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

30
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,30 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '0 12 * * *'
workflow_dispatch:
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
days-before-stale: 120
days-before-close: 7
stale-issue-label: 'stale'
stale-pr-label: 'stale'
exempt-issue-labels: 'pinned,keep,enhancement,confirmed'
exempt-pr-labels: 'pinned,keep,enhancement,confirmed'
exempt-all-milestones: true
operations-per-run: 1000
stale-issue-message: >
Hey! This issue has been open for quite some time without any new comments now.
It will be closed automatically in a week if no further activity occurs.
Thank you for using WLED! ✨
stale-pr-message: >
Hey! This pull request has been open for quite some time without any new comments now.
It will be closed automatically in a week if no further activity occurs.
Thank you for contributing to WLED! ❤️

View File

@@ -1,5 +1,34 @@
## WLED changelog
#### Build 2405180
- WLED 0.14.4 release
- Fix for #3978
#### Build 2404040
- WLED 0.14.3 release
- Fix for transition 0 (#3854, #3832, #3720)
- Fix for #3855 via #3873 (by @willmmiles)
#### Build 2403170
- WLED 0.14.2 release
#### Build 2403110
- Beta WLED 0.14.2-b2
- New AsyncWebServer (improved performance and reduced memory use)
- New builds for ESP8266 with 160MHz CPU clock
- Fixing stairway usermod and adding buildflags (#3758 by @lost-hope)
- Fixing a potential array bounds violation in ESPDMX
- Reduced RAM usage (moved strings and TZ data (by @willmmiles) to PROGMEM)
- LockedJsonResponse: Release early if possible (by @willmmiles)
#### Build 2402120
- Beta WLED 0.14.2-b1
- Possible fix for #3589 & partial fix for #3605
- Prevent JSON buffer clear after failed lock attempt
- Multiple analog button fix for #3549
- UM Audioreactive: add two compiler options (#3732 by @wled-install)
- Fix for #3693
#### Build 2401141
- Official release of WLED 0.14.1
- Fix for #3566, #3665, #3672

View File

@@ -2,6 +2,20 @@
Here are a few suggestions to make it easier for you to contribute!
### Describe your PR
Please add a description of your proposed code changes. It does not need to be an exhaustive essay, however a PR with no description or just a few words might not get accepted, simply because very basic information is missing.
A good description helps us to review and understand your proposed changes. For example, you could say a few words about
* what you try to achieve (new feature, fixing a bug, refactoring, security enhancements, etc.)
* how your code works (short technical summary - focus on important aspects that might not be obvious when reading the code)
* testing you performed, known limitations, open ends you possibly could not solve.
* any areas where you like to get help from an experienced maintainer (yes WLED has become big 😉)
### Target branch for pull requests
Please make all PRs against the `0_15` branch.
### Code style
When in doubt, it is easiest to replicate the code style you find in the files you want to edit :)
@@ -73,6 +87,6 @@ Good:
<!-- This is an HTML comment -->
```
There is no set character limit for a comment within a line,
though as a rule of thumb you should wrap your comment if it exceeds the width of your editor window.
Inline comments are OK if they describe that line only and are not exceedingly wide.
There is no hard character limit for a comment within a line,
though as a rule of thumb consider wrapping after 120 characters.
Inline comments are OK if they describe that line only and are not exceedingly wide.

1605
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "wled",
"version": "0.14.1",
"version": "0.14.4",
"description": "Tools for WLED project",
"main": "tools/cdata.js",
"directories": {

View File

@@ -11,7 +11,7 @@
# CI binaries
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth # ESP32 variant builds are temporarily excluded from CI due to toolchain issues on the GitHub Actions Linux environment
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, esp32dev_audioreactive, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB, esp32s3dev_8MB_PSRAM_opi
default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, nodemcuv2_160, esp8266_2m_160, esp01_1m_full_160, esp32dev, esp32_eth, esp32dev_audioreactive, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB, esp32s3dev_8MB_PSRAM_opi
# Release binaries
; default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, esp32dev, esp32_eth, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB
@@ -63,7 +63,7 @@ arduino_core_2_7_4 = espressif8266@2.6.2
arduino_core_3_0_0 = espressif8266@3.0.0
arduino_core_3_2_0 = espressif8266@3.2.0
arduino_core_4_1_0 = espressif8266@4.1.0
arduino_core_3_1_2 = espressif8266@4.2.0
arduino_core_3_1_2 = espressif8266@4.2.1
# Development platforms
arduino_core_develop = https://github.com/platformio/platform-espressif8266#develop
@@ -73,8 +73,7 @@ arduino_core_git = https://github.com/platformio/platform-espressif8266#feature/
platform_wled_default = ${common.arduino_core_3_1_2}
# We use 2.7.4.7 for all, includes PWM flicker fix and Wstring optimization
#platform_packages = tasmota/framework-arduinoespressif8266 @ 3.20704.7
platform_packages = platformio/framework-arduinoespressif8266
platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
platform_packages = platformio/toolchain-xtensa @ ~2.100300.220621 #2.40802.200502
platformio/tool-esptool #@ ~1.413.0
platformio/tool-esptoolpy #@ ~1.30000.0
@@ -181,7 +180,7 @@ lib_deps =
fastled/FastLED @ 3.6.0
IRremoteESP8266 @ 2.8.2
makuna/NeoPixelBus @ 2.7.5
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.7
https://github.com/Aircoookie/ESPAsyncWebServer.git @ 2.2.1
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
#TFT_eSPI
#For compatible OLED display uncomment following
@@ -245,7 +244,7 @@ lib_deps =
${env.lib_deps}
# additional build flags for audioreactive
AR_build_flags = -D USERMOD_AUDIOREACTIVE -D UM_AUDIOREACTIVE_USE_NEW_FFT
AR_lib_deps = https://github.com/kosme/arduinoFFT#develop @ ^1.9.2
AR_lib_deps = https://github.com/kosme/arduinoFFT#419d7b0
[esp32_idf_V4]
;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5
@@ -337,6 +336,11 @@ build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266 #-DWLED
lib_deps = ${esp8266.lib_deps}
monitor_filters = esp8266_exception_decoder
[env:nodemcuv2_160]
extends = env:nodemcuv2
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP8266_160 #-DWLED_DISABLE_2D
[env:esp8266_2m]
board = esp_wroom_02
platform = ${common.platform_wled_default}
@@ -346,6 +350,11 @@ build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02
lib_deps = ${esp8266.lib_deps}
[env:esp8266_2m_160]
extends = env:esp8266_2m
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP02_160
[env:esp01_1m_full]
board = esp01_1m
platform = ${common.platform_wled_default}
@@ -356,6 +365,12 @@ build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_D
; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 7064 bytes FLASH and 975 bytes RAM
lib_deps = ${esp8266.lib_deps}
[env:esp01_1m_full_160]
extends = env:esp01_1m_full
board_build.f_cpu = 160000000L
build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01_160 -D WLED_DISABLE_OTA
; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 7064 bytes FLASH and 975 bytes RAM
[env:esp07]
board = esp07
platform = ${common.platform_wled_default}

View File

@@ -1,65 +0,0 @@
# Example PlatformIO Project Configuration Override
# ------------------------------------------------------------------------------
# Copy to platformio_override.ini to activate overrides
# ------------------------------------------------------------------------------
# Please visit documentation: https://docs.platformio.org/page/projectconf.html
[platformio]
default_envs = WLED_tasmota_1M
[env:WLED_tasmota_1M]
board = esp01_1m
platform = ${common.platform_wled_default}
platform_packages = ${common.platform_packages}
board_build.ldscript = ${common.ldscript_1m128k}
lib_deps = ${esp8266.lib_deps}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags_esp8266}
; *********************************************************************
; *** Use custom settings from file my_config.h
-DWLED_USE_MY_CONFIG
; *********************************************************************
;
;
; *** To use the below defines/overrides, copy and paste each onto it's own line just below build_flags in the section above.
;
; disable specific features
; -D WLED_DISABLE_OTA
; -D WLED_DISABLE_ALEXA
; -D WLED_DISABLE_HUESYNC
; -D WLED_DISABLE_INFRARED
; -D WLED_DISABLE_WEBSOCKETS
; PIN defines - uncomment and change, if needed:
; -D LEDPIN=2
; -D BTNPIN=0
; -D TOUCHPIN=T0
; -D IRPIN=4
; -D RLYPIN=12
; -D RLYMDE=1
; digital LED strip types - uncomment only one ! - this will disable WS281x / SK681x support
; -D USE_APA102
; -D USE_WS2801
; -D USE_LPD8806
; PIN defines for 2 wire LEDs
-D CLKPIN=0
-D DATAPIN=2
; to drive analog LED strips (aka 5050) hardware configuration is no longer necessary
; configure the settings in the UI as follows (hard):
; for the Magic Home LED Controller use PWM pins 5,12,13,15
; for the H801 controller use PINs 15,13,12,14 (W2 = 04)
; for the BW-LT11 controller use PINs 12,4,14,5
;
; set the name of the module - make sure there is a quote-backslash-quote before the name and a backslash-quote-quote after the name
; -D SERVERNAME="\"WLED\""
;
; set the number of LEDs
; -D DEFAULT_LED_COUNT=30
;
; set milliampere limit when using ESP pin to power leds
; -D ABL_MILLIAMPS_DEFAULT=850
;
; enable IR by setting remote type
; -D IRTYPE=0 ;0 Remote disabled | 1 24-key RGB | 2 24-key with CT | 3 40-key blue | 4 40-key RGB | 5 21-key RGB | 6 6-key black | 7 9-key red | 8 JSON remote
;
; set default color order of your led strip
; -D DEFAULT_LED_COLOR_ORDER=COL_ORDER_GRB

View File

@@ -26,7 +26,7 @@ h11==0.14.0
# via
# uvicorn
# wsproto
idna==3.4
idna==3.7
# via
# anyio
# requests
@@ -50,6 +50,8 @@ starlette==0.23.1
# via platformio
tabulate==0.9.0
# via platformio
typing-extensions==4.11.0
# via starlette
urllib3==1.26.18
# via requests
uvicorn==0.20.0

View File

@@ -73,7 +73,11 @@ static uint8_t audioSyncEnabled = 0; // bit field: bit 0 - send, bit 1
static bool udpSyncConnected = false; // UDP connection status -> true if connected to multicast group
// user settable parameters for limitSoundDynamics()
static bool limiterOn = true; // bool: enable / disable dynamics limiter
#ifdef UM_AUDIOREACTIVE_DYNAMICS_LIMITER_OFF
static bool limiterOn = false; // bool: enable / disable dynamics limiter
#else
static bool limiterOn = true;
#endif
static uint16_t attackTime = 80; // int: attack time in milliseconds. Default 0.08sec
static uint16_t decayTime = 1400; // int: decay time in milliseconds. Default 1.40sec
// user settable options for FFTResult scaling
@@ -173,9 +177,6 @@ constexpr uint16_t samplesFFT_2 = 256; // meaningfull part of FFT resul
// These are the input and output vectors. Input vectors receive computed results from FFT.
static float vReal[samplesFFT] = {0.0f}; // FFT sample inputs / freq output - these are our raw result bins
static float vImag[samplesFFT] = {0.0f}; // imaginary parts
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
static float windowWeighingFactors[samplesFFT] = {0.0f};
#endif
// Create FFT object
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
@@ -194,9 +195,15 @@ static float windowWeighingFactors[samplesFFT] = {0.0f};
#include <arduinoFFT.h>
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
static ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, windowWeighingFactors);
#if defined(FFT_LIB_REV) && FFT_LIB_REV > 0x19
// arduinoFFT 2.x has a slightly different API
static ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, true);
#else
static arduinoFFT FFT = arduinoFFT(vReal, vImag, samplesFFT, SAMPLE_RATE);
static float windowWeighingFactors[samplesFFT] = {0.0f}; // cache for FFT windowing factors
static ArduinoFFT<float> FFT = ArduinoFFT<float>( vReal, vImag, samplesFFT, SAMPLE_RATE, windowWeighingFactors);
#endif
#else
static arduinoFFT FFT = arduinoFFT(vReal, vImag, samplesFFT, SAMPLE_RATE);
#endif
// Helper functions
@@ -296,7 +303,12 @@ void FFTcode(void * parameter)
#endif
#ifdef UM_AUDIOREACTIVE_USE_NEW_FFT
#if defined(FFT_LIB_REV) && FFT_LIB_REV > 0x19
// arduinoFFT 2.x has a slightly different API
FFT.majorPeak(&FFT_MajorPeak, &FFT_Magnitude); // let the effects know which freq was most dominant
#else
FFT.majorPeak(FFT_MajorPeak, FFT_Magnitude); // let the effects know which freq was most dominant
#endif
#else
FFT.MajorPeak(&FFT_MajorPeak, &FFT_Magnitude); // let the effects know which freq was most dominant
#endif
@@ -612,7 +624,12 @@ class AudioReactive : public Usermod {
};
// set your config variables to their boot default value (this can also be done in readFromConfig() or a constructor if you prefer)
#ifdef UM_AUDIOREACTIVE_ENABLE
bool enabled = true;
#else
bool enabled = false;
#endif
bool initDone = false;
// variables for UDP sound sync

View File

@@ -38,7 +38,7 @@ Alternatively, you can use the latest arduinoFFT development version.
ArduinoFFT `develop` library is slightly more accurate, and slightly faster than our customised library, however also needs additional 2kB RAM.
* `build_flags` = `-D USERMOD_AUDIOREACTIVE` `-D UM_AUDIOREACTIVE_USE_NEW_FFT`
* `lib_deps`= `https://github.com/kosme/arduinoFFT#develop @ 1.9.2`
* `lib_deps`= `https://github.com/kosme/arduinoFFT#419d7b0`
## Configuration
@@ -55,6 +55,11 @@ If you want to define default GPIOs during compile time, use the following (defa
- `-D ES7243_SDAPIN` : GPIO for I2C SDA pin on ES7243 microphone (-1)
- `-D ES7243_SCLPIN` : GPIO for I2C SCL pin on ES7243 microphone (-1)
Other options:
- `-D UM_AUDIOREACTIVE_ENABLE` : makes usermod default enabled (not the same as include into build option!)
- `-D UM_AUDIOREACTIVE_DYNAMICS_LIMITER_OFF` : disables rise/fall limiter default
**NOTE** I2S is used for analog audio sampling. Hence, the analog *buttons* (i.e. potentiometers) are disabled when running this usermod with an analog microphone.
### Advanced Compile-Time Options

View File

@@ -1,5 +1,13 @@
### Stairway lighting
# Stairway lighting
## Install
Add the buildflag `-D USERMOD_STAIRCASE_WIPE` to your enviroment to activate it.
### Configuration
`-D STAIRCASE_WIPE_OFF`
<br>Have the LEDs wipe off instead of fading out
## Description
Quick usermod to accomplish something similar to [this video](https://www.youtube.com/watch?v=NHkju5ncC4A).
This usermod enables you to add a lightstrip alongside or on the steps of a staircase.

View File

@@ -19,10 +19,12 @@ class StairwayWipeUsermod : public Usermod {
unsigned long timeStaticStart = 0;
uint16_t previousUserVar0 = 0;
//moved to buildflag
//comment this out if you want the turn off effect to be just fading out instead of reverse wipe
#define STAIRCASE_WIPE_OFF
//#define STAIRCASE_WIPE_OFF
public:
void setup() {
}
void loop() {
//userVar0 (U0 in HTTP API):
//has to be set to 1 if movement is detected on the PIR that is the same side of the staircase as the ESP8266
@@ -84,7 +86,7 @@ class StairwayWipeUsermod : public Usermod {
uint16_t getId()
{
return USERMOD_ID_EXAMPLE;
return USERMOD_ID_STAIRWAY_WIPE;
}

View File

@@ -4863,25 +4863,25 @@ uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline
SEGMENT.fill(BLACK);
}
uint16_t xscale = SEGMENT.intensity*4;
uint32_t yscale = SEGMENT.speed*8;
uint8_t indexx = 0;
unsigned xscale = SEGMENT.intensity*4;
unsigned yscale = SEGMENT.speed*8;
unsigned indexx = 0;
SEGPALETTE = CRGBPalette16( CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0), CRGB(0,0,0),
CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange,
CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
CRGBPalette16 pal = SEGMENT.check1 ? SEGPALETTE : CRGBPalette16(CRGB::Black, CRGB::Black, CRGB::Black, CRGB::Black,
CRGB::Red, CRGB::Red, CRGB::Red, CRGB::DarkOrange,
CRGB::DarkOrange,CRGB::DarkOrange, CRGB::Orange, CRGB::Orange,
CRGB::Yellow, CRGB::Orange, CRGB::Yellow, CRGB::Yellow);
for (int j=0; j < cols; j++) {
for (int i=0; i < rows; i++) {
indexx = inoise8(j*yscale*rows/255, i*xscale+millis()/4); // We're moving along our Perlin map.
SEGMENT.setPixelColorXY(j, i, ColorFromPalette(SEGPALETTE, min(i*(indexx)>>4, 255), i*255/cols, LINEARBLEND)); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
indexx = inoise8(j*yscale*rows/255, i*xscale+strip.now/4); // We're moving along our Perlin map.
SEGMENT.setPixelColorXY(j, i, ColorFromPalette(pal, min(i*(indexx)>>4, 255U), i*255/cols, LINEARBLEND)); // With that value, look up the 8 bit colour palette value and assign it to the current LED.
} // for i
} // for j
return FRAMETIME;
} // mode_2Dfirenoise()
static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y scale;;!;2";
static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y scale,,,,Palette;;!;2;pal=66";
//////////////////////////////

View File

@@ -91,7 +91,7 @@
//#define SEGCOLOR(x) strip._segments[strip.getCurrSegmentId()].currentColor(x, strip._segments[strip.getCurrSegmentId()].colors[x])
//#define SEGLEN strip._segments[strip.getCurrSegmentId()].virtualLength()
#define SEGCOLOR(x) strip.segColor(x) /* saves us a few kbytes of code */
#define SEGPALETTE strip._currentPalette
#define SEGPALETTE Segment::getCurrentPalette()
#define SEGLEN strip._virtualSegmentLength /* saves us a few kbytes of code */
#define SPEED_FORMULA_L (5U + (50U*(255U - SEGMENT.speed))/SEGLEN)
@@ -414,6 +414,7 @@ typedef struct Segment {
static uint16_t _usedSegmentData;
// perhaps this should be per segment, not static
static CRGBPalette16 _currentPalette; // palette used for current effect (includes transition, used in color_from_palette())
static CRGBPalette16 _randomPalette; // actual random palette
static CRGBPalette16 _newRandomPalette; // target random palette
static unsigned long _lastPaletteChange; // last random palette change time in millis()
@@ -530,6 +531,7 @@ typedef struct Segment {
static void modeBlend(bool blend) { _modeBlend = blend; }
#endif
static void handleRandomPalette();
inline static const CRGBPalette16 &getCurrentPalette(void) { return Segment::_currentPalette; }
void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1, uint8_t segId = 255);
bool setColor(uint8_t slot, uint32_t c); //returns true if changed
@@ -567,7 +569,7 @@ typedef struct Segment {
uint8_t currentMode(void);
uint32_t currentColor(uint8_t slot);
CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal);
CRGBPalette16 &currentPalette(CRGBPalette16 &tgt, uint8_t paletteID);
void setCurrentPalette(void);
// 1D strip
uint16_t virtualLength(void) const;
@@ -693,7 +695,6 @@ class WS2812FX { // 96 bytes
panels(1),
#endif
// semi-private (just obscured) used in effect functions through macros
_currentPalette(CRGBPalette16(CRGB::Black)),
_colors_t{0,0,0},
_virtualSegmentLength(0),
// true private variables
@@ -888,7 +889,6 @@ class WS2812FX { // 96 bytes
// end 2D support
void loadCustomPalettes(void); // loads custom palettes from JSON
CRGBPalette16 _currentPalette; // palette used for current effect (includes transition)
std::vector<CRGBPalette16> customPalettes; // TODO: move custom palettes out of WS2812FX class
// using public variables to reduce code size increase due to inline function getSegment() (with bounds checking)

View File

@@ -77,6 +77,7 @@ uint16_t Segment::_usedSegmentData = 0U; // amount of RAM all segments use for t
uint16_t Segment::maxWidth = DEFAULT_LED_COUNT;
uint16_t Segment::maxHeight = 1;
CRGBPalette16 Segment::_currentPalette = CRGBPalette16(CRGB::Black);
CRGBPalette16 Segment::_randomPalette = CRGBPalette16(DEFAULT_COLOR);
CRGBPalette16 Segment::_newRandomPalette = CRGBPalette16(DEFAULT_COLOR);
unsigned long Segment::_lastPaletteChange = 0; // perhaps it should be per segment
@@ -201,7 +202,7 @@ void Segment::resetIfRequired() {
CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
if (pal < 245 && pal > GRADIENT_PALETTE_COUNT+13) pal = 0;
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0;
if (pal > 245 && (strip.customPalettes.size() == 0 || 255U-pal > strip.customPalettes.size()-1)) pal = 0; // TODO remove strip dependency by moving customPalettes out of strip
//default palette. Differs depending on effect
if (pal == 0) switch (mode) {
case FX_MODE_FIRE_2012 : pal = 35; break; // heat palette
@@ -343,8 +344,8 @@ void Segment::handleTransition() {
// transition progression between 0-65535
uint16_t Segment::progress() {
if (isInTransition()) {
unsigned long timeNow = millis();
if (_t->_dur > 0 && timeNow - _t->_start < _t->_dur) return (timeNow - _t->_start) * 0xFFFFU / _t->_dur;
unsigned diff = millis() - _t->_start;
if (_t->_dur > 0 && diff < _t->_dur) return diff * 0xFFFFU / _t->_dur;
}
return 0xFFFFU;
}
@@ -426,7 +427,7 @@ uint8_t Segment::currentBri(bool useCct) {
uint32_t prog = progress();
if (prog < 0xFFFFU) {
uint32_t curBri = (useCct ? cct : (on ? opacity : 0)) * prog;
curBri += (useCct ? _t->_cctT : (on ? _t->_briT : 0)) * (0xFFFFU - prog);
curBri += (useCct ? _t->_cctT : _t->_briT) * (0xFFFFU - prog);
return curBri / 0xFFFFU;
}
return (useCct ? cct : (on ? opacity : 0));
@@ -448,18 +449,17 @@ uint32_t Segment::currentColor(uint8_t slot) {
#endif
}
CRGBPalette16 &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) {
loadPalette(targetPalette, pal);
uint16_t prog = progress();
void Segment::setCurrentPalette() {
loadPalette(_currentPalette, palette);
unsigned prog = progress();
if (strip.paletteFade && prog < 0xFFFFU) {
// blend palettes
// there are about 255 blend passes of 48 "blends" to completely blend two palettes (in _dur time)
// minimum blend time is 100ms maximum is 65535ms
uint16_t noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends;
for (int i=0; i<noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48);
targetPalette = _t->_palT; // copy transitioning/temporary palette
unsigned noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends;
for (unsigned i = 0; i < noOfBlends; i++, _t->_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, _currentPalette, 48);
_currentPalette = _t->_palT; // copy transitioning/temporary palette
}
return targetPalette;
}
// relies on WS2812FX::service() to call it max every 8ms or more (MIN_SHOW_DELAY)
@@ -1078,11 +1078,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_
uint8_t paletteIndex = i;
if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1);
if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end"
CRGBPalette16 curPal;
curPal = currentPalette(curPal, palette);
//if (isInTransition()) curPal = _t->_palT;
//else loadPalette(curPal, palette);
CRGB fastled_col = ColorFromPalette(curPal, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
CRGB fastled_col = ColorFromPalette(_currentPalette, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global
return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0);
}
@@ -1187,7 +1183,7 @@ void WS2812FX::service() {
_colors_t[0] = seg.currentColor(0);
_colors_t[1] = seg.currentColor(1);
_colors_t[2] = seg.currentColor(2);
seg.currentPalette(_currentPalette, seg.palette); // we need to pass reference
seg.setCurrentPalette(); // load actual palette
if (!cctFromRgb || correctWB) busses.setSegmentCCT(seg.currentBri(true), correctWB);
for (int c = 0; c < NUM_COLORS; c++) _colors_t[c] = gamma32(_colors_t[c]);

View File

@@ -226,11 +226,11 @@ void handleAnalog(uint8_t b)
void handleButton()
{
static unsigned long lastRead = 0UL;
static unsigned long lastAnalogRead = 0UL;
static unsigned long lastRun = 0UL;
unsigned long now = millis();
if (strip.isUpdating() && (now - lastRun < 400)) return; // don't interfere with strip update (unless strip is updating continuously, e.g. very long strips)
if (strip.isUpdating() && (now - lastRun < ANALOG_BTN_READ_CYCLE+1)) return; // don't interfere with strip update (unless strip is updating continuously, e.g. very long strips)
lastRun = now;
for (uint8_t b=0; b<WLED_MAX_BUTTONS; b++) {
@@ -243,9 +243,8 @@ void handleButton()
if (usermods.handleButton(b)) continue; // did usermod handle buttons
if (buttonType[b] == BTN_TYPE_ANALOG || buttonType[b] == BTN_TYPE_ANALOG_INVERTED) { // button is not a button but a potentiometer
if (now - lastRead > ANALOG_BTN_READ_CYCLE) {
if (now - lastAnalogRead > ANALOG_BTN_READ_CYCLE) {
handleAnalog(b);
lastRead = now;
}
continue;
}
@@ -325,6 +324,9 @@ void handleButton()
shortPressAction(b);
}
}
if (now - lastAnalogRead > ANALOG_BTN_READ_CYCLE) {
lastAnalogRead = now;
}
}
// If enabled, RMT idle level is set to HIGH when off

View File

@@ -151,6 +151,7 @@
#define USERMOD_ID_WIREGUARD 41 //Usermod "wireguard.h"
#define USERMOD_ID_INTERNAL_TEMPERATURE 42 //Usermod "usermod_internal_temperature.h"
#define USERMOD_ID_LDR_DUSK_DAWN 43 //Usermod "usermod_LDR_Dusk_Dawn_v2.h"
#define USERMOD_ID_STAIRWAY_WIPE 44 //Usermod "stairway-wipe-usermod-v2.h"
//Access point behavior
#define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot

View File

@@ -134,7 +134,7 @@
<a href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a> version ##VERSION##<!-- Autoreplaced from package.json --><br><br>
<a href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits" target="_blank">Contributors, dependencies and special thanks</a><br>
A huge thank you to everyone who helped me create WLED!<br><br>
(c) 2016-2023 Christian Schwinne <br>
(c) 2016-2024 Christian Schwinne <br>
<i>Licensed under the <a href="https://github.com/Aircoookie/WLED/blob/master/LICENSE" target="_blank">MIT license</a></i><br><br>
Server message: <span class="sip"> Response error! </span><hr>
<div id="toast"></div>

View File

@@ -44,7 +44,7 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()=====";
const uint16_t PAGE_update_length = 613;
const uint8_t PAGE_update[] PROGMEM = {
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x75, 0x53, 0x5d, 0x6f, 0xd4, 0x30,
0x10, 0x7c, 0xcf, 0xaf, 0x70, 0xfd, 0x74, 0x27, 0x51, 0x9b, 0x22, 0x5e, 0x28, 0x49, 0x0a, 0x47,
0x10, 0x7c, 0xcf, 0xaf, 0x70, 0xfd, 0x74, 0x27, 0x51, 0x1b, 0x50, 0x5f, 0x28, 0x49, 0x0a, 0x47,
0x2b, 0x54, 0x09, 0xa9, 0x95, 0xda, 0x82, 0x78, 0x42, 0x8e, 0xbd, 0xb9, 0x98, 0x73, 0xec, 0xd4,
0xde, 0xdc, 0xe9, 0x84, 0xfa, 0xdf, 0xd9, 0x38, 0x77, 0x05, 0xf1, 0xf1, 0x12, 0xc5, 0xd9, 0xd9,
0xf1, 0xee, 0xcc, 0xa4, 0x3c, 0xb9, 0xbc, 0xf9, 0x70, 0xff, 0xf5, 0xf6, 0x8a, 0x75, 0xd8, 0xbb,
@@ -60,13 +60,13 @@ const uint8_t PAGE_update[] PROGMEM = {
0x5d, 0x71, 0x99, 0x00, 0xd1, 0xfa, 0x75, 0x92, 0x49, 0x7c, 0x4f, 0x17, 0x43, 0xf5, 0x86, 0xd7,
0xbf, 0x21, 0x27, 0xaa, 0xba, 0x78, 0x67, 0xfb, 0x49, 0x00, 0x36, 0x46, 0xb7, 0xe0, 0x33, 0xbd,
0x4e, 0x89, 0x2f, 0xdf, 0x12, 0x32, 0x23, 0x4a, 0x39, 0x4b, 0xda, 0x04, 0xb3, 0x67, 0xc1, 0xbb,
0xa0, 0x4c, 0xc5, 0x3f, 0x02, 0x7e, 0x5e, 0x2c, 0x89, 0xae, 0x7b, 0x55, 0x17, 0x59, 0xb2, 0xbb,
0xa0, 0x4c, 0xc5, 0x3f, 0x02, 0x7e, 0x5e, 0x2c, 0x89, 0xae, 0x7b, 0x5d, 0x17, 0x59, 0xb2, 0xbb,
0xd0, 0xe2, 0x4e, 0x45, 0x78, 0xd6, 0x8e, 0x2a, 0x65, 0x1b, 0x62, 0xcf, 0xc8, 0x8b, 0x2e, 0x50,
0xcf, 0xed, 0xcd, 0xdd, 0x3d, 0x67, 0x2a, 0xcb, 0x53, 0x71, 0x21, 0xc7, 0x0c, 0xe4, 0xcc, 0x52,
0x8d, 0x04, 0x61, 0x05, 0x90, 0x74, 0xfb, 0x81, 0x5c, 0xe9, 0x47, 0x87, 0x76, 0x50, 0x11, 0xe5,
0x44, 0x70, 0x4a, 0x30, 0xc5, 0xe9, 0xea, 0x34, 0x36, 0xbd, 0x25, 0x3b, 0x1f, 0xa6, 0x9b, 0xaf,
0x7d, 0x42, 0xe5, 0x1c, 0x18, 0xb6, 0x85, 0x98, 0x88, 0xf2, 0x9c, 0x95, 0x69, 0x50, 0x9e, 0x15,
0xda, 0xa9, 0x94, 0x2a, 0x9e, 0xec, 0xc0, 0xeb, 0x97, 0xe2, 0xec, 0xb5, 0x38, 0xa3, 0x55, 0xa8,
0xda, 0xa9, 0x94, 0x2a, 0x9e, 0xec, 0xc0, 0xeb, 0x97, 0xe2, 0xd5, 0x99, 0x38, 0xa3, 0x55, 0xa8,
0x42, 0x2b, 0xc4, 0xfa, 0x32, 0xec, 0xf2, 0x0a, 0x0c, 0x3b, 0x60, 0x8e, 0xee, 0x4f, 0xc8, 0x1a,
0xeb, 0x55, 0xdc, 0x53, 0xbf, 0x62, 0x45, 0x17, 0xa1, 0xad, 0x78, 0x87, 0x38, 0xa4, 0x73, 0x29,
0xd7, 0x16, 0xbb, 0xb1, 0x11, 0x3a, 0xf4, 0xf2, 0xbd, 0x8d, 0x3a, 0x84, 0xb0, 0xb1, 0x20, 0xa7,
@@ -80,8 +80,8 @@ const uint8_t PAGE_update[] PROGMEM = {
0xff, 0xd5, 0x94, 0x0d, 0xaa, 0x4b, 0x63, 0xb7, 0x45, 0xf6, 0x71, 0x4a, 0x29, 0xd1, 0xd4, 0x99,
0x9d, 0xa2, 0x27, 0x84, 0x20, 0x70, 0x26, 0xbf, 0xcd, 0xcb, 0x32, 0x13, 0x98, 0x0f, 0xc8, 0xb4,
0x0b, 0x74, 0x08, 0x91, 0x66, 0x6d, 0x23, 0xa4, 0x2e, 0xfb, 0x31, 0xa8, 0x35, 0xb0, 0xf3, 0x65,
0x29, 0x89, 0x6f, 0x5a, 0x77, 0x8a, 0xdc, 0x94, 0xbf, 0xe9, 0xc7, 0xfe, 0x09, 0xf9, 0xeb, 0x48,
0xda, 0xee, 0x03, 0x00, 0x00
0x29, 0x89, 0x6f, 0x5a, 0x77, 0x8a, 0xdc, 0x94, 0xbf, 0xe9, 0xc7, 0xfe, 0x09, 0xb5, 0x43, 0x19,
0xed, 0xee, 0x03, 0x00, 0x00
};

View File

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

View File

@@ -210,7 +210,7 @@ void sendImprovInfoResponse() {
//Use serverDescription if it has been changed from the default "WLED", else mDNS name
bool useMdnsName = (strcmp(serverDescription, "WLED") == 0 && strlen(cmDNS) > 0);
char vString[20];
sprintf_P(vString, PSTR("0.14.1/%i"), VERSION);
sprintf_P(vString, PSTR("0.14.3/%i"), VERSION);
const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription};
sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str);

View File

@@ -214,7 +214,14 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId)
#endif
byte fx = seg.mode;
if (getVal(elem["fx"], &fx, 0, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 0-255 exact value)
byte last = strip.getModeCount();
// partial fix for #3605
if (!elem["fx"].isNull() && elem["fx"].is<const char*>()) {
const char *tmp = elem["fx"].as<const char *>();
if (strlen(tmp) > 3 && (strchr(tmp,'r') || strchr(tmp,'~') != strrchr(tmp,'~'))) last = 0; // we have "X~Y(r|[w]~[-])" form
}
// end fix
if (getVal(elem["fx"], &fx, 0, last)) { //load effect ('r' random, '~' inc/dec, 0-255 exact value, 5~10r pick random between 5 & 10)
if (!presetId && currentPlaylist>=0) unloadPlaylist();
if (fx != seg.mode) seg.setMode(fx, elem[F("fxdef")]);
}
@@ -1013,17 +1020,30 @@ void serializeModeNames(JsonArray arr)
}
}
// Global buffer locking response helper class
class GlobalBufferAsyncJsonResponse: public JSONBufferGuard, public AsyncJsonResponse {
// Global buffer locking response helper class (to make sure lock is released when AsyncJsonResponse is destroyed)
class LockedJsonResponse: public AsyncJsonResponse {
bool _holding_lock;
public:
inline GlobalBufferAsyncJsonResponse(bool isArray) : JSONBufferGuard(17), AsyncJsonResponse(&doc, isArray) {};
virtual ~GlobalBufferAsyncJsonResponse() {};
// WARNING: constructor assumes requestJSONBufferLock() was successfully acquired externally/prior to constructing the instance
// Not a good practice with C++. Unfortunately AsyncJsonResponse only has 2 constructors - for dynamic buffer or existing buffer,
// with existing buffer it clears its content during construction
// if the lock was not acquired (using JSONBufferGuard class) previous implementation still cleared existing buffer
inline LockedJsonResponse(JsonDocument* doc, bool isArray) : AsyncJsonResponse(doc, isArray), _holding_lock(true) {};
// Other members are inherited
virtual size_t _fillBuffer(uint8_t *buf, size_t maxLen) {
size_t result = AsyncJsonResponse::_fillBuffer(buf, maxLen);
// Release lock as soon as we're done filling content
if (((result + _sentLength) >= (_contentLength)) && _holding_lock) {
releaseJSONBufferLock();
_holding_lock = false;
}
return result;
}
// destructor will remove JSON buffer lock when response is destroyed in AsyncWebServer
virtual ~LockedJsonResponse() { if (_holding_lock) releaseJSONBufferLock(); };
};
void serveJson(AsyncWebServerRequest* request)
{
byte subJson = 0;
@@ -1043,10 +1063,10 @@ void serveJson(AsyncWebServerRequest* request)
}
#endif
else if (url.indexOf("pal") > 0) {
request->send_P(200, "application/json", JSON_palette_names);
request->send_P(200, F("application/json"), JSON_palette_names);
return;
}
else if (url.indexOf("cfg") > 0 && handleFileRead(request, "/cfg.json")) {
else if (url.indexOf("cfg") > 0 && handleFileRead(request, F("/cfg.json"))) {
return;
}
else if (url.length() > 6) { //not just /json
@@ -1054,12 +1074,13 @@ void serveJson(AsyncWebServerRequest* request)
return;
}
GlobalBufferAsyncJsonResponse *response = new GlobalBufferAsyncJsonResponse(subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
if (!response->owns_lock()) {
if (!requestJSONBufferLock(17)) {
request->send(503, "application/json", F("{\"error\":3}"));
delete response;
return;
}
// releaseJSONBufferLock() will be called when "response" is destroyed (from AsyncWebServer)
// make sure you delete "response" if no "request->send(response);" is made
LockedJsonResponse *response = new LockedJsonResponse(&doc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary
JsonVariant lDoc = response->getRoot();
@@ -1072,7 +1093,7 @@ void serveJson(AsyncWebServerRequest* request)
case JSON_PATH_NODES:
serializeNodes(lDoc); break;
case JSON_PATH_PALETTES:
serializePalettes(lDoc, request->hasParam("page") ? request->getParam("page")->value().toInt() : 0); break;
serializePalettes(lDoc, request->hasParam(F("page")) ? request->getParam(F("page"))->value().toInt() : 0); break;
case JSON_PATH_EFFECTS:
serializeModeNames(lDoc); break;
case JSON_PATH_FXDATA:
@@ -1141,7 +1162,7 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient)
oappendi(n);
oappend("}");
if (request) {
request->send(200, "application/json", buffer);
request->send(200, F("application/json"), buffer);
}
#ifdef WLED_ENABLE_WEBSOCKETS
else {

View File

@@ -137,6 +137,8 @@ void stateUpdated(byte callMode) {
if (strip.getTransition() == 0) {
jsonTransitionOnce = false;
transitionActive = false;
applyFinalBri();
strip.trigger();
return;
}

View File

@@ -48,129 +48,118 @@ Timezone* tz;
#define TZ_ANCHORAGE 20
#define TZ_MX_CENTRAL 21
#define TZ_PAKISTAN 22
#define TZ_COUNT 23
#define TZ_INIT 255
byte tzCurrent = TZ_INIT; //uninitialized
/* C++11 form -- static std::array<std::pair<TimeChangeRule, TimeChangeRule>, TZ_COUNT> TZ_TABLE PROGMEM = {{ */
static const std::pair<TimeChangeRule, TimeChangeRule> TZ_TABLE[] PROGMEM = {
/* TZ_UTC */ {
{Last, Sun, Mar, 1, 0}, // UTC
{Last, Sun, Mar, 1, 0} // Same
},
/* TZ_UK */ {
{Last, Sun, Mar, 1, 60}, //British Summer Time
{Last, Sun, Oct, 2, 0} //Standard Time
},
/* TZ_EUROPE_CENTRAL */ {
{Last, Sun, Mar, 2, 120}, //Central European Summer Time
{Last, Sun, Oct, 3, 60} //Central European Standard Time
},
/* TZ_EUROPE_EASTERN */ {
{Last, Sun, Mar, 3, 180}, //East European Summer Time
{Last, Sun, Oct, 4, 120} //East European Standard Time
},
/* TZ_US_EASTERN */ {
{Second, Sun, Mar, 2, -240}, //EDT = UTC - 4 hours
{First, Sun, Nov, 2, -300} //EST = UTC - 5 hours
},
/* TZ_US_CENTRAL */ {
{Second, Sun, Mar, 2, -300}, //CDT = UTC - 5 hours
{First, Sun, Nov, 2, -360} //CST = UTC - 6 hours
},
/* TZ_US_MOUNTAIN */ {
{Second, Sun, Mar, 2, -360}, //MDT = UTC - 6 hours
{First, Sun, Nov, 2, -420} //MST = UTC - 7 hours
},
/* TZ_US_ARIZONA */ {
{First, Sun, Nov, 2, -420}, //MST = UTC - 7 hours
{First, Sun, Nov, 2, -420} //MST = UTC - 7 hours
},
/* TZ_US_PACIFIC */ {
{Second, Sun, Mar, 2, -420}, //PDT = UTC - 7 hours
{First, Sun, Nov, 2, -480} //PST = UTC - 8 hours
},
/* TZ_CHINA */ {
{Last, Sun, Mar, 1, 480}, //CST = UTC + 8 hours
{Last, Sun, Mar, 1, 480}
},
/* TZ_JAPAN */ {
{Last, Sun, Mar, 1, 540}, //JST = UTC + 9 hours
{Last, Sun, Mar, 1, 540}
},
/* TZ_AUSTRALIA_EASTERN */ {
{First, Sun, Oct, 2, 660}, //AEDT = UTC + 11 hours
{First, Sun, Apr, 3, 600} //AEST = UTC + 10 hours
},
/* TZ_NEW_ZEALAND */ {
{Last, Sun, Sep, 2, 780}, //NZDT = UTC + 13 hours
{First, Sun, Apr, 3, 720} //NZST = UTC + 12 hours
},
/* TZ_NORTH_KOREA */ {
{Last, Sun, Mar, 1, 510}, //Pyongyang Time = UTC + 8.5 hours
{Last, Sun, Mar, 1, 510}
},
/* TZ_INDIA */ {
{Last, Sun, Mar, 1, 330}, //India Standard Time = UTC + 5.5 hours
{Last, Sun, Mar, 1, 330}
},
/* TZ_SASKACHEWAN */ {
{First, Sun, Nov, 2, -360}, //CST = UTC - 6 hours
{First, Sun, Nov, 2, -360}
},
/* TZ_AUSTRALIA_NORTHERN */ {
{First, Sun, Apr, 3, 570}, //ACST = UTC + 9.5 hours
{First, Sun, Apr, 3, 570}
},
/* TZ_AUSTRALIA_SOUTHERN */ {
{First, Sun, Oct, 2, 630}, //ACDT = UTC + 10.5 hours
{First, Sun, Apr, 3, 570} //ACST = UTC + 9.5 hours
},
/* TZ_HAWAII */ {
{Last, Sun, Mar, 1, -600}, //HST = UTC - 10 hours
{Last, Sun, Mar, 1, -600}
},
/* TZ_NOVOSIBIRSK */ {
{Last, Sun, Mar, 1, 420}, //CST = UTC + 7 hours
{Last, Sun, Mar, 1, 420}
},
/* TZ_ANCHORAGE */ {
{Second, Sun, Mar, 2, -480}, //AKDT = UTC - 8 hours
{First, Sun, Nov, 2, -540} //AKST = UTC - 9 hours
},
/* TZ_MX_CENTRAL */ {
{First, Sun, Apr, 2, -360}, //CST = UTC - 6 hours
{First, Sun, Apr, 2, -360}
},
/* TZ_PAKISTAN */ {
{Last, Sun, Mar, 1, 300}, //Pakistan Standard Time = UTC + 5 hours
{Last, Sun, Mar, 1, 300}
}
};
void updateTimezone() {
delete tz;
TimeChangeRule tcrDaylight = {Last, Sun, Mar, 1, 0}; //UTC
TimeChangeRule tcrStandard = tcrDaylight; //UTC
switch (currentTimezone) {
case TZ_UK : {
tcrDaylight = {Last, Sun, Mar, 1, 60}; //British Summer Time
tcrStandard = {Last, Sun, Oct, 2, 0}; //Standard Time
break;
}
case TZ_EUROPE_CENTRAL : {
tcrDaylight = {Last, Sun, Mar, 2, 120}; //Central European Summer Time
tcrStandard = {Last, Sun, Oct, 3, 60}; //Central European Standard Time
break;
}
case TZ_EUROPE_EASTERN : {
tcrDaylight = {Last, Sun, Mar, 3, 180}; //East European Summer Time
tcrStandard = {Last, Sun, Oct, 4, 120}; //East European Standard Time
break;
}
case TZ_US_EASTERN : {
tcrDaylight = {Second, Sun, Mar, 2, -240}; //EDT = UTC - 4 hours
tcrStandard = {First, Sun, Nov, 2, -300}; //EST = UTC - 5 hours
break;
}
case TZ_US_CENTRAL : {
tcrDaylight = {Second, Sun, Mar, 2, -300}; //CDT = UTC - 5 hours
tcrStandard = {First, Sun, Nov, 2, -360}; //CST = UTC - 6 hours
break;
}
case TZ_US_MOUNTAIN : {
tcrDaylight = {Second, Sun, Mar, 2, -360}; //MDT = UTC - 6 hours
tcrStandard = {First, Sun, Nov, 2, -420}; //MST = UTC - 7 hours
break;
}
case TZ_US_ARIZONA : {
tcrDaylight = {First, Sun, Nov, 2, -420}; //MST = UTC - 7 hours
tcrStandard = {First, Sun, Nov, 2, -420}; //MST = UTC - 7 hours
break;
}
case TZ_US_PACIFIC : {
tcrDaylight = {Second, Sun, Mar, 2, -420}; //PDT = UTC - 7 hours
tcrStandard = {First, Sun, Nov, 2, -480}; //PST = UTC - 8 hours
break;
}
case TZ_CHINA : {
tcrDaylight = {Last, Sun, Mar, 1, 480}; //CST = UTC + 8 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_JAPAN : {
tcrDaylight = {Last, Sun, Mar, 1, 540}; //JST = UTC + 9 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_AUSTRALIA_EASTERN : {
tcrDaylight = {First, Sun, Oct, 2, 660}; //AEDT = UTC + 11 hours
tcrStandard = {First, Sun, Apr, 3, 600}; //AEST = UTC + 10 hours
break;
}
case TZ_NEW_ZEALAND : {
tcrDaylight = {Last, Sun, Sep, 2, 780}; //NZDT = UTC + 13 hours
tcrStandard = {First, Sun, Apr, 3, 720}; //NZST = UTC + 12 hours
break;
}
case TZ_NORTH_KOREA : {
tcrDaylight = {Last, Sun, Mar, 1, 510}; //Pyongyang Time = UTC + 8.5 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_INDIA : {
tcrDaylight = {Last, Sun, Mar, 1, 330}; //India Standard Time = UTC + 5.5 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_SASKACHEWAN : {
tcrDaylight = {First, Sun, Nov, 2, -360}; //CST = UTC - 6 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_AUSTRALIA_NORTHERN : {
tcrDaylight = {First, Sun, Apr, 3, 570}; //ACST = UTC + 9.5 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_AUSTRALIA_SOUTHERN : {
tcrDaylight = {First, Sun, Oct, 2, 630}; //ACDT = UTC + 10.5 hours
tcrStandard = {First, Sun, Apr, 3, 570}; //ACST = UTC + 9.5 hours
break;
}
case TZ_HAWAII : {
tcrDaylight = {Last, Sun, Mar, 1, -600}; //HST = UTC - 10 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_NOVOSIBIRSK : {
tcrDaylight = {Last, Sun, Mar, 1, 420}; //CST = UTC + 7 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_ANCHORAGE : {
tcrDaylight = {Second, Sun, Mar, 2, -480}; //AKDT = UTC - 8 hours
tcrStandard = {First, Sun, Nov, 2, -540}; //AKST = UTC - 9 hours
break;
}
case TZ_MX_CENTRAL : {
tcrDaylight = {First, Sun, Apr, 2, -360}; //CST = UTC - 6 hours
tcrStandard = tcrDaylight;
break;
}
case TZ_PAKISTAN : {
tcrDaylight = {Last, Sun, Mar, 1, 300}; //Pakistan Standard Time = UTC + 5 hours
tcrStandard = tcrDaylight;
break;
}
TimeChangeRule tcrDaylight, tcrStandard;
auto tz_table_entry = currentTimezone;
if (tz_table_entry >= TZ_COUNT) {
tz_table_entry = 0;
}
tzCurrent = currentTimezone;
memcpy_P(&tcrDaylight, &TZ_TABLE[tz_table_entry].first, sizeof(tcrDaylight));
memcpy_P(&tcrStandard, &TZ_TABLE[tz_table_entry].second, sizeof(tcrStandard));
tz = new Timezone(tcrDaylight, tcrStandard);
}

View File

@@ -30,8 +30,8 @@
bool dmxStarted = false;
int sendPin = 2; //default on ESP8266
//DMX value array and size. Entry 0 will hold startbyte
uint8_t dmxDataStore[dmxMaxChannel] = {};
//DMX value array and size. Entry 0 will hold startbyte, so we need 512+1 elements
uint8_t dmxDataStore[dmxMaxChannel+1] = {};
int channelSize;
@@ -106,4 +106,4 @@ void DMXESPSerial::update() {
// Function to update the DMX bus
#endif
#endif

View File

@@ -195,6 +195,8 @@ void exitRealtime() {
realtimeIP[0] = 0;
if (useMainSegmentOnly) { // unfreeze live segment again
strip.getMainSegment().freeze = false;
} else {
strip.show(); // possible fix for #3589
}
updateInterfaces(CALL_MODE_WS_SEND);
}

View File

@@ -170,7 +170,7 @@
#endif
#ifdef USERMOD_KLIPPER_PERCENTAGE
#include "..\usermods\usermod_v2_klipper_percentage\usermod_v2_klipper_percentage.h"
#include "../usermods/usermod_v2_klipper_percentage/usermod_v2_klipper_percentage.h"
#endif
#ifdef USERMOD_BOBLIGHT
@@ -201,6 +201,9 @@
#include "../usermods/LDR_Dusk_Dawn_v2/usermod_LDR_Dusk_Dawn_v2.h"
#endif
#ifdef USERMOD_STAIRCASE_WIPE
#include "../usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h"
#endif
void registerUsermods()
{
/*
@@ -380,4 +383,8 @@ void registerUsermods()
#ifdef USERMOD_LDR_DUSK_DAWN
usermods.add(new LDR_Dusk_Dawn_v2());
#endif
#ifdef USERMOD_STAIRCASE_WIPE
usermods.add(new StairwayWipeUsermod());
#endif
}

View File

@@ -3,12 +3,12 @@
/*
Main sketch, global variable declarations
@title WLED project sketch
@version 0.14.1
@version 0.14.3
@author Christian Schwinne
*/
// version code in format yymmddb (b = daily build)
#define VERSION 2401141
#define VERSION 2405180
//uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG

View File

@@ -80,13 +80,13 @@ void createEditHandler(bool enable) {
editHandler = &server.addHandler(new SPIFFSEditor("","",WLED_FS));//http_username,http_password));
#endif
#else
editHandler = &server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){
editHandler = &server.on(SET_F("/edit"), HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 501, "Not implemented", F("The FS editor is disabled in this build."), 254);
});
#endif
} else {
editHandler = &server.on("/edit", HTTP_ANY, [](AsyncWebServerRequest *request){
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_cfg), 254);
editHandler = &server.on(SET_F("/edit"), HTTP_ANY, [](AsyncWebServerRequest *request){
serveMessage(request, 401, F("Access Denied"), FPSTR(s_unlock_cfg), 254);
});
}
}
@@ -95,11 +95,11 @@ bool captivePortal(AsyncWebServerRequest *request)
{
if (ON_STA_FILTER(request)) return false; //only serve captive in AP mode
String hostH;
if (!request->hasHeader("Host")) return false;
hostH = request->getHeader("Host")->value();
if (!request->hasHeader(F("Host"))) return false;
hostH = request->getHeader(F("Host"))->value();
if (!isIp(hostH) && hostH.indexOf("wled.me") < 0 && hostH.indexOf(cmDNS) < 0) {
DEBUG_PRINTLN("Captive portal");
if (!isIp(hostH) && hostH.indexOf(F("wled.me")) < 0 && hostH.indexOf(cmDNS) < 0) {
DEBUG_PRINTLN(F("Captive portal"));
AsyncWebServerResponse *response = request->beginResponse(302);
response->addHeader(F("Location"), F("http://4.3.2.1"));
request->send(response);
@@ -117,7 +117,7 @@ void initServer()
#ifdef WLED_ENABLE_WEBSOCKETS
#ifndef WLED_DISABLE_2D
server.on("/liveview2D", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/liveview2D"), HTTP_GET, [](AsyncWebServerRequest *request){
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveviewws2D, PAGE_liveviewws2D_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
@@ -126,7 +126,7 @@ void initServer()
});
#endif
#endif
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/liveview"), HTTP_GET, [](AsyncWebServerRequest *request){
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveview, PAGE_liveview_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
@@ -135,13 +135,13 @@ void initServer()
});
//settings page
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/settings"), HTTP_GET, [](AsyncWebServerRequest *request){
serveSettings(request);
});
// "/settings/settings.js&p=x" request also handled by serveSettings()
server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/style.css"), HTTP_GET, [](AsyncWebServerRequest *request){
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
@@ -149,31 +149,31 @@ void initServer()
request->send(response);
});
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/favicon.ico"), HTTP_GET, [](AsyncWebServerRequest *request){
if(!handleFileRead(request, "/favicon.ico"))
{
request->send_P(200, "image/x-icon", favicon, 156);
}
});
server.on("/welcome", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/welcome"), HTTP_GET, [](AsyncWebServerRequest *request){
serveSettings(request);
});
server.on("/reset", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/reset"), HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 200,F("Rebooting now..."),F("Please wait ~10 seconds..."),129);
doReboot = true;
});
server.on("/settings", HTTP_POST, [](AsyncWebServerRequest *request){
server.on(SET_F("/settings"), HTTP_POST, [](AsyncWebServerRequest *request){
serveSettings(request, true);
});
server.on("/json", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/json"), HTTP_GET, [](AsyncWebServerRequest *request){
serveJson(request);
});
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request) {
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler(F("/json"), [](AsyncWebServerRequest *request) {
bool verboseResponse = false;
bool isConfig = false;
@@ -222,15 +222,15 @@ void initServer()
}, JSON_BUFFER_SIZE);
server.addHandler(handler);
server.on("/version", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/version"), HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", (String)VERSION);
});
server.on("/uptime", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/uptime"), HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", (String)millis());
});
server.on("/freeheap", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/freeheap"), HTTP_GET, [](AsyncWebServerRequest *request){
request->send(200, "text/plain", (String)ESP.getFreeHeap());
});
@@ -244,17 +244,17 @@ void initServer()
});
#endif
server.on("/teapot", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/teapot"), HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 418, F("418. I'm a teapot."), F("(Tangible Embedded Advanced Project Of Twinkling)"), 254);
});
server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request) {},
server.on(SET_F("/upload"), HTTP_POST, [](AsyncWebServerRequest *request) {},
[](AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data,
size_t len, bool final) {handleUpload(request, filename, index, data, len, final);}
);
#ifdef WLED_ENABLE_SIMPLE_UI
server.on("/simple.htm", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/simple.htm"), HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, "/simple.htm")) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_simple, PAGE_simple_L);
@@ -264,14 +264,14 @@ void initServer()
});
#endif
server.on("/iro.js", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/iro.js"), HTTP_GET, [](AsyncWebServerRequest *request){
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", iroJs, iroJs_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
request->send(response);
});
server.on("/rangetouch.js", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/rangetouch.js"), HTTP_GET, [](AsyncWebServerRequest *request){
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", rangetouchJs, rangetouchJs_length);
response->addHeader(FPSTR(s_content_enc),"gzip");
setStaticContentCacheHeaders(response);
@@ -282,20 +282,20 @@ void initServer()
#ifndef WLED_DISABLE_OTA
//init ota page
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/update"), HTTP_GET, [](AsyncWebServerRequest *request){
if (otaLock) {
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254);
serveMessage(request, 401, F("Access Denied"), FPSTR(s_unlock_ota), 254);
} else
serveSettings(request); // checks for "upd" in URL and handles PIN
});
server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
server.on(SET_F("/update"), HTTP_POST, [](AsyncWebServerRequest *request){
if (!correctPIN) {
serveSettings(request, true); // handle PIN page POST request
return;
}
if (otaLock) {
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254);
serveMessage(request, 401, F("Access Denied"), FPSTR(s_unlock_ota), 254);
return;
}
if (Update.hasError()) {
@@ -328,19 +328,19 @@ void initServer()
}
});
#else
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 501, "Not implemented", F("OTA updating is disabled in this build."), 254);
server.on(SET_F("/update"), HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 501, F("Not implemented"), F("OTA updating is disabled in this build."), 254);
});
#endif
#ifdef WLED_ENABLE_DMX
server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
request->send_P(200, "text/html", PAGE_dmxmap , dmxProcessor);
});
#else
server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 501, "Not implemented", F("DMX support is not enabled in this build."), 254);
server.on(SET_F("/dmxmap"), HTTP_GET, [](AsyncWebServerRequest *request){
serveMessage(request, 501, F("Not implemented"), F("DMX support is not enabled in this build."), 254);
});
#endif
@@ -354,8 +354,8 @@ void initServer()
});
#ifdef WLED_ENABLE_PIXART
server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, "/pixart.htm")) return;
server.on(SET_F("/pixart.htm"), HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, F("/pixart.htm"))) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pixart, PAGE_pixart_L);
response->addHeader(FPSTR(s_content_enc),"gzip");
@@ -365,8 +365,8 @@ void initServer()
#endif
#ifndef WLED_DISABLE_PXMAGIC
server.on("/pxmagic.htm", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, "/pxmagic.htm")) return;
server.on(SET_F("/pxmagic.htm"), HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, F("/pxmagic.htm"))) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pxmagic, PAGE_pxmagic_L);
response->addHeader(FPSTR(s_content_enc),"gzip");
@@ -375,8 +375,8 @@ void initServer()
});
#endif
server.on("/cpal.htm", HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, "/cpal.htm")) return;
server.on(SET_F("/cpal.htm"), HTTP_GET, [](AsyncWebServerRequest *request){
if (handleFileRead(request, F("/cpal.htm"))) return;
if (handleIfNoneMatchCacheHeader(request)) return;
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_cpal, PAGE_cpal_L);
response->addHeader(FPSTR(s_content_enc),"gzip");
@@ -442,7 +442,7 @@ void setStaticContentCacheHeaders(AsyncWebServerResponse *response)
void serveIndex(AsyncWebServerRequest* request)
{
if (handleFileRead(request, "/index.htm")) return;
if (handleFileRead(request, F("/index.htm"))) return;
if (handleIfNoneMatchCacheHeader(request)) return;
@@ -586,7 +586,7 @@ void serveSettings(AsyncWebServerRequest* request, bool post)
// if OTA locked or too frequent PIN entry requests fail hard
if ((subPage == SUBPAGE_WIFI && wifiLock && otaLock) || (post && !correctPIN && millis()-lastEditTime < PIN_RETRY_COOLDOWN))
{
serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254); return;
serveMessage(request, 401, F("Access Denied"), FPSTR(s_unlock_ota), 254); return;
}
if (post) { //settings/set POST request, saving