diff --git a/.github/workflows/wled-ci.yml b/.github/workflows/wled-ci.yml index 2b599e6f6..7d27717dd 100644 --- a/.github/workflows/wled-ci.yml +++ b/.github/workflows/wled-ci.yml @@ -39,6 +39,11 @@ jobs: environment: ${{ fromJSON(needs.get_default_envs.outputs.environments) }} steps: - uses: actions/checkout@v3 + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + cache: 'npm' + - run: npm install - name: Cache pip uses: actions/cache@v3 with: diff --git a/.gitignore b/.gitignore index 789de0a9e..8a2319a72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,24 @@ -.pio .cache +.clang-format +.direnv +.DS_Store +.idea +.pio .pioenvs .piolibdeps .vscode -/wled00/Release -/wled00/extLibs -/platformio_override.ini -/wled00/my_config.h -/build_output -.DS_Store -.gitignore -.clang-format -node_modules -.idea -.direnv -wled-update.sh + esp01-update.sh -/wled00/LittleFS +platformio_override.ini replace_fs.py -wled00/wled00.ino.cpp +wled-update.sh + +/build_output/ +/node_modules/ + +/wled00/extLibs +/wled00/LittleFS +/wled00/my_config.h +/wled00/Release +/wled00/wled00.ino.cpp +/wled00/html_*.h \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 2ee772ce1..f46f002b4 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -9,8 +9,8 @@ ], "dependsOrder": "sequence", "problemMatcher": [ - "$platformio", - ], + "$platformio" + ] }, { "type": "PlatformIO", @@ -18,7 +18,7 @@ "task": "Build", "group": { "kind": "build", - "isDefault": true, + "isDefault": true }, "problemMatcher": [ "$platformio" diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d792e73b..17c37c530 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,119 @@ ## WLED changelog +#### Build 2309120 till build 2201060 +- WLED version 0.15.0-a0 +- Global JSON buffer guarding (#3648 by @willmmiles, resolves #3641, #3312, #3367, #3637, #3646, #3447) +- Effect: Fireworks 1D (fix for matrix trailing strip) +- BREAKING: Reduced number of segments (12) on ESP8266 due to less available RAM +- Increased available effect data buffer (increases more if board has PSRAM) +- Custom palette editor mobile UI enhancement (by @imeszaros) +- Per port Auto Brightness Limiter (ABL) +- Use PSRAM for JSON buffer (double size, larger ledmaps, up to 2k) +- Reduced heap fragmentation by allocating ledmap array only once and not deallocating effect buffer +- HTTP retries on failed UI load +- UI Search: scroll to top (#3587 by @WoodyLetsCode) +- Return to inline iro.js and rangetouch.js (#3597 by @WoodyLetsCode) +- Better caching (#3591 by @WoodyLetsCode) +- Do not send 404 for missing `skin.css` (#3590 by @WoodyLetsCode) +- Simplified UI rework (#3511 by @WoodyLetsCode) +- Domoticz device ID for PIR and Temperature usermods +- Bugfix for UCS8904 `hasWhite()` +- Better search in UI (#3540 by @WoodyLetsCode) +- Seeding FastLED PRNG (#3552 by @TripleWhy) +- WIZ Smart Button support (#3547 by @micw) +- New button type (button switch, fix for #3537) +- Pixel Magic Tool update (#3483 by @ajotanc) +- Effect: 2D Matrix fix for gaps +- Bugfix #3526, #3533, #3561 +- Spookier Halloween Eyes (#3501) +- Compile time options for Multi Relay usermod (#3498) +- Effect: Fix for Dissolve (#3502) +- Better reverse proxy support (nested paths) +- Implement global JSON API boolean toggle (i.e. instead of "var":true or "var":false -> "var":"t"). +- Sort presets by ID +- Fix for #3641, #3312, #3367, #3637, #3646, #3447, #3632, #3496, #2922, #3593, #3514, #3522, #3578 (partial), #3606 (@WoodyLetsCode) +- Improved random bg image and added random bg image options (@WoodyLetsCode, #3481) +- Audio palettes (Audioreactive usermod, credit @netmindz) +- Better UI tooltips (@ajotnac, #3464) +- Better effect filters (filter dropdown) +- UDP sync fix (for #3487) +- Power button override (solves #3431) +- Additional HTTP request throttling (ESP8266) +- Additional UI/UX improvements +- Segment class optimisations (internal) +- ESP-NOW sync +- ESP-NOW Wiz remote JSON overrides (similar to IR JSON) & bugfixes +- Gamma correction for custom palettes (#3399). +- Restore presets from browser local storage +- Optional effect blending +- Restructured UDP Sync (internal) + - Remove sync receive + - Sync clarification +- Disallow 2D effects on non-2D segments +- Return of 2 audio simulations +- Bugfix in sync #3344 (internal) + - remove excessive segments + - ignore inactive segments if not syncing bounds + - send UDP/WS on segment change + - pop_back() when removing last segment + +#### Build 2311160 +- Version bump: 0.14.1-b1 +- Bugfixes (#3526, #3502, #3496, #3484, #3487, #3445, #3466, #3296, #3382, #3312) +- New feature: Sort presets by ID +- New usermod: LDR sensor (#3490 by @JeffWDH) +- Effect: Twinklefox & Tinklecat metadata fix +- Effect: separate #HH and #MM for Scrolling Text (#3480) +- SSDR usermod enhancements (#3368) +- PWM fan usermod enhancements (#3414) + +#### Build 2310010, build 2310130 +- Release of WLED version 0.14.0 "Hoshi" +- Bugfixes for #3400, #3403, #3405 +- minor HTML optimizations +- audioreactive: bugfix for UDP sound sync (partly initialized packets) + +#### Build 2309240 +- Release of WLED beta version 0.14.0-b6 "Hoshi" +- Effect bugfixes and improvements (Meteor, Meteor Smooth, Scrolling Text) +- audioreactive: bugfixes for ES8388 and ES7243 init; minor improvements for analog inputs + +#### Build 2309100 +- Release of WLED beta version 0.14.0-b5 "Hoshi" +- New standard esp32 build with audioreactive +- Effect blending bugfixes, and minor optimizations + +#### Build 2309050 +- Effect blending (#3311) (finally effect transitions!) + *WARNING*: May not work well with ESP8266, with plenty of segments or usermods (low RAM condition)!!! +- Added receive and send sync groups to JSON API (#3317) (you can change sync groups using preset) +- Internal temperature usermod (#3246) +- MQTT server and topic length overrides (#3354) (new build flags) +- Animated Staircase usermod enhancement (#3348) (on/off toggle/relay control) +- Added local time info to Info page (#3351) +- New effect: Rolling Balls (a.k.a. linear bounce) (#1039) +- Various bug fixes and enhancements. + +#### Build 2308110 +- Release of WLED beta version 0.14.0-b4 "Hoshi" +- Reset effect data immediately upon mode change + +#### Build 2308030 +- Improved random palette handling and blending +- Soap bugfix +- Fix ESP-NOW crash with AP mode Always + +#### Build 2307180 +- Bus-level global buffering (#3280) +- Removed per-segment LED buffer (SEGMENT.leds) +- various fixes and improvements (ESP variants platform 5.3.0, effect optimizations, /json/cfg pin allocation) + #### Build 2307130 - larger `oappend()` stack buffer (3.5k) for ESP32 - Preset cycle bugfix (#3262) - Rotary encoder ALT fix for large LED count (#3276) - effect updates (2D Plasmaball), `blur()` speedup -- On/Off toggle from nodes view (may show unknow device type on older versions) (#3291) +- On/Off toggle from nodes view (may show unknown device type on older versions) (#3291) - various fixes and improvements (ABL, crashes when changing presets with different segments) #### Build 2306270 @@ -18,7 +126,7 @@ #### Build 2306210 - 0.14.0-b3 release -- respect global I2C in all usermods (no local initilaisation of I2C bus) +- respect global I2C in all usermods (no local initialization of I2C bus) - Multi relay usermod compile-time enabled option (-D MULTI_RELAY_ENABLED=true|false) #### Build 2306180 @@ -44,7 +152,7 @@ #### Build 2306020 - Support for segment sets (PR #3171) -- Reduce sound simulation modes to 2 to facilitiate segment sets +- Reduce sound simulation modes to 2 to facilitate segment sets - Trigger button immediately on press if all configured presets are the same (PR #3226) - Changes for allowing Alexa to change light color to White when auto-calculating from RGB (PR #3211) diff --git a/package-lock.json b/package-lock.json index c4fe9b1c4..55fc0b17b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "wled", - "version": "0.14.0-b3", + "version": "0.15.0-a0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d57c87d5d..68bd16b82 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wled", - "version": "0.14.0-b3", + "version": "0.15.0-a0", "description": "Tools for WLED project", "main": "tools/cdata.js", "directories": { diff --git a/pio-scripts/build_ui.py b/pio-scripts/build_ui.py new file mode 100644 index 000000000..f3688a5d4 --- /dev/null +++ b/pio-scripts/build_ui.py @@ -0,0 +1,3 @@ +Import('env') + +env.Execute("npm run build") \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 551014309..d242cbc22 100644 --- a/platformio.ini +++ b/platformio.ini @@ -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, lolin_s2_mini, esp32c3dev, esp32s3dev_8MB, esp32s3dev_8MB_PSRAM_opi +default_envs = nodemcuv2, esp8266_2m, esp01_1m_full, 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 @@ -87,11 +87,13 @@ platform_packages = platformio/framework-arduinoespressif8266 # ------------------------------------------------------------------------------ # FLAGS: DEBUG -# +# esp8266 : see https://docs.platformio.org/en/latest/platforms/espressif8266.html#debug-level +# esp32 : see https://docs.platformio.org/en/latest/platforms/espressif32.html#debug-level # ------------------------------------------------------------------------------ -debug_flags = -D DEBUG=1 -D WLED_DEBUG -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM -#if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h" -#-DDEBUG_ESP_CORE is not working right now +debug_flags = -D DEBUG=1 -D WLED_DEBUG + -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM ;; for esp8266 + # if needed (for memleaks etc) also add; -DDEBUG_ESP_OOM -include "umm_malloc/umm_malloc_cfg.h" + # -DDEBUG_ESP_CORE is not working right now # ------------------------------------------------------------------------------ # FLAGS: ldscript (available ldscripts at https://github.com/esp8266/Arduino/tree/master/tools/sdk/ld) @@ -135,6 +137,7 @@ build_flags = ; -D USERMOD_SENSORSTOMQTT #For ADS1115 sensor uncomment following ; -D USERMOD_ADS1115 + ; -D USERMOD_ANIMARTRIX build_unflags = @@ -153,6 +156,7 @@ extra_scripts = post:pio-scripts/output_bins.py post:pio-scripts/strip-floats.py pre:pio-scripts/user_config_copy.py + pre:pio-scripts/build_ui.py # ------------------------------------------------------------------------------ # COMMON SETTINGS: @@ -179,6 +183,9 @@ lib_deps = IRremoteESP8266 @ 2.8.2 makuna/NeoPixelBus @ 2.7.5 https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.7 + # ESP-NOW library (includes mandatory QuickDebug library) + ; gmag11/QuickESPNow @ 0.6.2 + https://github.com/blazoncek/QuickESPNow.git#optional-debug #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 @@ -193,6 +200,11 @@ lib_deps = #For ADS1115 sensor uncomment following ; adafruit/Adafruit BusIO @ 1.13.2 ; adafruit/Adafruit ADS1X15 @ 2.4.0 + #For MPU6050 IMU uncomment follwoing + ; electroniccats/MPU6050 @1.0.1 + # For -D USERMOD_ANIMARTRIX + # CC BY-NC 3.0 licensed effects by Stefan Petrick, include this usermod only if you accept the terms! + ; https://github.com/netmindz/animartrix.git#18bf17389e57c69f11bc8d04ebe1d215422c7fb7 extra_scripts = ${scripts_defaults.extra_scripts} @@ -214,6 +226,10 @@ build_flags = -DVTABLES_IN_FLASH ; restrict to minimal mime-types -DMIMETYPE_MINIMAL + ; other special-purpose framework flags (see https://docs.platformio.org/en/latest/platforms/espressif8266.html) + ; decrease code cache size and increase IRAM to fit all pixel functions + -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48 ;; in case of linker errors like "section `.text1' will not fit in region `iram1_0_seg'" + ; -D PIO_FRAMEWORK_ARDUINO_MMU_CACHE16_IRAM48_SECHEAP_SHARED ;; (experimental) adds some extra heap, but may cause slowdown lib_deps = #https://github.com/lorol/LITTLEFS.git @@ -224,9 +240,7 @@ lib_deps = [esp32] #platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.2.3/platform-espressif32-2.0.2.3.zip platform = espressif32@3.5.0 - platform_packages = framework-arduinoespressif32 @ https://github.com/Aircoookie/arduino-esp32.git#1.0.6.4 - build_flags = -g -DARDUINO_ARCH_ESP32 #-DCONFIG_LITTLEFS_FOR_IDF_3_2 @@ -234,16 +248,16 @@ build_flags = -g #use LITTLEFS library by lorol in ESP32 core 1.x.x instead of built-in in 2.x.x -D LOROL_LITTLEFS ; -DARDUINO_USB_CDC_ON_BOOT=0 ;; this flag is mandatory for "classic ESP32" when building with arduino-esp32 >=2.0.3 - default_partitions = tools/WLED_ESP32_4MB_1MB_FS.csv - lib_deps = https://github.com/lorol/LITTLEFS.git https://github.com/pbolduc/AsyncTCP.git @ 1.2.0 bitbank2/AnimatedGIF@^1.4.7 pixelmatix/GifDecoder@^1.1.0 ${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 [esp32_idf_V4] ;; experimental build environment for ESP32 using ESP-IDF 4.4.x / arduino-esp32 v2.0.5 @@ -351,6 +365,7 @@ platform_packages = ${common.platform_packages} board_build.ldscript = ${common.ldscript_1m128k} build_unflags = ${common.build_unflags} build_flags = ${common.build_flags_esp8266} -D WLED_RELEASE_NAME=ESP01 -D WLED_DISABLE_OTA + ; -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:esp07] @@ -401,6 +416,20 @@ lib_deps = ${esp32.lib_deps} monitor_filters = esp32_exception_decoder board_build.partitions = ${esp32.default_partitions} +[env:esp32dev_audioreactive] +board = esp32dev +platform = ${esp32.platform} +platform_packages = ${esp32.platform_packages} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_audioreactive #-D WLED_DISABLE_BROWNOUT_DET + ${esp32.AR_build_flags} +lib_deps = ${esp32.lib_deps} + ${esp32.AR_lib_deps} +monitor_filters = esp32_exception_decoder +board_build.partitions = ${esp32.default_partitions} +; board_build.f_flash = 80000000L +; board_build.flash_mode = dio + [env:esp32dev_qio80] board = esp32dev platform = ${esp32.platform} @@ -435,6 +464,7 @@ platform_packages = ${esp32.platform_packages} upload_speed = 921600 build_unflags = ${common.build_unflags} build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1 + -D WLED_DISABLE_ESPNOW ;; ESP-NOW requires wifi, may crash with ethernet only lib_deps = ${esp32.lib_deps} board_build.partitions = ${esp32.default_partitions} @@ -459,7 +489,7 @@ platform_packages = ${esp32c3.platform_packages} framework = arduino board = esp32-c3-devkitm-1 board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv -build_flags = ${common.build_flags} ${esp32c3.build_flags} #-D WLED_RELEASE_NAME=ESP32-C3 +build_flags = ${common.build_flags} ${esp32c3.build_flags} -D WLED_RELEASE_NAME=ESP32-C3 -D WLED_WATCHDOG_TIMEOUT=0 -DLOLIN_WIFI_FIX ; seems to work much better with this -DARDUINO_USB_CDC_ON_BOOT=1 ;; for virtual CDC USB @@ -475,7 +505,7 @@ platform = ${esp32s3.platform} platform_packages = ${esp32s3.platform_packages} upload_speed = 921600 ; or 460800 build_unflags = ${common.build_unflags} -build_flags = ${common.build_flags} ${esp32s3.build_flags} +build_flags = ${common.build_flags} ${esp32s3.build_flags} -D WLED_RELEASE_NAME=ESP32-S3_8MB -D CONFIG_LITTLEFS_FOR_IDF_3_2 -D WLED_WATCHDOG_TIMEOUT=0 -D ARDUINO_USB_CDC_ON_BOOT=0 ;; -D ARDUINO_USB_MODE=1 ;; for boards with serial-to-USB chip ;-D ARDUINO_USB_CDC_ON_BOOT=1 ;; -D ARDUINO_USB_MODE=1 ;; for boards with USB-OTG connector only (USBCDC or "TinyUSB") @@ -582,13 +612,14 @@ platform_packages = ${esp32s2.platform_packages} board = lolin_s2_mini board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv build_unflags = ${common.build_unflags} #-DARDUINO_USB_CDC_ON_BOOT=1 -build_flags = ${common.build_flags} ${esp32s2.build_flags} #-D WLED_RELEASE_NAME=LolinS2 +build_flags = ${common.build_flags} ${esp32s2.build_flags} -D WLED_RELEASE_NAME=ESP32-S2 -DBOARD_HAS_PSRAM -DARDUINO_USB_CDC_ON_BOOT=1 # try disabling and enabling unflag above in case of board-specific issues, will disable Serial -DARDUINO_USB_MSC_ON_BOOT=0 -DARDUINO_USB_DFU_ON_BOOT=0 -DLOLIN_WIFI_FIX ; seems to work much better with this -D WLED_USE_PSRAM + ; -D WLED_USE_UNREAL_MATH ;; may cause wrong sunset/sunrise times, but saves 6792 bytes FLASH -D WLED_WATCHDOG_TIMEOUT=0 -D CONFIG_ASYNC_TCP_USE_WDT=0 -D LEDPIN=16 diff --git a/readme.md b/readme.md index dda6634a1..b5100e248 100644 --- a/readme.md +++ b/readme.md @@ -3,7 +3,7 @@ - + @@ -66,7 +66,7 @@ Credits [here](https://kno.wled.ge/about/contributors/)! Join the Discord server to discuss everything about WLED! - + Check out the WLED [Discourse forum](https://wled.discourse.group)! diff --git a/tools/cdata.js b/tools/cdata.js index 90619ba67..4b0d15d4f 100644 --- a/tools/cdata.js +++ b/tools/cdata.js @@ -16,12 +16,15 @@ */ const fs = require("fs"); +const path = require('path'); const inliner = require("inliner"); const zlib = require("zlib"); const CleanCSS = require("clean-css"); const MinifyHTML = require("html-minifier-terser").minify; const packageJson = require("../package.json"); +const output = ["wled00/html_ui.h", "wled00/html_pixart.h", "wled00/html_cpal.h", "wled00/html_pxmagic.h", "wled00/html_settings.h", "wled00/html_other.h"] + /** * */ @@ -182,7 +185,7 @@ ${result} const result = hexdump(buf); const chunk = ` // Autogenerated from ${srcDir}/${s.file}, do not edit!! -const uint16_t ${s.name}_length = ${result.length}; +const uint16_t ${s.name}_length = ${buf.length}; const uint8_t ${s.name}[] PROGMEM = { ${result} }; @@ -204,12 +207,13 @@ function writeChunks(srcDir, specs, resultFile) { */ `; specs.forEach((s) => { + const file = srcDir + "/" + s.file; try { - console.info("Reading " + srcDir + "/" + s.file + " as " + s.name); + console.info("Reading " + file + " as " + s.name); src += specToChunk(srcDir, s); } catch (e) { console.warn( - "Failed " + s.name + " from " + srcDir + "/" + s.file, + "Failed " + s.name + " from " + file, e.message.length > 60 ? e.message.substring(0, 60) : e.message ); } @@ -218,37 +222,57 @@ function writeChunks(srcDir, specs, resultFile) { fs.writeFileSync(resultFile, src); } +// Check if a file is newer than a given time +function isFileNewerThan(filePath, time) { + try { + const stats = fs.statSync(filePath); + return stats.mtimeMs > time; + } catch (e) { + console.error(`Failed to get stats for file ${filePath}:`, e); + return false; + } +} + +// Check if any file in a folder (or its subfolders) is newer than a given time +function isAnyFileInFolderNewerThan(folderPath, time) { + const files = fs.readdirSync(folderPath, { withFileTypes: true }); + for (const file of files) { + const filePath = path.join(folderPath, file.name); + if (isFileNewerThan(filePath, time)) { + return true; + } + if (file.isDirectory() && isAnyFileInFolderNewerThan(filePath, time)) { + return true; + } + } + return false; +} + +function isAlreadyBuilt(folderPath) { + let lastBuildTime = Infinity; + + for (const file of output) { + try { + lastBuildTime = Math.min(lastBuildTime, fs.statSync(file).mtimeMs); + } + catch (e) { + return false; + } + } + + return !isAnyFileInFolderNewerThan(folderPath, lastBuildTime); +} + +if (isAlreadyBuilt("wled00/data") && process.argv[2] !== '--force' && process.argv[2] !== '-f') { + console.info("Web UI is already built"); + return; +} + writeHtmlGzipped("wled00/data/index.htm", "wled00/html_ui.h", 'index'); -writeHtmlGzipped("wled00/data/simple.htm", "wled00/html_simple.h", 'simple'); writeHtmlGzipped("wled00/data/pixart/pixart.htm", "wled00/html_pixart.h", 'pixart'); writeHtmlGzipped("wled00/data/cpal/cpal.htm", "wled00/html_cpal.h", 'cpal'); writeHtmlGzipped("wled00/data/pxmagic/pxmagic.htm", "wled00/html_pxmagic.h", 'pxmagic'); -/* -writeChunks( - "wled00/data", - [ - { - file: "simple.css", - name: "PAGE_simpleCss", - method: "gzip", - filter: "css-minify", - }, - { - file: "simple.js", - name: "PAGE_simpleJs", - method: "gzip", - filter: "js-minify", - }, - { - file: "simple.htm", - name: "PAGE_simple", - method: "gzip", - filter: "html-minify-ui", - } - ], - "wled00/html_simplex.h" -); -*/ + writeChunks( "wled00/data", [ @@ -406,16 +430,6 @@ const char PAGE_dmxmap[] PROGMEM = R"=====()====="; file: "favicon.ico", name: "favicon", method: "binary", - }, - { - file: "iro.js", - name: "iroJs", - method: "gzip" - }, - { - file: "rangetouch.js", - name: "rangetouchJs", - method: "gzip" } ], "wled00/html_other.h" diff --git a/usermods/Animated_Staircase/Animated_Staircase.h b/usermods/Animated_Staircase/Animated_Staircase.h index 151cf1d4a..147497211 100644 --- a/usermods/Animated_Staircase/Animated_Staircase.h +++ b/usermods/Animated_Staircase/Animated_Staircase.h @@ -25,6 +25,7 @@ class Animated_Staircase : public Usermod { bool useUSSensorBottom = false; // using PIR or UltraSound sensor? unsigned int topMaxDist = 50; // default maximum measured distance in cm, top unsigned int bottomMaxDist = 50; // default maximum measured distance in cm, bottom + bool togglePower = false; // toggle power on/off with staircase on/off /* runtime variables */ bool initDone = false; @@ -90,7 +91,8 @@ class Animated_Staircase : public Usermod { static const char _bottomEcho_pin[]; static const char _topEchoCm[]; static const char _bottomEchoCm[]; - + static const char _togglePower[]; + void publishMqtt(bool bottom, const char* state) { #ifndef WLED_DISABLE_MQTT //Check if MQTT Connected, otherwise it will crash the 8266 @@ -196,6 +198,7 @@ class Animated_Staircase : public Usermod { if (on) { lastSensor = topSensorRead; } else { + if (togglePower && onIndex == offIndex && offMode) toggleOnOff(); // toggle power on if off // If the bottom sensor triggered, we need to swipe up, ON swipe = bottomSensorRead; @@ -249,7 +252,10 @@ class Animated_Staircase : public Usermod { offIndex = MAX(onIndex, offIndex - 1); } } - if (oldOn != onIndex || oldOff != offIndex) updateSegments(); // reduce the number of updates to necessary ones + if (oldOn != onIndex || oldOff != offIndex) { + updateSegments(); // reduce the number of updates to necessary ones + if (togglePower && onIndex == offIndex && !offMode && !on) toggleOnOff(); // toggle power off for all segments off + } } } @@ -291,10 +297,11 @@ class Animated_Staircase : public Usermod { offIndex = maxSegmentId = strip.getLastActiveSegmentId() + 1; // shorten the strip transition time to be equal or shorter than segment delay - transitionDelayTemp = transitionDelay = segment_delay_ms; - strip.setTransition(segment_delay_ms/100); + transitionDelay = segment_delay_ms; + strip.setTransition(segment_delay_ms); strip.trigger(); } else { + if (togglePower && !on && offMode) toggleOnOff(); // toggle power on if off // Restore segment options for (int i = 0; i <= strip.getLastActiveSegmentId(); i++) { Segment &seg = strip.getSegment(i); @@ -444,6 +451,7 @@ class Animated_Staircase : public Usermod { staircase[FPSTR(_bottomEcho_pin)] = useUSSensorBottom ? bottomEchoPin : -1; staircase[FPSTR(_topEchoCm)] = topMaxDist; staircase[FPSTR(_bottomEchoCm)] = bottomMaxDist; + staircase[FPSTR(_togglePower)] = togglePower; DEBUG_PRINTLN(F("Staircase config saved.")); } @@ -488,6 +496,8 @@ class Animated_Staircase : public Usermod { bottomMaxDist = top[FPSTR(_bottomEchoCm)] | bottomMaxDist; bottomMaxDist = min(150,max(30,(int)bottomMaxDist)); // max distance ~1.5m (a lag of 9ms may be expected) + togglePower = top[FPSTR(_togglePower)] | togglePower; // staircase toggles power on/off + DEBUG_PRINT(FPSTR(_name)); if (!initDone) { // first run: reading from cfg.json @@ -511,7 +521,7 @@ class Animated_Staircase : public Usermod { if (changed) setup(); } // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return true; + return !top[FPSTR(_togglePower)].isNull(); } /* @@ -551,3 +561,4 @@ const char Animated_Staircase::_bottomPIRorTrigger_pin[] PROGMEM = "bottomPIR const char Animated_Staircase::_bottomEcho_pin[] PROGMEM = "bottomEcho_pin"; const char Animated_Staircase::_topEchoCm[] PROGMEM = "top-dist-cm"; const char Animated_Staircase::_bottomEchoCm[] PROGMEM = "bottom-dist-cm"; +const char Animated_Staircase::_togglePower[] PROGMEM = "toggle-on-off"; diff --git a/usermods/EXAMPLE_v2/usermod_v2_example.h b/usermods/EXAMPLE_v2/usermod_v2_example.h index 43648b588..910e0cae2 100644 --- a/usermods/EXAMPLE_v2/usermod_v2_example.h +++ b/usermods/EXAMPLE_v2/usermod_v2_example.h @@ -87,7 +87,7 @@ class MyExampleUsermod : public Usermod { * readFromConfig() is called prior to setup() * You can use it to initialize variables, sensors or similar. */ - void setup() { + void setup() override { // do your set-up here //Serial.println("Hello from my usermod!"); initDone = true; @@ -98,7 +98,7 @@ class MyExampleUsermod : public Usermod { * connected() is called every time the WiFi is (re)connected * Use it to initialize network interfaces */ - void connected() { + void connected() override { //Serial.println("Connected to WiFi!"); } @@ -113,7 +113,7 @@ class MyExampleUsermod : public Usermod { * 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds. * Instead, use a timer check as shown here. */ - void loop() { + void loop() override { // if usermod is disabled or called during strip updating just exit // NOTE: on very long strips strip.isUpdating() may always return true so update accordingly if (!enabled || strip.isUpdating()) return; @@ -131,7 +131,7 @@ class MyExampleUsermod : public Usermod { * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI. * Below it is shown how this could be used for e.g. a light sensor */ - void addToJsonInfo(JsonObject& root) + void addToJsonInfo(JsonObject& root) override { // if "u" object does not exist yet wee need to create it JsonObject user = root["u"]; @@ -156,7 +156,7 @@ class MyExampleUsermod : public Usermod { * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void addToJsonState(JsonObject& root) + void addToJsonState(JsonObject& root) override { if (!initDone || !enabled) return; // prevent crash on boot applyPreset() @@ -171,7 +171,7 @@ class MyExampleUsermod : public Usermod { * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void readFromJsonState(JsonObject& root) + void readFromJsonState(JsonObject& root) override { if (!initDone) return; // prevent crash on boot applyPreset() @@ -220,7 +220,7 @@ class MyExampleUsermod : public Usermod { * * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! */ - void addToConfig(JsonObject& root) + void addToConfig(JsonObject& root) override { JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = enabled; @@ -253,7 +253,7 @@ class MyExampleUsermod : public Usermod { * * This function is guaranteed to be called on boot, but could also be called every time settings are updated */ - bool readFromConfig(JsonObject& root) + bool readFromConfig(JsonObject& root) override { // default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor // setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed) @@ -285,7 +285,7 @@ class MyExampleUsermod : public Usermod { * it may add additional metadata for certain entry fields (adding drop down is possible) * be careful not to add too much as oappend() buffer is limited to 3k */ - void appendConfigData() + void appendConfigData() override { oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":great")); oappend(SET_F("',1,'(this is a great config value)');")); oappend(SET_F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(SET_F(":testString")); oappend(SET_F("',1,'enter any string you want');")); @@ -300,7 +300,7 @@ class MyExampleUsermod : public Usermod { * Use this to blank out some LEDs or set them to a different color regardless of the set effect mode. * Commonly used for custom clocks (Cronixie, 7 segment) */ - void handleOverlayDraw() + void handleOverlayDraw() override { //strip.setPixelColor(0, RGBW32(0,0,0,0)) // set the first pixel to black } @@ -311,7 +311,7 @@ class MyExampleUsermod : public Usermod { * will prevent button working in a default way. * Replicating button.cpp */ - bool handleButton(uint8_t b) { + bool handleButton(uint8_t b) override { yield(); // ignore certain button types as they may have other consequences if (!enabled @@ -334,7 +334,7 @@ class MyExampleUsermod : public Usermod { * handling of MQTT message * topic only contains stripped topic (part after /wled/MAC) */ - bool onMqttMessage(char* topic, char* payload) { + bool onMqttMessage(char* topic, char* payload) override { // check if we received a command //if (strlen(topic) == 8 && strncmp_P(topic, PSTR("/command"), 8) == 0) { // String action = payload; @@ -355,7 +355,7 @@ class MyExampleUsermod : public Usermod { /** * onMqttConnect() is called when MQTT connection is established */ - void onMqttConnect(bool sessionPresent) { + void onMqttConnect(bool sessionPresent) override { // do any MQTT related initialisation here //publishMqtt("I am alive!"); } @@ -366,7 +366,7 @@ class MyExampleUsermod : public Usermod { * onStateChanged() is used to detect WLED state change * @mode parameter is CALL_MODE_... parameter used for notifications */ - void onStateChange(uint8_t mode) { + void onStateChange(uint8_t mode) override { // do something if WLED state changed (color, brightness, effect, preset, etc) } @@ -375,7 +375,7 @@ class MyExampleUsermod : public Usermod { * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - uint16_t getId() + uint16_t getId() override { return USERMOD_ID_EXAMPLE; } diff --git a/usermods/Internal_Temperature_v2/readme.md b/usermods/Internal_Temperature_v2/readme.md new file mode 100644 index 000000000..58a9e1939 --- /dev/null +++ b/usermods/Internal_Temperature_v2/readme.md @@ -0,0 +1,17 @@ +# Internal Temperature Usermod +This usermod adds the temperature readout to the Info tab and also publishes that over the topic `mcutemp` topic. + +## Important +A shown temp of 53,33°C might indicate that the internal temp is not supported. + +ESP8266 does not have a internal temp sensor + +ESP32S2 seems to crash on reading the sensor -> disabled + +## Installation +Add a build flag `-D USERMOD_INTERNAL_TEMPERATURE` to your `platformio.ini` (or `platformio_override.ini`). + +## Authors +Soeren Willrodt [@lost-hope](https://github.com/lost-hope) + +Dimitry Zhemkov [@dima-zhemkov](https://github.com/dima-zhemkov) \ No newline at end of file diff --git a/usermods/Internal_Temperature_v2/usermod_internal_temperature.h b/usermods/Internal_Temperature_v2/usermod_internal_temperature.h new file mode 100644 index 000000000..180176a2f --- /dev/null +++ b/usermods/Internal_Temperature_v2/usermod_internal_temperature.h @@ -0,0 +1,117 @@ +#pragma once + +#include "wled.h" + +class InternalTemperatureUsermod : public Usermod +{ + +private: + unsigned long loopInterval = 10000; + unsigned long lastTime = 0; + bool isEnabled = false; + float temperature = 0; + + static const char _name[]; + static const char _enabled[]; + static const char _loopInterval[]; + + // any private methods should go here (non-inline methosd should be defined out of class) + void publishMqtt(const char *state, bool retain = false); // example for publishing MQTT message + +public: + void setup() + { + } + + void loop() + { + // if usermod is disabled or called during strip updating just exit + // NOTE: on very long strips strip.isUpdating() may always return true so update accordingly + if (!isEnabled || strip.isUpdating() || millis() - lastTime <= loopInterval) + return; + + lastTime = millis(); + +#ifdef ESP8266 // ESP8266 + // does not seem possible + temperature = -1; +#elif defined(CONFIG_IDF_TARGET_ESP32S2) // ESP32S2 + temperature = -1; +#else // ESP32 ESP32S3 and ESP32C3 + temperature = roundf(temperatureRead() * 10) / 10; +#endif + +#ifndef WLED_DISABLE_MQTT + if (WLED_MQTT_CONNECTED) + { + char array[10]; + snprintf(array, sizeof(array), "%f", temperature); + publishMqtt(array); + } +#endif + } + + void addToJsonInfo(JsonObject &root) + { + if (!isEnabled) + return; + + // if "u" object does not exist yet wee need to create it + JsonObject user = root["u"]; + if (user.isNull()) + user = root.createNestedObject("u"); + + JsonArray userTempArr = user.createNestedArray(FPSTR(_name)); + userTempArr.add(temperature); + userTempArr.add(F(" °C")); + + // if "sensor" object does not exist yet wee need to create it + JsonObject sensor = root[F("sensor")]; + if (sensor.isNull()) + sensor = root.createNestedObject(F("sensor")); + + JsonArray sensorTempArr = sensor.createNestedArray(FPSTR(_name)); + sensorTempArr.add(temperature); + sensorTempArr.add(F("°C")); + } + + void addToConfig(JsonObject &root) + { + JsonObject top = root.createNestedObject(FPSTR(_name)); + top[FPSTR(_enabled)] = isEnabled; + top[FPSTR(_loopInterval)] = loopInterval; + } + + bool readFromConfig(JsonObject &root) + { + JsonObject top = root[FPSTR(_name)]; + bool configComplete = !top.isNull(); + configComplete &= getJsonValue(top[FPSTR(_enabled)], isEnabled); + configComplete &= getJsonValue(top[FPSTR(_loopInterval)], loopInterval); + + return configComplete; + } + + uint16_t getId() + { + return USERMOD_ID_INTERNAL_TEMPERATURE; + } +}; + +const char InternalTemperatureUsermod::_name[] PROGMEM = "Internal Temperature"; +const char InternalTemperatureUsermod::_enabled[] PROGMEM = "Enabled"; +const char InternalTemperatureUsermod::_loopInterval[] PROGMEM = "Loop Interval"; + +void InternalTemperatureUsermod::publishMqtt(const char *state, bool retain) +{ +#ifndef WLED_DISABLE_MQTT + // Check if MQTT Connected, otherwise it will crash the 8266 + if (WLED_MQTT_CONNECTED) + { + char subuf[64]; + strcpy(subuf, mqttDeviceTopic); + strcat_P(subuf, PSTR("/mcutemp")); + mqtt->publish(subuf, 0, retain, state); + } +#endif +} \ No newline at end of file diff --git a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h index 8a4b9a608..2e909ae0e 100644 --- a/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h +++ b/usermods/PIR_sensor_switch/usermod_PIR_sensor_switch.h @@ -50,8 +50,7 @@ private: volatile unsigned long offTimerStart = 0; // off timer start time volatile bool PIRtriggered = false; // did PIR trigger? - byte NotifyUpdateMode = CALL_MODE_NO_NOTIFY; // notification mode for stateUpdated(): CALL_MODE_NO_NOTIFY or CALL_MODE_DIRECT_CHANGE - byte sensorPinState = LOW; // current PIR sensor pin state + bool sensorPinState = LOW; // current PIR sensor pin state bool initDone = false; // status of initialization unsigned long lastLoop = 0; @@ -70,6 +69,7 @@ private: // Home Assistant bool HomeAssistantDiscovery = false; // is HA discovery turned on + int16_t idx = -1; // Domoticz virtual switch idx // strings to reduce flash memory usage (used more than twice) static const char _name[]; @@ -81,8 +81,8 @@ private: static const char _mqttOnly[]; static const char _offOnly[]; static const char _haDiscovery[]; - static const char _notify[]; static const char _override[]; + static const char _domoticzIDX[]; /** * check if it is daytime @@ -94,7 +94,7 @@ private: * switch strip on/off */ void switchStrip(bool switchOn); - void publishMqtt(const char* state); + void publishMqtt(bool switchOn); // Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop. void publishHomeAssistantAutodiscovery(); @@ -117,7 +117,7 @@ public: * setup() is called once at boot. WiFi is not yet connected at this point. * You can use it to initialize variables, sensors or similar. */ - void setup(); + void setup() override; /** * connected() is called every time the WiFi is (re)connected @@ -128,24 +128,24 @@ public: /** * onMqttConnect() is called when MQTT connection is established */ - void onMqttConnect(bool sessionPresent); + void onMqttConnect(bool sessionPresent) override; /** * loop() is called continuously. Here you can check for events, read sensors, etc. */ - void loop(); + void loop() override; /** * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. * * Add PIR sensor state and switch off timer duration to jsoninfo */ - void addToJsonInfo(JsonObject &root); + void addToJsonInfo(JsonObject &root) override; /** * onStateChanged() is used to detect WLED state change */ - void onStateChange(uint8_t mode); + void onStateChange(uint8_t mode) override; /** * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). @@ -157,17 +157,17 @@ public: * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void readFromJsonState(JsonObject &root); + void readFromJsonState(JsonObject &root) override; /** * provide the changeable values */ - void addToConfig(JsonObject &root); + void addToConfig(JsonObject &root) override; /** * provide UI information and allow extending UI options */ - void appendConfigData(); + void appendConfigData() override; /** * restore the changeable values @@ -175,13 +175,13 @@ public: * * The function should return true if configuration was successfully loaded or false if there was no configuration. */ - bool readFromConfig(JsonObject &root); + bool readFromConfig(JsonObject &root) override; /** * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - uint16_t getId() { return USERMOD_ID_PIRSWITCH; } + uint16_t getId() override { return USERMOD_ID_PIRSWITCH; } }; // strings to reduce flash memory usage (used more than twice) @@ -194,8 +194,8 @@ const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only"; const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only"; const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only"; const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery"; -const char PIRsensorSwitch::_notify[] PROGMEM = "notifications"; const char PIRsensorSwitch::_override[] PROGMEM = "override"; +const char PIRsensorSwitch::_domoticzIDX[] PROGMEM = "domoticz-idx"; bool PIRsensorSwitch::isDayTime() { updateLocalTime(); @@ -235,24 +235,24 @@ void PIRsensorSwitch::switchStrip(bool switchOn) prevPlaylist = 0; prevPreset = 255; } - applyPreset(m_onPreset, NotifyUpdateMode); + applyPreset(m_onPreset, CALL_MODE_BUTTON_PRESET); return; } // preset not assigned if (bri == 0) { bri = briLast; - stateUpdated(NotifyUpdateMode); + stateUpdated(CALL_MODE_BUTTON); } } else { if (m_offPreset) { - applyPreset(m_offPreset, NotifyUpdateMode); + applyPreset(m_offPreset, CALL_MODE_BUTTON_PRESET); return; } else if (prevPlaylist) { - if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, NotifyUpdateMode); + if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPlaylist, CALL_MODE_BUTTON_PRESET); prevPlaylist = 0; return; } else if (prevPreset) { - if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, NotifyUpdateMode); } + if (prevPreset<255) { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyPreset(prevPreset, CALL_MODE_BUTTON_PRESET); } else { if (currentPreset==m_onPreset || currentPlaylist==m_onPreset) applyTemporaryPreset(); } prevPreset = 0; return; @@ -261,19 +261,29 @@ void PIRsensorSwitch::switchStrip(bool switchOn) if (bri != 0) { briLast = bri; bri = 0; - stateUpdated(NotifyUpdateMode); + stateUpdated(CALL_MODE_BUTTON); } } } -void PIRsensorSwitch::publishMqtt(const char* state) +void PIRsensorSwitch::publishMqtt(bool switchOn) { #ifndef WLED_DISABLE_MQTT //Check if MQTT Connected, otherwise it will crash the 8266 if (WLED_MQTT_CONNECTED) { - char buf[64]; + char buf[128]; sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40 - mqtt->publish(buf, 0, false, state); + mqtt->publish(buf, 0, false, switchOn?"on":"off"); + // Domoticz formatted message + if (idx > 0) { + StaticJsonDocument <128> msg; + msg[F("idx")] = idx; + msg[F("RSSI")] = WiFi.RSSI(); + msg[F("command")] = F("switchlight"); + msg[F("switchcmd")] = switchOn ? F("On") : F("Off"); + serializeJson(msg, buf, 128); + mqtt->publish("domoticz/in", 0, false, buf); + } } #endif } @@ -322,13 +332,11 @@ bool PIRsensorSwitch::updatePIRsensorState() if (sensorPinState == HIGH) { offTimerStart = 0; if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()))) switchStrip(true); - else if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND); - publishMqtt("on"); } else { // start switch off timer offTimerStart = millis(); - if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND); } + publishMqtt(sensorPinState == HIGH); return true; } return false; @@ -338,11 +346,7 @@ bool PIRsensorSwitch::handleOffTimer() { if (offTimerStart > 0 && millis() - offTimerStart > m_switchOffDelay) { offTimerStart = 0; - if (enabled == true) { - if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false); - else if (NotifyUpdateMode != CALL_MODE_NO_NOTIFY) updateInterfaces(CALL_MODE_WS_SEND); - publishMqtt("off"); - } + if (!m_mqttOnly && (!m_nightTimeOnly || (m_nightTimeOnly && !isDayTime()) || PIRtriggered)) switchStrip(false); return true; } return false; @@ -482,14 +486,13 @@ void PIRsensorSwitch::addToConfig(JsonObject &root) top[FPSTR(_offOnly)] = m_offOnly; top[FPSTR(_override)] = m_override; top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery; - top[FPSTR(_notify)] = (NotifyUpdateMode != CALL_MODE_NO_NOTIFY); + top[FPSTR(_domoticzIDX)] = idx; DEBUG_PRINTLN(F("PIR config saved.")); } void PIRsensorSwitch::appendConfigData() { oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field - oappend(SET_F("addInfo('PIRsensorSwitch:notifications',1,'Periodic WS updates');")); // 0 is field type, 1 is actual field oappend(SET_F("addInfo('PIRsensorSwitch:override',1,'Cancel timer on change');")); // 0 is field type, 1 is actual field } @@ -521,8 +524,7 @@ bool PIRsensorSwitch::readFromConfig(JsonObject &root) m_offOnly = top[FPSTR(_offOnly)] | m_offOnly; m_override = top[FPSTR(_override)] | m_override; HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery; - - NotifyUpdateMode = top[FPSTR(_notify)] ? CALL_MODE_DIRECT_CHANGE : CALL_MODE_NO_NOTIFY; + idx = top[FPSTR(_domoticzIDX)] | idx; if (!initDone) { // reading config prior to setup() @@ -549,5 +551,5 @@ bool PIRsensorSwitch::readFromConfig(JsonObject &root) DEBUG_PRINTLN(F(" config (re)loaded.")); } // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return !top[FPSTR(_override)].isNull(); + return !top[FPSTR(_domoticzIDX)].isNull(); } diff --git a/usermods/PWM_fan/usermod_PWM_fan.h b/usermods/PWM_fan/usermod_PWM_fan.h index f7fe0e10f..1b78cfd4c 100644 --- a/usermods/PWM_fan/usermod_PWM_fan.h +++ b/usermods/PWM_fan/usermod_PWM_fan.h @@ -52,9 +52,15 @@ class PWMFanUsermod : public Usermod { uint8_t tachoUpdateSec = 30; float targetTemperature = 35.0; uint8_t minPWMValuePct = 0; + uint8_t maxPWMValuePct = 100; uint8_t numberOfInterrupsInOneSingleRotation = 2; // Number of interrupts ESP32 sees on tacho signal on a single fan rotation. All the fans I've seen trigger two interrups. uint8_t pwmValuePct = 0; + // constant values + static const uint8_t _pwmMaxValue = 255; + static const uint8_t _pwmMaxStepCount = 7; + float _pwmTempStepSize = 0.5f; + // strings to reduce flash memory usage (used more than twice) static const char _name[]; static const char _enabled[]; @@ -63,6 +69,7 @@ class PWMFanUsermod : public Usermod { static const char _temperature[]; static const char _tachoUpdateSec[]; static const char _minPWMValuePct[]; + static const char _maxPWMValuePct[]; static const char _IRQperRotation[]; static const char _speed[]; static const char _lock[]; @@ -156,38 +163,32 @@ class PWMFanUsermod : public Usermod { void setFanPWMbasedOnTemperature(void) { float temp = getActualTemperature(); - float difftemp = temp - targetTemperature; - // Default to run fan at full speed. - int newPWMvalue = 255; - int pwmStep = ((100 - minPWMValuePct) * newPWMvalue) / (7*100); - int pwmMinimumValue = (minPWMValuePct * newPWMvalue) / 100; + // dividing minPercent and maxPercent into equal pwmvalue sizes + int pwmStepSize = ((maxPWMValuePct - minPWMValuePct) * _pwmMaxValue) / (_pwmMaxStepCount*100); + int pwmStep = calculatePwmStep(temp - targetTemperature); + // minimum based on full speed - not entered MaxPercent + int pwmMinimumValue = (minPWMValuePct * _pwmMaxValue) / 100; + updateFanSpeed(pwmMinimumValue + pwmStep*pwmStepSize); + } - if ((temp == NAN) || (temp <= -100.0)) { + uint8_t calculatePwmStep(float diffTemp){ + if ((diffTemp == NAN) || (diffTemp <= -100.0)) { DEBUG_PRINTLN(F("WARNING: no temperature value available. Cannot do temperature control. Will set PWM fan to 255.")); - } else if (difftemp <= 0.0) { - // Temperature is below target temperature. Run fan at minimum speed. - newPWMvalue = pwmMinimumValue; - } else if (difftemp <= 0.5) { - newPWMvalue = pwmMinimumValue + pwmStep; - } else if (difftemp <= 1.0) { - newPWMvalue = pwmMinimumValue + 2*pwmStep; - } else if (difftemp <= 1.5) { - newPWMvalue = pwmMinimumValue + 3*pwmStep; - } else if (difftemp <= 2.0) { - newPWMvalue = pwmMinimumValue + 4*pwmStep; - } else if (difftemp <= 2.5) { - newPWMvalue = pwmMinimumValue + 5*pwmStep; - } else if (difftemp <= 3.0) { - newPWMvalue = pwmMinimumValue + 6*pwmStep; + return _pwmMaxStepCount; } - updateFanSpeed(newPWMvalue); + if(diffTemp <=0){ + return 0; + } + int calculatedStep = (diffTemp / _pwmTempStepSize)+1; + // anything greater than max stepcount gets max + return (uint8_t)min((int)_pwmMaxStepCount,calculatedStep); } public: // gets called once at boot. Do all initialization that doesn't depend on // network here - void setup() { + void setup() override { #ifdef USERMOD_DALLASTEMPERATURE // This Usermod requires Temperature usermod tempUM = (UsermodTemperature*) usermods.lookup(USERMOD_ID_TEMPERATURE); @@ -202,12 +203,12 @@ class PWMFanUsermod : public Usermod { // gets called every time WiFi is (re-)connected. Initialize own network // interfaces here - void connected() {} + void connected() override {} /* * Da loop. */ - void loop() { + void loop() override { if (!enabled || strip.isUpdating()) return; unsigned long now = millis(); @@ -222,7 +223,7 @@ class PWMFanUsermod : public Usermod { * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI. * Below it is shown how this could be used for e.g. a light sensor */ - void addToJsonInfo(JsonObject& root) { + void addToJsonInfo(JsonObject& root) override { JsonObject user = root["u"]; if (user.isNull()) user = root.createNestedObject("u"); @@ -271,7 +272,7 @@ class PWMFanUsermod : public Usermod { * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void readFromJsonState(JsonObject& root) { + void readFromJsonState(JsonObject& root) override { if (!initDone) return; // prevent crash on boot applyPreset() JsonObject usermod = root[FPSTR(_name)]; if (!usermod.isNull()) { @@ -304,7 +305,7 @@ class PWMFanUsermod : public Usermod { * * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! */ - void addToConfig(JsonObject& root) { + void addToConfig(JsonObject& root) override { JsonObject top = root.createNestedObject(FPSTR(_name)); // usermodname top[FPSTR(_enabled)] = enabled; top[FPSTR(_pwmPin)] = pwmPin; @@ -312,6 +313,7 @@ class PWMFanUsermod : public Usermod { top[FPSTR(_tachoUpdateSec)] = tachoUpdateSec; top[FPSTR(_temperature)] = targetTemperature; top[FPSTR(_minPWMValuePct)] = minPWMValuePct; + top[FPSTR(_maxPWMValuePct)] = maxPWMValuePct; top[FPSTR(_IRQperRotation)] = numberOfInterrupsInOneSingleRotation; DEBUG_PRINTLN(F("Autosave config saved.")); } @@ -326,7 +328,7 @@ class PWMFanUsermod : public Usermod { * * The function should return true if configuration was successfully loaded or false if there was no configuration. */ - bool readFromConfig(JsonObject& root) { + bool readFromConfig(JsonObject& root) override { int8_t newTachoPin = tachoPin; int8_t newPwmPin = pwmPin; @@ -345,6 +347,8 @@ class PWMFanUsermod : public Usermod { targetTemperature = top[FPSTR(_temperature)] | targetTemperature; minPWMValuePct = top[FPSTR(_minPWMValuePct)] | minPWMValuePct; minPWMValuePct = (uint8_t) min(100,max(0,(int)minPWMValuePct)); // bounds checking + maxPWMValuePct = top[FPSTR(_maxPWMValuePct)] | maxPWMValuePct; + maxPWMValuePct = (uint8_t) min(100,max((int)minPWMValuePct,(int)maxPWMValuePct)); // bounds checking numberOfInterrupsInOneSingleRotation = top[FPSTR(_IRQperRotation)] | numberOfInterrupsInOneSingleRotation; numberOfInterrupsInOneSingleRotation = (uint8_t) max(1,(int)numberOfInterrupsInOneSingleRotation); // bounds checking @@ -376,7 +380,7 @@ class PWMFanUsermod : public Usermod { * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - uint16_t getId() { + uint16_t getId() override { return USERMOD_ID_PWM_FAN; } }; @@ -389,6 +393,7 @@ const char PWMFanUsermod::_pwmPin[] PROGMEM = "PWM-pin"; const char PWMFanUsermod::_temperature[] PROGMEM = "target-temp-C"; const char PWMFanUsermod::_tachoUpdateSec[] PROGMEM = "tacho-update-s"; const char PWMFanUsermod::_minPWMValuePct[] PROGMEM = "min-PWM-percent"; +const char PWMFanUsermod::_maxPWMValuePct[] PROGMEM = "max-PWM-percent"; const char PWMFanUsermod::_IRQperRotation[] PROGMEM = "IRQs-per-rotation"; const char PWMFanUsermod::_speed[] PROGMEM = "speed"; const char PWMFanUsermod::_lock[] PROGMEM = "lock"; diff --git a/usermods/ST7789_display/ST7789_display.h b/usermods/ST7789_display/ST7789_display.h index 144cccbfa..281fba25d 100644 --- a/usermods/ST7789_display/ST7789_display.h +++ b/usermods/ST7789_display/ST7789_display.h @@ -132,7 +132,7 @@ class St7789DisplayUsermod : public Usermod { * setup() is called once at boot. WiFi is not yet connected at this point. * You can use it to initialize variables, sensors or similar. */ - void setup() + void setup() override { PinManagerPinType spiPins[] = { { spi_mosi, true }, { spi_miso, false}, { spi_sclk, true } }; if (!pinManager.allocateMultiplePins(spiPins, 3, PinOwner::HW_SPI)) { enabled = false; return; } @@ -162,7 +162,7 @@ class St7789DisplayUsermod : public Usermod { * connected() is called every time the WiFi is (re)connected * Use it to initialize network interfaces */ - void connected() { + void connected() override { //Serial.println("Connected to WiFi!"); } @@ -176,7 +176,7 @@ class St7789DisplayUsermod : public Usermod { * 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds. * Instead, use a timer check as shown here. */ - void loop() { + void loop() override { char buff[LINE_BUFFER_SIZE]; // Check if we time interval for redrawing passes. @@ -307,7 +307,7 @@ class St7789DisplayUsermod : public Usermod { // Print estimated milliamp usage (must specify the LED type in LED prefs for this to be a reasonable estimate). tft.print("Current: "); tft.setTextColor(TFT_ORANGE); - tft.print(strip.currentMilliamps); + tft.print(BusManager::currentMilliamps()); tft.print("mA"); } @@ -316,7 +316,7 @@ class St7789DisplayUsermod : public Usermod { * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI. * Below it is shown how this could be used for e.g. a light sensor */ - void addToJsonInfo(JsonObject& root) + void addToJsonInfo(JsonObject& root) override { JsonObject user = root["u"]; if (user.isNull()) user = root.createNestedObject("u"); @@ -330,7 +330,7 @@ class St7789DisplayUsermod : public Usermod { * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void addToJsonState(JsonObject& root) + void addToJsonState(JsonObject& root) override { //root["user0"] = userVar0; } @@ -340,7 +340,7 @@ class St7789DisplayUsermod : public Usermod { * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void readFromJsonState(JsonObject& root) + void readFromJsonState(JsonObject& root) override { //userVar0 = root["user0"] | userVar0; //if "user0" key exists in JSON, update, else keep old value //if (root["bri"] == 255) Serial.println(F("Don't burn down your garage!")); @@ -361,7 +361,7 @@ class St7789DisplayUsermod : public Usermod { * * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! */ - void addToConfig(JsonObject& root) + void addToConfig(JsonObject& root) override { JsonObject top = root.createNestedObject("ST7789"); JsonArray pins = top.createNestedArray("pin"); @@ -373,7 +373,7 @@ class St7789DisplayUsermod : public Usermod { } - void appendConfigData() { + void appendConfigData() override { oappend(SET_F("addInfo('ST7789:pin[]',0,'','SPI CS');")); oappend(SET_F("addInfo('ST7789:pin[]',1,'','SPI DC');")); oappend(SET_F("addInfo('ST7789:pin[]',2,'','SPI RST');")); @@ -388,7 +388,7 @@ class St7789DisplayUsermod : public Usermod { * but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup. * If you don't know what that is, don't fret. It most likely doesn't affect your use case :) */ - bool readFromConfig(JsonObject& root) + bool readFromConfig(JsonObject& root) override { //JsonObject top = root["top"]; //userVar0 = top["great"] | 42; //The value right of the pipe "|" is the default value in case your setting was not present in cfg.json (e.g. first boot) @@ -400,7 +400,7 @@ class St7789DisplayUsermod : public Usermod { * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - uint16_t getId() + uint16_t getId() override { return USERMOD_ID_ST7789_DISPLAY; } diff --git a/usermods/Temperature/usermod_temperature.h b/usermods/Temperature/usermod_temperature.h index a15baf878..4d4f04368 100644 --- a/usermods/Temperature/usermod_temperature.h +++ b/usermods/Temperature/usermod_temperature.h @@ -48,6 +48,7 @@ class UsermodTemperature : public Usermod { bool enabled = true; bool HApublished = false; + int16_t idx = -1; // Domoticz virtual sensor idx // strings to reduce flash memory usage (used more than twice) static const char _name[]; @@ -55,6 +56,7 @@ class UsermodTemperature : public Usermod { static const char _readInterval[]; static const char _parasite[]; static const char _parasitePin[]; + static const char _domoticzIDX[]; //Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013 float readDallas(); @@ -74,26 +76,26 @@ class UsermodTemperature : public Usermod { inline float getTemperatureF() { return temperature * 1.8f + 32.0f; } float getTemperature(); const char *getTemperatureUnit(); - uint16_t getId() { return USERMOD_ID_TEMPERATURE; } + uint16_t getId() override { return USERMOD_ID_TEMPERATURE; } - void setup(); - void loop(); - //void connected(); + void setup() override; + void loop() override; + //void connected() override; #ifndef WLED_DISABLE_MQTT - void onMqttConnect(bool sessionPresent); + void onMqttConnect(bool sessionPresent) override; #endif - //void onUpdateBegin(bool init); + //void onUpdateBegin(bool init) override; - //bool handleButton(uint8_t b); - //void handleOverlayDraw(); + //bool handleButton(uint8_t b) override; + //void handleOverlayDraw() override; - void addToJsonInfo(JsonObject& root); - //void addToJsonState(JsonObject &root); - //void readFromJsonState(JsonObject &root); - void addToConfig(JsonObject &root); - bool readFromConfig(JsonObject &root); + void addToJsonInfo(JsonObject& root) override; + //void addToJsonState(JsonObject &root) override; + //void readFromJsonState(JsonObject &root) override; + void addToConfig(JsonObject &root) override; + bool readFromConfig(JsonObject &root) override; - void appendConfigData(); + void appendConfigData() override; }; //Dallas sensor quick (& dirty) reading. Credit to - Author: Peter Scargill, August 17th, 2013 @@ -264,7 +266,7 @@ void UsermodTemperature::loop() { #ifndef WLED_DISABLE_MQTT if (WLED_MQTT_CONNECTED) { - char subuf[64]; + char subuf[128]; strcpy(subuf, mqttDeviceTopic); if (temperature > -100.0f) { // dont publish super low temperature as the graph will get messed up @@ -274,6 +276,15 @@ void UsermodTemperature::loop() { mqtt->publish(subuf, 0, false, String(getTemperatureC()).c_str()); strcat_P(subuf, PSTR("_f")); mqtt->publish(subuf, 0, false, String(getTemperatureF()).c_str()); + if (idx > 0) { + StaticJsonDocument <128> msg; + msg[F("idx")] = idx; + msg[F("RSSI")] = WiFi.RSSI(); + msg[F("nvalue")] = 0; + msg[F("svalue")] = String(getTemperatureC()); + serializeJson(msg, subuf, 127); + mqtt->publish("domoticz/in", 0, false, subuf); + } } else { // publish something else to indicate status? } @@ -360,6 +371,7 @@ void UsermodTemperature::addToConfig(JsonObject &root) { top[FPSTR(_readInterval)] = readingInterval / 1000; top[FPSTR(_parasite)] = parasite; top[FPSTR(_parasitePin)] = parasitePin; + top[FPSTR(_domoticzIDX)] = idx; DEBUG_PRINTLN(F("Temperature config saved.")); } @@ -386,6 +398,7 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) { readingInterval = min(120,max(10,(int)readingInterval)) * 1000; // convert to ms parasite = top[FPSTR(_parasite)] | parasite; parasitePin = top[FPSTR(_parasitePin)] | parasitePin; + idx = top[FPSTR(_domoticzIDX)] | idx; if (!initDone) { // first run: reading from cfg.json @@ -406,7 +419,7 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) { } } // use "return !top["newestParameter"].isNull();" when updating Usermod with new features - return !top[FPSTR(_parasitePin)].isNull(); + return !top[FPSTR(_domoticzIDX)].isNull(); } void UsermodTemperature::appendConfigData() { @@ -430,3 +443,4 @@ const char UsermodTemperature::_enabled[] PROGMEM = "enabled"; const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s"; const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr"; const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin"; +const char UsermodTemperature::_domoticzIDX[] PROGMEM = "domoticz-idx"; diff --git a/usermods/audioreactive/audio_reactive.h b/usermods/audioreactive/audio_reactive.h index 357e612c3..50555ca54 100644 --- a/usermods/audioreactive/audio_reactive.h +++ b/usermods/audioreactive/audio_reactive.h @@ -20,6 +20,12 @@ * .... */ +#if !defined(FFTTASK_PRIORITY) +#define FFTTASK_PRIORITY 1 // standard: looptask prio +//#define FFTTASK_PRIORITY 2 // above looptask, below asyc_tcp +//#define FFTTASK_PRIORITY 4 // above asyc_tcp +#endif + // Comment/Uncomment to toggle usb serial debugging // #define MIC_LOGGER // MIC sampling & sound input debugging (serial plotter) // #define FFT_SAMPLING_LOG // FFT result debugging @@ -45,6 +51,8 @@ #define PLOT_PRINTF(x...) #endif +#define MAX_PALETTES 3 + // use audio source class (ESP32 specific) #include "audio_source.h" constexpr i2s_port_t I2S_PORT = I2S_NUM_0; // I2S port to use (do not change !) @@ -104,7 +112,7 @@ static float sampleAgc = 0.0f; // Smoothed AGC sample // peak detection static bool samplePeak = false; // Boolean flag for peak - used in effects. Responding routine may reset this flag. Auto-reset after strip.getMinShowDelay() -static uint8_t maxVol = 10; // Reasonable value for constant volume for 'peak detector', as it won't always trigger (deprecated) +static uint8_t maxVol = 31; // Reasonable value for constant volume for 'peak detector', as it won't always trigger (deprecated) static uint8_t binNum = 8; // Used to select the bin for FFT based beat detection (deprecated) static bool udpSamplePeak = false; // Boolean flag for peak. Set at the same tiem as samplePeak, but reset by transmitAudioData static unsigned long timeOfPeak = 0; // time of last sample peak detection. @@ -173,13 +181,18 @@ static float windowWeighingFactors[samplesFFT] = {0.0f}; // Create FFT object #ifdef UM_AUDIOREACTIVE_USE_NEW_FFT -// lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2 -#define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc), and an a few other speedups -#define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt -#define sqrt(x) sqrtf(x) // little hack that reduces FFT time by 50% on ESP32 (as alternative to FFT_SQRT_APPROXIMATION) + // lib_deps += https://github.com/kosme/arduinoFFT#develop @ 1.9.2 + // these options actually cause slow-downs on all esp32 processors, don't use them. + // #define FFT_SPEED_OVER_PRECISION // enables use of reciprocals (1/x etc) - not faster on ESP32 + // #define FFT_SQRT_APPROXIMATION // enables "quake3" style inverse sqrt - slower on ESP32 + // Below options are forcing ArduinoFFT to use sqrtf() instead of sqrt() + #define sqrt(x) sqrtf(x) // little hack that reduces FFT time by 10-50% on ESP32 + #define sqrt_internal sqrtf // see https://github.com/kosme/arduinoFFT/pull/83 #else -// lib_deps += https://github.com/blazoncek/arduinoFFT.git + // around 40% slower on -S2 + // lib_deps += https://github.com/blazoncek/arduinoFFT.git #endif + #include #ifdef UM_AUDIOREACTIVE_USE_NEW_FFT @@ -411,7 +424,7 @@ static void runMicFilter(uint16_t numSamples, float *sampleBuffer) // p //constexpr float beta1 = 0.8285f; // 18Khz constexpr float beta1 = 0.85f; // 20Khz - constexpr float beta2 = (1.0f - beta1) / 2.0; + constexpr float beta2 = (1.0f - beta1) / 2.0f; static float last_vals[2] = { 0.0f }; // FIR high freq cutoff filter static float lowfilt = 0.0f; // IIR low frequency cutoff filter @@ -464,17 +477,17 @@ static void postProcessFFTResults(bool noiseGateOpen, int numberOfChannels) // p switch (FFTScalingMode) { case 1: // Logarithmic scaling - currentResult *= 0.42; // 42 is the answer ;-) - currentResult -= 8.0; // this skips the lowest row, giving some room for peaks - if (currentResult > 1.0) currentResult = logf(currentResult); // log to base "e", which is the fastest log() function - else currentResult = 0.0; // special handling, because log(1) = 0; log(0) = undefined + currentResult *= 0.42f; // 42 is the answer ;-) + currentResult -= 8.0f; // this skips the lowest row, giving some room for peaks + if (currentResult > 1.0f) currentResult = logf(currentResult); // log to base "e", which is the fastest log() function + else currentResult = 0.0f; // special handling, because log(1) = 0; log(0) = undefined currentResult *= 0.85f + (float(i)/18.0f); // extra up-scaling for high frequencies currentResult = mapf(currentResult, 0, LOG_256, 0, 255); // map [log(1) ... log(255)] to [0 ... 255] break; case 2: // Linear scaling currentResult *= 0.30f; // needs a bit more damping, get stay below 255 - currentResult -= 4.0; // giving a bit more room for peaks + currentResult -= 4.0f; // giving a bit more room for peaks if (currentResult < 1.0f) currentResult = 0.0f; currentResult *= 0.85f + (float(i)/1.8f); // extra up-scaling for high frequencies break; @@ -482,8 +495,8 @@ static void postProcessFFTResults(bool noiseGateOpen, int numberOfChannels) // p // square root scaling currentResult *= 0.38f; currentResult -= 6.0f; - if (currentResult > 1.0) currentResult = sqrtf(currentResult); - else currentResult = 0.0; // special handling, because sqrt(0) = undefined + if (currentResult > 1.0f) currentResult = sqrtf(currentResult); + else currentResult = 0.0f; // special handling, because sqrt(0) = undefined currentResult *= 0.85f + (float(i)/4.5f); // extra up-scaling for high frequencies currentResult = mapf(currentResult, 0.0, 16.0, 0.0, 255.0); // map [sqrt(1) ... sqrt(256)] to [0 ... 255] break; @@ -511,11 +524,11 @@ static void postProcessFFTResults(bool noiseGateOpen, int numberOfChannels) // p // peak detection is called from FFT task when vReal[] contains valid FFT results static void detectSamplePeak(void) { bool havePeak = false; - + // softhack007: this code continuously triggers while amplitude in the selected bin is above a certain threshold. So it does not detect peaks - it detects high activity in a frequency bin. // Poor man's beat detection by seeing if sample > Average + some value. // This goes through ALL of the 255 bins - but ignores stupid settings // Then we got a peak, else we don't. The peak has to time out on its own in order to support UDP sound sync. - if ((sampleAvg > 1) && (maxVol > 0) && (binNum > 1) && (vReal[binNum] > maxVol) && ((millis() - timeOfPeak) > 100)) { + if ((sampleAvg > 1) && (maxVol > 0) && (binNum > 4) && (vReal[binNum] > maxVol) && ((millis() - timeOfPeak) > 100)) { havePeak = true; } @@ -603,6 +616,8 @@ 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) bool enabled = false; bool initDone = false; + bool addPalettes = false; + int8_t palettes = 0; // variables for UDP sound sync WiFiUDP fftUdp; // UDP object for sound sync (from WiFi UDP, not Async UDP!) @@ -641,10 +656,15 @@ class AudioReactive : public Usermod { static const char _inputLvl[]; static const char _analogmic[]; static const char _digitalmic[]; + static const char _addPalettes[]; static const char UDP_SYNC_HEADER[]; static const char UDP_SYNC_HEADER_v1[]; // private methods + void removeAudioPalettes(void); + void createAudioPalettes(void); + CRGB getCRGBForBand(int x, int pal); + void fillAudioPalettes(void); //////////////////// // Debug support // @@ -758,7 +778,7 @@ class AudioReactive : public Usermod { if (time_now - last_time > 2) { last_time = time_now; - if((fabsf(sampleReal) < 2.0f) || (sampleMax < 1.0f)) { + if((fabsf(sampleReal) < 2.0f) || (sampleMax < 1.0)) { // MIC signal is "squelched" - deliver silence tmpAgc = 0; // we need to "spin down" the intgrated error buffer @@ -873,8 +893,8 @@ class AudioReactive : public Usermod { // keep "peak" sample, but decay value if current sample is below peak if ((sampleMax < sampleReal) && (sampleReal > 0.5f)) { sampleMax = sampleMax + 0.5f * (sampleReal - sampleMax); // new peak - with some filtering - // another simple way to detect samplePeak - if ((binNum < 10) && (millis() - timeOfPeak > 80) && (sampleAvg > 1)) { + // another simple way to detect samplePeak - cannot detect beats, but reacts on peak volume + if (((binNum < 12) || ((maxVol < 1))) && (millis() - timeOfPeak > 80) && (sampleAvg > 1)) { samplePeak = true; timeOfPeak = millis(); udpSamplePeak = true; @@ -949,6 +969,8 @@ class AudioReactive : public Usermod { //DEBUGSR_PRINTLN("Transmitting UDP Mic Packet"); audioSyncPacket transmitData; + memset(reinterpret_cast(&transmitData), 0, sizeof(transmitData)); // make sure that the packet - including "invisible" padding bytes added by the compiler - is fully initialized + strncpy_P(transmitData.header, PSTR(UDP_SYNC_HEADER), 6); // transmit samples that were not modified by limitSampleDynamics() transmitData.sampleRaw = (soundAgc) ? rawSampleAgc: sampleRaw; @@ -964,9 +986,10 @@ class AudioReactive : public Usermod { transmitData.FFT_Magnitude = my_magnitude; transmitData.FFT_MajorPeak = FFT_MajorPeak; - fftUdp.beginMulticastPacket(); - fftUdp.write(reinterpret_cast(&transmitData), sizeof(transmitData)); - fftUdp.endPacket(); + if (fftUdp.beginMulticastPacket() != 0) { // beginMulticastPacket returns 0 in case of error + fftUdp.write(reinterpret_cast(&transmitData), sizeof(transmitData)); + fftUdp.endPacket(); + } return; } // transmitAudioData() @@ -1071,7 +1094,7 @@ class AudioReactive : public Usermod { * You can use it to initialize variables, sensors or similar. * It is called *AFTER* readFromConfig() */ - void setup() + void setup() override { disableSoundProcessing = true; // just to be sure if (!initDone) { @@ -1163,6 +1186,7 @@ class AudioReactive : public Usermod { DEBUGSR_PRINTLN(F("AR: Analog Microphone (left channel only).")); audioSource = new I2SAdcSource(SAMPLE_RATE, BLOCK_SIZE); delay(100); + useBandPassFilter = true; // PDM bandpass filter seems to help for bad quality analog if (audioSource) audioSource->initialize(audioPin); break; #endif @@ -1184,6 +1208,7 @@ class AudioReactive : public Usermod { } if (enabled) connectUDPSoundSync(); + if (enabled && addPalettes) createAudioPalettes(); initDone = true; } @@ -1192,7 +1217,7 @@ class AudioReactive : public Usermod { * connected() is called every time the WiFi is (re)connected * Use it to initialize network interfaces */ - void connected() + void connected() override { if (udpSyncConnected) { // clean-up: if open, close old UDP sync connection udpSyncConnected = false; @@ -1219,7 +1244,7 @@ class AudioReactive : public Usermod { * 2. Try to avoid using the delay() function. NEVER use delays longer than 10 milliseconds. * Instead, use a timer check as shown here. */ - void loop() + void loop() override { static unsigned long lastUMRun = millis(); @@ -1272,9 +1297,10 @@ class AudioReactive : public Usermod { #ifdef WLED_DEBUG // complain when audio userloop has been delayed for long time. Currently we need userloop running between 500 and 1500 times per second. - if ((userloopDelay > 23) && !disableSoundProcessing && (audioSyncEnabled == 0)) { - DEBUG_PRINTF("[AR userLoop] hickup detected -> was inactive for last %d millis!\n", userloopDelay); - } + // softhack007 disabled temporarily - avoid serial console spam with MANY leds and low FPS + //if ((userloopDelay > 65) && !disableSoundProcessing && (audioSyncEnabled == 0)) { + //DEBUG_PRINTF("[AR userLoop] hickup detected -> was inactive for last %d millis!\n", userloopDelay); + //} #endif // run filters, and repeat in case of loop delays (hick-up compensation) @@ -1311,6 +1337,9 @@ class AudioReactive : public Usermod { if (millis() - lastTime > delayMs) { have_new_sample = receiveAudioData(); if (have_new_sample) last_UDPTime = millis(); +#ifdef ARDUINO_ARCH_ESP32 + else fftUdp.flush(); // Flush udp input buffers if we haven't read it - avoids hickups in receive mode. Does not work on 8266. +#endif lastTime = millis(); } if (have_new_sample) syncVolumeSmth = volumeSmth; // remember received sample @@ -1329,7 +1358,7 @@ class AudioReactive : public Usermod { // Info Page: keep max sample from last 5 seconds if ((millis() - sampleMaxTimer) > CYCLE_SAMPLEMAX) { sampleMaxTimer = millis(); - maxSample5sec = (0.15 * maxSample5sec) + 0.85 *((soundAgc) ? sampleAgc : sampleAvg); // reset, and start with some smoothing + maxSample5sec = (0.15f * maxSample5sec) + 0.85f *((soundAgc) ? sampleAgc : sampleAvg); // reset, and start with some smoothing if (sampleAvg < 1) maxSample5sec = 0; // noise gate } else { if ((sampleAvg >= 1)) maxSample5sec = fmaxf(maxSample5sec, (soundAgc) ? rawSampleAgc : sampleRaw); // follow maximum volume @@ -1342,10 +1371,11 @@ class AudioReactive : public Usermod { lastTime = millis(); } + fillAudioPalettes(); } - bool getUMData(um_data_t **data) + bool getUMData(um_data_t **data) override { if (!data || !enabled) return false; // no pointer provided by caller or not enabled -> exit *data = um_data; @@ -1353,7 +1383,7 @@ class AudioReactive : public Usermod { } - void onUpdateBegin(bool init) + void onUpdateBegin(bool init) override { #ifdef WLED_DEBUG fftTime = sampleTime = 0; @@ -1373,10 +1403,11 @@ class AudioReactive : public Usermod { memset(fftAvg, 0, sizeof(fftAvg)); memset(fftResult, 0, sizeof(fftResult)); for(int i=(init?0:1); i 1.0) { + if (maxSample5sec > 1.0f) { float my_usage = 100.0f * (maxSample5sec / 255.0f); snprintf_P(myStringBuffer, 15, PSTR(" - peak %3d%%"), int(my_usage)); infoArr.add(myStringBuffer); @@ -1503,7 +1533,7 @@ class AudioReactive : public Usermod { } else { // error during audio source setup infoArr.add(F("not initialized")); - infoArr.add(F(" - check GPIO config")); + infoArr.add(F(" - check pin settings")); } } @@ -1570,7 +1600,7 @@ class AudioReactive : public Usermod { * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void addToJsonState(JsonObject& root) + void addToJsonState(JsonObject& root) override { if (!initDone) return; // prevent crash on boot applyPreset() JsonObject usermod = root[FPSTR(_name)]; @@ -1585,7 +1615,7 @@ class AudioReactive : public Usermod { * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void readFromJsonState(JsonObject& root) + void readFromJsonState(JsonObject& root) override { if (!initDone) return; // prevent crash on boot applyPreset() bool prevEnabled = enabled; @@ -1594,13 +1624,28 @@ class AudioReactive : public Usermod { if (usermod[FPSTR(_enabled)].is()) { enabled = usermod[FPSTR(_enabled)].as(); if (prevEnabled != enabled) onUpdateBegin(!enabled); + if (addPalettes) { + // add/remove custom/audioreactive palettes + if (prevEnabled && !enabled) removeAudioPalettes(); + if (!prevEnabled && enabled) createAudioPalettes(); + } } if (usermod[FPSTR(_inputLvl)].is()) { inputLevel = min(255,max(0,usermod[FPSTR(_inputLvl)].as())); } } + if (root.containsKey(F("rmcpal")) && root[F("rmcpal")].as()) { + // handle removal of custom palettes from JSON call so we don't break things + removeAudioPalettes(); + } } + void onStateChange(uint8_t callMode) override { + if (initDone && enabled && addPalettes && palettes==0 && strip.customPalettes.size()<10) { + // if palettes were removed during JSON call re-add them + createAudioPalettes(); + } + } /* * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object. @@ -1637,10 +1682,11 @@ class AudioReactive : public Usermod { * * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! */ - void addToConfig(JsonObject& root) + void addToConfig(JsonObject& root) override { JsonObject top = root.createNestedObject(FPSTR(_name)); top[FPSTR(_enabled)] = enabled; + top[FPSTR(_addPalettes)] = addPalettes; #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) JsonObject amic = top.createNestedObject(FPSTR(_analogmic)); @@ -1689,12 +1735,15 @@ class AudioReactive : public Usermod { * * This function is guaranteed to be called on boot, but could also be called every time settings are updated */ - bool readFromConfig(JsonObject& root) + bool readFromConfig(JsonObject& root) override { JsonObject top = root[FPSTR(_name)]; bool configComplete = !top.isNull(); + bool oldEnabled = enabled; + bool oldAddPalettes = addPalettes; configComplete &= getJsonValue(top[FPSTR(_enabled)], enabled); + configComplete &= getJsonValue(top[FPSTR(_addPalettes)], addPalettes); #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) configComplete &= getJsonValue(top[FPSTR(_analogmic)]["pin"], audioPin); @@ -1728,11 +1777,16 @@ class AudioReactive : public Usermod { configComplete &= getJsonValue(top["sync"][F("port")], audioSyncPort); configComplete &= getJsonValue(top["sync"][F("mode")], audioSyncEnabled); + if (initDone) { + // add/remove custom/audioreactive palettes + if ((oldAddPalettes && !addPalettes) || (oldAddPalettes && !enabled)) removeAudioPalettes(); + if ((addPalettes && !oldAddPalettes && enabled) || (addPalettes && !oldEnabled && enabled)) createAudioPalettes(); + } // else setup() will create palettes return configComplete; } - void appendConfigData() + void appendConfigData() override { oappend(SET_F("dd=addDropdown('AudioReactive','digitalmic:type');")); #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) @@ -1787,7 +1841,7 @@ class AudioReactive : public Usermod { * Use this to blank out some LEDs or set them to a different color regardless of the set effect mode. * Commonly used for custom clocks (Cronixie, 7 segment) */ - //void handleOverlayDraw() + //void handleOverlayDraw() override //{ //strip.setPixelColor(0, RGBW32(0,0,0,0)) // set the first pixel to black //} @@ -1797,17 +1851,106 @@ class AudioReactive : public Usermod { * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - uint16_t getId() + uint16_t getId() override { return USERMOD_ID_AUDIOREACTIVE; } }; +void AudioReactive::removeAudioPalettes(void) { + DEBUG_PRINTLN(F("Removing audio palettes.")); + while (palettes>0) { + strip.customPalettes.pop_back(); + DEBUG_PRINTLN(palettes); + palettes--; + } + DEBUG_PRINT(F("Total # of palettes: ")); DEBUG_PRINTLN(strip.customPalettes.size()); +} + +void AudioReactive::createAudioPalettes(void) { + DEBUG_PRINT(F("Total # of palettes: ")); DEBUG_PRINTLN(strip.customPalettes.size()); + if (palettes) return; + DEBUG_PRINTLN(F("Adding audio palettes.")); + for (int i=0; i= palettes) lastCustPalette -= palettes; + for (size_t pal=0; pal #include @@ -22,14 +22,14 @@ // see https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/hw-reference/chip-series-comparison.html#related-documents // and https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/api-reference/peripherals/i2s.html#overview-of-all-modes -#if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(ESP8266) || defined(ESP8265) +#if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C5) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(ESP8266) || defined(ESP8265) // there are two things in these MCUs that could lead to problems with audio processing: // * no floating point hardware (FPU) support - FFT uses float calculations. If done in software, a strong slow-down can be expected (between 8x and 20x) // * single core, so FFT task might slow down other things like LED updates #if !defined(SOC_I2S_NUM) || (SOC_I2S_NUM < 1) - #error This audio reactive usermod does not support ESP32-C2, ESP32-C3 or ESP32-S2. + #error This audio reactive usermod does not support ESP32-C2 or ESP32-C3. #else - #warning This audio reactive usermod does not support ESP32-C2, ESP32-C3 or ESP32-S2. + #warning This audio reactive usermod does not support ESP32-C2 and ESP32-C3. #endif #endif @@ -71,7 +71,7 @@ * if you want to receive two channels, one is the actual data from microphone and another channel is suppose to receive 0, it's different data in two channels, you need to choose I2S_CHANNEL_FMT_RIGHT_LEFT in this case. */ -#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)) && (ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(4, 4, 3)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0)) && (ESP_IDF_VERSION <= ESP_IDF_VERSION_VAL(4, 4, 4)) // espressif bug: only_left has no sound, left and right are swapped // https://github.com/espressif/esp-idf/issues/9635 I2S mic not working since 4.4 (IDFGH-8138) // https://github.com/espressif/esp-idf/issues/8538 I2S channel selection issue? (IDFGH-6918) @@ -122,7 +122,7 @@ class AudioSource { This function needs to take care of anything that needs to be done before samples can be obtained from the microphone. */ - virtual void initialize(int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) = 0; + virtual void initialize(int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) = 0; /* Deinitialize Release all resources and deactivate any functionality that is used @@ -191,7 +191,8 @@ class I2SSource : public AudioSource { }; } - virtual void initialize(int8_t i2swsPin = I2S_PIN_NO_CHANGE, int8_t i2ssdPin = I2S_PIN_NO_CHANGE, int8_t i2sckPin = I2S_PIN_NO_CHANGE, int8_t mclkPin = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) { + virtual void initialize(int8_t i2swsPin = I2S_PIN_NO_CHANGE, int8_t i2ssdPin = I2S_PIN_NO_CHANGE, int8_t i2sckPin = I2S_PIN_NO_CHANGE, int8_t mclkPin = I2S_PIN_NO_CHANGE) { + DEBUGSR_PRINTLN("I2SSource:: initialize()."); if (i2swsPin != I2S_PIN_NO_CHANGE && i2ssdPin != I2S_PIN_NO_CHANGE) { if (!pinManager.allocatePin(i2swsPin, true, PinOwner::UM_Audioreactive) || !pinManager.allocatePin(i2ssdPin, false, PinOwner::UM_Audioreactive)) { // #206 @@ -412,6 +413,7 @@ public: }; void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) { + DEBUGSR_PRINTLN("ES7243:: initialize();"); if ((i2sckPin < 0) || (mclkPin < 0)) { DEBUGSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin); return; @@ -527,7 +529,7 @@ class ES8388Source : public I2SSource { }; void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t mclkPin) { - + DEBUGSR_PRINTLN("ES8388Source:: initialize();"); if ((i2sckPin < 0) || (mclkPin < 0)) { DEBUGSR_PRINTF("\nAR: invalid I2S pin: SCK=%d, MCLK=%d\n", i2sckPin, mclkPin); return; @@ -584,7 +586,8 @@ class I2SAdcSource : public I2SSource { /* identify Audiosource type - I2S-ADC*/ AudioSourceType getType(void) {return(Type_I2SAdc);} - void initialize(int8_t audioPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) { + void initialize(int8_t audioPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) { + DEBUGSR_PRINTLN("I2SAdcSource:: initialize()."); _myADCchannel = 0x0F; if(!pinManager.allocatePin(audioPin, false, PinOwner::UM_Audioreactive)) { DEBUGSR_PRINTF("failed to allocate GPIO for audio analog input: %d\n", audioPin); @@ -755,7 +758,8 @@ class SPH0654 : public I2SSource { I2SSource(sampleRate, blockSize, sampleScale) {} - void initialize(uint8_t i2swsPin, uint8_t i2ssdPin, uint8_t i2sckPin, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE, int8_t = I2S_PIN_NO_CHANGE) { + void initialize(int8_t i2swsPin, int8_t i2ssdPin, int8_t i2sckPin, int8_t = I2S_PIN_NO_CHANGE) { + DEBUGSR_PRINTLN("SPH0654:: initialize();"); I2SSource::initialize(i2swsPin, i2ssdPin, i2sckPin); #if !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32C3) && !defined(CONFIG_IDF_TARGET_ESP32S3) // these registers are only existing in "classic" ESP32 @@ -766,3 +770,4 @@ class SPH0654 : public I2SSource { #endif } }; +#endif \ No newline at end of file diff --git a/usermods/boblight/boblight.h b/usermods/boblight/boblight.h index a1e257758..b11a22a83 100644 --- a/usermods/boblight/boblight.h +++ b/usermods/boblight/boblight.h @@ -187,7 +187,7 @@ class BobLightUsermod : public Usermod { public: - void setup() { + void setup() override { uint16_t totalLights = bottom + left + top + right; if ( totalLights > strip.getLengthTotal() ) { DEBUG_PRINTLN(F("BobLight: Too many lights.")); @@ -202,14 +202,14 @@ class BobLightUsermod : public Usermod { initDone = true; } - void connected() { + void connected() override { // we can only start server when WiFi is connected if (!bob) bob = new WiFiServer(bobPort, 1); bob->begin(); bob->setNoDelay(true); } - void loop() { + void loop() override { if (!enabled || strip.isUpdating()) return; if (millis() - lastTime > 10) { lastTime = millis(); @@ -225,7 +225,7 @@ class BobLightUsermod : public Usermod { * topic only contains stripped topic (part after /wled/MAC) * topic should look like: /swipe with amessage of [up|down] */ - bool onMqttMessage(char* topic, char* payload) { + bool onMqttMessage(char* topic, char* payload) override { //if (strlen(topic) == 6 && strncmp_P(topic, PSTR("/subtopic"), 6) == 0) { // String action = payload; // if (action == "on") { @@ -242,7 +242,7 @@ class BobLightUsermod : public Usermod { /** * subscribe to MQTT topic for controlling usermod */ - void onMqttConnect(bool sessionPresent) { + void onMqttConnect(bool sessionPresent) override { //char subuf[64]; //if (mqttDeviceTopic[0] != 0) { // strcpy(subuf, mqttDeviceTopic); @@ -252,7 +252,7 @@ class BobLightUsermod : public Usermod { } #endif - void addToJsonInfo(JsonObject& root) + void addToJsonInfo(JsonObject& root) override { JsonObject user = root["u"]; if (user.isNull()) user = root.createNestedObject("u"); @@ -273,7 +273,7 @@ class BobLightUsermod : public Usermod { * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void addToJsonState(JsonObject& root) + void addToJsonState(JsonObject& root) override { } @@ -281,7 +281,7 @@ class BobLightUsermod : public Usermod { * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void readFromJsonState(JsonObject& root) { + void readFromJsonState(JsonObject& root) override { if (!initDone) return; // prevent crash on boot applyPreset() bool en = enabled; JsonObject um = root[FPSTR(_name)]; @@ -304,7 +304,7 @@ class BobLightUsermod : public Usermod { } } - void appendConfigData() { + void appendConfigData() override { //oappend(SET_F("dd=addDropdown('usermod','selectfield');")); //oappend(SET_F("addOption(dd,'1st value',0);")); //oappend(SET_F("addOption(dd,'2nd value',1);")); @@ -315,7 +315,7 @@ class BobLightUsermod : public Usermod { oappend(SET_F("addInfo('BobLight:pct',1,'Depth of scan [%]');")); // 0 is field type, 1 is actual field } - void addToConfig(JsonObject& root) { + void addToConfig(JsonObject& root) override { JsonObject umData = root.createNestedObject(FPSTR(_name)); umData[FPSTR(_enabled)] = enabled; umData[F("port")] = bobPort; @@ -326,7 +326,7 @@ class BobLightUsermod : public Usermod { umData[F("pct")] = pct; } - bool readFromConfig(JsonObject& root) { + bool readFromConfig(JsonObject& root) override { JsonObject umData = root[FPSTR(_name)]; bool configComplete = !umData.isNull(); @@ -355,11 +355,11 @@ class BobLightUsermod : public Usermod { * Use this to blank out some LEDs or set them to a different color regardless of the set effect mode. * Commonly used for custom clocks (Cronixie, 7 segment) */ - void handleOverlayDraw() { + void handleOverlayDraw() override { //strip.setPixelColor(0, RGBW32(0,0,0,0)) // set the first pixel to black } - uint16_t getId() { return USERMOD_ID_BOBLIGHT; } + uint16_t getId() override { return USERMOD_ID_BOBLIGHT; } }; diff --git a/usermods/mpu6050_imu/readme.md b/usermods/mpu6050_imu/readme.md index 412004151..b804ba602 100644 --- a/usermods/mpu6050_imu/readme.md +++ b/usermods/mpu6050_imu/readme.md @@ -20,14 +20,11 @@ react to the globes orientation. See the blog post on building it + +constexpr auto ESTIMATED_G = 9.801; // m/s^2 +constexpr auto ESTIMATED_G_COUNTS = 8350.; +constexpr auto ESTIMATED_ANGULAR_RATE = (M_PI * 2000) / (INT16_MAX * 180); // radians per second + +// Horribly lame digital filter code +// Currently implements a static IIR filter. +template +class xir_filter { + typedef Eigen::Array array_t; + const array_t a_coeff, b_coeff; + const T gain; + array_t x, y; + + public: + xir_filter(T gain_, array_t a, array_t b) : a_coeff(std::move(a)), b_coeff(std::move(b)), gain(gain_), x(array_t::Zero()), y(array_t::Zero()) {}; + + T operator()(T input) { + x.head(C-1) = x.tail(C-1); // shift by one + x(C-1) = input / gain; + y.head(C-1) = y.tail(C-1); // shift by one + y(C-1) = (x * b_coeff).sum(); + y(C-1) -= (y.head(C-1) * a_coeff.head(C-1)).sum(); + return y(C-1); + } + + T last() { return y(C-1); }; +}; + + + +class GyroSurge : public Usermod { + private: + static const char _name[]; + bool enabled = true; + + // Params + uint8_t max = 0; + float sensitivity = 0; + + // State + uint32_t last_sample; + // 100hz input + // butterworth low pass filter at 20hz + xir_filter filter = { 1., { -0.36952738, 0.19581571, 1.}, {0.20657208, 0.41314417, 0.20657208} }; + // { 1., { 0., 0., 1.}, { 0., 0., 1. } }; // no filter + + + public: + + /* + * setup() is called once at boot. WiFi is not yet connected at this point. + */ + void setup() {}; + + + /* + * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object. + * It will be called by WLED when settings are actually saved (for example, LED settings are saved) + * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! + */ + void addToConfig(JsonObject& root) + { + JsonObject top = root.createNestedObject(FPSTR(_name)); + + //save these vars persistently whenever settings are saved + top["max"] = max; + top["sensitivity"] = sensitivity; + } + + + /* + * readFromConfig() can be used to read back the custom settings you added with addToConfig(). + * This is called by WLED when settings are loaded (currently this only happens immediately after boot, or after saving on the Usermod Settings page) + * + * readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes), + * but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup. + * If you don't know what that is, don't fret. It most likely doesn't affect your use case :) + * + * Return true in case the config values returned from Usermod Settings were complete, or false if you'd like WLED to save your defaults to disk (so any missing values are editable in Usermod Settings) + * + * getJsonValue() returns false if the value is missing, or copies the value into the variable provided and returns true if the value is present + * The configComplete variable is true only if the "exampleUsermod" object and all values are present. If any values are missing, WLED will know to call addToConfig() to save them + * + * This function is guaranteed to be called on boot, but could also be called every time settings are updated + */ + bool readFromConfig(JsonObject& root) + { + // default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor + // setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed) + + JsonObject top = root[FPSTR(_name)]; + + bool configComplete = !top.isNull(); + + configComplete &= getJsonValue(top["max"], max, 0); + configComplete &= getJsonValue(top["sensitivity"], sensitivity, 10); + + return configComplete; + } + + void loop() { + // get IMU data + um_data_t *um_data; + if (!usermods.getUMData(&um_data, USERMOD_ID_IMU)) { + // Apply max + strip.getSegment(0).fadeToBlackBy(max); + return; + } + uint32_t sample_count = *(uint32_t*)(um_data->u_data[8]); + + if (sample_count != last_sample) { + last_sample = sample_count; + // Calculate based on new data + // We use the raw gyro data (angular rate) + auto gyros = (int16_t*)um_data->u_data[4]; // 16384 == 2000 deg/s + + // Compute the overall rotation rate + // For my application (a plasma sword) we ignore X axis rotations (eg. around the long axis) + auto gyro_q = Eigen::AngleAxis { + //Eigen::AngleAxis(ESTIMATED_ANGULAR_RATE * gyros[0], Eigen::Vector3f::UnitX()) * + Eigen::AngleAxis(ESTIMATED_ANGULAR_RATE * gyros[1], Eigen::Vector3f::UnitY()) * + Eigen::AngleAxis(ESTIMATED_ANGULAR_RATE * gyros[2], Eigen::Vector3f::UnitZ()) }; + + // Filter the results + filter(std::min(sensitivity * gyro_q.angle(), 1.0f)); // radians per second +/* + Serial.printf("[%lu] Gy: %d, %d, %d -- ", millis(), (int)gyros[0], (int)gyros[1], (int)gyros[2]); + Serial.print(gyro_q.angle()); + Serial.print(", "); + Serial.print(sensitivity * gyro_q.angle()); + Serial.print(" --> "); + Serial.println(filter.last()); +*/ + } + }; // noop + + /* + * handleOverlayDraw() is called just before every show() (LED strip update frame) after effects have set the colors. + * Use this to blank out some LEDs or set them to a different color regardless of the set effect mode. + * Commonly used for custom clocks (Cronixie, 7 segment) + */ + void handleOverlayDraw() + { + + // TODO: some kind of timing analysis for filtering ... + + // Calculate brightness boost + auto r_float = std::max(std::min(filter.last(), 1.0f), 0.f); + auto result = (uint8_t) (r_float * max); + //Serial.printf("[%lu] %d -- ", millis(), result); + //Serial.println(r_float); + // TODO - multiple segment handling?? + strip.getSegment(0).fadeToBlackBy(max - result); + } +}; + +const char GyroSurge::_name[] PROGMEM = "GyroSurge"; \ No newline at end of file diff --git a/usermods/mpu6050_imu/usermod_mpu6050_imu.h b/usermods/mpu6050_imu/usermod_mpu6050_imu.h index 748ddf1a6..a3301bfff 100644 --- a/usermods/mpu6050_imu/usermod_mpu6050_imu.h +++ b/usermods/mpu6050_imu/usermod_mpu6050_imu.h @@ -20,11 +20,11 @@ XCL not connected AD0 not connected INT D8 (GPIO15) Interrupt pin - + Using usermod: 1. Copy the usermod into the sketch folder (same folder as wled00.ino) 2. Register the usermod by adding #include "usermod_filename.h" in the top and registerUsermod(new MyUsermodClass()) in the bottom of usermods_list.cpp - 3. I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h file + 3. I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h file for both classes must be in the include path of your project. To install the libraries add I2Cdevlib-MPU6050@fbde122cc5 to lib_deps in the platformio.ini file. 4. You also need to change lib_compat_mode from strict to soft in platformio.ini (This ignores that I2Cdevlib-MPU6050 doesn't list platform compatibility) @@ -33,6 +33,9 @@ #include "I2Cdev.h" +#undef DEBUG_PRINT +#undef DEBUG_PRINTLN +#undef DEBUG_PRINTF #include "MPU6050_6Axis_MotionApps20.h" //#include "MPU6050.h" // not necessary if using MotionApps include file @@ -42,6 +45,23 @@ #include "Wire.h" #endif +// Restore debug macros +// MPU6050 unfortunately uses the same macro names as WLED :( +#undef DEBUG_PRINT +#undef DEBUG_PRINTLN +#undef DEBUG_PRINTF +#ifdef WLED_DEBUG + #define DEBUG_PRINT(x) DEBUGOUT.print(x) + #define DEBUG_PRINTLN(x) DEBUGOUT.println(x) + #define DEBUG_PRINTF(x...) DEBUGOUT.printf(x) +#else + #define DEBUG_PRINT(x) + #define DEBUG_PRINTLN(x) + #define DEBUG_PRINTF(x...) +#endif + + + // ================================================================ // === INTERRUPT DETECTION ROUTINE === // ================================================================ @@ -52,21 +72,31 @@ void IRAM_ATTR dmpDataReady() { } + class MPU6050Driver : public Usermod { private: MPU6050 mpu; - bool enabled = true; + + // configuration state + // default values are set in readFromConfig + // By making this a struct, we enable easy backup and comparison in the readFromConfig class + struct config_t { + bool enabled; + int8_t interruptPin; + int16_t gyro_offset[3]; + int16_t accel_offset[3]; + }; + config_t config; // MPU control/status vars + bool irqBound = false; // set true if we have bound the IRQ pin bool dmpReady = false; // set true if DMP init was successful - uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) uint16_t packetSize; // expected DMP packet size (default is 42 bytes) uint16_t fifoCount; // count of all bytes currently in FIFO uint8_t fifoBuffer[64]; // FIFO storage buffer - //NOTE: some of these can be removed to save memory, processing time - // if the measurement isn't needed + // TODO: some of these can be removed to save memory, processing time if the measurement isn't needed Quaternion qat; // [w, x, y, z] quaternion container float euler[3]; // [psi, theta, phi] Euler angle container float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container @@ -75,17 +105,67 @@ class MPU6050Driver : public Usermod { VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements VectorFloat gravity; // [x, y, z] gravity vector + uint32 sample_count; - static const int INTERRUPT_PIN = 15; // use pin 15 on ESP8266 + // Usermod output + um_data_t um_data; + + // config element names as progmem strs + static const char _name[]; + static const char _enabled[]; + static const char _interrupt_pin[]; + static const char _x_acc_bias[]; + static const char _y_acc_bias[]; + static const char _z_acc_bias[]; + static const char _x_gyro_bias[]; + static const char _y_gyro_bias[]; + static const char _z_gyro_bias[]; public: - //Functions called by WLED + inline bool initDone() { return um_data.u_size != 0; }; // recycle this instead of storing an extra variable + + //Functions called by WLED /* * setup() is called once at boot. WiFi is not yet connected at this point. */ void setup() { - if (i2c_scl<0 || i2c_sda<0) { enabled = false; return; } + dmpReady = false; // Start clean + + // one time init + if (!initDone()) { + um_data.u_size = 9; + um_data.u_type = new um_types_t[um_data.u_size]; + um_data.u_data = new void*[um_data.u_size]; + um_data.u_data[0] = &qat; + um_data.u_type[0] = UMT_FLOAT_ARR; + um_data.u_data[1] = &euler; + um_data.u_type[1] = UMT_FLOAT_ARR; + um_data.u_data[2] = &ypr; + um_data.u_type[2] = UMT_FLOAT_ARR; + um_data.u_data[3] = &aa; + um_data.u_type[3] = UMT_INT16_ARR; + um_data.u_data[4] = &gy; + um_data.u_type[4] = UMT_INT16_ARR; + um_data.u_data[5] = &aaReal; + um_data.u_type[5] = UMT_INT16_ARR; + um_data.u_data[6] = &aaWorld; + um_data.u_type[6] = UMT_INT16_ARR; + um_data.u_data[7] = &gravity; + um_data.u_type[7] = UMT_FLOAT_ARR; + um_data.u_data[8] = &sample_count; + um_data.u_type[8] = UMT_UINT32; + } + + if (!config.enabled) return; + if (i2c_scl<0 || i2c_sda<0) { DEBUG_PRINTLN(F("MPU6050: I2C is no good.")); return; } + // Check the interrupt pin + if (config.interruptPin >= 0) { + irqBound = pinManager.allocatePin(config.interruptPin, false, PinOwner::UM_IMU); + if (!irqBound) { DEBUG_PRINTLN(F("MPU6050: IRQ pin already in use.")); return; } + pinMode(config.interruptPin, INPUT); + }; + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE Wire.setClock(400000U); // 400kHz I2C clock. Comment this line if having compilation difficulties #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE @@ -95,7 +175,6 @@ class MPU6050Driver : public Usermod { // initialize device DEBUG_PRINTLN(F("Initializing I2C devices...")); mpu.initialize(); - pinMode(INTERRUPT_PIN, INPUT); // verify connection DEBUG_PRINTLN(F("Testing device connections...")); @@ -105,11 +184,16 @@ class MPU6050Driver : public Usermod { DEBUG_PRINTLN(F("Initializing DMP...")); devStatus = mpu.dmpInitialize(); - // supply your own gyro offsets here, scaled for min sensitivity - mpu.setXGyroOffset(220); - mpu.setYGyroOffset(76); - mpu.setZGyroOffset(-85); - mpu.setZAccelOffset(1788); // 1688 factory default for my test chip + // set offsets (from config) + mpu.setXGyroOffset(config.gyro_offset[0]); + mpu.setYGyroOffset(config.gyro_offset[1]); + mpu.setZGyroOffset(config.gyro_offset[2]); + mpu.setXAccelOffset(config.accel_offset[0]); + mpu.setYAccelOffset(config.accel_offset[1]); + mpu.setZAccelOffset(config.accel_offset[2]); + + // set sample rate + mpu.setRate(16); // ~100Hz // make sure it worked (returns 0 if so) if (devStatus == 0) { @@ -117,17 +201,19 @@ class MPU6050Driver : public Usermod { DEBUG_PRINTLN(F("Enabling DMP...")); mpu.setDMPEnabled(true); - // enable Arduino interrupt detection - DEBUG_PRINTLN(F("Enabling interrupt detection (Arduino external interrupt 0)...")); - attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING); - mpuIntStatus = mpu.getIntStatus(); - - // set our DMP Ready flag so the main loop() function knows it's okay to use it - DEBUG_PRINTLN(F("DMP ready! Waiting for first interrupt...")); - dmpReady = true; + mpuInterrupt = true; + if (irqBound) { + // enable Arduino interrupt detection + DEBUG_PRINTLN(F("Enabling interrupt detection (Arduino external interrupt 0)...")); + attachInterrupt(digitalPinToInterrupt(config.interruptPin), dmpDataReady, RISING); + } // get expected DMP packet size for later comparison packetSize = mpu.dmpGetFIFOPacketSize(); + + // set our DMP Ready flag so the main loop() function knows it's okay to use it + DEBUG_PRINTLN(F("DMP ready!")); + dmpReady = true; } else { // ERROR! // 1 = initial memory load failed @@ -137,6 +223,9 @@ class MPU6050Driver : public Usermod { DEBUG_PRINT(devStatus); DEBUG_PRINTLN(")"); } + + fifoCount = 0; + sample_count = 0; } /* @@ -153,28 +242,31 @@ class MPU6050Driver : public Usermod { */ void loop() { // if programming failed, don't try to do anything - if (!enabled || !dmpReady || strip.isUpdating()) return; + if (!config.enabled || !dmpReady || strip.isUpdating()) return; // wait for MPU interrupt or extra packet(s) available + // mpuInterrupt is fixed on if interrupt pin is disabled if (!mpuInterrupt && fifoCount < packetSize) return; // reset interrupt flag and get INT_STATUS byte - mpuInterrupt = false; - mpuIntStatus = mpu.getIntStatus(); - - // get current FIFO count + auto mpuIntStatus = mpu.getIntStatus(); + // Update current FIFO count fifoCount = mpu.getFIFOCount(); // check for overflow (this should never happen unless our code is too inefficient) if ((mpuIntStatus & 0x10) || fifoCount == 1024) { // reset so we can continue cleanly mpu.resetFIFO(); - DEBUG_PRINTLN(F("FIFO overflow!")); + DEBUG_PRINTLN(F("MPU6050: FIFO overflow!")); - // otherwise, check for DMP data ready interrupt (this should happen frequently) - } else if (mpuIntStatus & 0x02) { - // wait for correct available data length, should be a VERY short wait - while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount(); + // otherwise, check for data ready + } else if (fifoCount >= packetSize) { + // clear local interrupt pending status, if not polling + mpuInterrupt = !irqBound; + + // DEBUG_PRINT(F("MPU6050: Processing packet: ")); + // DEBUG_PRINT(fifoCount); + // DEBUG_PRINTLN(F(" bytes in FIFO")); // read a packet from FIFO mpu.getFIFOBytes(fifoBuffer, packetSize); @@ -183,7 +275,6 @@ class MPU6050Driver : public Usermod { // (this lets us immediately read more without waiting for an interrupt) fifoCount -= packetSize; - //NOTE: some of these can be removed to save memory, processing time // if the measurement isn't needed mpu.dmpGetQuaternion(&qat, fifoBuffer); @@ -194,87 +285,141 @@ class MPU6050Driver : public Usermod { mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity); mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &qat); mpu.dmpGetYawPitchRoll(ypr, &qat, &gravity); + ++sample_count; } } - - void addToJsonInfo(JsonObject& root) { - int reading = 20; - //this code adds "u":{"Light":[20," lux"]} to the info object JsonObject user = root["u"]; if (user.isNull()) user = root.createNestedObject("u"); - JsonObject imu_meas = user.createNestedObject("IMU"); - JsonArray quat_json = imu_meas.createNestedArray("Quat"); + // Unfortunately the web UI doesn't know how to print sub-objects: you just see '[object Object]' + // For now, we just put everything in the root userdata object. + //auto imu_meas = user.createNestedObject("IMU"); + auto& imu_meas = user; + + // If an element is an array, the UI expects two elements in the form [value, unit] + // Since our /value/ is an array, wrap it, eg. [[a, b, c]] + JsonArray quat_json = imu_meas.createNestedArray("Quat").createNestedArray(); quat_json.add(qat.w); quat_json.add(qat.x); quat_json.add(qat.y); quat_json.add(qat.z); - JsonArray euler_json = imu_meas.createNestedArray("Euler"); + JsonArray euler_json = imu_meas.createNestedArray("Euler").createNestedArray(); euler_json.add(euler[0]); euler_json.add(euler[1]); euler_json.add(euler[2]); - JsonArray accel_json = imu_meas.createNestedArray("Accel"); + JsonArray accel_json = imu_meas.createNestedArray("Accel").createNestedArray(); accel_json.add(aa.x); accel_json.add(aa.y); accel_json.add(aa.z); - JsonArray gyro_json = imu_meas.createNestedArray("Gyro"); + JsonArray gyro_json = imu_meas.createNestedArray("Gyro").createNestedArray(); gyro_json.add(gy.x); gyro_json.add(gy.y); gyro_json.add(gy.z); - JsonArray world_json = imu_meas.createNestedArray("WorldAccel"); + JsonArray world_json = imu_meas.createNestedArray("WorldAccel").createNestedArray(); world_json.add(aaWorld.x); world_json.add(aaWorld.y); world_json.add(aaWorld.z); - JsonArray real_json = imu_meas.createNestedArray("RealAccel"); + JsonArray real_json = imu_meas.createNestedArray("RealAccel").createNestedArray(); real_json.add(aaReal.x); real_json.add(aaReal.y); real_json.add(aaReal.z); - JsonArray grav_json = imu_meas.createNestedArray("Gravity"); + JsonArray grav_json = imu_meas.createNestedArray("Gravity").createNestedArray(); grav_json.add(gravity.x); grav_json.add(gravity.y); grav_json.add(gravity.z); - JsonArray orient_json = imu_meas.createNestedArray("Orientation"); + JsonArray orient_json = imu_meas.createNestedArray("Orientation").createNestedArray(); orient_json.add(ypr[0]); orient_json.add(ypr[1]); orient_json.add(ypr[2]); } - /* - * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). - * Values in the state object may be modified by connected clients - */ - //void addToJsonState(JsonObject& root) - //{ - //root["user0"] = userVar0; - //} - - - /* - * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). - * Values in the state object may be modified by connected clients - */ - //void readFromJsonState(JsonObject& root) - //{ - //if (root["bri"] == 255) DEBUG_PRINTLN(F("Don't burn down your garage!")); - //} - - /* * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object. * It will be called by WLED when settings are actually saved (for example, LED settings are saved) * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! */ -// void addToConfig(JsonObject& root) -// { -// JsonObject top = root.createNestedObject("MPU6050_IMU"); -// JsonArray pins = top.createNestedArray("pin"); -// pins.add(HW_PIN_SCL); -// pins.add(HW_PIN_SDA); -// } + void addToConfig(JsonObject& root) + { + JsonObject top = root.createNestedObject(FPSTR(_name)); + + //save these vars persistently whenever settings are saved + top[FPSTR(_enabled)] = config.enabled; + top[FPSTR(_interrupt_pin)] = config.interruptPin; + top[FPSTR(_x_acc_bias)] = config.accel_offset[0]; + top[FPSTR(_y_acc_bias)] = config.accel_offset[1]; + top[FPSTR(_z_acc_bias)] = config.accel_offset[2]; + top[FPSTR(_x_gyro_bias)] = config.gyro_offset[0]; + top[FPSTR(_y_gyro_bias)] = config.gyro_offset[1]; + top[FPSTR(_z_gyro_bias)] = config.gyro_offset[2]; + } + + /* + * readFromConfig() can be used to read back the custom settings you added with addToConfig(). + * This is called by WLED when settings are loaded (currently this only happens immediately after boot, or after saving on the Usermod Settings page) + * + * readFromConfig() is called BEFORE setup(). This means you can use your persistent values in setup() (e.g. pin assignments, buffer sizes), + * but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup. + * If you don't know what that is, don't fret. It most likely doesn't affect your use case :) + * + * Return true in case the config values returned from Usermod Settings were complete, or false if you'd like WLED to save your defaults to disk (so any missing values are editable in Usermod Settings) + * + * getJsonValue() returns false if the value is missing, or copies the value into the variable provided and returns true if the value is present + * The configComplete variable is true only if the "exampleUsermod" object and all values are present. If any values are missing, WLED will know to call addToConfig() to save them + * + * This function is guaranteed to be called on boot, but could also be called every time settings are updated + */ + bool readFromConfig(JsonObject& root) + { + // default settings values could be set here (or below using the 3-argument getJsonValue()) instead of in the class definition or constructor + // setting them inside readFromConfig() is slightly more robust, handling the rare but plausible use case of single value being missing after boot (e.g. if the cfg.json was manually edited and a value was removed) + auto old_cfg = config; + + JsonObject top = root[FPSTR(_name)]; + + bool configComplete = top.isNull(); + // Ensure default configuration is loaded + configComplete &= getJsonValue(top[FPSTR(_enabled)], config.enabled, true); + configComplete &= getJsonValue(top[FPSTR(_interrupt_pin)], config.interruptPin, -1); + configComplete &= getJsonValue(top[FPSTR(_x_acc_bias)], config.accel_offset[0], 0); + configComplete &= getJsonValue(top[FPSTR(_y_acc_bias)], config.accel_offset[1], 0); + configComplete &= getJsonValue(top[FPSTR(_z_acc_bias)], config.accel_offset[2], 0); + configComplete &= getJsonValue(top[FPSTR(_x_gyro_bias)], config.gyro_offset[0], 0); + configComplete &= getJsonValue(top[FPSTR(_y_gyro_bias)], config.gyro_offset[1], 0); + configComplete &= getJsonValue(top[FPSTR(_z_gyro_bias)], config.gyro_offset[2], 0); + + DEBUG_PRINT(FPSTR(_name)); + if (top.isNull()) { + DEBUG_PRINTLN(F(": No config found. (Using defaults.)")); + } else if (!initDone()) { + DEBUG_PRINTLN(F(": config loaded.")); + } else if (memcmp(&config, &old_cfg, sizeof(config)) == 0) { + DEBUG_PRINTLN(F(": config unchanged.")); + } else { + DEBUG_PRINTLN(F(": config updated.")); + // Previously loaded and config changed + if (irqBound && ((old_cfg.interruptPin != config.interruptPin) || !config.enabled)) { + detachInterrupt(old_cfg.interruptPin); + pinManager.deallocatePin(old_cfg.interruptPin, PinOwner::UM_IMU); + irqBound = false; + } + + // Just re-init + setup(); + } + + return configComplete; + } + + bool getUMData(um_data_t **data) + { + if (!data || !config.enabled || !dmpReady) return false; // no pointer provided by caller or not enabled -> exit + *data = &um_data; + return true; + } /* * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). @@ -285,3 +430,14 @@ class MPU6050Driver : public Usermod { } }; + + +const char MPU6050Driver::_name[] PROGMEM = "MPU6050_IMU"; +const char MPU6050Driver::_enabled[] PROGMEM = "enabled"; +const char MPU6050Driver::_interrupt_pin[] PROGMEM = "interrupt_pin"; +const char MPU6050Driver::_x_acc_bias[] PROGMEM = "x_acc_bias"; +const char MPU6050Driver::_y_acc_bias[] PROGMEM = "y_acc_bias"; +const char MPU6050Driver::_z_acc_bias[] PROGMEM = "z_acc_bias"; +const char MPU6050Driver::_x_gyro_bias[] PROGMEM = "x_gyro_bias"; +const char MPU6050Driver::_y_gyro_bias[] PROGMEM = "y_gyro_bias"; +const char MPU6050Driver::_z_gyro_bias[] PROGMEM = "z_gyro_bias"; diff --git a/usermods/multi_relay/readme.md b/usermods/multi_relay/readme.md index 71a540701..00addb7e9 100644 --- a/usermods/multi_relay/readme.md +++ b/usermods/multi_relay/readme.md @@ -47,6 +47,24 @@ or You can override the default maximum number of relays (which is 4) by defining MULTI_RELAY_MAX_RELAYS. +Some settings can be defined (defaults) at compile time by setting the following defines: + +```cpp +// enable or disable HA discovery for externally controlled relays +#define MULTI_RELAY_HA_DISCOVERY true +``` + +The following definitions should be a list of values (maximum number of entries is MULTI_RELAY_MAX_RELAYS) that will be applied to the relays in order: +(e.g. assuming MULTI_RELAY_MAX_RELAYS=2) + +```cpp +#define MULTI_RELAY_PINS 12,18 +#define MULTI_RELAY_DELAYS 0,0 +#define MULTI_RELAY_EXTERNALS false,true +#define MULTI_RELAY_INVERTS false,false +``` +These can be set via your `platformio_override.ini` file or as `#define` in your `my_config.h` (remember to set `WLED_USE_MY_CONFIG` in your `platformio_override.ini`) + Example **usermods_list.cpp**: ```cpp @@ -107,4 +125,7 @@ Have fun - @blazoncek * Added button support. 2023-05 -* Added support for PCF8574 I2C port expander (multiple) \ No newline at end of file +* Added support for PCF8574 I2C port expander (multiple) + +2023-11 +* @chrisburrows Added support for compile time defaults for setting DELAY, EXTERNAL, INVERTS and HA discovery \ No newline at end of file diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h index 7234df908..22fa6496d 100644 --- a/usermods/multi_relay/usermod_multi_relay.h +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -2,6 +2,8 @@ #include "wled.h" +#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) + #ifndef MULTI_RELAY_MAX_RELAYS #define MULTI_RELAY_MAX_RELAYS 4 #else @@ -19,6 +21,22 @@ #define MULTI_RELAY_ENABLED true #endif +#ifndef MULTI_RELAY_HA_DISCOVERY + #define MULTI_RELAY_HA_DISCOVERY false +#endif + +#ifndef MULTI_RELAY_DELAYS + #define MULTI_RELAY_DELAYS 0 +#endif + +#ifndef MULTI_RELAY_EXTERNALS + #define MULTI_RELAY_EXTERNALS false +#endif + +#ifndef MULTI_RELAY_INVERTS + #define MULTI_RELAY_INVERTS false +#endif + #define WLED_DEBOUNCE_THRESHOLD 50 //only consider button input of at least 50ms as valid (debouncing) #define ON true @@ -125,7 +143,7 @@ class MultiRelay : public Usermod { * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - inline uint16_t getId() { return USERMOD_ID_MULTI_RELAY; } + inline uint16_t getId() override { return USERMOD_ID_MULTI_RELAY; } /** * switch relay on/off @@ -143,22 +161,22 @@ class MultiRelay : public Usermod { * setup() is called once at boot. WiFi is not yet connected at this point. * You can use it to initialize variables, sensors or similar. */ - void setup(); + void setup() override; /** * connected() is called every time the WiFi is (re)connected * Use it to initialize network interfaces */ - inline void connected() { InitHtmlAPIHandle(); } + inline void connected() override { InitHtmlAPIHandle(); } /** * loop() is called continuously. Here you can check for events, read sensors, etc. */ - void loop(); + void loop() override; #ifndef WLED_DISABLE_MQTT - bool onMqttMessage(char* topic, char* payload); - void onMqttConnect(bool sessionPresent); + bool onMqttMessage(char* topic, char* payload) override; + void onMqttConnect(bool sessionPresent) override; #endif /** @@ -166,31 +184,31 @@ class MultiRelay : public Usermod { * will prevent button working in a default way. * Replicating button.cpp */ - bool handleButton(uint8_t b); + bool handleButton(uint8_t b) override; /** * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. */ - void addToJsonInfo(JsonObject &root); + void addToJsonInfo(JsonObject &root) override; /** * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void addToJsonState(JsonObject &root); + void addToJsonState(JsonObject &root) override; /** * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - void readFromJsonState(JsonObject &root); + void readFromJsonState(JsonObject &root) override; /** * provide the changeable values */ - void addToConfig(JsonObject &root); + void addToConfig(JsonObject &root) override; - void appendConfigData(); + void appendConfigData() override; /** * restore the changeable values @@ -198,7 +216,7 @@ class MultiRelay : public Usermod { * * The function should return true if configuration was successfully loaded or false if there was no configuration. */ - bool readFromConfig(JsonObject &root); + bool readFromConfig(JsonObject &root) override; }; @@ -343,18 +361,22 @@ MultiRelay::MultiRelay() , initDone(false) , usePcf8574(USE_PCF8574) , addrPcf8574(PCF8574_ADDRESS) - , HAautodiscovery(false) + , HAautodiscovery(MULTI_RELAY_HA_DISCOVERY) , periodicBroadcastSec(60) , lastBroadcast(0) { const int8_t defPins[] = {MULTI_RELAY_PINS}; + const int8_t relayDelays[] = {MULTI_RELAY_DELAYS}; + const bool relayExternals[] = {MULTI_RELAY_EXTERNALS}; + const bool relayInverts[] = {MULTI_RELAY_INVERTS}; + for (size_t i=0; igetPins(pins); @@ -104,11 +104,11 @@ class QuinLEDAnPentaUsermod : public Usermod void getCurrentLedcValues() { - byte numBusses = busses.getNumBusses(); + byte numBusses = BusManager::getNumBusses(); byte numLedc = 0; for (int8_t b = 0; b < numBusses; b++) { - Bus* curBus = busses.getBus(b); + Bus* curBus = BusManager::getBus(b); if (curBus != nullptr) { uint32_t curPixColor = curBus->getPixelColor(0); uint8_t _data[5] = {255, 255, 255, 255, 255}; diff --git a/usermods/sd_card/readme.md b/usermods/sd_card/readme.md index 299b68ebc..96390c05a 100644 --- a/usermods/sd_card/readme.md +++ b/usermods/sd_card/readme.md @@ -20,7 +20,7 @@ | `pinSourceSelect` | GPIO that is connected to SD's `SS`(source select) / `CS`(chip select) | 16 | | `pinSourceClock` | GPIO that is connected to SD's `SCLK` (source clock) / `CLK`(clock) | 14 | | `pinPoci` | GPIO that is connected to SD's `POCI` (Peripheral-Out-Ctrl-In) / `MISO` (deprecated) | 36 | - | `pinPico` | GPIO that is connected to SD's `PICO` (Peripheral-In-Ctrl-Out) / `MOSI` (deprecated) | 14 | + | `pinPico` | GPIO that is connected to SD's `PICO` (Peripheral-In-Ctrl-Out) / `MOSI` (deprecated) | 15 | | `sdEnable` | Enable to read data from the SD-card | true | Following new naming convention of [OSHWA](https://www.oshwa.org/a-resolution-to-redefine-spi-signal-names/) @@ -31,4 +31,4 @@ - checks if the specified file is available on the SD card ```cpp bool file_onSD(const char *filepath) {...} - ``` \ No newline at end of file + ``` diff --git a/usermods/seven_segment_display_reloaded/readme.md b/usermods/seven_segment_display_reloaded/readme.md index d373a7eee..a3398c3e5 100644 --- a/usermods/seven_segment_display_reloaded/readme.md +++ b/usermods/seven_segment_display_reloaded/readme.md @@ -24,6 +24,9 @@ Enables the inverted mode in which the background should be enabled and the digi ### Colon-blinking Enables the blinking colon(s) if they are defined +### Leading-Zero +Shows the leading zero of the hour if it exists (i.e. shows `07` instead of `7`) + ### enable-auto-brightness Enables the auto brightness feature. Can be used only when the usermod SN_Photoresistor is installed. diff --git a/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h b/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h index 279774057..bf0b4703b 100644 --- a/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h +++ b/usermods/seven_segment_display_reloaded/usermod_seven_segment_reloaded.h @@ -17,6 +17,7 @@ private: bool umSSDRDisplayTime = false; bool umSSDRInverted = false; bool umSSDRColonblink = true; + bool umSSDRLeadingZero = false; bool umSSDREnableLDR = false; String umSSDRHours = ""; String umSSDRMinutes = ""; @@ -79,6 +80,7 @@ private: static const char _str_timeEnabled[]; static const char _str_inverted[]; static const char _str_colonblink[]; + static const char _str_leadingZero[]; static const char _str_displayMask[]; static const char _str_hours[]; static const char _str_minutes[]; @@ -105,15 +107,15 @@ private: switch (umSSDRDisplayMask[index]) { case 'h': timeVar = hourFormat12(localTime); - _showElements(&umSSDRHours, timeVar, 0, 1); + _showElements(&umSSDRHours, timeVar, 0, !umSSDRLeadingZero); break; case 'H': timeVar = hour(localTime); - _showElements(&umSSDRHours, timeVar, 0, 1); + _showElements(&umSSDRHours, timeVar, 0, !umSSDRLeadingZero); break; case 'k': timeVar = hour(localTime) + 1; - _showElements(&umSSDRHours, timeVar, 0, 0); + _showElements(&umSSDRHours, timeVar, 0, !umSSDRLeadingZero); break; case 'm': timeVar = minute(localTime); @@ -309,6 +311,9 @@ private: if (_cmpIntSetting_P(topic, payload, _str_colonblink, &umSSDRColonblink)) { return true; } + if (_cmpIntSetting_P(topic, payload, _str_leadingZero, &umSSDRLeadingZero)) { + return true; + } if (strcmp_P(topic, _str_displayMask) == 0) { umSSDRDisplayMask = String(payload); _publishMQTTstr_P(_str_displayMask, umSSDRDisplayMask); @@ -323,6 +328,7 @@ private: _publishMQTTint_P(_str_ldrEnabled, umSSDREnableLDR); _publishMQTTint_P(_str_inverted, umSSDRInverted); _publishMQTTint_P(_str_colonblink, umSSDRColonblink); + _publishMQTTint_P(_str_leadingZero, umSSDRLeadingZero); _publishMQTTstr_P(_str_hours, umSSDRHours); _publishMQTTstr_P(_str_minutes, umSSDRMinutes); @@ -347,6 +353,7 @@ private: ssdrObj[FPSTR(_str_ldrEnabled)] = umSSDREnableLDR; ssdrObj[FPSTR(_str_inverted)] = umSSDRInverted; ssdrObj[FPSTR(_str_colonblink)] = umSSDRColonblink; + ssdrObj[FPSTR(_str_leadingZero)] = umSSDRLeadingZero; ssdrObj[FPSTR(_str_displayMask)] = umSSDRDisplayMask; ssdrObj[FPSTR(_str_hours)] = umSSDRHours; ssdrObj[FPSTR(_str_minutes)] = umSSDRMinutes; @@ -425,6 +432,8 @@ public: invert.add(umSSDRInverted); JsonArray blink = user.createNestedArray("Blinking colon"); blink.add(umSSDRColonblink); + JsonArray zero = user.createNestedArray("Show the hour leading zero"); + zero.add(umSSDRLeadingZero); JsonArray ldrEnable = user.createNestedArray("Auto Brightness enabled"); ldrEnable.add(umSSDREnableLDR); @@ -454,6 +463,7 @@ public: umSSDREnableLDR = ssdrObj[FPSTR(_str_ldrEnabled)] | umSSDREnableLDR; umSSDRInverted = ssdrObj[FPSTR(_str_inverted)] | umSSDRInverted; umSSDRColonblink = ssdrObj[FPSTR(_str_colonblink)] | umSSDRColonblink; + umSSDRLeadingZero = ssdrObj[FPSTR(_str_leadingZero)] | umSSDRLeadingZero; umSSDRDisplayMask = ssdrObj[FPSTR(_str_displayMask)] | umSSDRDisplayMask; } } @@ -516,6 +526,7 @@ public: umSSDREnableLDR = (top[FPSTR(_str_ldrEnabled)] | umSSDREnableLDR); umSSDRInverted = (top[FPSTR(_str_inverted)] | umSSDRInverted); umSSDRColonblink = (top[FPSTR(_str_colonblink)] | umSSDRColonblink); + umSSDRLeadingZero = (top[FPSTR(_str_leadingZero)] | umSSDRLeadingZero); umSSDRDisplayMask = top[FPSTR(_str_displayMask)] | umSSDRDisplayMask; umSSDRHours = top[FPSTR(_str_hours)] | umSSDRHours; @@ -546,6 +557,7 @@ const char UsermodSSDR::_str_name[] PROGMEM = "UsermodSSDR"; const char UsermodSSDR::_str_timeEnabled[] PROGMEM = "enabled"; const char UsermodSSDR::_str_inverted[] PROGMEM = "inverted"; const char UsermodSSDR::_str_colonblink[] PROGMEM = "Colon-blinking"; +const char UsermodSSDR::_str_leadingZero[] PROGMEM = "Leading-Zero"; const char UsermodSSDR::_str_displayMask[] PROGMEM = "Display-Mask"; const char UsermodSSDR::_str_hours[] PROGMEM = "LED-Numbers-Hours"; const char UsermodSSDR::_str_minutes[] PROGMEM = "LED-Numbers-Minutes"; diff --git a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h index 238ec7d9c..9cc0bea4c 100644 --- a/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h +++ b/usermods/stairway_wipe_basic/stairway-wipe-usermod-v2.h @@ -91,7 +91,8 @@ class StairwayWipeUsermod : public Usermod { void startWipe() { bri = briLast; //turn on - transitionDelayTemp = 0; //no transition + jsonTransitionOnce = true; + strip.setTransition(0); //no transition effectCurrent = FX_MODE_COLOR_WIPE; resetTimebase(); //make sure wipe starts from beginning @@ -105,10 +106,11 @@ class StairwayWipeUsermod : public Usermod { void turnOff() { + jsonTransitionOnce = true; #ifdef STAIRCASE_WIPE_OFF - transitionDelayTemp = 0; //turn off immediately after wipe completed + strip.setTransition(0); //turn off immediately after wipe completed #else - transitionDelayTemp = 4000; //fade out slowly + strip.setTransition(4000); //fade out slowly #endif bri = 0; stateUpdated(CALL_MODE_NOTIFICATION); diff --git a/usermods/usermod_v2_animartrix/readme.md b/usermods/usermod_v2_animartrix/readme.md new file mode 100644 index 000000000..42d463c50 --- /dev/null +++ b/usermods/usermod_v2_animartrix/readme.md @@ -0,0 +1,14 @@ +# ANIMartRIX + +Addes the effects from ANIMartRIX to WLED + +CC BY-NC 3.0 licensed effects by Stefan Petrick, include this usermod only if you accept the terms! + +## Installation + +Please uncomment the two references to ANIMartRIX in your platform.ini + +lib_dep to a version of https://github.com/netmindz/animartrix.git +and the build_flags -D USERMOD_ANIMARTRIX + + diff --git a/usermods/usermod_v2_animartrix/usermod_v2_animartrix.h b/usermods/usermod_v2_animartrix/usermod_v2_animartrix.h new file mode 100644 index 000000000..d91cf6c96 --- /dev/null +++ b/usermods/usermod_v2_animartrix/usermod_v2_animartrix.h @@ -0,0 +1,456 @@ +#pragma once + +#include "wled.h" +#include + +#warning WLED usermod: CC BY-NC 3.0 licensed effects by Stefan Petrick, include this usermod only if you accept the terms! +//======================================================================================================================== + + +static const char _data_FX_mode_Module_Experiment10[] PROGMEM = "Z💡Module_Experiment10@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment9[] PROGMEM = "Z💡Module_Experiment9@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment8[] PROGMEM = "Z💡Module_Experiment8@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment7[] PROGMEM = "Z💡Module_Experiment7@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment6[] PROGMEM = "Z💡Module_Experiment6@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment5[] PROGMEM = "Z💡Module_Experiment5@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment4[] PROGMEM = "Z💡Module_Experiment4@Speed;;1;2"; +static const char _data_FX_mode_Zoom2[] PROGMEM = "Z💡Zoom2@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment3[] PROGMEM = "Z💡Module_Experiment3@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment2[] PROGMEM = "Z💡Module_Experiment2@Speed;;1;2"; +static const char _data_FX_mode_Module_Experiment1[] PROGMEM = "Z💡Module_Experiment1@Speed;;1;2"; +static const char _data_FX_mode_Parametric_Water[] PROGMEM = "Z💡Parametric_Water@Speed;;1;2"; +static const char _data_FX_mode_Water[] PROGMEM = "Z💡Water@Speed;;1;2"; +static const char _data_FX_mode_Complex_Kaleido_6[] PROGMEM = "Z💡Complex_Kaleido_6@Speed;;1;2"; +static const char _data_FX_mode_Complex_Kaleido_5[] PROGMEM = "Z💡Complex_Kaleido_5@Speed;;1;2"; +static const char _data_FX_mode_Complex_Kaleido_4[] PROGMEM = "Z💡Complex_Kaleido_4@Speed;;1;2"; +static const char _data_FX_mode_Complex_Kaleido_3[] PROGMEM = "Z💡Complex_Kaleido_3@Speed;;1;2"; +static const char _data_FX_mode_Complex_Kaleido_2[] PROGMEM = "Z💡Complex_Kaleido_2@Speed;;1;2"; +static const char _data_FX_mode_Complex_Kaleido[] PROGMEM = "Z💡Complex_Kaleido@Speed;;1;2"; +static const char _data_FX_mode_SM10[] PROGMEM = "Z💡SM10@Speed;;1;2"; +static const char _data_FX_mode_SM9[] PROGMEM = "Z💡SM9@Speed;;1;2"; +static const char _data_FX_mode_SM8[] PROGMEM = "Z💡SM8@Speed;;1;2"; +static const char _data_FX_mode_SM7[] PROGMEM = "Z💡SM7@Speed;;1;2"; +static const char _data_FX_mode_SM6[] PROGMEM = "Z💡SM6@Speed;;1;2"; +static const char _data_FX_mode_SM5[] PROGMEM = "Z💡SM5@Speed;;1;2"; +static const char _data_FX_mode_SM4[] PROGMEM = "Z💡SM4@Speed;;1;2"; +static const char _data_FX_mode_SM3[] PROGMEM = "Z💡SM3@Speed;;1;2"; +static const char _data_FX_mode_SM2[] PROGMEM = "Z💡SM2@Speed;;1;2"; +static const char _data_FX_mode_SM1[] PROGMEM = "Z💡SM1@Speed;;1;2"; +static const char _data_FX_mode_Big_Caleido[] PROGMEM = "Z💡Big_Caleido@Speed;;1;2"; +static const char _data_FX_mode_RGB_Blobs5[] PROGMEM = "Z💡RGB_Blobs5@Speed;;1;2"; +static const char _data_FX_mode_RGB_Blobs4[] PROGMEM = "Z💡RGB_Blobs4@Speed;;1;2"; +static const char _data_FX_mode_RGB_Blobs3[] PROGMEM = "Z💡RGB_Blobs3@Speed;;1;2"; +static const char _data_FX_mode_RGB_Blobs2[] PROGMEM = "Z💡RGB_Blobs2@Speed;;1;2"; +static const char _data_FX_mode_RGB_Blobs[] PROGMEM = "Z💡RGB_Blobs@Speed;;1;2"; +static const char _data_FX_mode_Polar_Waves[] PROGMEM = "Z💡Polar_Waves@Speed;;1;2"; +static const char _data_FX_mode_Slow_Fade[] PROGMEM = "Z💡Slow_Fade@Speed;;1;2"; +static const char _data_FX_mode_Zoom[] PROGMEM = "Z💡Zoom@Speed;;1;2"; +static const char _data_FX_mode_Hot_Blob[] PROGMEM = "Z💡Hot_Blob@Speed;;1;2"; +static const char _data_FX_mode_Spiralus2[] PROGMEM = "Z💡Spiralus2@Speed;;1;2"; +static const char _data_FX_mode_Spiralus[] PROGMEM = "Z💡Spiralus@Speed;;1;2"; +static const char _data_FX_mode_Yves[] PROGMEM = "Z💡Yves@Speed;;1;2"; +static const char _data_FX_mode_Scaledemo1[] PROGMEM = "Z💡Scaledemo1@Speed;;1;2"; +static const char _data_FX_mode_Lava1[] PROGMEM = "Z💡Lava1@Speed;;1;2"; +static const char _data_FX_mode_Caleido3[] PROGMEM = "Z💡Caleido3@Speed;;1;2"; +static const char _data_FX_mode_Caleido2[] PROGMEM = "Z💡Caleido2@Speed;;1;2"; +static const char _data_FX_mode_Caleido1[] PROGMEM = "Z💡Caleido1@Speed;;1;2"; +static const char _data_FX_mode_Distance_Experiment[] PROGMEM = "Z💡Distance_Experiment@Speed;;1;2"; +static const char _data_FX_mode_Center_Field[] PROGMEM = "Z💡Center_Field@Speed;;1;2"; +static const char _data_FX_mode_Waves[] PROGMEM = "Z💡Waves@Speed;;1;2"; +static const char _data_FX_mode_Chasing_Spirals[] PROGMEM = "Z💡Chasing_Spirals@Speed;;1;2"; +static const char _data_FX_mode_Rotating_Blob[] PROGMEM = "Z💡Rotating_Blob@Speed;;1;2"; + + +class ANIMartRIXMod:public ANIMartRIX { + public: + void initEffect() { + if (SEGENV.call == 0) { + init(SEGMENT.virtualWidth(), SEGMENT.virtualHeight(), false); + } + float speedFactor = 1.0; + if (SEGMENT.speed < 128) { + speedFactor = (float) map(SEGMENT.speed, 0, 127, 1, 10) / 10.0f; + } + else{ + speedFactor = map(SEGMENT.speed, 128, 255, 10, 100) / 10; + } + setSpeedFactor(speedFactor); + } + void setPixelColor(int x, int y, rgb pixel) { + SEGMENT.setPixelColorXY(x, y, CRGB(pixel.red, pixel.green, pixel.blue)); + } + void setPixelColor(int index, rgb pixel) { + SEGMENT.setPixelColor(index, CRGB(pixel.red, pixel.green, pixel.blue)); + } + + // Add any extra custom effects not part of the ANIMartRIX libary here +}; +ANIMartRIXMod anim; + +uint16_t mode_Module_Experiment10() { + anim.initEffect(); + anim.Module_Experiment10(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment9() { + anim.initEffect(); + anim.Module_Experiment9(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment8() { + anim.initEffect(); + anim.Module_Experiment8(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment7() { + anim.initEffect(); + anim.Module_Experiment7(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment6() { + anim.initEffect(); + anim.Module_Experiment6(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment5() { + anim.initEffect(); + anim.Module_Experiment5(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment4() { + anim.initEffect(); + anim.Module_Experiment4(); + return FRAMETIME; +} +uint16_t mode_Zoom2() { + anim.initEffect(); + anim.Zoom2(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment3() { + anim.initEffect(); + anim.Module_Experiment3(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment2() { + anim.initEffect(); + anim.Module_Experiment2(); + return FRAMETIME; +} +uint16_t mode_Module_Experiment1() { + anim.initEffect(); + anim.Module_Experiment1(); + return FRAMETIME; +} +uint16_t mode_Parametric_Water() { + anim.initEffect(); + anim.Parametric_Water(); + return FRAMETIME; +} +uint16_t mode_Water() { + anim.initEffect(); + anim.Water(); + return FRAMETIME; +} +uint16_t mode_Complex_Kaleido_6() { + anim.initEffect(); + anim.Complex_Kaleido_6(); + return FRAMETIME; +} +uint16_t mode_Complex_Kaleido_5() { + anim.initEffect(); + anim.Complex_Kaleido_5(); + return FRAMETIME; +} +uint16_t mode_Complex_Kaleido_4() { + anim.initEffect(); + anim.Complex_Kaleido_4(); + return FRAMETIME; +} +uint16_t mode_Complex_Kaleido_3() { + anim.initEffect(); + anim.Complex_Kaleido_3(); + return FRAMETIME; +} +uint16_t mode_Complex_Kaleido_2() { + anim.initEffect(); + anim.Complex_Kaleido_2(); + return FRAMETIME; +} +uint16_t mode_Complex_Kaleido() { + anim.initEffect(); + anim.Complex_Kaleido(); + return FRAMETIME; +} +uint16_t mode_SM10() { + anim.initEffect(); + anim.SM10(); + return FRAMETIME; +} +uint16_t mode_SM9() { + anim.initEffect(); + anim.SM9(); + return FRAMETIME; +} +uint16_t mode_SM8() { + anim.initEffect(); + anim.SM8(); + return FRAMETIME; +} +// uint16_t mode_SM7() { +// anim.initEffect(); +// anim.SM7(); +// +// return FRAMETIME; +// } +uint16_t mode_SM6() { + anim.initEffect(); + anim.SM6(); + return FRAMETIME; +} +uint16_t mode_SM5() { + anim.initEffect(); + anim.SM5(); + return FRAMETIME; +} +uint16_t mode_SM4() { + anim.initEffect(); + anim.SM4(); + return FRAMETIME; +} +uint16_t mode_SM3() { + anim.initEffect(); + anim.SM3(); + return FRAMETIME; +} +uint16_t mode_SM2() { + anim.initEffect(); + anim.SM2(); + return FRAMETIME; +} +uint16_t mode_SM1() { + anim.initEffect(); + anim.SM1(); + return FRAMETIME; +} +uint16_t mode_Big_Caleido() { + anim.initEffect(); + anim.Big_Caleido(); + return FRAMETIME; +} +uint16_t mode_RGB_Blobs5() { + anim.initEffect(); + anim.RGB_Blobs5(); + return FRAMETIME; +} +uint16_t mode_RGB_Blobs4() { + anim.initEffect(); + anim.RGB_Blobs4(); + return FRAMETIME; +} +uint16_t mode_RGB_Blobs3() { + anim.initEffect(); + anim.RGB_Blobs3(); + return FRAMETIME; +} +uint16_t mode_RGB_Blobs2() { + anim.initEffect(); + anim.RGB_Blobs2(); + return FRAMETIME; +} +uint16_t mode_RGB_Blobs() { + anim.initEffect(); + anim.RGB_Blobs(); + return FRAMETIME; +} +uint16_t mode_Polar_Waves() { + anim.initEffect(); + anim.Polar_Waves(); + return FRAMETIME; +} +uint16_t mode_Slow_Fade() { + anim.initEffect(); + anim.Slow_Fade(); + return FRAMETIME; +} +uint16_t mode_Zoom() { + anim.initEffect(); + anim.Zoom(); + return FRAMETIME; +} +uint16_t mode_Hot_Blob() { + anim.initEffect(); + anim.Hot_Blob(); + return FRAMETIME; +} +uint16_t mode_Spiralus2() { + anim.initEffect(); + anim.Spiralus2(); + return FRAMETIME; +} +uint16_t mode_Spiralus() { + anim.initEffect(); + anim.Spiralus(); + return FRAMETIME; +} +uint16_t mode_Yves() { + anim.initEffect(); + anim.Yves(); + return FRAMETIME; +} +uint16_t mode_Scaledemo1() { + anim.initEffect(); + anim.Scaledemo1(); + return FRAMETIME; +} +uint16_t mode_Lava1() { + anim.initEffect(); + anim.Lava1(); + return FRAMETIME; +} +uint16_t mode_Caleido3() { + anim.initEffect(); + anim.Caleido3(); + return FRAMETIME; +} +uint16_t mode_Caleido2() { + anim.initEffect(); + anim.Caleido2(); + return FRAMETIME; +} +uint16_t mode_Caleido1() { + anim.initEffect(); + anim.Caleido1(); + return FRAMETIME; +} +uint16_t mode_Distance_Experiment() { + anim.initEffect(); + anim.Distance_Experiment(); + return FRAMETIME; +} +uint16_t mode_Center_Field() { + anim.initEffect(); + anim.Center_Field(); + return FRAMETIME; +} +uint16_t mode_Waves() { + anim.initEffect(); + anim.Waves(); + return FRAMETIME; +} +uint16_t mode_Chasing_Spirals() { + anim.initEffect(); + anim.Chasing_Spirals(); + return FRAMETIME; +} +uint16_t mode_Rotating_Blob() { + anim.initEffect(); + anim.Rotating_Blob(); + return FRAMETIME; +} + + +class AnimartrixUsermod : public Usermod { + protected: + bool enabled = false; //WLEDMM + const char *_name; //WLEDMM + bool initDone = false; //WLEDMM + unsigned long lastTime = 0; //WLEDMM + + public: + + AnimartrixUsermod(const char *name, bool enabled) { + this->_name = name; + this->enabled = enabled; + } //WLEDMM + + + void setup() { + + strip.addEffect(255, &mode_Module_Experiment10, _data_FX_mode_Module_Experiment10); + strip.addEffect(255, &mode_Module_Experiment9, _data_FX_mode_Module_Experiment9); + strip.addEffect(255, &mode_Module_Experiment8, _data_FX_mode_Module_Experiment8); + strip.addEffect(255, &mode_Module_Experiment7, _data_FX_mode_Module_Experiment7); + strip.addEffect(255, &mode_Module_Experiment6, _data_FX_mode_Module_Experiment6); + strip.addEffect(255, &mode_Module_Experiment5, _data_FX_mode_Module_Experiment5); + strip.addEffect(255, &mode_Module_Experiment4, _data_FX_mode_Module_Experiment4); + strip.addEffect(255, &mode_Zoom2, _data_FX_mode_Zoom2); + strip.addEffect(255, &mode_Module_Experiment3, _data_FX_mode_Module_Experiment3); + strip.addEffect(255, &mode_Module_Experiment2, _data_FX_mode_Module_Experiment2); + strip.addEffect(255, &mode_Module_Experiment1, _data_FX_mode_Module_Experiment1); + strip.addEffect(255, &mode_Parametric_Water, _data_FX_mode_Parametric_Water); + strip.addEffect(255, &mode_Water, _data_FX_mode_Water); + strip.addEffect(255, &mode_Complex_Kaleido_6, _data_FX_mode_Complex_Kaleido_6); + strip.addEffect(255, &mode_Complex_Kaleido_5, _data_FX_mode_Complex_Kaleido_5); + strip.addEffect(255, &mode_Complex_Kaleido_4, _data_FX_mode_Complex_Kaleido_4); + strip.addEffect(255, &mode_Complex_Kaleido_3, _data_FX_mode_Complex_Kaleido_3); + strip.addEffect(255, &mode_Complex_Kaleido_2, _data_FX_mode_Complex_Kaleido_2); + strip.addEffect(255, &mode_Complex_Kaleido, _data_FX_mode_Complex_Kaleido); + strip.addEffect(255, &mode_SM10, _data_FX_mode_SM10); + strip.addEffect(255, &mode_SM9, _data_FX_mode_SM9); + strip.addEffect(255, &mode_SM8, _data_FX_mode_SM8); + // strip.addEffect(255, &mode_SM7, _data_FX_mode_SM7); + strip.addEffect(255, &mode_SM6, _data_FX_mode_SM6); + strip.addEffect(255, &mode_SM5, _data_FX_mode_SM5); + strip.addEffect(255, &mode_SM4, _data_FX_mode_SM4); + strip.addEffect(255, &mode_SM3, _data_FX_mode_SM3); + strip.addEffect(255, &mode_SM2, _data_FX_mode_SM2); + strip.addEffect(255, &mode_SM1, _data_FX_mode_SM1); + strip.addEffect(255, &mode_Big_Caleido, _data_FX_mode_Big_Caleido); + strip.addEffect(255, &mode_RGB_Blobs5, _data_FX_mode_RGB_Blobs5); + strip.addEffect(255, &mode_RGB_Blobs4, _data_FX_mode_RGB_Blobs4); + strip.addEffect(255, &mode_RGB_Blobs3, _data_FX_mode_RGB_Blobs3); + strip.addEffect(255, &mode_RGB_Blobs2, _data_FX_mode_RGB_Blobs2); + strip.addEffect(255, &mode_RGB_Blobs, _data_FX_mode_RGB_Blobs); + strip.addEffect(255, &mode_Polar_Waves, _data_FX_mode_Polar_Waves); + strip.addEffect(255, &mode_Slow_Fade, _data_FX_mode_Slow_Fade); + strip.addEffect(255, &mode_Zoom, _data_FX_mode_Zoom); + strip.addEffect(255, &mode_Hot_Blob, _data_FX_mode_Hot_Blob); + strip.addEffect(255, &mode_Spiralus2, _data_FX_mode_Spiralus2); + strip.addEffect(255, &mode_Spiralus, _data_FX_mode_Spiralus); + strip.addEffect(255, &mode_Yves, _data_FX_mode_Yves); + strip.addEffect(255, &mode_Scaledemo1, _data_FX_mode_Scaledemo1); + strip.addEffect(255, &mode_Lava1, _data_FX_mode_Lava1); + strip.addEffect(255, &mode_Caleido3, _data_FX_mode_Caleido3); + strip.addEffect(255, &mode_Caleido2, _data_FX_mode_Caleido2); + strip.addEffect(255, &mode_Caleido1, _data_FX_mode_Caleido1); + strip.addEffect(255, &mode_Distance_Experiment, _data_FX_mode_Distance_Experiment); + strip.addEffect(255, &mode_Center_Field, _data_FX_mode_Center_Field); + strip.addEffect(255, &mode_Waves, _data_FX_mode_Waves); + strip.addEffect(255, &mode_Chasing_Spirals, _data_FX_mode_Chasing_Spirals); + strip.addEffect(255, &mode_Rotating_Blob, _data_FX_mode_Rotating_Blob); + + initDone = true; + } + + void loop() { + if (!enabled || strip.isUpdating()) return; + + // do your magic here + if (millis() - lastTime > 1000) { + //USER_PRINTLN("I'm alive!"); + lastTime = millis(); + } + } + + void addToJsonInfo(JsonObject& root) + { + char myStringBuffer[16]; // buffer for snprintf() + JsonObject user = root["u"]; + if (user.isNull()) user = root.createNestedObject("u"); + + JsonArray infoArr = user.createNestedArray(FPSTR(_name)); + + String uiDomString = F("Animartrix requires the Creative Commons Attribution License CC BY-NC 3.0"); + infoArr.add(uiDomString); + } + + uint16_t getId() + { + return USERMOD_ID_ANIMARTRIX; + } + +}; + + + diff --git a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h index 5a99c3cdb..40136a92d 100644 --- a/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h +++ b/usermods/usermod_v2_four_line_display_ALT/usermod_v2_four_line_display_ALT.h @@ -211,16 +211,16 @@ class FourLineDisplayUsermod : public Usermod { // gets called once at boot. Do all initialization that doesn't depend on // network here - void setup(); + void setup() override; // gets called every time WiFi is (re-)connected. Initialize own network // interfaces here - void connected(); + void connected() override; /** * Da loop. */ - void loop(); + void loop() override; //function to update lastredraw inline void updateRedrawTime() { lastRedraw = millis(); } @@ -287,28 +287,28 @@ class FourLineDisplayUsermod : public Usermod { */ bool handleButton(uint8_t b); - void onUpdateBegin(bool init); + void onUpdateBegin(bool init) override; /* * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. * Creating an "u" object allows you to add custom key/value pairs to the Info section of the WLED web UI. * Below it is shown how this could be used for e.g. a light sensor */ - //void addToJsonInfo(JsonObject& root); + //void addToJsonInfo(JsonObject& root) override; /* * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - //void addToJsonState(JsonObject& root); + //void addToJsonState(JsonObject& root) override; /* * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - //void readFromJsonState(JsonObject& root); + //void readFromJsonState(JsonObject& root) override; - void appendConfigData(); + void appendConfigData() override; /* * addToConfig() can be used to add custom persistent settings to the cfg.json file in the "um" (usermod) object. @@ -324,7 +324,7 @@ class FourLineDisplayUsermod : public Usermod { * * I highly recommend checking out the basics of ArduinoJson serialization and deserialization in order to use custom settings! */ - void addToConfig(JsonObject& root); + void addToConfig(JsonObject& root) override; /* * readFromConfig() can be used to read back the custom settings you added with addToConfig(). @@ -334,13 +334,13 @@ class FourLineDisplayUsermod : public Usermod { * but also that if you want to write persistent values to a dynamic buffer, you'd need to allocate it here instead of in setup. * If you don't know what that is, don't fret. It most likely doesn't affect your use case :) */ - bool readFromConfig(JsonObject& root); + bool readFromConfig(JsonObject& root) override; /* * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - uint16_t getId() { + uint16_t getId() override { return USERMOD_ID_FOUR_LINE_DISP; } }; @@ -1081,7 +1081,7 @@ bool FourLineDisplayUsermod::handleButton(uint8_t b) { static bool buttonLongPressed = false; static unsigned long buttonPressedTime = 0; static unsigned long buttonWaitTime = 0; - bool handled = true; + bool handled = false; //momentary button logic if (isButtonPressed(b)) { //pressed @@ -1090,11 +1090,12 @@ bool FourLineDisplayUsermod::handleButton(uint8_t b) { buttonPressedBefore = true; if (now - buttonPressedTime > 600) { //long press - buttonLongPressed = true; //TODO: handleButton() handles button 0 without preset in a different way for double click //so we need to override with same behaviour - longPressAction(0); - //handled = false; + //DEBUG_PRINTLN(F("4LD action.")); + //if (!buttonLongPressed) longPressAction(0); + buttonLongPressed = true; + return false; } } else if (!isButtonPressed(b) && buttonPressedBefore) { //released @@ -1126,7 +1127,7 @@ bool FourLineDisplayUsermod::handleButton(uint8_t b) { buttonWaitTime = 0; //TODO: handleButton() handles button 0 without preset in a different way for double click //so we need to override with same behaviour - shortPressAction(0); + //shortPressAction(0); //handled = false; } return handled; diff --git a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h index b142f9037..adea86774 100644 --- a/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h +++ b/usermods/usermod_v2_rotary_encoder_ui_ALT/usermod_v2_rotary_encoder_ui_ALT.h @@ -285,7 +285,7 @@ class RotaryEncoderUIUsermod : public Usermod { * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). * This could be used in the future for the system to determine whether your usermod is installed. */ - uint16_t getId() { return USERMOD_ID_ROTARY_ENC_UI; } + uint16_t getId() override { return USERMOD_ID_ROTARY_ENC_UI; } /** * Enable/Disable the usermod */ @@ -300,7 +300,7 @@ class RotaryEncoderUIUsermod : public Usermod { * setup() is called once at boot. WiFi is not yet connected at this point. * You can use it to initialize variables, sensors or similar. */ - void setup(); + void setup() override; /** * connected() is called every time the WiFi is (re)connected @@ -311,11 +311,11 @@ class RotaryEncoderUIUsermod : public Usermod { /** * loop() is called continuously. Here you can check for events, read sensors, etc. */ - void loop(); + void loop() override; #ifndef WLED_DISABLE_MQTT - //bool onMqttMessage(char* topic, char* payload); - //void onMqttConnect(bool sessionPresent); + //bool onMqttMessage(char* topic, char* payload) override; + //void onMqttConnect(bool sessionPresent) override; #endif /** @@ -323,31 +323,31 @@ class RotaryEncoderUIUsermod : public Usermod { * will prevent button working in a default way. * Replicating button.cpp */ - //bool handleButton(uint8_t b); + //bool handleButton(uint8_t b) override; /** * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. */ - //void addToJsonInfo(JsonObject &root); + //void addToJsonInfo(JsonObject &root) override; /** * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - //void addToJsonState(JsonObject &root); + //void addToJsonState(JsonObject &root) override; /** * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). * Values in the state object may be modified by connected clients */ - //void readFromJsonState(JsonObject &root); + //void readFromJsonState(JsonObject &root) override; /** * provide the changeable values */ - void addToConfig(JsonObject &root); + void addToConfig(JsonObject &root) override; - void appendConfigData(); + void appendConfigData() override; /** * restore the changeable values @@ -355,7 +355,7 @@ class RotaryEncoderUIUsermod : public Usermod { * * The function should return true if configuration was successfully loaded or false if there was no configuration. */ - bool readFromConfig(JsonObject &root); + bool readFromConfig(JsonObject &root) override; // custom methods void displayNetworkInfo(); @@ -398,8 +398,14 @@ void RotaryEncoderUIUsermod::sortModesAndPalettes() { modes_alpha_indexes = re_initIndexArray(strip.getModeCount()); re_sortModes(modes_qstrings, modes_alpha_indexes, strip.getModeCount(), MODE_SORT_SKIP_COUNT); - palettes_qstrings = re_findModeStrings(JSON_palette_names, strip.getPaletteCount()); - palettes_alpha_indexes = re_initIndexArray(strip.getPaletteCount()); // only use internal palettes + palettes_qstrings = re_findModeStrings(JSON_palette_names, strip.getPaletteCount()+strip.customPalettes.size()); + palettes_alpha_indexes = re_initIndexArray(strip.getPaletteCount()+strip.customPalettes.size()); + if (strip.customPalettes.size()) { + for (int i=0; i=0) pinMode(pinC, USERMOD_ROTARY_ENCODER_GPIO); } loopTime = millis(); @@ -682,21 +688,25 @@ void RotaryEncoderUIUsermod::displayNetworkInfo() { void RotaryEncoderUIUsermod::findCurrentEffectAndPalette() { DEBUG_PRINTLN(F("Finding current mode and palette.")); currentEffectAndPaletteInitialized = true; - for (uint8_t i = 0; i < strip.getModeCount(); i++) { + + effectCurrentIndex = 0; + for (int i = 0; i < strip.getModeCount(); i++) { if (modes_alpha_indexes[i] == effectCurrent) { effectCurrentIndex = i; + DEBUG_PRINTLN(F("Found current mode.")); break; } } - DEBUG_PRINTLN(F("Found current mode.")); - for (uint8_t i = 0; i < strip.getPaletteCount(); i++) { + effectPaletteIndex = 0; + DEBUG_PRINTLN(effectPalette); + for (uint8_t i = 0; i < strip.getPaletteCount()+strip.customPalettes.size(); i++) { if (palettes_alpha_indexes[i] == effectPalette) { effectPaletteIndex = i; + DEBUG_PRINTLN(F("Found palette.")); break; } } - DEBUG_PRINTLN(F("Found palette.")); } bool RotaryEncoderUIUsermod::changeState(const char *stateName, byte markedLine, byte markedCol, byte glyph) { @@ -731,7 +741,9 @@ void RotaryEncoderUIUsermod::changeBrightness(bool increase) { } display->updateRedrawTime(); #endif - bri = max(min((increase ? bri+fadeAmount : bri-fadeAmount), 255), 0); + //bri = max(min((increase ? bri+fadeAmount : bri-fadeAmount), 255), 0); + if (bri < 40) bri = max(min((increase ? bri+fadeAmount/2 : bri-fadeAmount/2), 255), 0); // slower steps when brightness < 16% + else bri = max(min((increase ? bri+fadeAmount : bri-fadeAmount), 255), 0); lampUdated(); #ifdef USERMOD_FOUR_LINE_DISPLAY display->updateBrightness(); @@ -878,7 +890,7 @@ void RotaryEncoderUIUsermod::changePalette(bool increase) { } display->updateRedrawTime(); #endif - effectPaletteIndex = max(min((increase ? effectPaletteIndex+1 : effectPaletteIndex-1), strip.getPaletteCount()-1), 0); + effectPaletteIndex = max(min((unsigned)(increase ? effectPaletteIndex+1 : effectPaletteIndex-1), strip.getPaletteCount()+strip.customPalettes.size()-1), 0U); effectPalette = palettes_alpha_indexes[effectPaletteIndex]; stateChanged = true; if (applyToAll) { diff --git a/wled00/FX.cpp b/wled00/FX.cpp index 58eb73ec8..be21ebe0e 100644 --- a/wled00/FX.cpp +++ b/wled00/FX.cpp @@ -80,7 +80,7 @@ int8_t tristate_square8(uint8_t x, uint8_t pulsewidth, uint8_t attdec) { */ uint16_t mode_static(void) { SEGMENT.fill(SEGCOLOR(0)); - return 350; + return strip.isOffRefreshRequired() ? FRAMETIME : 350; } static const char _data_FX_MODE_STATIC[] PROGMEM = "Solid"; @@ -177,11 +177,11 @@ uint16_t color_wipe(bool rev, bool useRandomColors) { SEGENV.step = 3; } if (SEGENV.step == 1) { //if flag set, change to new random color - SEGENV.aux1 = SEGMENT.get_random_wheel_index(SEGENV.aux0); + SEGENV.aux1 = get_random_wheel_index(SEGENV.aux0); SEGENV.step = 2; } if (SEGENV.step == 3) { - SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux1); + SEGENV.aux0 = get_random_wheel_index(SEGENV.aux1); SEGENV.step = 0; } } @@ -271,7 +271,7 @@ uint16_t mode_random_color(void) { if (it != SEGENV.step) //new color { SEGENV.aux1 = SEGENV.aux0; - SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index + SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); //aux0 will store our random color wheel index SEGENV.step = it; } @@ -587,7 +587,7 @@ uint16_t mode_twinkle(void) { uint16_t PRNG16 = SEGENV.aux1; - for (uint16_t i = 0; i < SEGENV.aux0; i++) + for (unsigned i = 0; i < SEGENV.aux0; i++) { PRNG16 = (uint16_t)(PRNG16 * 2053) + 13849; // next 'random' number uint32_t p = (uint32_t)SEGLEN * (uint32_t)PRNG16; @@ -604,27 +604,36 @@ static const char _data_FX_MODE_TWINKLE[] PROGMEM = "Twinkle@!,!;!,!;!;;m12=0"; * Dissolve function */ uint16_t dissolve(uint32_t color) { - //bool wa = (SEGCOLOR(1) != 0 && strip.getBrightness() < 255); //workaround, can't compare getPixel to color if not full brightness + uint16_t dataSize = (SEGLEN+7) >> 3; //1 bit per LED + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (SEGENV.call == 0) { - SEGMENT.fill(SEGCOLOR(1)); + memset(SEGMENT.data, 0xFF, dataSize); // start by fading pixels up + SEGENV.aux0 = 1; } for (int j = 0; j <= SEGLEN / 15; j++) { if (random8() <= SEGMENT.intensity) { - for (size_t times = 0; times < 10; times++) //attempt to spawn a new pixel 10 times - { - uint16_t i = random16(SEGLEN); + for (size_t times = 0; times < 10; times++) { //attempt to spawn a new pixel 10 times + unsigned i = random16(SEGLEN); + unsigned index = i >> 3; + unsigned bitNum = i & 0x07; + bool fadeUp = bitRead(SEGENV.data[index], bitNum); if (SEGENV.aux0) { //dissolve to primary/palette - if (SEGMENT.getPixelColor(i) == SEGCOLOR(1) /*|| wa*/) { + if (fadeUp) { if (color == SEGCOLOR(0)) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } else { SEGMENT.setPixelColor(i, color); } + bitWrite(SEGENV.data[index], bitNum, false); break; //only spawn 1 new pixel per frame per 50 LEDs } } else { //dissolve to secondary - if (SEGMENT.getPixelColor(i) != SEGCOLOR(1)) { SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; } + if (!fadeUp) { + SEGMENT.setPixelColor(i, SEGCOLOR(1)); break; + bitWrite(SEGENV.data[index], bitNum, true); + } } } } @@ -633,6 +642,7 @@ uint16_t dissolve(uint32_t color) { if (SEGENV.step > (255 - SEGMENT.speed) + 15U) { SEGENV.aux0 = !SEGENV.aux0; SEGENV.step = 0; + memset(SEGMENT.data, (SEGENV.aux0 ? 0xFF : 0), dataSize); // switch fading } else { SEGENV.step++; } @@ -686,7 +696,7 @@ static const char _data_FX_MODE_SPARKLE[] PROGMEM = "Sparkle@!,,,,,,Overlay;!,!; * Inspired by www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/ */ uint16_t mode_flash_sparkle(void) { - if (!SEGMENT.check2) for(uint16_t i = 0; i < SEGLEN; i++) { + if (!SEGMENT.check2) for (int i = 0; i < SEGLEN; i++) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 0)); } @@ -713,7 +723,7 @@ uint16_t mode_hyper_sparkle(void) { if (strip.now - SEGENV.aux0 > SEGENV.step) { if (random8((255-SEGMENT.intensity) >> 4) == 0) { - for (int i = 0; i < MAX(1, SEGLEN/3); i++) { + for (int i = 0; i < max(1, SEGLEN/3); i++) { SEGMENT.setPixelColor(random16(SEGLEN), SEGCOLOR(1)); } } @@ -764,7 +774,7 @@ uint16_t mode_android(void) { SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1)); } - if (SEGENV.aux1 > ((float)SEGMENT.intensity/255.0)*(float)SEGLEN) + if (SEGENV.aux1 > (SEGMENT.intensity*SEGLEN)/255) { SEGENV.aux0 = 1; } else @@ -814,21 +824,21 @@ static const char _data_FX_MODE_ANDROID[] PROGMEM = "Android@!,Width;!,!;!;;m12= */ uint16_t chase(uint32_t color1, uint32_t color2, uint32_t color3, bool do_palette) { uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); - uint16_t a = counter * SEGLEN >> 16; + uint16_t a = (counter * SEGLEN) >> 16; bool chase_random = (SEGMENT.mode == FX_MODE_CHASE_RANDOM); if (chase_random) { if (a < SEGENV.step) //we hit the start again, choose new color for Chase random { SEGENV.aux1 = SEGENV.aux0; //store previous random color - SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0); + SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); } color1 = SEGMENT.color_wheel(SEGENV.aux0); } SEGENV.step = a; // Use intensity setting to vary chase up to 1/2 string length - uint8_t size = 1 + (SEGMENT.intensity * SEGLEN >> 10); + uint8_t size = 1 + ((SEGMENT.intensity * SEGLEN) >> 10); uint16_t b = a + size; //"trail" of chase, filled with color1 if (b > SEGLEN) b -= SEGLEN; @@ -1061,7 +1071,7 @@ uint16_t mode_chase_flash_random(void) { SEGENV.aux1 = (SEGENV.aux1 + 1) % SEGLEN; if (SEGENV.aux1 == 0) { - SEGENV.aux0 = SEGMENT.get_random_wheel_index(SEGENV.aux0); + SEGENV.aux0 = get_random_wheel_index(SEGENV.aux0); } } return delay; @@ -1116,8 +1126,9 @@ static const char _data_FX_MODE_RUNNING_RANDOM[] PROGMEM = "Stream@!,Zone size;; uint16_t larson_scanner(bool dual) { + if (SEGLEN == 1) return mode_static(); uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); - uint16_t index = counter * SEGLEN >> 16; + uint16_t index = (counter * SEGLEN) >> 16; SEGMENT.fade_out(SEGMENT.intensity); @@ -1204,7 +1215,6 @@ uint16_t mode_fireworks() { const uint16_t height = SEGMENT.virtualHeight(); if (SEGENV.call == 0) { - SEGMENT.fill(SEGCOLOR(1)); SEGENV.aux0 = UINT16_MAX; SEGENV.aux1 = UINT16_MAX; } @@ -1220,7 +1230,7 @@ uint16_t mode_fireworks() { if (valid1) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv1); else SEGMENT.setPixelColor(SEGENV.aux0, sv1); } // restore spark color after blur if (valid2) { if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(x, y, sv2); else SEGMENT.setPixelColor(SEGENV.aux1, sv2); } // restore old spark color after blur - for (int i=0; i> 1)) == 0) { uint16_t index = random16(width*height); x = index % width; @@ -1305,24 +1315,23 @@ static const char _data_FX_MODE_FIRE_FLICKER[] PROGMEM = "Fire Flicker@!,!;!;!;0 * Gradient run base function */ uint16_t gradient_base(bool loading) { + if (SEGLEN == 1) return mode_static(); uint16_t counter = strip.now * ((SEGMENT.speed >> 2) + 1); - uint16_t pp = counter * SEGLEN >> 16; + uint16_t pp = (counter * SEGLEN) >> 16; if (SEGENV.call == 0) pp = 0; - float val; //0.0 = sec 1.0 = pri - float brd = loading ? SEGMENT.intensity : SEGMENT.intensity/2; - if (brd <1.0) brd = 1.0; + int val; //0 = sec 1 = pri + int brd = 1 + loading ? SEGMENT.intensity/2 : SEGMENT.intensity/4; + //if (brd < 1) brd = 1; int p1 = pp-SEGLEN; int p2 = pp+SEGLEN; - for (int i = 0; i < SEGLEN; i++) - { - if (loading) - { - val = abs(((i>pp) ? p2:pp) -i); + for (int i = 0; i < SEGLEN; i++) { + if (loading) { + val = abs(((i>pp) ? p2:pp) - i); } else { - val = MIN(abs(pp-i),MIN(abs(p1-i),abs(p2-i))); + val = min(abs(pp-i),min(abs(p1-i),abs(p2-i))); } - val = (brd > val) ? val/brd * 255 : 255; + val = (brd > val) ? (val * 255) / brd : 255; SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(0), SEGMENT.color_from_palette(i, true, PALETTE_SOLID_WRAP, 1), val)); } @@ -1705,7 +1714,7 @@ uint16_t mode_multi_comet(void) { } comets[i]++; } else { - if(!random(SEGLEN)) { + if(!random16(SEGLEN)) { comets[i] = 0; } } @@ -1903,12 +1912,8 @@ static const char _data_FX_MODE_PRIDE_2015[] PROGMEM = "Pride 2015@!;;"; //eight colored dots, weaving in and out of sync with each other uint16_t mode_juggle(void) { if (SEGLEN == 1) return mode_static(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } SEGMENT.fadeToBlackBy(192 - (3*SEGMENT.intensity/4)); - CRGB fastled_col; byte dothue = 0; for (int i = 0; i < 8; i++) { @@ -1985,7 +1990,7 @@ uint16_t mode_fire_2012() { // Step 1. Cool down every cell a little for (int i = 0; i < SEGLEN; i++) { - uint8_t cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random(4); + uint8_t cool = (it != SEGENV.step) ? random8((((20 + SEGMENT.speed/3) * 16) / SEGLEN)+2) : random8(4); uint8_t minTemp = (i28 ? 8 + (SEGMENT.speed>>2) : 68-strip.getBrightness(); fract8 fadeDownAmount = strip.getBrightness()>28 ? 8 + (SEGMENT.speed>>3) : 68-strip.getBrightness(); - for (uint16_t i = 0; i < SEGLEN; i++) { + for (int i = 0; i < SEGLEN; i++) { fastled_col = SEGMENT.getPixelColor(i); prev = fastled_col; uint16_t index = i >> 3; @@ -2222,9 +2224,9 @@ uint16_t mode_colortwinkle() { } } - for (uint16_t j = 0; j <= SEGLEN / 50; j++) { + for (unsigned j = 0; j <= SEGLEN / 50; j++) { if (random8() <= SEGMENT.intensity) { - for (uint8_t times = 0; times < 5; times++) { //attempt to spawn a new pixel 5 times + for (unsigned times = 0; times < 5; times++) { //attempt to spawn a new pixel 5 times int i = random16(SEGLEN); if (SEGMENT.getPixelColor(i) == 0) { fastled_col = ColorFromPalette(SEGPALETTE, random8(), 64, NOBLEND); @@ -2273,33 +2275,35 @@ uint16_t mode_meteor() { byte* trail = SEGENV.data; - byte meteorSize= 1+ SEGLEN / 10; + const unsigned meteorSize= 1 + SEGLEN / 20; // 5% uint16_t counter = strip.now * ((SEGMENT.speed >> 2) +8); uint16_t in = counter * SEGLEN >> 16; + const int max = SEGMENT.palette==5 || !SEGMENT.check1 ? 240 : 255; // fade all leds to colors[1] in LEDs one step for (int i = 0; i < SEGLEN; i++) { - if (random8() <= 255 - SEGMENT.intensity) - { - byte meteorTrailDecay = 128 + random8(127); + if (random8() <= 255 - SEGMENT.intensity) { + byte meteorTrailDecay = 162 + random8(92); trail[i] = scale8(trail[i], meteorTrailDecay); - SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, false, 0, trail[i])); + uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(i, true, false, 0, trail[i]) : SEGMENT.color_from_palette(trail[i], false, true, 255); + SEGMENT.setPixelColor(i, col); } } // draw meteor - for (int j = 0; j < meteorSize; j++) { + for (unsigned j = 0; j < meteorSize; j++) { uint16_t index = in + j; if (index >= SEGLEN) { index -= SEGLEN; } - trail[index] = 240; - SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(index, true, false, 0, 255)); + trail[index] = max; + uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(index, true, false, 0, trail[index]) : SEGMENT.color_from_palette(trail[index], false, true, 255); + SEGMENT.setPixelColor(index, col); } return FRAMETIME; } -static const char _data_FX_MODE_METEOR[] PROGMEM = "Meteor@!,Trail length;!;!"; +static const char _data_FX_MODE_METEOR[] PROGMEM = "Meteor@!,Trail,,,,Gradient;;!;1"; // smooth meteor effect @@ -2311,35 +2315,35 @@ uint16_t mode_meteor_smooth() { byte* trail = SEGENV.data; - byte meteorSize= 1+ SEGLEN / 10; + const unsigned meteorSize= 1+ SEGLEN / 20; // 5% uint16_t in = map((SEGENV.step >> 6 & 0xFF), 0, 255, 0, SEGLEN -1); + const int max = SEGMENT.palette==5 || !SEGMENT.check1 ? 240 : 255; // fade all leds to colors[1] in LEDs one step for (int i = 0; i < SEGLEN; i++) { - if (trail[i] != 0 && random8() <= 255 - SEGMENT.intensity) - { - int change = 3 - random8(12); //change each time between -8 and +3 - trail[i] += change; - if (trail[i] > 245) trail[i] = 0; - if (trail[i] > 240) trail[i] = 240; - SEGMENT.setPixelColor(i, SEGMENT.color_from_palette(i, true, false, 0, trail[i])); + if (/*trail[i] != 0 &&*/ random8() <= 255 - SEGMENT.intensity) { + int change = trail[i] + 4 - random8(24); //change each time between -20 and +4 + trail[i] = constrain(change, 0, max); + uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(i, true, false, 0, trail[i]) : SEGMENT.color_from_palette(trail[i], false, true, 255); + SEGMENT.setPixelColor(i, col); } } // draw meteor - for (int j = 0; j < meteorSize; j++) { + for (unsigned j = 0; j < meteorSize; j++) { uint16_t index = in + j; if (index >= SEGLEN) { index -= SEGLEN; } - trail[index] = 240; - SEGMENT.setPixelColor(index, SEGMENT.color_from_palette(index, true, false, 0, 255)); + trail[index] = max; + uint32_t col = SEGMENT.check1 ? SEGMENT.color_from_palette(index, true, false, 0, trail[index]) : SEGMENT.color_from_palette(trail[index], false, true, 255); + SEGMENT.setPixelColor(index, col); } SEGENV.step += SEGMENT.speed +1; return FRAMETIME; } -static const char _data_FX_MODE_METEOR_SMOOTH[] PROGMEM = "Meteor Smooth@!,Trail length;!;!"; +static const char _data_FX_MODE_METEOR_SMOOTH[] PROGMEM = "Meteor Smooth@!,Trail,,,,Gradient;;!;1"; //Railway Crossing / Christmas Fairy lights @@ -2413,9 +2417,10 @@ uint16_t ripple_base() #ifndef WLED_DISABLE_2D if (SEGMENT.is2D()) { + propI /= 2; uint16_t cx = rippleorigin >> 8; uint16_t cy = rippleorigin & 0xFF; - uint8_t mag = scale8(cubicwave8((propF>>2)), amp); + uint8_t mag = scale8(sin8((propF>>2)), amp); if (propI > 0) SEGMENT.draw_circle(cx, cy, propI, color_blend(SEGMENT.getPixelColorXY(cx + propI, cy), col, mag)); } else #endif @@ -2431,7 +2436,7 @@ uint16_t ripple_base() ripplestate += rippledecay; ripples[i].state = (ripplestate > 254) ? 0 : ripplestate; } else {//randomly create new wave - if (random16(IBN + 10000) <= SEGMENT.intensity) { + if (random16(IBN + 10000) <= (SEGMENT.intensity >> (SEGMENT.is2D()*3))) { ripples[i].state = 1; ripples[i].pos = SEGMENT.is2D() ? ((random8(SEGENV.virtualWidth())<<8) | (random8(SEGENV.virtualHeight()))) : random16(SEGLEN); ripples[i].color = random8(); //color @@ -2447,6 +2452,7 @@ uint16_t ripple_base() uint16_t mode_ripple(void) { if (SEGLEN == 1) return mode_static(); if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); + else SEGMENT.fade_out(250); return ripple_base(); } static const char _data_FX_MODE_RIPPLE[] PROGMEM = "Ripple@!,Wave #,,,,,Overlay;,!;!;12"; @@ -2475,12 +2481,6 @@ static const char _data_FX_MODE_RIPPLE_RAINBOW[] PROGMEM = "Ripple Rainbow@!,Wav // // TwinkleFOX: Twinkling 'holiday' lights that fade in and out. // Colors are chosen from a palette. Read more about this effect using the link above! - -// If COOL_LIKE_INCANDESCENT is set to 1, colors will -// fade out slighted 'reddened', similar to how -// incandescent bulbs change color as they get dim down. -#define COOL_LIKE_INCANDESCENT 1 - CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) { // Overall twinkle speed (changed) @@ -2519,7 +2519,7 @@ CRGB twinklefox_one_twinkle(uint32_t ms, uint8_t salt, bool cat) CRGB c; if (bright > 0) { c = ColorFromPalette(SEGPALETTE, hue, bright, NOBLEND); - if(COOL_LIKE_INCANDESCENT == 1) { + if (!SEGMENT.check1) { // This code takes a pixel, and if its in the 'fading down' // part of the cycle, it adjusts the color a little bit like the // way that incandescent bulbs fade toward 'red' as they dim. @@ -2605,19 +2605,38 @@ uint16_t mode_twinklefox() { return twinklefox_base(false); } -static const char _data_FX_MODE_TWINKLEFOX[] PROGMEM = "Twinklefox@!,Twinkle rate;;!"; +static const char _data_FX_MODE_TWINKLEFOX[] PROGMEM = "Twinklefox@!,Twinkle rate,,,,Cool;!,!;!"; uint16_t mode_twinklecat() { return twinklefox_base(true); } -static const char _data_FX_MODE_TWINKLECAT[] PROGMEM = "Twinklecat@!,Twinkle rate;;!"; +static const char _data_FX_MODE_TWINKLECAT[] PROGMEM = "Twinklecat@!,Twinkle rate,,,,Cool;!,!;!"; -//inspired by https://www.tweaking4all.com/hardware/arduino/adruino-led-strip-effects/#LEDStripEffectBlinkingHalloweenEyes uint16_t mode_halloween_eyes() { + enum eyeState : uint8_t { + initializeOn = 0, + on, + blink, + initializeOff, + off, + + count + }; + struct EyeData { + eyeState state; + uint8_t color; + uint16_t startPos; + // duration + endTime could theoretically be replaced by a single endTime, however we would lose + // the ability to end the animation early when the user reduces the animation time. + uint16_t duration; + uint32_t startTime; + uint32_t blinkEndTime; + }; + if (SEGLEN == 1) return mode_static(); const uint16_t maxWidth = strip.isMatrix ? SEGMENT.virtualWidth() : SEGLEN; const uint16_t HALLOWEEN_EYE_SPACE = MAX(2, strip.isMatrix ? SEGMENT.virtualWidth()>>4: SEGLEN>>5); @@ -2625,57 +2644,132 @@ uint16_t mode_halloween_eyes() uint16_t eyeLength = (2*HALLOWEEN_EYE_WIDTH) + HALLOWEEN_EYE_SPACE; if (eyeLength >= maxWidth) return mode_static(); //bail if segment too short + if (!SEGENV.allocateData(sizeof(EyeData))) return mode_static(); //allocation failed + EyeData& data = *reinterpret_cast(SEGENV.data); + if (!SEGMENT.check2) SEGMENT.fill(SEGCOLOR(1)); //fill background - uint8_t state = SEGENV.aux1 >> 8; - uint16_t stateTime = SEGENV.call; - if (stateTime == 0) stateTime = 2000; + data.state = static_cast(data.state % eyeState::count); + uint16_t duration = max(uint16_t{1u}, data.duration); + const uint32_t elapsedTime = strip.now - data.startTime; - if (state == 0) { //spawn eyes - SEGENV.aux0 = random16(0, maxWidth - eyeLength - 1); //start pos - SEGENV.aux1 = random8(); //color - if (strip.isMatrix) SEGMENT.offset = random16(SEGMENT.virtualHeight()-1); // a hack: reuse offset since it is not used in matrices - state = 1; - } + switch (data.state) { + case eyeState::initializeOn: { + // initialize the eyes-on state: + // - select eye position and color + // - select a duration + // - immediately switch to eyes on state. - if (state < 2) { //fade eyes - uint16_t startPos = SEGENV.aux0; - uint16_t start2ndEye = startPos + HALLOWEEN_EYE_WIDTH + HALLOWEEN_EYE_SPACE; + data.startPos = random16(0, maxWidth - eyeLength - 1); + data.color = random8(); + if (strip.isMatrix) SEGMENT.offset = random16(SEGMENT.virtualHeight()-1); // a hack: reuse offset since it is not used in matrices + duration = 128u + random16(SEGMENT.intensity*64u); + data.duration = duration; + data.state = eyeState::on; + [[fallthrough]]; + } + case eyeState::on: { + // eyes-on steate: + // - fade eyes in for some time + // - keep eyes on until the pre-selected duration is over + // - randomly switch to the blink (sub-)state, and initialize it with a blink duration (more precisely, a blink end time stamp) + // - never switch to the blink state if the animation just started or is about to end - uint32_t fadestage = (strip.now - SEGENV.step)*255 / stateTime; - if (fadestage > 255) fadestage = 255; - uint32_t c = color_blend(SEGMENT.color_from_palette(SEGENV.aux1 & 0xFF, false, false, 0), SEGCOLOR(1), fadestage); + uint16_t start2ndEye = data.startPos + HALLOWEEN_EYE_WIDTH + HALLOWEEN_EYE_SPACE; + // If the user reduces the input while in this state, limit the duration. + duration = min(duration, static_cast(128u + (SEGMENT.intensity * 64u))); - for (int i = 0; i < HALLOWEEN_EYE_WIDTH; i++) { - if (strip.isMatrix) { - SEGMENT.setPixelColorXY(startPos + i, SEGMENT.offset, c); - SEGMENT.setPixelColorXY(start2ndEye + i, SEGMENT.offset, c); - } else { - SEGMENT.setPixelColor(startPos + i, c); - SEGMENT.setPixelColor(start2ndEye + i, c); + constexpr uint32_t minimumOnTimeBegin = 1024u; + constexpr uint32_t minimumOnTimeEnd = 1024u; + const uint32_t fadeInAnimationState = elapsedTime * uint32_t{256u * 8u} / duration; + const uint32_t backgroundColor = SEGCOLOR(1); + const uint32_t eyeColor = SEGMENT.color_from_palette(data.color, false, false, 0); + uint32_t c = eyeColor; + if (fadeInAnimationState < 256u) { + c = color_blend(backgroundColor, eyeColor, fadeInAnimationState); + } else if (elapsedTime > minimumOnTimeBegin) { + const uint32_t remainingTime = (elapsedTime >= duration) ? 0u : (duration - elapsedTime); + if (remainingTime > minimumOnTimeEnd) { + if (random8() < 4u) + { + c = backgroundColor; + data.state = eyeState::blink; + data.blinkEndTime = strip.now + random8(8, 128); + } + } } + + if (c != backgroundColor) { + // render eyes + for (int i = 0; i < HALLOWEEN_EYE_WIDTH; i++) { + if (strip.isMatrix) { + SEGMENT.setPixelColorXY(data.startPos + i, SEGMENT.offset, c); + SEGMENT.setPixelColorXY(start2ndEye + i, SEGMENT.offset, c); + } else { + SEGMENT.setPixelColor(data.startPos + i, c); + SEGMENT.setPixelColor(start2ndEye + i, c); + } + } + } + break; + } + case eyeState::blink: { + // eyes-on but currently blinking state: + // - wait until the blink time is over, then switch back to eyes-on + + if (strip.now >= data.blinkEndTime) { + data.state = eyeState::on; + } + break; + } + case eyeState::initializeOff: { + // initialize eyes-off state: + // - select a duration + // - immediately switch to eyes-off state + + const uint16_t eyeOffTimeBase = SEGMENT.speed*128u; + duration = eyeOffTimeBase + random16(eyeOffTimeBase); + data.duration = duration; + data.state = eyeState::off; + [[fallthrough]]; + } + case eyeState::off: { + // eyes-off state: + // - not much to do here + + // If the user reduces the input while in this state, limit the duration. + const uint16_t eyeOffTimeBase = SEGMENT.speed*128u; + duration = min(duration, static_cast(2u * eyeOffTimeBase)); + break; + } + case eyeState::count: { + // Can't happen, not an actual state. + data.state = eyeState::initializeOn; + break; } } - if (strip.now - SEGENV.step > stateTime) { - state++; - if (state > 2) state = 0; - - if (state < 2) { - stateTime = 100 + SEGMENT.intensity*10; //eye fade time - } else { - uint16_t eyeOffTimeBase = (256 - SEGMENT.speed)*10; - stateTime = eyeOffTimeBase + random16(eyeOffTimeBase); + if (elapsedTime > duration) { + // The current state duration is over, switch to the next state. + switch (data.state) { + case eyeState::initializeOn: + case eyeState::on: + case eyeState::blink: + data.state = eyeState::initializeOff; + break; + case eyeState::initializeOff: + case eyeState::off: + case eyeState::count: + default: + data.state = eyeState::initializeOn; + break; } - SEGENV.step = strip.now; - SEGENV.call = stateTime; + data.startTime = strip.now; } - SEGENV.aux1 = (SEGENV.aux1 & 0xFF) + (state << 8); //save state - return FRAMETIME; } -static const char _data_FX_MODE_HALLOWEEN_EYES[] PROGMEM = "Halloween Eyes@Duration,Eye fade time,,,,,Overlay;!,!;!;12"; +static const char _data_FX_MODE_HALLOWEEN_EYES[] PROGMEM = "Halloween Eyes@Eye off time,Eye on time,,,,,Overlay;!,!;!;12"; //Speed slider sets amount of LEDs lit, intensity sets unlit @@ -2853,6 +2947,107 @@ uint16_t mode_bouncing_balls(void) { static const char _data_FX_MODE_BOUNCINGBALLS[] PROGMEM = "Bouncing Balls@Gravity,# of balls,,,,,Overlay;!,!,!;!;1;m12=1"; //bar +/* + * bouncing balls on a track track Effect modified from Aircoookie's bouncing balls + * Courtesy of pjhatch (https://github.com/pjhatch) + * https://github.com/Aircoookie/WLED/pull/1039 + */ +// modified for balltrack mode +typedef struct RollingBall { + unsigned long lastBounceUpdate; + float mass; // could fix this to be = 1. if memory is an issue + float velocity; + float height; +} rball_t; + +static uint16_t rolling_balls(void) { + //allocate segment data + const uint16_t maxNumBalls = 16; // 255/16 + 1 + uint16_t dataSize = sizeof(rball_t) * maxNumBalls; + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + + rball_t *balls = reinterpret_cast(SEGENV.data); + + // number of balls based on intensity setting to max of 16 (cycles colors) + // non-chosen color is a random color + uint8_t numBalls = SEGMENT.intensity/16 + 1; + bool hasCol2 = SEGCOLOR(2); + + if (SEGENV.call == 0) { + SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); // start clean + for (int i = 0; i < maxNumBalls; i++) { + balls[i].lastBounceUpdate = strip.now; + balls[i].velocity = 20.0f * float(random16(1000, 10000))/10000.0f; // number from 1 to 10 + if (random8()<128) balls[i].velocity = -balls[i].velocity; // 50% chance of reverse direction + balls[i].height = (float(random16(0, 10000)) / 10000.0f); // from 0. to 1. + balls[i].mass = (float(random16(1000, 10000)) / 10000.0f); // from .1 to 1. + } + } + + float cfac = float(scale8(8, 255-SEGMENT.speed) +1)*20000.0f; // this uses the Aircoookie conversion factor for scaling time using speed slider + + if (SEGMENT.check3) SEGMENT.fade_out(250); // 2-8 pixel trails (optional) + else { + if (!SEGMENT.check2) SEGMENT.fill(hasCol2 ? BLACK : SEGCOLOR(1)); // don't fill with background color if user wants to see trails + } + + for (int i = 0; i < numBalls; i++) { + float timeSinceLastUpdate = float((strip.now - balls[i].lastBounceUpdate))/cfac; + float thisHeight = balls[i].height + balls[i].velocity * timeSinceLastUpdate; // this method keeps higher resolution + // test if intensity level was increased and some balls are way off the track then put them back + if (thisHeight < -0.5f || thisHeight > 1.5f) { + thisHeight = balls[i].height = (float(random16(0, 10000)) / 10000.0f); // from 0. to 1. + balls[i].lastBounceUpdate = strip.now; + } + // check if reached ends of the strip + if ((thisHeight <= 0.0f && balls[i].velocity < 0.0f) || (thisHeight >= 1.0f && balls[i].velocity > 0.0f)) { + balls[i].velocity = -balls[i].velocity; // reverse velocity + balls[i].lastBounceUpdate = strip.now; + balls[i].height = thisHeight; + } + // check for collisions + if (SEGMENT.check1) { + for (int j = i+1; j < numBalls; j++) { + if (balls[j].velocity != balls[i].velocity) { + // tcollided + balls[j].lastBounceUpdate is acutal time of collision (this keeps precision with long to float conversions) + float tcollided = (cfac*(balls[i].height - balls[j].height) + + balls[i].velocity*float(balls[j].lastBounceUpdate - balls[i].lastBounceUpdate))/(balls[j].velocity - balls[i].velocity); + + if ((tcollided > 2.0f) && (tcollided < float(strip.now - balls[j].lastBounceUpdate))) { // 2ms minimum to avoid duplicate bounces + balls[i].height = balls[i].height + balls[i].velocity*(tcollided + float(balls[j].lastBounceUpdate - balls[i].lastBounceUpdate))/cfac; + balls[j].height = balls[i].height; + balls[i].lastBounceUpdate = (unsigned long)(tcollided + 0.5f) + balls[j].lastBounceUpdate; + balls[j].lastBounceUpdate = balls[i].lastBounceUpdate; + float vtmp = balls[i].velocity; + balls[i].velocity = ((balls[i].mass - balls[j].mass)*vtmp + 2.0f*balls[j].mass*balls[j].velocity)/(balls[i].mass + balls[j].mass); + balls[j].velocity = ((balls[j].mass - balls[i].mass)*balls[j].velocity + 2.0f*balls[i].mass*vtmp) /(balls[i].mass + balls[j].mass); + thisHeight = balls[i].height + balls[i].velocity*(strip.now - balls[i].lastBounceUpdate)/cfac; + } + } + } + } + + uint32_t color = SEGCOLOR(0); + if (SEGMENT.palette) { + //color = SEGMENT.color_wheel(i*(256/MAX(numBalls, 8))); + color = SEGMENT.color_from_palette(i*255/numBalls, false, PALETTE_SOLID_WRAP, 0); + } else if (hasCol2) { + color = SEGCOLOR(i % NUM_COLORS); + } + + if (thisHeight < 0.0f) thisHeight = 0.0f; + if (thisHeight > 1.0f) thisHeight = 1.0f; + uint16_t pos = round(thisHeight * (SEGLEN - 1)); + SEGMENT.setPixelColor(pos, color); + balls[i].lastBounceUpdate = strip.now; + balls[i].height = thisHeight; + } + + return FRAMETIME; +} +static const char _data_FX_MODE_ROLLINGBALLS[] PROGMEM = "Rolling Balls@!,# of balls,,,,Collisions,Overlay,Trails;!,!,!;!;1;m12=1"; //bar + + /* * Sinelon stolen from FASTLED examples */ @@ -2930,7 +3125,7 @@ uint16_t mode_glitter() static const char _data_FX_MODE_GLITTER[] PROGMEM = "Glitter@!,!,,,,,Overlay;1,2,Glitter color;!;;pal=0,m12=0"; //pixels -//Solid colour background with glitter +//Solid colour background with glitter (can be replaced by Glitter) uint16_t mode_solid_glitter() { SEGMENT.fill(SEGCOLOR(0)); @@ -3020,10 +3215,9 @@ static const char _data_FX_MODE_POPCORN[] PROGMEM = "Popcorn@!,!,,,,,Overlay;!,! uint16_t candle(bool multi) { - if (multi) - { + if (multi && SEGLEN > 1) { //allocate segment data - uint16_t dataSize = (SEGLEN -1) *3; //max. 1365 pixels (ESP8266) + uint16_t dataSize = max(1, SEGLEN -1) *3; //max. 1365 pixels (ESP8266) if (!SEGENV.allocateData(dataSize)) return candle(false); //allocation failed } @@ -3156,7 +3350,7 @@ uint16_t mode_starburst(void) { if (random8((144-(SEGMENT.speed >> 1))) == 0 && stars[j].birth == 0) { // Pick a random color and location. - uint16_t startPos = random16(SEGLEN-1); + uint16_t startPos = (SEGLEN > 1) ? random16(SEGLEN-1) : 0; float multiplier = (float)(random8())/255.0 * 1.0; stars[j].color = CRGB(SEGMENT.color_wheel(random8())); @@ -3250,8 +3444,8 @@ static const char _data_FX_MODE_STARBURST[] PROGMEM = "Fireworks Starburst@Chanc uint16_t mode_exploding_fireworks(void) { if (SEGLEN == 1) return mode_static(); - const uint16_t cols = strip.isMatrix ? SEGMENT.virtualWidth() : 1; - const uint16_t rows = strip.isMatrix ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); + const uint16_t cols = SEGMENT.is2D() ? SEGMENT.virtualWidth() : 1; + const uint16_t rows = SEGMENT.is2D() ? SEGMENT.virtualHeight() : SEGMENT.virtualLength(); //allocate segment data uint16_t maxData = FAIR_DATA_PER_SEG; //ESP8266: 256 ESP32: 640 @@ -3282,11 +3476,11 @@ uint16_t mode_exploding_fireworks(void) if (SEGENV.aux0 < 2) { //FLARE if (SEGENV.aux0 == 0) { //init flare flare->pos = 0; - flare->posX = strip.isMatrix ? random16(2,cols-3) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D + flare->posX = SEGMENT.is2D() ? random16(2,cols-3) : (SEGMENT.intensity > random8()); // will enable random firing side on 1D uint16_t peakHeight = 75 + random8(180); //0-255 peakHeight = (peakHeight * (rows -1)) >> 8; flare->vel = sqrtf(-2.0f * gravity * peakHeight); - flare->velX = strip.isMatrix ? (random8(9)-4)/32.f : 0; // no X velocity on 1D + flare->velX = SEGMENT.is2D() ? (random8(9)-4)/64.0f : 0; // no X velocity on 1D flare->col = 255; //brightness SEGENV.aux0 = 1; } @@ -3294,12 +3488,14 @@ uint16_t mode_exploding_fireworks(void) // launch if (flare->vel > 12 * gravity) { // flare - if (strip.isMatrix) SEGMENT.setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col); - else SEGMENT.setPixelColor(int(flare->posX) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col); + if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(int(flare->posX), rows - uint16_t(flare->pos) - 1, flare->col, flare->col, flare->col); + else SEGMENT.setPixelColor((flare->posX > 0.0f) ? rows - int(flare->pos) - 1 : int(flare->pos), flare->col, flare->col, flare->col); flare->pos += flare->vel; - flare->posX += flare->velX; flare->pos = constrain(flare->pos, 0, rows-1); - flare->posX = constrain(flare->posX, 0, cols-strip.isMatrix); + if (SEGMENT.is2D()) { + flare->posX += flare->velX; + flare->posX = constrain(flare->posX, 0, cols-1); + } flare->vel += gravity; flare->col -= 2; } else { @@ -3322,12 +3518,12 @@ uint16_t mode_exploding_fireworks(void) sparks[i].posX = flare->posX; sparks[i].vel = (float(random16(20001)) / 10000.0f) - 0.9f; // from -0.9 to 1.1 sparks[i].vel *= rows<32 ? 0.5f : 1; // reduce velocity for smaller strips - sparks[i].velX = strip.isMatrix ? (float(random16(10001)) / 10000.0f) - 0.5f : 0; // from -0.5 to 0.5 + sparks[i].velX = SEGMENT.is2D() ? (float(random16(20001)) / 10000.0f) - 1.0f : 0; // from -1 to 1 sparks[i].col = 345;//abs(sparks[i].vel * 750.0); // set colors before scaling velocity to keep them bright //sparks[i].col = constrain(sparks[i].col, 0, 345); sparks[i].colIndex = random8(); sparks[i].vel *= flare->pos/rows; // proportional to height - sparks[i].velX *= strip.isMatrix ? flare->posX/cols : 0; // proportional to width + sparks[i].velX *= SEGMENT.is2D() ? flare->posX/cols : 0; // proportional to width sparks[i].vel *= -gravity *50; } //sparks[1].col = 345; // this will be our known spark @@ -3340,11 +3536,11 @@ uint16_t mode_exploding_fireworks(void) sparks[i].pos += sparks[i].vel; sparks[i].posX += sparks[i].velX; sparks[i].vel += *dying_gravity; - sparks[i].velX += strip.isMatrix ? *dying_gravity : 0; + sparks[i].velX += SEGMENT.is2D() ? *dying_gravity : 0; if (sparks[i].col > 3) sparks[i].col -= 4; if (sparks[i].pos > 0 && sparks[i].pos < rows) { - if (strip.isMatrix && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue; + if (SEGMENT.is2D() && !(sparks[i].posX >= 0 && sparks[i].posX < cols)) continue; uint16_t prog = sparks[i].col; uint32_t spColor = (SEGMENT.palette) ? SEGMENT.color_wheel(sparks[i].colIndex) : SEGCOLOR(0); CRGB c = CRGB::Black; //HeatColor(sparks[i].col); @@ -3356,7 +3552,7 @@ uint16_t mode_exploding_fireworks(void) c.g = qsub8(c.g, cooling); c.b = qsub8(c.b, cooling * 2); } - if (strip.isMatrix) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue); + if (SEGMENT.is2D()) SEGMENT.setPixelColorXY(int(sparks[i].posX), rows - int(sparks[i].pos) - 1, c.red, c.green, c.blue); else SEGMENT.setPixelColor(int(sparks[i].posX) ? rows - int(sparks[i].pos) - 1 : int(sparks[i].pos), c.red, c.green, c.blue); } } @@ -3400,7 +3596,7 @@ uint16_t mode_drip(void) uint8_t numDrops = 1 + (SEGMENT.intensity >> 6); // 255>>6 = 3 float gravity = -0.0005 - (SEGMENT.speed/50000.0); - gravity *= SEGLEN-1; + gravity *= max(1, SEGLEN-1); int sourcedrop = 12; for (int j=0;j> 11)); if (SEGMENT.speed == 255) size = 255; @@ -3881,6 +4077,7 @@ static const char _data_FX_MODE_PHASEDNOISE[] PROGMEM = "Phased Noise@!,!;!,!;!" uint16_t mode_twinkleup(void) { // A very short twinkle routine with fade-in and dual controls. By Andrew Tuline. + uint16_t prevSeed = random16_get_seed(); // save seed so we can restore it at the end of the function random16_set_seed(535); // The randomizer needs to be re-set each time through the loop in order for the same 'random' numbers to be the same each time through. for (int i = 0; i < SEGLEN; i++) { @@ -3890,6 +4087,7 @@ uint16_t mode_twinkleup(void) { // A very short twinkle routine SEGMENT.setPixelColor(i, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(random8()+strip.now/100, false, PALETTE_SOLID_WRAP, 0), pixBri)); } + random16_set_seed(prevSeed); // restore original seed so other effects can use "random" PRNG return FRAMETIME; } static const char _data_FX_MODE_TWINKLEUP[] PROGMEM = "Twinkleup@!,Intensity;!,!;!;;m12=0"; @@ -4382,15 +4580,15 @@ class AuroraWave { public: void init(uint32_t segment_length, CRGB color) { - ttl = random(500, 1501); + ttl = random16(500, 1501); basecolor = color; - basealpha = random(60, 101) / (float)100; + basealpha = random8(60, 101) / (float)100; age = 0; - width = random(segment_length / 20, segment_length / W_WIDTH_FACTOR); //half of width to make math easier + width = random16(segment_length / 20, segment_length / W_WIDTH_FACTOR); //half of width to make math easier if (!width) width = 1; - center = random(101) / (float)100 * segment_length; - goingleft = random(0, 2) == 0; - speed_factor = (random(10, 31) / (float)100 * W_MAX_SPEED / 255); + center = random8(101) / (float)100 * segment_length; + goingleft = random8(0, 2) == 0; + speed_factor = (random8(10, 31) / (float)100 * W_MAX_SPEED / 255); alive = true; } @@ -4475,7 +4673,7 @@ uint16_t mode_aurora(void) { waves = reinterpret_cast(SEGENV.data); for (int i = 0; i < SEGENV.aux1; i++) { - waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random(0, 3)))); + waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random8(0, 3)))); } } else { waves = reinterpret_cast(SEGENV.data); @@ -4487,7 +4685,7 @@ uint16_t mode_aurora(void) { if(!(waves[i].stillAlive())) { //If a wave dies, reinitialize it starts over. - waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random(0, 3)))); + waves[i].init(SEGLEN, CRGB(SEGMENT.color_from_palette(random8(), false, false, random8(0, 3)))); } } @@ -4586,17 +4784,12 @@ static const char _data_FX_MODE_FLOWSTRIPE[] PROGMEM = "Flow Stripe@Hue speed,Ef // Black hole uint16_t mode_2DBlackHole(void) { // By: Stepko https://editor.soulmatelights.com/gallery/1012 , Modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); uint16_t x, y; - // initialize on first call - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - SEGMENT.fadeToBlackBy(16 + (SEGMENT.speed>>3)); // create fading trails unsigned long t = millis()/128; // timebase // outer stars @@ -4625,13 +4818,12 @@ static const char _data_FX_MODE_2DBLACKHOLE[] PROGMEM = "Black Hole@Fade rate,Ou // 2D Colored Bursts // //////////////////////////// uint16_t mode_2DColoredBursts() { // By: ldirko https://editor.soulmatelights.com/gallery/819-colored-bursts , modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); SEGENV.aux0 = 0; // start with red hue } @@ -4678,17 +4870,12 @@ static const char _data_FX_MODE_2DCOLOREDBURSTS[] PROGMEM = "Colored Bursts@Spee // 2D DNA // ///////////////////// uint16_t mode_2Ddna(void) { // dna originally by by ldirko at https://pastebin.com/pCkkkzcs. Updated by Preyy. WLED conversion by Andrew Tuline. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - SEGMENT.fadeToBlackBy(64); - for (int i = 0; i < cols; i++) { SEGMENT.setPixelColorXY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4 ), ColorFromPalette(SEGPALETTE, i*5+millis()/17, beatsin8(5, 55, 255, 0, i*10), LINEARBLEND)); SEGMENT.setPixelColorXY(i, beatsin8(SEGMENT.speed/8, 0, rows-1, 0, i*4+128), ColorFromPalette(SEGPALETTE, i*5+128+millis()/17, beatsin8(5, 55, 255, 0, i*10+128), LINEARBLEND)); @@ -4704,7 +4891,7 @@ static const char _data_FX_MODE_2DDNA[] PROGMEM = "DNA@Scroll speed,Blur;;!;2"; // 2D DNA Spiral // ///////////////////////// uint16_t mode_2DDNASpiral() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4749,17 +4936,12 @@ static const char _data_FX_MODE_2DDNASPIRAL[] PROGMEM = "DNA Spiral@Scroll speed // 2D Drift // ///////////////////////// uint16_t mode_2DDrift() { // By: Stepko https://editor.soulmatelights.com/gallery/884-drift , Modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - SEGMENT.fadeToBlackBy(128); - const uint16_t maxDim = MAX(cols, rows)/2; unsigned long t = millis() / (32 - (SEGMENT.speed>>3)); unsigned long t_20 = t/20; // softhack007: pre-calculating this gives about 10% speedup @@ -4780,7 +4962,7 @@ static const char _data_FX_MODE_2DDRIFT[] PROGMEM = "Drift@Rotation speed,Blur a // 2D Firenoise // ////////////////////////// uint16_t mode_2Dfirenoise(void) { // firenoise2d. By Andrew Tuline. Yet another short routine. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4814,15 +4996,11 @@ static const char _data_FX_MODE_2DFIRENOISE[] PROGMEM = "Firenoise@X scale,Y sca // 2D Frizzles // ////////////////////////////// uint16_t mode_2DFrizzles(void) { // By: Stepko https://editor.soulmatelights.com/gallery/640-color-frizzles , Modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - SEGMENT.fadeToBlackBy(16); for (size_t i = 8; i > 0; i--) { SEGMENT.addPixelColorXY(beatsin8(SEGMENT.speed/8 + i, 0, cols - 1), @@ -4845,7 +5023,7 @@ typedef struct ColorCount { } colorCount; uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https://natureofcode.com/book/chapter-7-cellular-automata/ and https://github.com/DougHaber/nlife-color - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4861,7 +5039,7 @@ uint16_t mode_2Dgameoflife(void) { // Written by Ewoud Wijma, inspired by https: if (SEGENV.call == 0 || strip.now - SEGMENT.step > 3000) { SEGENV.step = strip.now; SEGENV.aux0 = 0; - random16_set_seed(millis()>>2); //seed the random generator + //random16_set_seed(millis()>>2); //seed the random generator //give the leds random state and colors (based on intensity, colors from palette or all posible colors are chosen) for (int x = 0; x < cols; x++) for (int y = 0; y < rows; y++) { @@ -4951,7 +5129,7 @@ static const char _data_FX_MODE_2DGAMEOFLIFE[] PROGMEM = "Game Of Life@!;!,!;!;2 // 2D Hiphotic // ///////////////////////// uint16_t mode_2DHiphotic() { // By: ldirko https://editor.soulmatelights.com/gallery/810 , Modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -4983,7 +5161,7 @@ typedef struct Julia { } julia; uint16_t mode_2DJulia(void) { // An animated Julia set by Andrew Tuline. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5089,7 +5267,7 @@ static const char _data_FX_MODE_2DJULIA[] PROGMEM = "Julia@,Max iterations per p // 2D Lissajous // ////////////////////////////// uint16_t mode_2DLissajous(void) { // By: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5110,65 +5288,73 @@ uint16_t mode_2DLissajous(void) { // By: Andrew Tuline return FRAMETIME; } // mode_2DLissajous() -static const char _data_FX_MODE_2DLISSAJOUS[] PROGMEM = "Lissajous@X frequency,Fade rate,,,Speed;!;!;2;;c3=15"; +static const char _data_FX_MODE_2DLISSAJOUS[] PROGMEM = "Lissajous@X frequency,Fade rate,,,Speed;!;!;2;c3=15"; /////////////////////// // 2D Matrix // /////////////////////// -uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up +uint16_t mode_2Dmatrix(void) { // Matrix2D. By Jeremy Williams. Adapted by Andrew Tuline & improved by merkisoft and ewowi, and softhack007. + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); + uint16_t dataSize = (SEGMENT.length()+7) >> 3; //1 bit per LED for trails + if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed + if (SEGENV.call == 0) { SEGMENT.fill(BLACK); + SEGENV.step = 0; } uint8_t fade = map(SEGMENT.custom1, 0, 255, 50, 250); // equals trail size uint8_t speed = (256-SEGMENT.speed) >> map(MIN(rows, 150), 0, 150, 0, 3); // slower speeds for small displays - CRGB spawnColor; - CRGB trailColor; + uint32_t spawnColor; + uint32_t trailColor; if (SEGMENT.check1) { spawnColor = SEGCOLOR(0); trailColor = SEGCOLOR(1); } else { - spawnColor = CRGB(175,255,175); - trailColor = CRGB(27,130,39); + spawnColor = RGBW32(175,255,175,0); + trailColor = RGBW32(27,130,39,0); } + bool emptyScreen = true; if (strip.now - SEGENV.step >= speed) { SEGENV.step = strip.now; - for (int row=rows-1; row>=0; row--) { - for (int col=0; col= 0; row--) { + for (int col = 0; col < cols; col++) { + unsigned index = XY(col, row) >> 3; + unsigned bitNum = XY(col, row) & 0x07; + if (bitRead(SEGENV.data[index], bitNum)) { SEGMENT.setPixelColorXY(col, row, trailColor); // create trail - if (row < rows-1) SEGMENT.setPixelColorXY(col, row+1, spawnColor); - } else { - // fade other pixels - SEGMENT.setPixelColorXY(col, row, pix.nscale8(fade)); + bitClear(SEGENV.data[index], bitNum); + if (row < rows-1) { + SEGMENT.setPixelColorXY(col, row+1, spawnColor); + index = XY(col, row+1) >> 3; + bitNum = XY(col, row+1) & 0x07; + bitSet(SEGENV.data[index], bitNum); + emptyScreen = false; + } } } } - // check for empty screen to ensure code spawn - bool emptyScreen = true; - for (int x=0; x> 3; + unsigned bitNum = XY(spawnX, 0) & 0x07; + bitSet(SEGENV.data[index], bitNum); } - } // if millis + } return FRAMETIME; } // mode_2Dmatrix() @@ -5179,7 +5365,7 @@ static const char _data_FX_MODE_2DMATRIX[] PROGMEM = "Matrix@!,Spawning rate,Tra // 2D Metaballs // ///////////////////////// uint16_t mode_2Dmetaballs(void) { // Metaballs by Stefan Petrick. Cannot have one of the dimensions be 2 or less. Adapted by Andrew Tuline. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5238,7 +5424,7 @@ static const char _data_FX_MODE_2DMETABALLS[] PROGMEM = "Metaballs@!;;!;2"; // 2D Noise // ////////////////////// uint16_t mode_2Dnoise(void) { // By Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5261,17 +5447,12 @@ static const char _data_FX_MODE_2DNOISE[] PROGMEM = "Noise2D@!,Scale;;!;2"; // 2D Plasma Ball // ////////////////////////////// uint16_t mode_2DPlasmaball(void) { // By: Stepko https://editor.soulmatelights.com/gallery/659-plasm-ball , Modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - SEGMENT.fadeToBlackBy(SEGMENT.custom1>>2); - uint_fast32_t t = (millis() * 8) / (256 - SEGMENT.speed); // optimized to avoid float for (int i = 0; i < cols; i++) { uint16_t thisVal = inoise8(i * 30, t, t); @@ -5306,7 +5487,7 @@ static const char _data_FX_MODE_2DPLASMABALL[] PROGMEM = "Plasma Ball@Speed,,Fad // return (out_max - out_min) * (x - in_min) / (in_max - in_min) + out_min; //} uint16_t mode_2DPolarLights(void) { // By: Kostyantyn Matviyevskyy https://editor.soulmatelights.com/gallery/762-polar-lights , Modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5357,17 +5538,12 @@ static const char _data_FX_MODE_2DPOLARLIGHTS[] PROGMEM = "Polar Lights@!,Scale; // 2D Pulser // ///////////////////////// uint16_t mode_2DPulser(void) { // By: ldirko https://editor.soulmatelights.com/gallery/878-pulse-test , modifed by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - SEGMENT.fadeToBlackBy(8 - (SEGMENT.intensity>>5)); - uint32_t a = strip.now / (18 - SEGMENT.speed / 16); uint16_t x = (a / 14) % cols; uint16_t y = map((sin8(a * 5) + sin8(a * 4) + sin8(a * 2)), 0, 765, rows-1, 0); @@ -5384,7 +5560,7 @@ static const char _data_FX_MODE_2DPULSER[] PROGMEM = "Pulser@!,Blur;;!;2"; // 2D Sindots // ///////////////////////// uint16_t mode_2DSindots(void) { // By: ldirko https://editor.soulmatelights.com/gallery/597-sin-dots , modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5415,19 +5591,14 @@ static const char _data_FX_MODE_2DSINDOTS[] PROGMEM = "Sindots@!,Dot distance,Fa // custom3 affects the blur amount. uint16_t mode_2Dsquaredswirl(void) { // By: Mark Kriegsman. https://gist.github.com/kriegsman/368b316c55221134b160 // Modifed by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - const uint8_t kBorderWidth = 2; SEGMENT.fadeToBlackBy(24); - uint8_t blurAmount = SEGMENT.custom3>>1; // reduced resolution slider SEGMENT.blur(blurAmount); @@ -5454,7 +5625,7 @@ static const char _data_FX_MODE_2DSQUAREDSWIRL[] PROGMEM = "Squared Swirl@,,,,Bl // 2D Sun Radiation // ////////////////////////////// uint16_t mode_2DSunradiation(void) { // By: ldirko https://editor.soulmatelights.com/gallery/599-sun-radiation , modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5504,7 +5675,7 @@ static const char _data_FX_MODE_2DSUNRADIATION[] PROGMEM = "Sun Radiation@Varian // 2D Tartan // ///////////////////////// uint16_t mode_2Dtartan(void) { // By: Elliott Kember https://editor.soulmatelights.com/gallery/3-tartan , Modified by: Andrew Tuline - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5543,15 +5714,11 @@ static const char _data_FX_MODE_2DTARTAN[] PROGMEM = "Tartan@X scale,Y scale,,,S // 2D spaceships // ///////////////////////// uint16_t mode_2Dspaceships(void) { //// Space ships by stepko (c)05.02.21 [https://editor.soulmatelights.com/gallery/639-space-ships], adapted by Blaz Kristan (AKA blazoncek) - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - uint32_t tb = strip.now >> 12; // every ~4s if (tb > SEGENV.step) { int8_t dir = ++SEGENV.aux0; @@ -5590,7 +5757,7 @@ static const char _data_FX_MODE_2DSPACESHIPS[] PROGMEM = "Spaceships@!,Blur;;!;2 //// Crazy bees by stepko (c)12.02.21 [https://editor.soulmatelights.com/gallery/651-crazy-bees], adapted by Blaz Kristan (AKA blazoncek) #define MAX_BEES 5 uint16_t mode_2Dcrazybees(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5601,7 +5768,7 @@ uint16_t mode_2Dcrazybees(void) { uint8_t posX, posY, aimX, aimY, hue; int8_t deltaX, deltaY, signX, signY, error; void aimed(uint16_t w, uint16_t h) { - random16_set_seed(millis()); + //random16_set_seed(millis()); aimX = random8(0, w); aimY = random8(0, h); hue = random8(); @@ -5617,7 +5784,6 @@ uint16_t mode_2Dcrazybees(void) { bee_t *bee = reinterpret_cast(SEGENV.data); if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); for (size_t i = 0; i < n; i++) { bee[i].posX = random8(0, cols); bee[i].posY = random8(0, rows); @@ -5626,7 +5792,7 @@ uint16_t mode_2Dcrazybees(void) { } if (millis() > SEGENV.step) { - SEGENV.step = millis() + (FRAMETIME * 8 / ((SEGMENT.speed>>5)+1)); + SEGENV.step = millis() + (FRAMETIME * 16 / ((SEGMENT.speed>>4)+1)); SEGMENT.fadeToBlackBy(32); @@ -5663,7 +5829,7 @@ static const char _data_FX_MODE_2DCRAZYBEES[] PROGMEM = "Crazy Bees@!,Blur;;;2"; //// Ghost Rider by stepko (c)2021 [https://editor.soulmatelights.com/gallery/716-ghost-rider], adapted by Blaz Kristan (AKA blazoncek) #define LIGHTERS_AM 64 // max lighters (adequate for 32x32 matrix) uint16_t mode_2Dghostrider(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5689,9 +5855,9 @@ uint16_t mode_2Dghostrider(void) { if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) { SEGENV.aux0 = cols; SEGENV.aux1 = rows; - SEGMENT.fill(BLACK); - random16_set_seed(strip.now); + //random16_set_seed(strip.now); lighter->angleSpeed = random8(0,20) - 10; + lighter->gAngle = random16(); lighter->Vspeed = 5; lighter->gPosX = (cols/2) * 10; lighter->gPosY = (rows/2) * 10; @@ -5699,6 +5865,7 @@ uint16_t mode_2Dghostrider(void) { lighter->lightersPosX[i] = lighter->gPosX; lighter->lightersPosY[i] = lighter->gPosY + i; lighter->time[i] = i * 2; + lighter->reg[i] = false; } } @@ -5729,7 +5896,7 @@ uint16_t mode_2Dghostrider(void) { if (lighter->reg[i]) { lighter->lightersPosY[i] = lighter->gPosY; lighter->lightersPosX[i] = lighter->gPosX; - lighter->Angle[i] = lighter->gAngle + random(-10, 10); + lighter->Angle[i] = lighter->gAngle + ((int)random8(20) - 10); lighter->time[i] = 0; lighter->reg[i] = false; } else { @@ -5752,7 +5919,7 @@ static const char _data_FX_MODE_2DGHOSTRIDER[] PROGMEM = "Ghost Rider@Fade rate, //// Floating Blobs by stepko (c)2021 [https://editor.soulmatelights.com/gallery/573-blobs], adapted by Blaz Kristan (AKA blazoncek) #define MAX_BLOBS 8 uint16_t mode_2Dfloatingblobs(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5773,7 +5940,7 @@ uint16_t mode_2Dfloatingblobs(void) { if (SEGENV.aux0 != cols || SEGENV.aux1 != rows) { SEGENV.aux0 = cols; // re-initialise if virtual size changes SEGENV.aux1 = rows; - SEGMENT.fill(BLACK); + //SEGMENT.fill(BLACK); for (size_t i = 0; i < MAX_BLOBS; i++) { blob->r[i] = random8(1, cols>8 ? (cols/4) : 2); blob->sX[i] = (float) random8(3, cols) / (float)(256 - SEGMENT.speed); // speed x @@ -5787,7 +5954,7 @@ uint16_t mode_2Dfloatingblobs(void) { } } - SEGMENT.fadeToBlackBy(20); + SEGMENT.fadeToBlackBy((SEGMENT.custom2>>3)+1); // Bounce balls around for (size_t i = 0; i < Amount; i++) { @@ -5843,20 +6010,20 @@ uint16_t mode_2Dfloatingblobs(void) { return FRAMETIME; } #undef MAX_BLOBS -static const char _data_FX_MODE_2DBLOBS[] PROGMEM = "Blobs@!,# blobs,Blur;!;!;2;c1=8"; +static const char _data_FX_MODE_2DBLOBS[] PROGMEM = "Blobs@!,# blobs,Blur,Trail;!;!;2;c1=8"; //////////////////////////// // 2D Scrolling text // //////////////////////////// uint16_t mode_2Dscrollingtext(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - int letterWidth; - int letterHeight; + int letterWidth, rotLW; + int letterHeight, rotLH; switch (map(SEGMENT.custom2, 0, 255, 1, 5)) { default: case 1: letterWidth = 4; letterHeight = 6; break; @@ -5865,59 +6032,86 @@ uint16_t mode_2Dscrollingtext(void) { case 4: letterWidth = 7; letterHeight = 9; break; case 5: letterWidth = 5; letterHeight = 12; break; } - const bool zero = SEGMENT.check3; - const int yoffset = map(SEGMENT.intensity, 0, 255, -rows/2, rows/2) + (rows-letterHeight)/2; + // letters are rotated + if (((SEGMENT.custom3+1)>>3) % 2) { + rotLH = letterWidth; + rotLW = letterHeight; + } else { + rotLW = letterWidth; + rotLH = letterHeight; + } + char text[WLED_MAX_SEGNAME_LEN+1] = {'\0'}; if (SEGMENT.name) for (size_t i=0,j=0; i31 && SEGMENT.name[i]<128) text[j++] = SEGMENT.name[i]; + const bool zero = strchr(text, '0') != nullptr; - if (!strlen(text) - || !strncmp_P(text,PSTR("#DATE"),5) - || !strncmp_P(text,PSTR("#DDMM"),5) - || !strncmp_P(text,PSTR("#MMDD"),5) - || !strncmp_P(text,PSTR("#TIME"),5) - || !strncmp_P(text,PSTR("#HHMM"),5)) { // fallback if empty segment name: display date and time - char sec[5]; - byte AmPmHour = hour(localTime); - boolean isitAM = true; - if (useAMPM) { - if (AmPmHour > 11) { AmPmHour -= 12; isitAM = false; } - if (AmPmHour == 0) { AmPmHour = 12; } - } - if (useAMPM) sprintf_P(sec, PSTR(" %2s"), (isitAM ? "AM" : "PM")); - else sprintf_P(sec, PSTR(":%02d"), second(localTime)); - if (!strncmp_P(text,PSTR("#DATE"),5)) sprintf_P(text, zero?PSTR("%02d.%02d.%04d"):PSTR("%d.%d.%d"), day(localTime), month(localTime), year(localTime)); - else if (!strncmp_P(text,PSTR("#DDMM"),5)) sprintf_P(text, zero?PSTR("%02d.%02d"):PSTR("%d.%d"), day(localTime), month(localTime)); - else if (!strncmp_P(text,PSTR("#MMDD"),5)) sprintf_P(text, zero?PSTR("%02d/%02d"):PSTR("%d/%d"), month(localTime), day(localTime)); - else if (!strncmp_P(text,PSTR("#TIME"),5)) sprintf_P(text, zero?PSTR("%02d:%02d%s"):PSTR("%2d:%02d%s"), AmPmHour, minute(localTime), sec); - else if (!strncmp_P(text,PSTR("#HHMM"),5)) sprintf_P(text, zero?PSTR("%02d:%02d"):PSTR("%d:%02d"), AmPmHour, minute(localTime)); - else sprintf_P(text, zero?PSTR("%s %02d, %04d %02d:%02d%s"):PSTR("%s %d, %d %d:%02d%s"), monthShortStr(month(localTime)), day(localTime), year(localTime), AmPmHour, minute(localTime), sec); + char sec[5]; + int AmPmHour = hour(localTime); + bool isitAM = true; + if (useAMPM) { + if (AmPmHour > 11) { AmPmHour -= 12; isitAM = false; } + if (AmPmHour == 0) { AmPmHour = 12; } + sprintf_P(sec, PSTR(" %2s"), (isitAM ? "AM" : "PM")); + } else { + sprintf_P(sec, PSTR(":%02d"), second(localTime)); } - const int numberOfLetters = strlen(text); - if (SEGENV.step < millis()) { - if ((numberOfLetters * letterWidth) > cols) ++SEGENV.aux0 %= (numberOfLetters * letterWidth) + cols; // offset - else SEGENV.aux0 = (cols + (numberOfLetters * letterWidth))/2; + if (!strlen(text)) { // fallback if empty segment name: display date and time + sprintf_P(text, PSTR("%s %d, %d %d:%02d%s"), monthShortStr(month(localTime)), day(localTime), year(localTime), AmPmHour, minute(localTime), sec); + } else { + if (!strncmp_P(text,PSTR("#DATE"),5)) sprintf_P(text, zero?PSTR("%02d.%02d.%04d"):PSTR("%d.%d.%d"), day(localTime), month(localTime), year(localTime)); + else if (!strncmp_P(text,PSTR("#DDMM"),5)) sprintf_P(text, zero?PSTR("%02d.%02d") :PSTR("%d.%d"), day(localTime), month(localTime)); + else if (!strncmp_P(text,PSTR("#MMDD"),5)) sprintf_P(text, zero?PSTR("%02d/%02d") :PSTR("%d/%d"), month(localTime), day(localTime)); + else if (!strncmp_P(text,PSTR("#TIME"),5)) sprintf_P(text, zero?PSTR("%02d:%02d%s") :PSTR("%2d:%02d%s"), AmPmHour, minute(localTime), sec); + else if (!strncmp_P(text,PSTR("#HHMM"),5)) sprintf_P(text, zero?PSTR("%02d:%02d") :PSTR("%d:%02d"), AmPmHour, minute(localTime)); + else if (!strncmp_P(text,PSTR("#HH"),3)) sprintf_P(text, zero?PSTR("%02d") :PSTR("%d"), AmPmHour); + else if (!strncmp_P(text,PSTR("#MM"),3)) sprintf_P(text, zero?PSTR("%02d") :PSTR("%d"), minute(localTime)); + } + + const int numberOfLetters = strlen(text); + const unsigned long now = millis(); // reduce millis() calls + int width = (numberOfLetters * rotLW); + int yoffset = map(SEGMENT.intensity, 0, 255, -rows/2, rows/2) + (rows-rotLH)/2; + if (width <= cols) { + // scroll vertically (e.g. ^^ Way out ^^) if it fits + int speed = map(SEGMENT.speed, 0, 255, 5000, 1000); + int frac = now % speed + 1; + if (SEGMENT.intensity == 255) { + yoffset = (2 * frac * rows)/speed - rows; + } else if (SEGMENT.intensity == 0) { + yoffset = rows - (2 * frac * rows)/speed; + } + } + + if (SEGENV.step < now) { + // calculate start offset + if (width > cols) { + if (SEGMENT.check3) { + if (SEGENV.aux0 == 0) SEGENV.aux0 = width + cols - 1; + else --SEGENV.aux0; + } else ++SEGENV.aux0 %= width + cols; + } else SEGENV.aux0 = (cols + width)/2; ++SEGENV.aux1 &= 0xFF; // color shift - SEGENV.step = millis() + map(SEGMENT.speed, 0, 255, 10*FRAMETIME_FIXED, 2*FRAMETIME_FIXED); - if (!SEGMENT.check2) { - for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++ ) - SEGMENT.blendPixelColorXY(x, y, SEGCOLOR(1), 255 - (SEGMENT.custom1>>1)); - } + SEGENV.step = now + map(SEGMENT.speed, 0, 255, 250, 50); // shift letters every ~250ms to ~50ms } + + if (!SEGMENT.check2) SEGMENT.fade_out(255 - (SEGMENT.custom1>>4)); // trail + for (int i = 0; i < numberOfLetters; i++) { - if (int(cols) - int(SEGENV.aux0) + letterWidth*(i+1) < 0) continue; // don't draw characters off-screen + int xoffset = int(cols) - int(SEGENV.aux0) + rotLW*i; + if (xoffset + rotLW < 0) continue; // don't draw characters off-screen uint32_t col1 = SEGMENT.color_from_palette(SEGENV.aux1, false, PALETTE_SOLID_WRAP, 0); uint32_t col2 = BLACK; if (SEGMENT.check1 && SEGMENT.palette == 0) { col1 = SEGCOLOR(0); col2 = SEGCOLOR(2); } - SEGMENT.drawCharacter(text[i], int(cols) - int(SEGENV.aux0) + letterWidth*i, yoffset, letterWidth, letterHeight, col1, col2); + SEGMENT.drawCharacter(text[i], xoffset, yoffset, letterWidth, letterHeight, col1, col2, map(SEGMENT.custom3, 0, 31, -2, 2)); } return FRAMETIME; } -static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,,Gradient,Overlay,0;!,!,Gradient;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0"; +static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Offset,Trail,Font size,Rotate,Gradient,Overlay,Reverse;!,!,Gradient;!;2;ix=128,c1=0,rev=0,mi=0,rY=0,mY=0"; //////////////////////////// @@ -5925,7 +6119,7 @@ static const char _data_FX_MODE_2DSCROLLTEXT[] PROGMEM = "Scrolling Text@!,Y Off //////////////////////////// //// Drift Rose by stepko (c)2021 [https://editor.soulmatelights.com/gallery/1369-drift-rose-pattern], adapted by Blaz Kristan (AKA blazoncek) uint16_t mode_2Ddriftrose(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -5934,10 +6128,6 @@ uint16_t mode_2Ddriftrose(void) { const float CY = (rows-rows%2)/2.f - .5f; const float L = min(cols, rows) / 2.f; - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - SEGMENT.fadeToBlackBy(32+(SEGMENT.speed>>3)); for (size_t i = 1; i < 37; i++) { uint32_t x = (CX + (sin_t(radians(i * 10)) * (beatsin8(i, 0, L*2)-L))) * 255.f; @@ -6083,7 +6273,7 @@ static const char _data_FX_MODE_RIPPLEPEAK[] PROGMEM = "Ripple Peak@Fade rate,Ma ///////////////////////// // By: Mark Kriegsman https://gist.github.com/kriegsman/5adca44e14ad025e6d3b , modified by Andrew Tuline uint16_t mode_2DSwirl(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -6110,8 +6300,6 @@ uint16_t mode_2DSwirl(void) { float volumeSmth = *(float*) um_data->u_data[0]; //ewowi: use instead of sampleAvg??? int16_t volumeRaw = *(int16_t*) um_data->u_data[1]; - // printUmData(); - SEGMENT.addPixelColorXY( i, j, ColorFromPalette(SEGPALETTE, (ms / 11 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND)); //CHSV( ms / 11, 200, 255); SEGMENT.addPixelColorXY( j, i, ColorFromPalette(SEGPALETTE, (ms / 13 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND)); //CHSV( ms / 13, 200, 255); SEGMENT.addPixelColorXY(ni,nj, ColorFromPalette(SEGPALETTE, (ms / 17 + volumeSmth*4), volumeRaw * SEGMENT.intensity / 64, LINEARBLEND)); //CHSV( ms / 17, 200, 255); @@ -6129,15 +6317,11 @@ static const char _data_FX_MODE_2DSWIRL[] PROGMEM = "Swirl@!,Sensitivity,Blur;,B ///////////////////////// // By: Stepko, https://editor.soulmatelights.com/gallery/652-wave , modified by Andrew Tuline uint16_t mode_2DWaverly(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); - if (SEGENV.call == 0) { - SEGMENT.fill(BLACK); - } - um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { // add support for no audio @@ -6185,6 +6369,7 @@ typedef struct Gravity { // * GRAVCENTER // /////////////////////// uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); const uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -6203,7 +6388,7 @@ uint16_t mode_gravcenter(void) { // Gravcenter. By Andrew Tuline. float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125; // divide by 8, to compensate for later "sensitivty" upscaling - float mySampleAvg = mapf(segmentSampleAvg*2.0, 0, 32, 0, (float)SEGLEN/2.0); // map to pixels available in current segment + float mySampleAvg = mapf(segmentSampleAvg*2.0, 0, 32, 0, (float)SEGLEN/2.0f); // map to pixels available in current segment uint16_t tempsamp = constrain(mySampleAvg, 0, SEGLEN/2); // Keep the sample from overflowing. uint8_t gravity = 8 - SEGMENT.speed/32; @@ -6233,6 +6418,7 @@ static const char _data_FX_MODE_GRAVCENTER[] PROGMEM = "Gravcenter@Rate of fall, // * GRAVCENTRIC // /////////////////////// uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -6251,10 +6437,10 @@ uint16_t mode_gravcentric(void) { // Gravcentric. By Andrew //SEGMENT.fade_out(240); // twice? really? SEGMENT.fade_out(253); // 50% - float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0; + float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0f; segmentSampleAvg *= 0.125f; // divide by 8, to compensate for later "sensitivty" upscaling - float mySampleAvg = mapf(segmentSampleAvg*2.0, 0.0f, 32.0f, 0.0f, (float)SEGLEN/2.0); // map to pixels availeable in current segment + float mySampleAvg = mapf(segmentSampleAvg*2.0, 0.0f, 32.0f, 0.0f, (float)SEGLEN/2.0f); // map to pixels availeable in current segment int tempsamp = constrain(mySampleAvg, 0, SEGLEN/2); // Keep the sample from overflowing. uint8_t gravity = 8 - SEGMENT.speed/32; @@ -6284,6 +6470,7 @@ static const char _data_FX_MODE_GRAVCENTRIC[] PROGMEM = "Gravcentric@Rate of fal // * GRAVIMETER // /////////////////////// uint16_t mode_gravimeter(void) { // Gravmeter. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed @@ -6330,6 +6517,7 @@ static const char _data_FX_MODE_GRAVIMETER[] PROGMEM = "Gravimeter@Rate of fall, // * JUGGLES // ////////////////////// uint16_t mode_juggles(void) { // Juggles. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { // add support for no audio @@ -6353,6 +6541,7 @@ static const char _data_FX_MODE_JUGGLES[] PROGMEM = "Juggles@!,# of balls;!,!;!; // * MATRIPIX // ////////////////////// uint16_t mode_matripix(void) { // Matripix. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment um_data_t *um_data; @@ -6384,6 +6573,7 @@ static const char _data_FX_MODE_MATRIPIX[] PROGMEM = "Matripix@!,Brightness;!,!; // * MIDNOISE // ////////////////////// uint16_t mode_midnoise(void) { // Midnoise. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); // Changing xdist to SEGENV.aux0 and ydist to SEGENV.aux1. um_data_t *um_data; @@ -6487,6 +6677,7 @@ static const char _data_FX_MODE_NOISEMETER[] PROGMEM = "Noisemeter@Fade rate,Wid // * PIXELWAVE // ////////////////////// uint16_t mode_pixelwave(void) { // Pixelwave. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment if (SEGENV.call == 0) { @@ -6562,10 +6753,11 @@ static const char _data_FX_MODE_PLASMOID[] PROGMEM = "Plasmoid@Phase,# of pixels /////////////////////// // Andrew's crappy peak detector. If I were 40+ years younger, I'd learn signal processing. uint16_t mode_puddlepeak(void) { // Puddlepeak. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); uint16_t size = 0; uint8_t fadeVal = map(SEGMENT.speed,0,255, 224, 254); - uint16_t pos = random(SEGLEN); // Set a random starting position. + uint16_t pos = random16(SEGLEN); // Set a random starting position. um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { @@ -6605,6 +6797,7 @@ static const char _data_FX_MODE_PUDDLEPEAK[] PROGMEM = "Puddlepeak@Fade rate,Pud // * PUDDLES // ////////////////////// uint16_t mode_puddles(void) { // Puddles. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); uint16_t size = 0; uint8_t fadeVal = map(SEGMENT.speed, 0, 255, 224, 254); uint16_t pos = random16(SEGLEN); // Set a random starting position. @@ -6636,6 +6829,7 @@ static const char _data_FX_MODE_PUDDLES[] PROGMEM = "Puddles@Fade rate,Puddle si // * PIXELS // ////////////////////// uint16_t mode_pixels(void) { // Pixels. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); if (!SEGENV.allocateData(32*sizeof(uint8_t))) return mode_static(); //allocation failed uint8_t *myVals = reinterpret_cast(SEGENV.data); // Used to store a pile of samples because WLED frame rate and WLED sample rate are not synchronized. Frame rate is too low. @@ -6669,6 +6863,7 @@ static const char _data_FX_MODE_PIXELS[] PROGMEM = "Pixels@Fade rate,# of pixels // ** Blurz // ////////////////////// uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline. + if (SEGLEN == 1) return mode_static(); // even with 1D effect we have to take logic for 2D segments for allocation as fill_solid() fills whole segment um_data_t *um_data; @@ -6689,7 +6884,7 @@ uint16_t mode_blurz(void) { // Blurz. By Andrew Tuline. SEGENV.step += FRAMETIME; if (SEGENV.step > SPEED_FORMULA_L) { uint16_t segLoc = random16(SEGLEN); - SEGMENT.setPixelColor(segLoc, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(2*fftResult[SEGENV.aux0%16]*240/(SEGLEN-1), false, PALETTE_SOLID_WRAP, 0), 2*fftResult[SEGENV.aux0%16])); + SEGMENT.setPixelColor(segLoc, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(2*fftResult[SEGENV.aux0%16]*240/max(1, SEGLEN-1), false, PALETTE_SOLID_WRAP, 0), 2*fftResult[SEGENV.aux0%16])); ++(SEGENV.aux0) %= 16; // make sure it doesn't cross 16 SEGENV.step = 1; @@ -6705,6 +6900,7 @@ static const char _data_FX_MODE_BLURZ[] PROGMEM = "Blurz@Fade rate,Blur;!,Color // ** DJLight // ///////////////////////// uint16_t mode_DJLight(void) { // Written by ??? Adapted by Will Tatam. + if (SEGLEN == 1) return mode_static(); const int mid = SEGLEN / 2; um_data_t *um_data; @@ -6738,6 +6934,7 @@ static const char _data_FX_MODE_DJLIGHT[] PROGMEM = "DJ Light@Speed;;;1f;m12=2,s // ** Freqmap // //////////////////// uint16_t mode_freqmap(void) { // Map FFT_MajorPeak to SEGLEN. Would be better if a higher framerate. + if (SEGLEN == 1) return mode_static(); // Start frequency = 60 Hz and log10(60) = 1.78 // End frequency = MAX_FREQUENCY in Hz and lo10(MAX_FREQUENCY) = MAX_FREQ_LOG10 @@ -6774,6 +6971,7 @@ static const char _data_FX_MODE_FREQMAP[] PROGMEM = "Freqmap@Fade rate,Starting // ** Freqmatrix // /////////////////////// uint16_t mode_freqmatrix(void) { // Freqmatrix. By Andreas Pleschung. + if (SEGLEN == 1) return mode_static(); um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { // add support for no audio @@ -6839,24 +7037,27 @@ uint16_t mode_freqpixels(void) { // Freqpixel. By Andrew Tuline. } float FFT_MajorPeak = *(float*)um_data->u_data[4]; float my_magnitude = *(float*)um_data->u_data[5] / 16.0f; - if (FFT_MajorPeak < 1) FFT_MajorPeak = 1; // log10(0) is "forbidden" (throws exception) + if (FFT_MajorPeak < 1) FFT_MajorPeak = 1.0f; // log10(0) is "forbidden" (throws exception) - uint16_t fadeRate = 2*SEGMENT.speed - SEGMENT.speed*SEGMENT.speed/255; // Get to 255 as quick as you can. + // this code translates to speed * (2 - speed/255) which is a) speed*2 or b) speed (when speed is 255) + // and since fade_out() can only take 0-255 it will behave incorrectly when speed > 127 + //uint16_t fadeRate = 2*SEGMENT.speed - SEGMENT.speed*SEGMENT.speed/255; // Get to 255 as quick as you can. + uint16_t fadeRate = SEGMENT.speed*SEGMENT.speed; // Get to 255 as quick as you can. + fadeRate = map(fadeRate, 0, 65535, 1, 255); - if (SEGENV.call == 0) SEGMENT.fill(BLACK); int fadeoutDelay = (256 - SEGMENT.speed) / 64; if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fade_out(fadeRate); + uint8_t pixCol = (log10f(FFT_MajorPeak) - 1.78f) * 255.0f/(MAX_FREQ_LOG10 - 1.78f); // Scale log10 of frequency values to the 255 colour index. + if (FFT_MajorPeak < 61.0f) pixCol = 0; // handle underflow for (int i=0; i < SEGMENT.intensity/32+1; i++) { uint16_t locn = random16(0,SEGLEN); - uint8_t pixCol = (log10f(FFT_MajorPeak) - 1.78f) * 255.0f/(MAX_FREQ_LOG10 - 1.78f); // Scale log10 of frequency values to the 255 colour index. - if (FFT_MajorPeak < 61.0f) pixCol = 0; // handle underflow SEGMENT.setPixelColor(locn, color_blend(SEGCOLOR(1), SEGMENT.color_from_palette(SEGMENT.intensity+pixCol, false, PALETTE_SOLID_WRAP, 0), (int)my_magnitude)); } return FRAMETIME; } // mode_freqpixels() -static const char _data_FX_MODE_FREQPIXELS[] PROGMEM = "Freqpixels@Fade rate,Starting color and # of pixels;;;1f;m12=0,si=0"; // Pixels, Beatsin +static const char _data_FX_MODE_FREQPIXELS[] PROGMEM = "Freqpixels@Fade rate,Starting color and # of pixels;!,!,;!;1f;m12=0,si=0"; // Pixels, Beatsin ////////////////////// @@ -6875,6 +7076,7 @@ static const char _data_FX_MODE_FREQPIXELS[] PROGMEM = "Freqpixels@Fade rate,Sta // As a compromise between speed and accuracy we are currently sampling with 10240Hz, from which we can then determine with a 512bin FFT our max frequency is 5120Hz. // Depending on the music stream you have you might find it useful to change the frequency mapping. uint16_t mode_freqwave(void) { // Freqwave. By Andreas Pleschung. + if (SEGLEN == 1) return mode_static(); um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { // add support for no audio @@ -6931,7 +7133,7 @@ static const char _data_FX_MODE_FREQWAVE[] PROGMEM = "Freqwave@Speed,Sound effec // ** Gravfreq // /////////////////////// uint16_t mode_gravfreq(void) { // Gravfreq. By Andrew Tuline. - + if (SEGLEN == 1) return mode_static(); uint16_t dataSize = sizeof(gravity); if (!SEGENV.allocateData(dataSize)) return mode_static(); //allocation failed Gravity* gravcen = reinterpret_cast(SEGENV.data); @@ -6948,9 +7150,9 @@ uint16_t mode_gravfreq(void) { // Gravfreq. By Andrew Tuline. SEGMENT.fade_out(250); float segmentSampleAvg = volumeSmth * (float)SEGMENT.intensity / 255.0f; - segmentSampleAvg *= 0.125; // divide by 8, to compensate for later "sensitivty" upscaling + segmentSampleAvg *= 0.125f; // divide by 8, to compensate for later "sensitivty" upscaling - float mySampleAvg = mapf(segmentSampleAvg*2.0f, 0,32, 0, (float)SEGLEN/2.0); // map to pixels availeable in current segment + float mySampleAvg = mapf(segmentSampleAvg*2.0f, 0,32, 0, (float)SEGLEN/2.0f); // map to pixels availeable in current segment int tempsamp = constrain(mySampleAvg,0,SEGLEN/2); // Keep the sample from overflowing. uint8_t gravity = 8 - SEGMENT.speed/32; @@ -6983,6 +7185,7 @@ static const char _data_FX_MODE_GRAVFREQ[] PROGMEM = "Gravfreq@Rate of fall,Sens // ** Noisemove // ////////////////////// uint16_t mode_noisemove(void) { // Noisemove. By: Andrew Tuline + if (SEGLEN == 1) return mode_static(); um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { // add support for no audio @@ -6990,8 +7193,6 @@ uint16_t mode_noisemove(void) { // Noisemove. By: Andrew Tuli } uint8_t *fftResult = (uint8_t*)um_data->u_data[2]; - if (SEGENV.call == 0) SEGMENT.fill(BLACK); - //SEGMENT.fade_out(224); // Just in case something doesn't get faded. int fadeoutDelay = (256 - SEGMENT.speed) / 96; if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fadeToBlackBy(4+ SEGMENT.speed/4); @@ -7011,6 +7212,7 @@ static const char _data_FX_MODE_NOISEMOVE[] PROGMEM = "Noisemove@Speed of perlin // ** Rocktaves // ////////////////////// uint16_t mode_rocktaves(void) { // Rocktaves. Same note from each octave is same colour. By: Andrew Tuline + if (SEGLEN == 1) return mode_static(); um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { // add support for no audio @@ -7019,8 +7221,7 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac float FFT_MajorPeak = *(float*) um_data->u_data[4]; float my_magnitude = *(float*) um_data->u_data[5] / 16.0f; - if (SEGENV.call == 0) SEGMENT.fill(BLACK); - SEGMENT.fadeToBlackBy(16); // Just in case something doesn't get faded. + SEGMENT.fadeToBlackBy(16); // Just in case something doesn't get faded. float frTemp = FFT_MajorPeak; uint8_t octCount = 0; // Octave counter. @@ -7035,8 +7236,8 @@ uint16_t mode_rocktaves(void) { // Rocktaves. Same note from eac frTemp = frTemp/2; } - frTemp -=132; // This should give us a base musical note of C3 - frTemp = fabsf(frTemp * 2.1f); // Fudge factors to compress octave range starting at 0 and going to 255; + frTemp -= 132.0f; // This should give us a base musical note of C3 + frTemp = fabsf(frTemp * 2.1f); // Fudge factors to compress octave range starting at 0 and going to 255; uint16_t i = map(beatsin8(8+octCount*4, 0, 255, 0, octCount*8), 0, 255, 0, SEGLEN-1); i = constrain(i, 0, SEGLEN-1); @@ -7052,7 +7253,7 @@ static const char _data_FX_MODE_ROCKTAVES[] PROGMEM = "Rocktaves@;!,!;!;1f;m12=1 /////////////////////// // Combines peak detection with FFT_MajorPeak and FFT_Magnitude. uint16_t mode_waterfall(void) { // Waterfall. By: Andrew Tuline - if (SEGENV.call == 0) SEGMENT.fill(BLACK); + if (SEGLEN == 1) return mode_static(); um_data_t *um_data; if (!usermods.getUMData(&um_data, USERMOD_ID_AUDIOREACTIVE)) { @@ -7103,7 +7304,7 @@ static const char _data_FX_MODE_WATERFALL[] PROGMEM = "Waterfall@!,Adjust color, // ** 2D GEQ // ///////////////////////// uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const int NUM_BANDS = map(SEGMENT.custom1, 0, 255, 1, 16); const uint16_t cols = SEGMENT.virtualWidth(); @@ -7127,7 +7328,6 @@ uint16_t mode_2DGEQ(void) { // By Will Tatam. Code reduction by Ewoud Wijma. rippleTime = true; } - if (SEGENV.call == 0) SEGMENT.fill(BLACK); int fadeoutDelay = (256 - SEGMENT.speed) / 64; if ((fadeoutDelay <= 1 ) || ((SEGENV.call % fadeoutDelay) == 0)) SEGMENT.fadeToBlackBy(SEGMENT.speed); @@ -7162,7 +7362,7 @@ static const char _data_FX_MODE_2DGEQ[] PROGMEM = "GEQ@Fade speed,Ripple decay,# // ** 2D Funky plank // ///////////////////////// uint16_t mode_2DFunkyPlank(void) { // Written by ??? Adapted by Will Tatam. - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -7254,7 +7454,7 @@ static uint8_t akemi[] PROGMEM = { }; uint16_t mode_2DAkemi(void) { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -7322,7 +7522,7 @@ static const char _data_FX_MODE_2DAKEMI[] PROGMEM = "Akemi@Color speed,Dance;Hea // https://editor.soulmatelights.com/gallery/1089-distorsion-waves // adapted for WLED by @blazoncek uint16_t mode_2Ddistortionwaves() { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -7377,7 +7577,7 @@ static const char _data_FX_MODE_2DDISTORTIONWAVES[] PROGMEM = "Distortion Waves@ //Idea from https://www.youtube.com/watch?v=DiHBgITrZck&ab_channel=StefanPetrick // adapted for WLED by @blazoncek uint16_t mode_2Dsoap() { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -7429,6 +7629,7 @@ uint16_t mode_2Dsoap() { int amplitude; int8_t shiftX = 0; //(SEGMENT.custom1 - 128) / 4; int8_t shiftY = 0; //(SEGMENT.custom2 - 128) / 4; + CRGB ledsbuff[MAX(cols,rows)]; amplitude = (cols >= 16) ? (cols-8)/8 : 1; for (int y = 0; y < rows; y++) { @@ -7449,9 +7650,9 @@ uint16_t mode_2Dsoap() { CRGB PixelB = CRGB::Black; if ((zF >= 0) && (zF < cols)) PixelB = SEGMENT.getPixelColorXY(zF, y); else PixelB = ColorFromPalette(SEGPALETTE, ~noise3d[XY(abs(zF),y)]*3); - CRGB pix = (PixelA.nscale8(ease8InOutApprox(255 - fraction))) + (PixelB.nscale8(ease8InOutApprox(fraction))); - SEGMENT.setPixelColorXY(x, y, pix); + ledsbuff[x] = (PixelA.nscale8(ease8InOutApprox(255 - fraction))) + (PixelB.nscale8(ease8InOutApprox(fraction))); } + for (int x = 0; x < cols; x++) SEGMENT.setPixelColorXY(x, y, ledsbuff[x]); } amplitude = (rows >= 16) ? (rows-8)/8 : 1; @@ -7473,9 +7674,9 @@ uint16_t mode_2Dsoap() { CRGB PixelB = CRGB::Black; if ((zF >= 0) && (zF < rows)) PixelB = SEGMENT.getPixelColorXY(x, zF); else PixelB = ColorFromPalette(SEGPALETTE, ~noise3d[XY(x,abs(zF))]*3); - CRGB pix = (PixelA.nscale8(ease8InOutApprox(255 - fraction))) + (PixelB.nscale8(ease8InOutApprox(fraction))); - SEGMENT.setPixelColorXY(x, y, pix); + ledsbuff[y] = (PixelA.nscale8(ease8InOutApprox(255 - fraction))) + (PixelB.nscale8(ease8InOutApprox(fraction))); } + for (int y = 0; y < rows; y++) SEGMENT.setPixelColorXY(x, y, ledsbuff[y]); } return FRAMETIME; @@ -7488,7 +7689,7 @@ static const char _data_FX_MODE_2DSOAP[] PROGMEM = "Soap@!,Smoothness;;!;2"; //Stepko and Sutaburosu // adapted for WLED by @blazoncek uint16_t mode_2Doctopus() { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -7544,7 +7745,7 @@ static const char _data_FX_MODE_2DOCTOPUS[] PROGMEM = "Octopus@!,,Offset X,Offse //@Stepko (https://editor.soulmatelights.com/gallery/1704-wavingcells) // adapted for WLED by @blazoncek uint16_t mode_2Dwavingcell() { - if (!strip.isMatrix) return mode_static(); // not a 2D set-up + if (!strip.isMatrix || !SEGMENT.is2D()) return mode_static(); // not a 2D set-up const uint16_t cols = SEGMENT.virtualWidth(); const uint16_t rows = SEGMENT.virtualHeight(); @@ -7644,6 +7845,7 @@ void WS2812FX::setupEffectData() { addEffect(FX_MODE_FIRE_FLICKER, &mode_fire_flicker, _data_FX_MODE_FIRE_FLICKER); addEffect(FX_MODE_GRADIENT, &mode_gradient, _data_FX_MODE_GRADIENT); addEffect(FX_MODE_LOADING, &mode_loading, _data_FX_MODE_LOADING); + addEffect(FX_MODE_ROLLINGBALLS, &rolling_balls, _data_FX_MODE_ROLLINGBALLS); addEffect(FX_MODE_FAIRY, &mode_fairy, _data_FX_MODE_FAIRY); addEffect(FX_MODE_TWO_DOTS, &mode_two_dots, _data_FX_MODE_TWO_DOTS); diff --git a/wled00/FX.h b/wled00/FX.h index 2e80b59d3..b51c9dfb5 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -62,10 +62,10 @@ //#define FRAMETIME _frametime #define FRAMETIME strip.getFrameTime() -/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of +/* each segment uses 82 bytes of SRAM memory, so if you're application fails because of insufficient memory, decreasing MAX_NUM_SEGMENTS may help */ #ifdef ESP8266 - #define MAX_NUM_SEGMENTS 16 + #define MAX_NUM_SEGMENTS 12 /* How much data bytes all segments combined may allocate */ #define MAX_SEGMENT_DATA 5120 #else @@ -73,9 +73,13 @@ #define MAX_NUM_SEGMENTS 32 #endif #if defined(ARDUINO_ARCH_ESP32S2) - #define MAX_SEGMENT_DATA 24576 + #if defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM) + #define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1024 // 32k by default + #else + #define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*768 // 24k by default + #endif #else - #define MAX_SEGMENT_DATA 32767 + #define MAX_SEGMENT_DATA MAX_NUM_SEGMENTS*1280 // 40k by default #endif #endif @@ -109,20 +113,15 @@ #define PINK (uint32_t)0xFF1493 #define ULTRAWHITE (uint32_t)0xFFFFFFFF #define DARKSLATEGRAY (uint32_t)0x2F4F4F -#define DARKSLATEGREY (uint32_t)0x2F4F4F +#define DARKSLATEGREY DARKSLATEGRAY -// options -// bit 7: segment is in transition mode -// bits 4-6: TBD -// bit 3: mirror effect within segment -// bit 2: segment is on -// bit 1: reverse segment -// bit 0: segment is selected +// segment options #define NO_OPTIONS (uint16_t)0x0000 -#define TRANSPOSED (uint16_t)0x0400 // rotated 90deg & reversed -#define REVERSE_Y_2D (uint16_t)0x0200 -#define MIRROR_Y_2D (uint16_t)0x0100 -#define TRANSITIONAL (uint16_t)0x0080 +#define TRANSPOSED (uint16_t)0x0100 // rotated 90deg & reversed +#define MIRROR_Y_2D (uint16_t)0x0080 +#define REVERSE_Y_2D (uint16_t)0x0040 +#define RESET_REQ (uint16_t)0x0020 +#define FROZEN (uint16_t)0x0010 #define MIRROR (uint16_t)0x0008 #define SEGMENT_ON (uint16_t)0x0004 #define REVERSE (uint16_t)0x0002 @@ -176,7 +175,7 @@ #define FX_MODE_FIRE_FLICKER 45 #define FX_MODE_GRADIENT 46 #define FX_MODE_LOADING 47 -// #define FX_MODE_POLICE 48 // removed in 0.14! +#define FX_MODE_ROLLINGBALLS 48 //was Police before 0.14 #define FX_MODE_FAIRY 49 //was Police All prior to 0.13.0-b6 (use "Two Dots" with Red/Blue and full intensity) #define FX_MODE_TWO_DOTS 50 #define FX_MODE_FAIRYTWINKLE 51 //was Two Areas prior to 0.13.0-b6 (use "Two Dots" with full intensity) @@ -283,7 +282,7 @@ #define FX_MODE_RIPPLEPEAK 148 #define FX_MODE_2DFIRENOISE 149 #define FX_MODE_2DSQUAREDSWIRL 150 -#define FX_MODE_2DFIRE2012 151 +// #define FX_MODE_2DFIRE2012 151 #define FX_MODE_2DDNA 152 #define FX_MODE_2DMATRIX 153 #define FX_MODE_2DMETABALLS 154 @@ -293,7 +292,7 @@ #define FX_MODE_GRAVFREQ 158 #define FX_MODE_DJLIGHT 159 #define FX_MODE_2DFUNKYPLANK 160 -#define FX_MODE_2DCENTERBARS 161 +//#define FX_MODE_2DCENTERBARS 161 #define FX_MODE_2DPULSER 162 #define FX_MODE_BLURZ 163 #define FX_MODE_2DDRIFT 164 @@ -348,12 +347,11 @@ typedef struct Segment { bool mirror : 1; // 3 : mirrored bool freeze : 1; // 4 : paused/frozen bool reset : 1; // 5 : indicates that Segment runtime requires reset - bool transitional: 1; // 6 : transitional (there is transition occuring) - bool reverse_y : 1; // 7 : reversed Y (2D) - bool mirror_y : 1; // 8 : mirrored Y (2D) - bool transpose : 1; // 9 : transposed (2D, swapped X & Y) - uint8_t map1D2D : 3; // 10-12 : mapping for 1D effect on 2D (0-use as strip, 1-expand vertically, 2-circular/arc, 3-rectangular/corner, ...) - uint8_t soundSim : 1; // 13 : 0-1 sound simulation types ("soft" & "hard" or "on"/"off") + bool reverse_y : 1; // 6 : reversed Y (2D) + bool mirror_y : 1; // 7 : mirrored Y (2D) + bool transpose : 1; // 8 : transposed (2D, swapped X & Y) + uint8_t map1D2D : 3; // 9-11 : mapping for 1D effect on 2D (0-use as strip, 1-expand vertically, 2-circular/arc, 3-rectangular/corner, ...) + uint8_t soundSim : 2; // 12-13 : 0-3 sound simulation types ("soft" & "hard" or "on"/"off") uint8_t set : 2; // 14-15 : 0-3 UI segment sets/groups }; }; @@ -381,6 +379,30 @@ typedef struct Segment { byte *data; // effect data pointer static uint16_t maxWidth, maxHeight; // these define matrix width & height (max. segment dimensions) + typedef struct TemporarySegmentData { + uint16_t _optionsT; + uint32_t _colorT[NUM_COLORS]; + uint8_t _speedT; + uint8_t _intensityT; + uint8_t _custom1T, _custom2T; // custom FX parameters/sliders + struct { + uint8_t _custom3T : 5; // reduced range slider (0-31) + bool _check1T : 1; // checkmark 1 + bool _check2T : 1; // checkmark 2 + bool _check3T : 1; // checkmark 3 + }; + uint16_t _aux0T; + uint16_t _aux1T; + uint32_t _stepT; + uint32_t _callT; + uint8_t *_dataT; + uint16_t _dataLenT; + TemporarySegmentData() + : _dataT(nullptr) // just in case... + , _dataLenT(0) + {} + } tmpsegd_t; + private: union { uint8_t _capabilities; @@ -395,39 +417,34 @@ typedef struct Segment { uint16_t _dataLen; static uint16_t _usedSegmentData; + // perhaps this should be per segment, not static + static CRGBPalette16 _randomPalette; // actual random palette + static CRGBPalette16 _newRandomPalette; // target random palette + static unsigned long _lastPaletteChange; // last random palette change time in millis() + #ifndef WLED_DISABLE_MODE_BLEND + static bool _modeBlend; // mode/effect blending semaphore + #endif + // transition data, valid only if transitional==true, holds values during transition (72 bytes) struct Transition { + #ifndef WLED_DISABLE_MODE_BLEND + tmpsegd_t _segT; // previous segment environment + uint8_t _modeT; // previous mode/effect + #else uint32_t _colorT[NUM_COLORS]; + #endif uint8_t _briT; // temporary brightness uint8_t _cctT; // temporary CCT CRGBPalette16 _palT; // temporary palette uint8_t _prevPaletteBlends; // number of previous palette blends (there are max 255 belnds possible) - uint8_t _modeP; // previous mode/effect - //uint16_t _aux0, _aux1; // previous mode/effect runtime data - //uint32_t _step, _call; // previous mode/effect runtime data - //byte *_data; // previous mode/effect runtime data - unsigned long _start; // must accommodate millis() + unsigned long _start; // must accommodate millis() uint16_t _dur; Transition(uint16_t dur=750) - : _briT(255) - , _cctT(127) - , _palT(CRGBPalette16(CRGB::Black)) + : _palT(CRGBPalette16(CRGB::Black)) , _prevPaletteBlends(0) - , _modeP(FX_MODE_STATIC) , _start(millis()) , _dur(dur) {} - Transition(uint16_t d, uint8_t b, uint8_t c, const uint32_t *o) - : _briT(b) - , _cctT(c) - , _palT(CRGBPalette16(CRGB::Black)) - , _prevPaletteBlends(0) - , _modeP(FX_MODE_STATIC) - , _start(millis()) - , _dur(d) - { - for (size_t i=0; i(%p)", (int)_dataLen, data); //Serial.println(); - //#endif + #endif if (name) { delete[] name; name = nullptr; } - if (_t) { transitional = false; delete _t; _t = nullptr; } + stopTransition(); deallocateData(); } @@ -497,6 +516,7 @@ typedef struct Segment { inline bool getOption(uint8_t n) const { return ((options >> n) & 0x01); } inline bool isSelected(void) const { return selected; } + inline bool isInTransition(void) const { return _t != nullptr; } inline bool isActive(void) const { return stop > start; } inline bool is2D(void) const { return (width()>1 && height()>1); } inline bool hasRGB(void) const { return _isRGB; } @@ -510,8 +530,12 @@ typedef struct Segment { static uint16_t getUsedSegmentData(void) { return _usedSegmentData; } static void addUsedSegmentData(int len) { _usedSegmentData += len; } + #ifndef WLED_DISABLE_MODE_BLEND + static void modeBlend(bool blend) { _modeBlend = blend; } + #endif + static void handleRandomPalette(); - void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1, uint8_t segId = 255); + void setUp(uint16_t i1, uint16_t i2, uint8_t grp=1, uint8_t spc=0, uint16_t ofs=UINT16_MAX, uint16_t i1Y=0, uint16_t i2Y=1); bool setColor(uint8_t slot, uint32_t c); //returns true if changed void setCCT(uint16_t k); void setOpacity(uint8_t o); @@ -523,9 +547,9 @@ typedef struct Segment { // runtime data functions inline uint16_t dataSize(void) const { return _dataLen; } - bool allocateData(size_t len); - void deallocateData(void); - void resetIfRequired(void); + bool allocateData(size_t len); // allocates effect data buffer in heap and clears it + void deallocateData(void); // deallocates (frees) effect data buffer from heap + void resetIfRequired(void); // sets all SEGENV variables to 0 and clears data buffer /** * Flags that before the next effect is calculated, * the internal segment state should be reset. @@ -535,59 +559,65 @@ typedef struct Segment { inline void markForReset(void) { reset = true; } // setOption(SEG_OPTION_RESET, true) // transition functions - void startTransition(uint16_t dur); // transition has to start before actual segment values change + void startTransition(uint16_t dur); // transition has to start before actual segment values change + void stopTransition(void); // ends transition mode by destroying transition structure void handleTransition(void); - uint16_t progress(void); //transition progression between 0-65535 - uint8_t currentBri(uint8_t briNew, bool useCct = false); - uint8_t currentMode(uint8_t modeNew); - uint32_t currentColor(uint8_t slot, uint32_t colorNew); + #ifndef WLED_DISABLE_MODE_BLEND + void swapSegenv(tmpsegd_t &tmpSegD); // copies segment data into specifed buffer, if buffer is not a transition buffer, segment data is overwritten from transition buffer + void restoreSegenv(tmpsegd_t &tmpSegD); // restores segment data from buffer, if buffer is not transition buffer, changed values are copied to transition buffer + #endif + uint16_t progress(void); // transition progression between 0-65535 + uint8_t currentBri(bool useCct = false); // current segment brightness/CCT (blended while in transition) + uint8_t currentMode(void); // currently active effect/mode (while in transition) + uint32_t currentColor(uint8_t slot); // currently active segment color (blended while in transition) CRGBPalette16 &loadPalette(CRGBPalette16 &tgt, uint8_t pal); CRGBPalette16 ¤tPalette(CRGBPalette16 &tgt, uint8_t paletteID); // 1D strip uint16_t virtualLength(void) const; void setPixelColor(int n, uint32_t c); // set relative pixel within segment with color - void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } // automatically inline - void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); } // automatically inline + inline void setPixelColor(unsigned n, uint32_t c) { setPixelColor(int(n), c); } + inline void setPixelColor(int n, byte r, byte g, byte b, byte w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } + inline void setPixelColor(int n, CRGB c) { setPixelColor(n, RGBW32(c.r,c.g,c.b,0)); } void setPixelColor(float i, uint32_t c, bool aa = true); - void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); } - void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); } + inline void setPixelColor(float i, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0, bool aa = true) { setPixelColor(i, RGBW32(r,g,b,w), aa); } + inline void setPixelColor(float i, CRGB c, bool aa = true) { setPixelColor(i, RGBW32(c.r,c.g,c.b,0), aa); } uint32_t getPixelColor(int i); // 1D support functions (some implement 2D as well) void blur(uint8_t); void fill(uint32_t c); void fade_out(uint8_t r); void fadeToBlackBy(uint8_t fadeBy); - void blendPixelColor(int n, uint32_t color, uint8_t blend); - void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.r,c.g,c.b,0), blend); } - void addPixelColor(int n, uint32_t color, bool fast = false); - void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); } // automatically inline - void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); } // automatically inline - void fadePixelColor(uint16_t n, uint8_t fade); - uint8_t get_random_wheel_index(uint8_t pos); + inline void blendPixelColor(int n, uint32_t color, uint8_t blend) { setPixelColor(n, color_blend(getPixelColor(n), color, blend)); } + inline void blendPixelColor(int n, CRGB c, uint8_t blend) { blendPixelColor(n, RGBW32(c.r,c.g,c.b,0), blend); } + inline void addPixelColor(int n, uint32_t color, bool fast = false) { setPixelColor(n, color_add(getPixelColor(n), color, fast)); } + inline void addPixelColor(int n, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(n, RGBW32(r,g,b,w), fast); } + inline void addPixelColor(int n, CRGB c, bool fast = false) { addPixelColor(n, RGBW32(c.r,c.g,c.b,0), fast); } + inline void fadePixelColor(uint16_t n, uint8_t fade) { setPixelColor(n, color_fade(getPixelColor(n), fade, true)); } uint32_t color_from_palette(uint16_t, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri = 255); uint32_t color_wheel(uint8_t pos); // 2D matrix - uint16_t virtualWidth(void) const; - uint16_t virtualHeight(void) const; - uint16_t nrOfVStrips(void) const; + uint16_t virtualWidth(void) const; // segment width in virtual pixels (accounts for groupping and spacing) + uint16_t virtualHeight(void) const; // segment height in virtual pixels (accounts for groupping and spacing) + uint16_t nrOfVStrips(void) const; // returns number of virtual vertical strips in 2D matrix (used to expand 1D effects into 2D) #ifndef WLED_DISABLE_2D uint16_t XY(uint16_t x, uint16_t y); // support function to get relative index within segment void setPixelColorXY(int x, int y, uint32_t c); // set relative pixel within segment with color - void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline - void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } // automatically inline + inline void setPixelColorXY(unsigned x, unsigned y, uint32_t c) { setPixelColorXY(int(x), int(y), c); } + inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } + inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } void setPixelColorXY(float x, float y, uint32_t c, bool aa = true); - void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } - void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); } + inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColorXY(x, y, RGBW32(r,g,b,w), aa); } + inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), aa); } uint32_t getPixelColorXY(uint16_t x, uint16_t y); // 2D support functions - void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend); - void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); } - void addPixelColorXY(int x, int y, uint32_t color, bool fast = false); - void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColorXY(x, y, RGBW32(r,g,b,w), fast); } // automatically inline - void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); } - void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade); + inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); } + inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), blend); } + inline void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { setPixelColorXY(x, y, color_add(getPixelColorXY(x,y), color, fast)); } + inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColorXY(x, y, RGBW32(r,g,b,w), fast); } + inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0), fast); } + inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), fade, true)); } void box_blur(uint16_t i, bool vertical, fract8 blur_amount); // 1D box blur (with weight) void blurRow(uint16_t row, fract8 blur_amount); void blurCol(uint16_t col, fract8 blur_amount); @@ -597,42 +627,43 @@ typedef struct Segment { void draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c); void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c); void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c); - void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline - void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0); - void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0)); } // automatic inline - void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0)); } // automatic inline + inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) { drawLine(x0, y0, x1, y1, RGBW32(c.r,c.g,c.b,0)); } // automatic inline + void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2 = 0, int8_t rotate = 0); + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0)); } // automatic inline + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0) { drawCharacter(chr, x, y, w, h, RGBW32(c.r,c.g,c.b,0), RGBW32(c2.r,c2.g,c2.b,0), rotate); } // automatic inline void wu_pixel(uint32_t x, uint32_t y, CRGB c); void blur1d(fract8 blur_amount); // blur all rows in 1 dimension - void blur2d(fract8 blur_amount) { blur(blur_amount); } - void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); } + inline void blur2d(fract8 blur_amount) { blur(blur_amount); } + inline void fill_solid(CRGB c) { fill(RGBW32(c.r,c.g,c.b,0)); } void nscale8(uint8_t scale); #else - uint16_t XY(uint16_t x, uint16_t y) { return x; } - void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); } - void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); } - void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); } - void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); } - void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); } - void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); } - uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); } - void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); } - void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); } - void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { addPixelColor(x, color, fast); } - void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(x, RGBW32(r,g,b,w), fast); } - void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); } - void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); } - void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {} - void blurRow(uint16_t row, fract8 blur_amount) {} - void blurCol(uint16_t col, fract8 blur_amount) {} - void moveX(int8_t delta, bool wrap = false) {} - void moveY(int8_t delta, bool wrap = false) {} - void move(uint8_t dir, uint8_t delta, bool wrap = false) {} - void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c) {} - void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {} - void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {} - void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color) {} - void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {} - void wu_pixel(uint32_t x, uint32_t y, CRGB c) {} + inline uint16_t XY(uint16_t x, uint16_t y) { return x; } + inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor(x, c); } + inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColor(x, RGBW32(r,g,b,w)); } + inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0)); } + inline void setPixelColorXY(float x, float y, uint32_t c, bool aa = true) { setPixelColor(x, c, aa); } + inline void setPixelColorXY(float x, float y, byte r, byte g, byte b, byte w = 0, bool aa = true) { setPixelColor(x, RGBW32(r,g,b,w), aa); } + inline void setPixelColorXY(float x, float y, CRGB c, bool aa = true) { setPixelColor(x, RGBW32(c.r,c.g,c.b,0), aa); } + inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(x); } + inline void blendPixelColorXY(uint16_t x, uint16_t y, uint32_t c, uint8_t blend) { blendPixelColor(x, c, blend); } + inline void blendPixelColorXY(uint16_t x, uint16_t y, CRGB c, uint8_t blend) { blendPixelColor(x, RGBW32(c.r,c.g,c.b,0), blend); } + inline void addPixelColorXY(int x, int y, uint32_t color, bool fast = false) { addPixelColor(x, color, fast); } + inline void addPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0, bool fast = false) { addPixelColor(x, RGBW32(r,g,b,w), fast); } + inline void addPixelColorXY(int x, int y, CRGB c, bool fast = false) { addPixelColor(x, RGBW32(c.r,c.g,c.b,0), fast); } + inline void fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { fadePixelColor(x, fade); } + inline void box_blur(uint16_t i, bool vertical, fract8 blur_amount) {} + inline void blurRow(uint16_t row, fract8 blur_amount) {} + inline void blurCol(uint16_t col, fract8 blur_amount) {} + inline void moveX(int8_t delta, bool wrap = false) {} + inline void moveY(int8_t delta, bool wrap = false) {} + inline void move(uint8_t dir, uint8_t delta, bool wrap = false) {} + inline void fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB c) {} + inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint32_t c) {} + inline void drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, CRGB c) {} + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t = 0, int8_t = 0) {} + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB color) {} + inline void drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, CRGB c, CRGB c2, int8_t rotate = 0) {} + inline void wu_pixel(uint32_t x, uint32_t y, CRGB c) {} #endif } segment; //static int segSize = sizeof(Segment); @@ -655,10 +686,7 @@ class WS2812FX { // 96 bytes WS2812FX() : paletteFade(0), paletteBlend(0), - milliampsPerLed(55), cctBlending(0), - ablMilliampsMax(ABL_MILLIAMPS_DEFAULT), - currentMilliamps(0), now(millis()), timebase(0), isMatrix(false), @@ -670,6 +698,7 @@ class WS2812FX { // 96 bytes _colors_t{0,0,0}, _virtualSegmentLength(0), // true private variables + _suspend(false), _length(DEFAULT_LED_COUNT), _brightness(DEFAULT_BRIGHTNESS), _transitionDur(750), @@ -718,41 +747,42 @@ class WS2812FX { // 96 bytes void #ifdef WLED_DEBUG - printSize(), + printSize(), // prints memory usage for strip components #endif - finalizeInit(), - service(void), - setMode(uint8_t segid, uint8_t m), - setColor(uint8_t slot, uint32_t c), - setCCT(uint16_t k), - setBrightness(uint8_t b, bool direct = false), - setRange(uint16_t i, uint16_t i2, uint32_t col), - setTransitionMode(bool t), - purgeSegments(bool force = false), + finalizeInit(), // initialises strip components + service(void), // executes effect functions when due and calls strip.show() + setMode(uint8_t segid, uint8_t m), // sets effect/mode for given segment (high level API) + setColor(uint8_t slot, uint32_t c), // sets color (in slot) for given segment (high level API) + setCCT(uint16_t k), // sets global CCT (either in relative 0-255 value or in K) + setBrightness(uint8_t b, bool direct = false), // sets strip brightness + setRange(uint16_t i, uint16_t i2, uint32_t col), // used for clock overlay + purgeSegments(void), // removes inactive segments from RAM (may incure penalty and memory fragmentation but reduces vector footprint) setSegment(uint8_t n, uint16_t start, uint16_t stop, uint8_t grouping = 1, uint8_t spacing = 0, uint16_t offset = UINT16_MAX, uint16_t startY=0, uint16_t stopY=1), setMainSegmentId(uint8_t n), - restartRuntime(), - resetSegments(), - makeAutoSegments(bool forceReset = false), - fixInvalidSegments(), - setPixelColor(int n, uint32_t c), - show(void), - setTargetFps(uint8_t fps); + resetSegments(), // marks all segments for reset + makeAutoSegments(bool forceReset = false), // will create segments based on configured outputs + fixInvalidSegments(), // fixes incorrect segment configuration + setPixelColor(unsigned n, uint32_t c), // paints absolute strip pixel with index n and color c + show(void), // initiates LED output + setTargetFps(uint8_t fps), + addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name), // add effect to the list; defined in FX.cpp + setupEffectData(void); // add default effects to the list; defined in FX.cpp - void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); } - void fill(uint32_t c) { for (int i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline) - void addEffect(uint8_t id, mode_ptr mode_fn, const char *mode_name); // add effect to the list; defined in FX.cpp - void setupEffectData(void); // add default effects to the list; defined in FX.cpp - - // outsmart the compiler :) by correctly overloading - inline void setPixelColor(int n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } - inline void setPixelColor(int n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); } - inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments. - inline void setShowCallback(show_callback cb) { _callback = cb; } - inline void setTransition(uint16_t t) { _transitionDur = t; } + inline void restartRuntime() { for (Segment &seg : _segments) seg.markForReset(); } + inline void setTransitionMode(bool t) { for (Segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); } + inline void setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setColor(slot, RGBW32(r,g,b,w)); } + inline void setPixelColor(unsigned n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0) { setPixelColor(n, RGBW32(r,g,b,w)); } + inline void setPixelColor(unsigned n, CRGB c) { setPixelColor(n, c.red, c.green, c.blue); } + inline void fill(uint32_t c) { for (unsigned i = 0; i < getLengthTotal(); i++) setPixelColor(i, c); } // fill whole strip with color (inline) + inline void trigger(void) { _triggered = true; } // Forces the next frame to be computed on all active segments. + inline void setShowCallback(show_callback cb) { _callback = cb; } + inline void setTransition(uint16_t t) { _transitionDur = t; } // sets transition time (in ms) inline void appendSegment(const Segment &seg = Segment()) { if (_segments.size() < getMaxSegments()) _segments.push_back(seg); } + inline void suspend(void) { _suspend = true; } // will suspend (and canacel) strip.service() execution + inline void resume(void) { _suspend = false; } // will resume strip.service() execution bool + paletteFade, checkSegmentAlignment(void), hasRGBWBus(void), hasCCTBus(void), @@ -760,14 +790,14 @@ class WS2812FX { // 96 bytes isUpdating(void), deserializeMap(uint8_t n=0); - inline bool isServicing(void) { return _isServicing; } - inline bool hasWhiteChannel(void) {return _hasWhiteChannel;} - inline bool isOffRefreshRequired(void) {return _isOffRefreshRequired;} + inline bool isServicing(void) { return _isServicing; } // returns true if strip.service() is executing + inline bool hasWhiteChannel(void) { return _hasWhiteChannel; } // returns true if strip contains separate white chanel + inline bool isOffRefreshRequired(void) { return _isOffRefreshRequired; } // returns true if strip requires regular updates (i.e. TM1814 chipset) + inline bool isSuspended(void) { return _suspend; } // returns true if strip.service() execution is suspended + inline bool needsUpdate(void) { return _triggered; } // returns true if strip received a trigger() request uint8_t - paletteFade, paletteBlend, - milliampsPerLed, cctBlending, getActiveSegmentsNum(void), getFirstSelectedSegId(void), @@ -775,34 +805,33 @@ class WS2812FX { // 96 bytes getActiveSegsLightCapabilities(bool selectedOnly = false), setPixelSegment(uint8_t n); - inline uint8_t getBrightness(void) { return _brightness; } - inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value) - inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments - inline uint8_t getCurrSegmentId(void) { return _segment_index; } - inline uint8_t getMainSegmentId(void) { return _mainSegment; } - inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count - inline uint8_t getTargetFps() { return _targetFps; } - inline uint8_t getModeCount() { return _modeCount; } + inline uint8_t getBrightness(void) { return _brightness; } // returns current strip brightness + inline uint8_t getMaxSegments(void) { return MAX_NUM_SEGMENTS; } // returns maximum number of supported segments (fixed value) + inline uint8_t getSegmentsNum(void) { return _segments.size(); } // returns currently present segments + inline uint8_t getCurrSegmentId(void) { return _segment_index; } // returns current segment index (only valid while strip.isServicing()) + inline uint8_t getMainSegmentId(void) { return _mainSegment; } // returns main segment index + inline uint8_t getPaletteCount() { return 13 + GRADIENT_PALETTE_COUNT; } // will only return built-in palette count + inline uint8_t getTargetFps() { return _targetFps; } // returns rough FPS value for las 2s interval + inline uint8_t getModeCount() { return _modeCount; } // returns number of registered modes/effects uint16_t - ablMilliampsMax, - currentMilliamps, getLengthPhysical(void), getLengthTotal(void), // will include virtual/nonexistent pixels in matrix - getFps(); + getFps(), + getMappedPixelIndex(uint16_t index); - inline uint16_t getFrameTime(void) { return _frametime; } - inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; } - inline uint16_t getLength(void) { return _length; } // 2D matrix may have less pixels than W*H - inline uint16_t getTransition(void) { return _transitionDur; } + inline uint16_t getFrameTime(void) { return _frametime; } // returns amount of time a frame should take (in ms) + inline uint16_t getMinShowDelay(void) { return MIN_SHOW_DELAY; } // returns minimum amount of time strip.service() can be delayed (constant) + inline uint16_t getLength(void) { return _length; } // returns actual amount of LEDs on a strip (2D matrix may have less LEDs than W*H) + inline uint16_t getTransition(void) { return _transitionDur; } // returns currently set transition time (in ms) uint32_t now, timebase, getPixelColor(uint16_t); - inline uint32_t getLastShow(void) { return _lastShow; } - inline uint32_t segColor(uint8_t i) { return _colors_t[i]; } + inline uint32_t getLastShow(void) { return _lastShow; } // returns millis() timestamp of last strip.show() call + inline uint32_t segColor(uint8_t i) { return _colors_t[i]; } // returns currently valid color (for slot i) AKA SEGCOLOR(); may be blended between two colors while in transition const char * getModeData(uint8_t id = 0) { return (id && id<_modeCount) ? _modeData[id] : PSTR("Solid"); } @@ -811,9 +840,9 @@ class WS2812FX { // 96 bytes getModeDataSrc(void) { return &(_modeData[0]); } // vectors use arrays for underlying data Segment& getSegment(uint8_t id); - inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; } - inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; } - inline Segment* getSegments(void) { return &(_segments[0]); } + inline Segment& getFirstSelectedSeg(void) { return _segments[getFirstSelectedSegId()]; } // returns reference to first segment that is "selected" + inline Segment& getMainSegment(void) { return _segments[getMainSegmentId()]; } // returns reference to main segment + inline Segment* getSegments(void) { return &(_segments[0]); } // returns pointer to segment vector structure (warning: use carefully) // 2D support (panels) bool @@ -849,16 +878,14 @@ class WS2812FX { // 96 bytes std::vector panel; #endif - void - setUpMatrix(), - setPixelColorXY(int x, int y, uint32_t c); + void setUpMatrix(); // sets up automatic matrix ledmap from panel configuration // outsmart the compiler :) by correctly overloading - inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } // automatically inline - inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } + inline void setPixelColorXY(int x, int y, uint32_t c) { setPixelColor((unsigned)(y * Segment::maxWidth + x), c); } + inline void setPixelColorXY(int x, int y, byte r, byte g, byte b, byte w = 0) { setPixelColorXY(x, y, RGBW32(r,g,b,w)); } + inline void setPixelColorXY(int x, int y, CRGB c) { setPixelColorXY(x, y, RGBW32(c.r,c.g,c.b,0)); } - uint32_t - getPixelColorXY(uint16_t, uint16_t); + inline uint32_t getPixelColorXY(uint16_t x, uint16_t y) { return getPixelColor(isMatrix ? y * Segment::maxWidth + x : x);} // end 2D support @@ -875,6 +902,8 @@ class WS2812FX { // 96 bytes friend class Segment; private: + volatile bool _suspend; + uint16_t _length; uint8_t _brightness; uint16_t _transitionDur; @@ -908,12 +937,10 @@ class WS2812FX { // 96 bytes uint16_t _qStart, _qStop, _qStartY, _qStopY; uint8_t _qGrouping, _qSpacing; uint16_t _qOffset; - - uint8_t - estimateCurrentAndLimitBri(void); - +/* void setUpSegmentFromQueuedChanges(void); +*/ }; extern const char JSON_mode_names[]; diff --git a/wled00/FX_2Dfcn.cpp b/wled00/FX_2Dfcn.cpp index 71000e904..6f5075d08 100644 --- a/wled00/FX_2Dfcn.cpp +++ b/wled00/FX_2Dfcn.cpp @@ -36,14 +36,9 @@ // so matrix should disable regular ledmap processing void WS2812FX::setUpMatrix() { #ifndef WLED_DISABLE_2D - // erase old ledmap, just in case. - if (customMappingTable != nullptr) delete[] customMappingTable; - customMappingTable = nullptr; - customMappingSize = 0; - // isMatrix is set in cfg.cpp or set.cpp if (isMatrix) { - // calculate width dynamically because it will have gaps + // calculate width dynamically because it may have gaps Segment::maxWidth = 1; Segment::maxHeight = 1; for (size_t i = 0; i < panel.size(); i++) { @@ -68,15 +63,17 @@ void WS2812FX::setUpMatrix() { return; } - customMappingTable = new uint16_t[Segment::maxWidth * Segment::maxHeight]; + customMappingSize = 0; // prevent use of mapping if anything goes wrong + + if (customMappingTable == nullptr) customMappingTable = new uint16_t[getLengthTotal()]; if (customMappingTable != nullptr) { - customMappingSize = Segment::maxWidth * Segment::maxHeight; + customMappingSize = getLengthTotal(); // fill with empty in case we don't fill the entire matrix - for (size_t i = 0; i< customMappingSize; i++) { - customMappingTable[i] = (uint16_t)-1; - } + unsigned matrixSize = Segment::maxWidth * Segment::maxHeight; + for (unsigned i = 0; i(); + JsonArray map = pDoc->as(); gapSize = map.size(); - if (!map.isNull() && gapSize >= customMappingSize) { // not an empty map + if (!map.isNull() && gapSize >= matrixSize) { // not an empty map gapTable = new int8_t[gapSize]; if (gapTable) for (size_t i = 0; i < gapSize; i++) { gapTable[i] = constrain(map[i], -1, 1); @@ -134,7 +131,7 @@ void WS2812FX::setUpMatrix() { #ifdef WLED_DEBUG DEBUG_PRINT(F("Matrix ledmap:")); - for (uint16_t i=0; i= _length) return; - busses.setPixelColor(index, col); -} - -// returns RGBW values of pixel -uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { -#ifndef WLED_DISABLE_2D - uint16_t index = (y * Segment::maxWidth + x); -#else - uint16_t index = x; -#endif - if (index < customMappingSize) index = customMappingTable[index]; - if (index >= _length) return 0; - return busses.getPixelColor(index); -} /////////////////////////////////////////////////////////// // Segment:: routines @@ -188,18 +160,19 @@ uint32_t WS2812FX::getPixelColorXY(uint16_t x, uint16_t y) { #ifndef WLED_DISABLE_2D // XY(x,y) - gets pixel index within current segment (often used to reference leds[] array element) -uint16_t /*IRAM_ATTR*/ Segment::XY(uint16_t x, uint16_t y) { +uint16_t IRAM_ATTR Segment::XY(uint16_t x, uint16_t y) +{ uint16_t width = virtualWidth(); // segment width in logical pixels (can be 0 if segment is inactive) uint16_t height = virtualHeight(); // segment height in logical pixels (is always >= 1) return isActive() ? (x%width) + (y%height) * width : 0; } -void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col) +void IRAM_ATTR Segment::setPixelColorXY(int x, int y, uint32_t col) { if (!isActive()) return; // not active if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit - uint8_t _bri_t = currentBri(on ? opacity : 0); + uint8_t _bri_t = currentBri(); if (_bri_t < 255) { byte r = scale8(R(col), _bri_t); byte g = scale8(G(col), _bri_t); @@ -216,23 +189,29 @@ void /*IRAM_ATTR*/ Segment::setPixelColorXY(int x, int y, uint32_t col) y *= groupLength(); // expand to physical pixels if (x >= width() || y >= height()) return; // if pixel would fall out of segment just exit + uint32_t tmpCol = col; for (int j = 0; j < grouping; j++) { // groupping vertically for (int g = 0; g < grouping; g++) { // groupping horizontally uint16_t xX = (x+g), yY = (y+j); if (xX >= width() || yY >= height()) continue; // we have reached one dimension's end - strip.setPixelColorXY(start + xX, startY + yY, col); +#ifndef WLED_DISABLE_MODE_BLEND + // if blending modes, blend with underlying pixel + if (_modeBlend) tmpCol = color_blend(strip.getPixelColorXY(start + xX, startY + yY), col, 0xFFFFU - progress(), true); +#endif + + strip.setPixelColorXY(start + xX, startY + yY, tmpCol); if (mirror) { //set the corresponding horizontally mirrored pixel - if (transpose) strip.setPixelColorXY(start + xX, startY + height() - yY - 1, col); - else strip.setPixelColorXY(start + width() - xX - 1, startY + yY, col); + if (transpose) strip.setPixelColorXY(start + xX, startY + height() - yY - 1, tmpCol); + else strip.setPixelColorXY(start + width() - xX - 1, startY + yY, tmpCol); } if (mirror_y) { //set the corresponding vertically mirrored pixel - if (transpose) strip.setPixelColorXY(start + width() - xX - 1, startY + yY, col); - else strip.setPixelColorXY(start + xX, startY + height() - yY - 1, col); + if (transpose) strip.setPixelColorXY(start + width() - xX - 1, startY + yY, tmpCol); + else strip.setPixelColorXY(start + xX, startY + height() - yY - 1, tmpCol); } if (mirror_y && mirror) { //set the corresponding vertically AND horizontally mirrored pixel - strip.setPixelColorXY(width() - xX - 1, height() - yY - 1, col); + strip.setPixelColorXY(width() - xX - 1, height() - yY - 1, tmpCol); } } } @@ -283,7 +262,7 @@ void Segment::setPixelColorXY(float x, float y, uint32_t col, bool aa) } // returns RGBW values of pixel -uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) { +uint32_t IRAM_ATTR Segment::getPixelColorXY(uint16_t x, uint16_t y) { if (!isActive()) return 0; // not active if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return 0; // if pixel would fall out of virtual segment just exit if (reverse ) x = virtualWidth() - x - 1; @@ -295,41 +274,9 @@ uint32_t Segment::getPixelColorXY(uint16_t x, uint16_t y) { return strip.getPixelColorXY(start + x, startY + y); } -// Blends the specified color with the existing pixel color. -void Segment::blendPixelColorXY(uint16_t x, uint16_t y, uint32_t color, uint8_t blend) { - setPixelColorXY(x, y, color_blend(getPixelColorXY(x,y), color, blend)); -} - -// Adds the specified color with the existing pixel color perserving color balance. -void Segment::addPixelColorXY(int x, int y, uint32_t color, bool fast) { - if (!isActive()) return; // not active - if (x >= virtualWidth() || y >= virtualHeight() || x<0 || y<0) return; // if pixel would fall out of virtual segment just exit - uint32_t col = getPixelColorXY(x,y); - uint8_t r = R(col); - uint8_t g = G(col); - uint8_t b = B(col); - uint8_t w = W(col); - if (fast) { - r = qadd8(r, R(color)); - g = qadd8(g, G(color)); - b = qadd8(b, B(color)); - w = qadd8(w, W(color)); - col = RGBW32(r,g,b,w); - } else { - col = color_add(col, color); - } - setPixelColorXY(x, y, col); -} - -void Segment::fadePixelColorXY(uint16_t x, uint16_t y, uint8_t fade) { - if (!isActive()) return; // not active - CRGB pix = CRGB(getPixelColorXY(x,y)).nscale8_video(fade); - setPixelColorXY(x, y, pix); -} - // blurRow: perform a blur on a row of a rectangular matrix void Segment::blurRow(uint16_t row, fract8 blur_amount) { - if (!isActive()) return; // not active + if (!isActive() || blur_amount == 0) return; // not active const uint_fast16_t cols = virtualWidth(); const uint_fast16_t rows = virtualHeight(); @@ -338,7 +285,7 @@ void Segment::blurRow(uint16_t row, fract8 blur_amount) { uint8_t keep = 255 - blur_amount; uint8_t seep = blur_amount >> 1; CRGB carryover = CRGB::Black; - for (uint_fast16_t x = 0; x < cols; x++) { + for (unsigned x = 0; x < cols; x++) { CRGB cur = getPixelColorXY(x, row); CRGB before = cur; // remember color before blur CRGB part = cur; @@ -357,7 +304,7 @@ void Segment::blurRow(uint16_t row, fract8 blur_amount) { // blurCol: perform a blur on a column of a rectangular matrix void Segment::blurCol(uint16_t col, fract8 blur_amount) { - if (!isActive()) return; // not active + if (!isActive() || blur_amount == 0) return; // not active const uint_fast16_t cols = virtualWidth(); const uint_fast16_t rows = virtualHeight(); @@ -366,7 +313,7 @@ void Segment::blurCol(uint16_t col, fract8 blur_amount) { uint8_t keep = 255 - blur_amount; uint8_t seep = blur_amount >> 1; CRGB carryover = CRGB::Black; - for (uint_fast16_t y = 0; y < rows; y++) { + for (unsigned y = 0; y < rows; y++) { CRGB cur = getPixelColorXY(col, y); CRGB part = cur; CRGB before = cur; // remember color before blur @@ -385,7 +332,7 @@ void Segment::blurCol(uint16_t col, fract8 blur_amount) { // 1D Box blur (with added weight - blur_amount: [0=no blur, 255=max blur]) void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) { - if (!isActive()) return; // not active + if (!isActive() || blur_amount == 0) return; // not active const uint16_t cols = virtualWidth(); const uint16_t rows = virtualHeight(); const uint16_t dim1 = vertical ? rows : cols; @@ -395,7 +342,7 @@ void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) { const float keep = 3.f - 2.f*seep; // 1D box blur CRGB tmp[dim1]; - for (uint16_t j = 0; j < dim1; j++) { + for (int j = 0; j < dim1; j++) { uint16_t x = vertical ? i : j; uint16_t y = vertical ? j : i; int16_t xp = vertical ? x : x-1; // "signed" to prevent underflow @@ -411,7 +358,7 @@ void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) { b = (curr.b*keep + (prev.b + next.b)*seep) / 3; tmp[j] = CRGB(r,g,b); } - for (uint16_t j = 0; j < dim1; j++) { + for (int j = 0; j < dim1; j++) { uint16_t x = vertical ? i : j; uint16_t y = vertical ? j : i; setPixelColorXY(x, y, tmp[j]); @@ -434,7 +381,7 @@ void Segment::box_blur(uint16_t i, bool vertical, fract8 blur_amount) { void Segment::blur1d(fract8 blur_amount) { const uint16_t rows = virtualHeight(); - for (uint16_t y = 0; y < rows; y++) blurRow(y, blur_amount); + for (unsigned y = 0; y < rows; y++) blurRow(y, blur_amount); } void Segment::moveX(int8_t delta, bool wrap) { @@ -492,7 +439,7 @@ void Segment::move(uint8_t dir, uint8_t delta, bool wrap) { } void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) { - if (!isActive()) return; // not active + if (!isActive() || radius == 0) return; // not active // Bresenham’s Algorithm int d = 3 - (2*radius); int y = radius, x = 0; @@ -517,7 +464,7 @@ void Segment::draw_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) { // by stepko, taken from https://editor.soulmatelights.com/gallery/573-blobs void Segment::fill_circle(uint16_t cx, uint16_t cy, uint8_t radius, CRGB col) { - if (!isActive()) return; // not active + if (!isActive() || radius == 0) return; // not active const uint16_t cols = virtualWidth(); const uint16_t rows = virtualHeight(); for (int16_t y = -radius; y <= radius; y++) { @@ -534,7 +481,7 @@ void Segment::nscale8(uint8_t scale) { if (!isActive()) return; // not active const uint16_t cols = virtualWidth(); const uint16_t rows = virtualHeight(); - for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { + for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) { setPixelColorXY(x, y, CRGB(getPixelColorXY(x, y)).nscale8(scale)); } } @@ -565,7 +512,7 @@ void Segment::drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint3 // draws a raster font character on canvas // only supports: 4x6=24, 5x8=40, 5x12=60, 6x8=48 and 7x9=63 fonts ATM -void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2) { +void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, uint8_t h, uint32_t color, uint32_t col2, int8_t rotate) { if (!isActive()) return; // not active if (chr < 32 || chr > 126) return; // only ASCII 32-126 supported chr -= 32; // align with font table entries @@ -578,9 +525,6 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, //if (w<5 || w>6 || h!=8) return; for (int i = 0; i= rows) break; // drawing off-screen uint8_t bits = 0; switch (font) { case 24: bits = pgm_read_byte_near(&console_font_4x6[(chr * h) + i]); break; // 5x8 font @@ -592,8 +536,16 @@ void Segment::drawCharacter(unsigned char chr, int16_t x, int16_t y, uint8_t w, } col = ColorFromPalette(grad, (i+1)*255/h, 255, NOBLEND); for (int j = 0; j= 0 || x0 < cols) && ((bits>>(j+(8-w))) & 0x01)) { // bit set & drawing on-screen + int x0, y0; + switch (rotate) { + case -1: x0 = x + (h-1) - i; y0 = y + (w-1) - j; break; // -90 deg + case -2: + case 2: x0 = x + j; y0 = y + (h-1) - i; break; // 180 deg + case 1: x0 = x + i; y0 = y + j; break; // +90 deg + default: x0 = x + (w-1) - j; y0 = y + i; break; // no rotation + } + if (x0 < 0 || x0 >= cols || y0 < 0 || y0 >= rows) continue; // drawing off-screen + if (((bits>>(j+(8-w))) & 0x01)) { // bit set setPixelColorXY(x0, y0, col); } } diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 74d61cb4b..4f334779d 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -77,92 +77,111 @@ 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::_randomPalette = CRGBPalette16(DEFAULT_COLOR); +CRGBPalette16 Segment::_newRandomPalette = CRGBPalette16(DEFAULT_COLOR); +unsigned long Segment::_lastPaletteChange = 0; // perhaps it should be per segment + +#ifndef WLED_DISABLE_MODE_BLEND +bool Segment::_modeBlend = false; +#endif + // copy constructor Segment::Segment(const Segment &orig) { - //DEBUG_PRINTLN(F("-- Copy segment constructor --")); + //DEBUG_PRINTF("-- Copy segment constructor: %p -> %p\n", &orig, this); memcpy((void*)this, (void*)&orig, sizeof(Segment)); - transitional = false; // copied segment cannot be in transition + _t = nullptr; // copied segment cannot be in transition name = nullptr; data = nullptr; _dataLen = 0; - _t = nullptr; if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); } - //if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } } // move constructor Segment::Segment(Segment &&orig) noexcept { - //DEBUG_PRINTLN(F("-- Move segment constructor --")); + //DEBUG_PRINTF("-- Move segment constructor: %p -> %p\n", &orig, this); memcpy((void*)this, (void*)&orig, sizeof(Segment)); - orig.transitional = false; // old segment cannot be in transition any more + orig._t = nullptr; // old segment cannot be in transition any more orig.name = nullptr; orig.data = nullptr; orig._dataLen = 0; - orig._t = nullptr; } // copy assignment Segment& Segment::operator= (const Segment &orig) { - //DEBUG_PRINTLN(F("-- Copying segment --")); + //DEBUG_PRINTF("-- Copying segment: %p -> %p\n", &orig, this); if (this != &orig) { // clean destination - transitional = false; // copied segment cannot be in transition - if (name) delete[] name; - if (_t) delete _t; + if (name) { delete[] name; name = nullptr; } + stopTransition(); deallocateData(); // copy source memcpy((void*)this, (void*)&orig, sizeof(Segment)); - transitional = false; // erase pointers to allocated data - name = nullptr; data = nullptr; _dataLen = 0; - _t = nullptr; // copy source data if (orig.name) { name = new char[strlen(orig.name)+1]; if (name) strcpy(name, orig.name); } if (orig.data) { if (allocateData(orig._dataLen)) memcpy(data, orig.data, orig._dataLen); } - //if (orig._t) { _t = new Transition(orig._t->_dur, orig._t->_briT, orig._t->_cctT, orig._t->_colorT); } } return *this; } // move assignment Segment& Segment::operator= (Segment &&orig) noexcept { - //DEBUG_PRINTLN(F("-- Moving segment --")); + //DEBUG_PRINTF("-- Moving segment: %p -> %p\n", &orig, this); if (this != &orig) { - transitional = false; // just temporary if (name) { delete[] name; name = nullptr; } // free old name + stopTransition(); deallocateData(); // free old runtime data - if (_t) { delete _t; _t = nullptr; } memcpy((void*)this, (void*)&orig, sizeof(Segment)); - orig.transitional = false; // old segment cannot be in transition orig.name = nullptr; orig.data = nullptr; orig._dataLen = 0; - orig._t = nullptr; + orig._t = nullptr; // old segment cannot be in transition } return *this; } -bool Segment::allocateData(size_t len) { - if (data && _dataLen == len) return true; //already allocated - deallocateData(); - if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) return false; //not enough memory +// allocates effect data buffer on heap and initialises (erases) it +bool IRAM_ATTR Segment::allocateData(size_t len) { + if (len == 0) return false; // nothing to do + if (data && _dataLen >= len) { // already allocated enough (reduce fragmentation) + if (call == 0) memset(data, 0, len); // erase buffer if called during effect initialisation + return true; + } + //DEBUG_PRINTF("-- Allocating data (%d): %p\n", len, this); + deallocateData(); // if the old buffer was smaller release it first + if (Segment::getUsedSegmentData() + len > MAX_SEGMENT_DATA) { + // not enough memory + DEBUG_PRINT(F("!!! Effect RAM depleted: ")); + DEBUG_PRINTF("%d/%d !!!\n", len, Segment::getUsedSegmentData()); + errorFlag = ERR_NORAM; + return false; + } // do not use SPI RAM on ESP32 since it is slow - data = (byte*) malloc(len); - if (!data) return false; //allocation failed + data = (byte*)calloc(len, sizeof(byte)); + if (!data) { DEBUG_PRINTLN(F("!!! Allocation failed. !!!")); return false; } // allocation failed Segment::addUsedSegmentData(len); + //DEBUG_PRINTF("--- Allocated data (%p): %d/%d -> %p\n", this, len, Segment::getUsedSegmentData(), data); _dataLen = len; - memset(data, 0, len); return true; } -void Segment::deallocateData() { - if (!data) return; - free(data); +void IRAM_ATTR Segment::deallocateData() { + if (!data) { _dataLen = 0; return; } + //DEBUG_PRINTF("--- Released data (%p): %d/%d -> %p\n", this, _dataLen, Segment::getUsedSegmentData(), data); + if ((Segment::getUsedSegmentData() > 0) && (_dataLen > 0)) { // check that we don't have a dangling / inconsistent data pointer + free(data); + } else { + DEBUG_PRINT(F("---- Released data ")); + DEBUG_PRINTF("(%p): ", this); + DEBUG_PRINT(F("inconsistent UsedSegmentData ")); + DEBUG_PRINTF("(%d/%d)", _dataLen, Segment::getUsedSegmentData()); + DEBUG_PRINTLN(F(", cowardly refusing to free nothing.")); + } data = nullptr; - Segment::addUsedSegmentData(-_dataLen); + Segment::addUsedSegmentData(_dataLen <= Segment::getUsedSegmentData() ? -_dataLen : -Segment::getUsedSegmentData()); _dataLen = 0; } @@ -175,17 +194,13 @@ void Segment::deallocateData() { */ void Segment::resetIfRequired() { if (!reset) return; - - deallocateData(); + //DEBUG_PRINTF("-- Segment reset: %p\n", this); + if (data && _dataLen > 0) memset(data, 0, _dataLen); // prevent heap fragmentation (just erase buffer instead of deallocateData()) next_time = 0; step = 0; call = 0; aux0 = 0; aux1 = 0; reset = false; } -CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { - static unsigned long _lastPaletteChange = 0; // perhaps it should be per segment - static CRGBPalette16 randomPalette = CRGBPalette16(DEFAULT_COLOR); - static CRGBPalette16 prevRandomPalette = CRGBPalette16(CRGB(BLACK)); - byte tcp[72]; +CRGBPalette16 IRAM_ATTR &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; //default palette. Differs depending on effect @@ -205,28 +220,19 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { switch (pal) { case 0: //default palette. Exceptions for specific effects above targetPalette = PartyColors_p; break; - case 1: {//periodically replace palette with a random one. Transition palette change in 500ms - uint32_t timeSinceLastChange = millis() - _lastPaletteChange; + case 1: {//periodically replace palette with a random one + unsigned long timeSinceLastChange = millis() - _lastPaletteChange; if (timeSinceLastChange > randomPaletteChangeTime * 1000U) { - prevRandomPalette = randomPalette; - randomPalette = CRGBPalette16( + _randomPalette = _newRandomPalette; + _newRandomPalette = CRGBPalette16( CHSV(random8(), random8(160, 255), random8(128, 255)), CHSV(random8(), random8(160, 255), random8(128, 255)), CHSV(random8(), random8(160, 255), random8(128, 255)), CHSV(random8(), random8(160, 255), random8(128, 255))); _lastPaletteChange = millis(); - timeSinceLastChange = 0; - } - if (timeSinceLastChange <= 250) { - targetPalette = prevRandomPalette; - // there needs to be 255 palette blends (48) for full blend but that is too resource intensive - // so 128 is a compromise (we need to perform full blend of the two palettes as each segment can have random - // palette selected but only 2 static palettes are used) - size_t noOfBlends = ((128U * timeSinceLastChange) / 250U); - for (size_t i=0; i245) { targetPalette = strip.customPalettes[255-pal]; // we checked bounds above } else { + byte tcp[72]; memcpy_P(tcp, (byte*)pgm_read_dword(&(gGradientPalettes[pal-13])), 72); targetPalette.loadDynamicGradientPalette(tcp); } @@ -277,84 +284,192 @@ CRGBPalette16 &Segment::loadPalette(CRGBPalette16 &targetPalette, uint8_t pal) { } void Segment::startTransition(uint16_t dur) { - if (!dur) { - transitional = false; - if (_t) { - delete _t; - _t = nullptr; - } + if (dur == 0) { + if (isInTransition()) _t->_dur = dur; // this will stop transition in next handleTransisiton() return; } - if (transitional && _t) return; // already in transition no need to store anything + if (isInTransition()) return; // already in transition no need to store anything // starting a transition has to occur before change so we get current values 1st _t = new Transition(dur); // no previous transition running if (!_t) return; // failed to allocate data - CRGBPalette16 _palT = CRGBPalette16(DEFAULT_COLOR); loadPalette(_palT, palette); - _t->_briT = on ? opacity : 0; - _t->_cctT = cct; - _t->_palT = _palT; - _t->_modeP = mode; - for (size_t i=0; i_colorT[i] = colors[i]; - transitional = true; // setOption(SEG_OPTION_TRANSITIONAL, true); -} - -// transition progression between 0-65535 -uint16_t Segment::progress() { - if (!transitional || !_t) return 0xFFFFU; - unsigned long timeNow = millis(); - if (timeNow - _t->_start > _t->_dur || _t->_dur == 0) return 0xFFFFU; - return (timeNow - _t->_start) * 0xFFFFU / _t->_dur; -} - -uint8_t Segment::currentBri(uint8_t briNew, bool useCct) { - uint32_t prog = progress(); - if (transitional && _t && prog < 0xFFFFU) { - if (useCct) return ((briNew * prog) + _t->_cctT * (0xFFFFU - prog)) >> 16; - else return ((briNew * prog) + _t->_briT * (0xFFFFU - prog)) >> 16; + //DEBUG_PRINTF("-- Started transition: %p (%p)\n", this, _t); + loadPalette(_t->_palT, palette); + _t->_briT = on ? opacity : 0; + _t->_cctT = cct; +#ifndef WLED_DISABLE_MODE_BLEND + if (modeBlending) { + swapSegenv(_t->_segT); + _t->_modeT = mode; + _t->_segT._dataLenT = 0; + _t->_segT._dataT = nullptr; + if (_dataLen > 0 && data) { + _t->_segT._dataT = (byte *)malloc(_dataLen); + if (_t->_segT._dataT) { + //DEBUG_PRINTF("-- Allocated duplicate data (%d) for %p: %p\n", _dataLen, this, _t->_segT._dataT); + memcpy(_t->_segT._dataT, data, _dataLen); + _t->_segT._dataLenT = _dataLen; + } + } } else { - return briNew; + for (size_t i=0; i_segT._colorT[i] = colors[i]; + } +#else + for (size_t i=0; i_colorT[i] = colors[i]; +#endif +} + +void Segment::stopTransition() { + if (isInTransition()) { + //DEBUG_PRINTF("-- Stopping transition: %p\n", this); + #ifndef WLED_DISABLE_MODE_BLEND + if (_t->_segT._dataT && _t->_segT._dataLenT > 0) { + //DEBUG_PRINTF("-- Released duplicate data (%d) for %p: %p\n", _t->_segT._dataLenT, this, _t->_segT._dataT); + free(_t->_segT._dataT); + _t->_segT._dataT = nullptr; + _t->_segT._dataLenT = 0; + } + #endif + delete _t; + _t = nullptr; } } -uint8_t Segment::currentMode(uint8_t newMode) { - return (progress()>32767U) ? newMode : _t->_modeP; // change effect in the middle of transition +void Segment::handleTransition() { + uint16_t _progress = progress(); + if (_progress == 0xFFFFU) stopTransition(); } -uint32_t Segment::currentColor(uint8_t slot, uint32_t colorNew) { - return transitional && _t ? color_blend(_t->_colorT[slot], colorNew, progress(), true) : colorNew; +// transition progression between 0-65535 +uint16_t IRAM_ATTR Segment::progress() { + if (isInTransition()) { + unsigned long timeNow = millis(); + if (_t->_dur > 0 && timeNow - _t->_start < _t->_dur) return (timeNow - _t->_start) * 0xFFFFU / _t->_dur; + } + return 0xFFFFU; } -CRGBPalette16 &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) { +#ifndef WLED_DISABLE_MODE_BLEND +void Segment::swapSegenv(tmpsegd_t &tmpSeg) { + //DEBUG_PRINTF("-- Saving temp seg: %p->(%p) [%d->%p]\n", this, &tmpSeg, _dataLen, data); + tmpSeg._optionsT = options; + for (size_t i=0; i_segT)) { + // swap SEGENV with transitional data + options = _t->_segT._optionsT; + for (size_t i=0; i_segT._colorT[i]; + speed = _t->_segT._speedT; + intensity = _t->_segT._intensityT; + custom1 = _t->_segT._custom1T; + custom2 = _t->_segT._custom2T; + custom3 = _t->_segT._custom3T; + check1 = _t->_segT._check1T; + check2 = _t->_segT._check2T; + check3 = _t->_segT._check3T; + aux0 = _t->_segT._aux0T; + aux1 = _t->_segT._aux1T; + step = _t->_segT._stepT; + call = _t->_segT._callT; + data = _t->_segT._dataT; + _dataLen = _t->_segT._dataLenT; + } +} + +void Segment::restoreSegenv(tmpsegd_t &tmpSeg) { + //DEBUG_PRINTF("-- Restoring temp seg: %p->(%p) [%d->%p]\n", &tmpSeg, this, _dataLen, data); + if (_t && &(_t->_segT) != &tmpSeg) { + // update possibly changed variables to keep old effect running correctly + _t->_segT._aux0T = aux0; + _t->_segT._aux1T = aux1; + _t->_segT._stepT = step; + _t->_segT._callT = call; + //if (_t->_segT._dataT != data) DEBUG_PRINTF("--- data re-allocated: (%p) %p -> %p\n", this, _t->_segT._dataT, data); + _t->_segT._dataT = data; + _t->_segT._dataLenT = _dataLen; + } + options = tmpSeg._optionsT; + for (size_t i=0; i_cctT : _t->_briT) * (0xFFFFU - prog); + return curBri / 0xFFFFU; + } + return (useCct ? cct : (on ? opacity : 0)); +} + +uint8_t IRAM_ATTR Segment::currentMode() { +#ifndef WLED_DISABLE_MODE_BLEND + uint16_t prog = progress(); + if (modeBlending && prog < 0xFFFFU) return _t->_modeT; +#endif + return mode; +} + +uint32_t IRAM_ATTR Segment::currentColor(uint8_t slot) { +#ifndef WLED_DISABLE_MODE_BLEND + return isInTransition() ? color_blend(_t->_segT._colorT[slot], colors[slot], progress(), true) : colors[slot]; +#else + return isInTransition() ? color_blend(_t->_colorT[slot], colors[slot], progress(), true) : colors[slot]; +#endif +} + +CRGBPalette16 IRAM_ATTR &Segment::currentPalette(CRGBPalette16 &targetPalette, uint8_t pal) { loadPalette(targetPalette, pal); - if (transitional && _t && progress() < 0xFFFFU) { + uint16_t 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 - unsigned long timeMS = millis() - _t->_start; - uint16_t noOfBlends = (255U * timeMS / _t->_dur) - _t->_prevPaletteBlends; + uint16_t noOfBlends = ((255U * prog) / 0xFFFFU) - _t->_prevPaletteBlends; for (int i=0; i_prevPaletteBlends++) nblendPaletteTowardPalette(_t->_palT, targetPalette, 48); targetPalette = _t->_palT; // copy transitioning/temporary palette } return targetPalette; } -void Segment::handleTransition() { - if (!transitional) return; - uint16_t _progress = progress(); - if (_progress == 0xFFFFU) transitional = false; // finish transitioning segment - if (_t) { // thanks to @nXm AKA https://github.com/NMeirer - if (_progress >= 32767U && _t->_modeP != mode) markForReset(); - if (_progress == 0xFFFFU) { - delete _t; - _t = nullptr; - } - } +// relies on WS2812FX::service() to call it max every 8ms or more (MIN_SHOW_DELAY) +void Segment::handleRandomPalette() { + // just do a blend; if the palettes are identical it will just compare 48 bytes (same as _randomPalette == _newRandomPalette) + // this will slowly blend _newRandomPalette into _randomPalette every 15ms or 8ms (depending on MIN_SHOW_DELAY) + nblendPaletteTowardPalette(_randomPalette, _newRandomPalette, 48); } // segId is given when called from network callback, changes are queued if that segment is currently in its effect function -void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y, uint8_t segId) { +void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t ofs, uint16_t i1Y, uint16_t i2Y) { // return if neither bounds nor grouping have changed bool boundsUnchanged = (start == i1 && stop == i2); #ifndef WLED_DISABLE_2D @@ -364,6 +479,8 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t && (!grp || (grouping == grp && spacing == spc)) && (ofs == UINT16_MAX || ofs == offset)) return; + stateChanged = true; // send UDP/WS broadcast + if (stop) fill(BLACK); // turn old segment range off (clears pixels if changing spacing) if (grp) { // prevent assignment of 0 grouping = grp; @@ -374,6 +491,10 @@ void Segment::setUp(uint16_t i1, uint16_t i2, uint8_t grp, uint8_t spc, uint16_t } if (ofs < UINT16_MAX) offset = ofs; + DEBUG_PRINT(F("setUp segment: ")); DEBUG_PRINT(i1); + DEBUG_PRINT(','); DEBUG_PRINT(i2); + DEBUG_PRINT(F(" -> ")); DEBUG_PRINT(i1Y); + DEBUG_PRINT(','); DEBUG_PRINTLN(i2Y); markForReset(); if (boundsUnchanged) return; @@ -437,37 +558,40 @@ void Segment::setOption(uint8_t n, bool val) { if (fadeTransition && n == SEG_OPTION_ON && val != prevOn) startTransition(strip.getTransition()); // start transition prior to change if (val) options |= 0x01 << n; else options &= ~(0x01 << n); - if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET || n == SEG_OPTION_TRANSITIONAL)) stateChanged = true; // send UDP/WS broadcast + if (!(n == SEG_OPTION_SELECTED || n == SEG_OPTION_RESET)) stateChanged = true; // send UDP/WS broadcast } void Segment::setMode(uint8_t fx, bool loadDefaults) { + // skip reserved + while (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4) == 0) fx++; + if (fx >= strip.getModeCount()) fx = 0; // set solid mode // if we have a valid mode & is not reserved - if (fx < strip.getModeCount() && strncmp_P("RSVD", strip.getModeData(fx), 4)) { - if (fx != mode) { - if (fadeTransition) startTransition(strip.getTransition()); // set effect transitions - mode = fx; - - // load default values from effect string - if (loadDefaults) { - int16_t sOpt; - sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED; - sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY; - sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1; - sOpt = extractModeDefaults(fx, "c2"); custom2 = (sOpt >= 0) ? sOpt : DEFAULT_C2; - sOpt = extractModeDefaults(fx, "c3"); custom3 = (sOpt >= 0) ? sOpt : DEFAULT_C3; - sOpt = extractModeDefaults(fx, "o1"); check1 = (sOpt >= 0) ? (bool)sOpt : false; - sOpt = extractModeDefaults(fx, "o2"); check2 = (sOpt >= 0) ? (bool)sOpt : false; - sOpt = extractModeDefaults(fx, "o3"); check3 = (sOpt >= 0) ? (bool)sOpt : false; - sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7); - sOpt = extractModeDefaults(fx, "si"); if (sOpt >= 0) soundSim = constrain(sOpt, 0, 1); - sOpt = extractModeDefaults(fx, "rev"); if (sOpt >= 0) reverse = (bool)sOpt; - sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business - sOpt = extractModeDefaults(fx, "rY"); if (sOpt >= 0) reverse_y = (bool)sOpt; - sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business - sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); //else setPalette(0); - } - stateChanged = true; // send UDP/WS broadcast + if (fx != mode) { +#ifndef WLED_DISABLE_MODE_BLEND + if (modeBlending) startTransition(strip.getTransition()); // set effect transitions +#endif + mode = fx; + // load default values from effect string + if (loadDefaults) { + int16_t sOpt; + sOpt = extractModeDefaults(fx, "sx"); speed = (sOpt >= 0) ? sOpt : DEFAULT_SPEED; + sOpt = extractModeDefaults(fx, "ix"); intensity = (sOpt >= 0) ? sOpt : DEFAULT_INTENSITY; + sOpt = extractModeDefaults(fx, "c1"); custom1 = (sOpt >= 0) ? sOpt : DEFAULT_C1; + sOpt = extractModeDefaults(fx, "c2"); custom2 = (sOpt >= 0) ? sOpt : DEFAULT_C2; + sOpt = extractModeDefaults(fx, "c3"); custom3 = (sOpt >= 0) ? sOpt : DEFAULT_C3; + sOpt = extractModeDefaults(fx, "o1"); check1 = (sOpt >= 0) ? (bool)sOpt : false; + sOpt = extractModeDefaults(fx, "o2"); check2 = (sOpt >= 0) ? (bool)sOpt : false; + sOpt = extractModeDefaults(fx, "o3"); check3 = (sOpt >= 0) ? (bool)sOpt : false; + sOpt = extractModeDefaults(fx, "m12"); if (sOpt >= 0) map1D2D = constrain(sOpt, 0, 7); else map1D2D = M12_Pixels; // reset mapping if not defined (2D FX may not work) + sOpt = extractModeDefaults(fx, "si"); if (sOpt >= 0) soundSim = constrain(sOpt, 0, 3); + sOpt = extractModeDefaults(fx, "rev"); if (sOpt >= 0) reverse = (bool)sOpt; + sOpt = extractModeDefaults(fx, "mi"); if (sOpt >= 0) mirror = (bool)sOpt; // NOTE: setting this option is a risky business + sOpt = extractModeDefaults(fx, "rY"); if (sOpt >= 0) reverse_y = (bool)sOpt; + sOpt = extractModeDefaults(fx, "mY"); if (sOpt >= 0) mirror_y = (bool)sOpt; // NOTE: setting this option is a risky business + sOpt = extractModeDefaults(fx, "pal"); if (sOpt >= 0) setPalette(sOpt); //else setPalette(0); } + markForReset(); + stateChanged = true; // send UDP/WS broadcast } } @@ -482,21 +606,21 @@ void Segment::setPalette(uint8_t pal) { } // 2D matrix -uint16_t Segment::virtualWidth() const { +uint16_t IRAM_ATTR Segment::virtualWidth() const { uint16_t groupLen = groupLength(); uint16_t vWidth = ((transpose ? height() : width()) + groupLen - 1) / groupLen; if (mirror) vWidth = (vWidth + 1) /2; // divide by 2 if mirror, leave at least a single LED return vWidth; } -uint16_t Segment::virtualHeight() const { +uint16_t IRAM_ATTR Segment::virtualHeight() const { uint16_t groupLen = groupLength(); uint16_t vHeight = ((transpose ? width() : height()) + groupLen - 1) / groupLen; if (mirror_y) vHeight = (vHeight + 1) /2; // divide by 2 if mirror, leave at least a single LED return vHeight; } -uint16_t Segment::nrOfVStrips() const { +uint16_t IRAM_ATTR Segment::nrOfVStrips() const { uint16_t vLen = 1; #ifndef WLED_DISABLE_2D if (is2D()) { @@ -511,7 +635,7 @@ uint16_t Segment::nrOfVStrips() const { } // 1D strip -uint16_t Segment::virtualLength() const { +uint16_t IRAM_ATTR Segment::virtualLength() const { #ifndef WLED_DISABLE_2D if (is2D()) { uint16_t vW = virtualWidth(); @@ -606,7 +730,7 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) #endif uint16_t len = length(); - uint8_t _bri_t = currentBri(on ? opacity : 0); + uint8_t _bri_t = currentBri(); if (_bri_t < 255) { byte r = scale8(R(col), _bri_t); byte g = scale8(G(col), _bri_t); @@ -626,19 +750,26 @@ void IRAM_ATTR Segment::setPixelColor(int i, uint32_t col) } i += start; // starting pixel in a group + uint32_t tmpCol = col; // set all the pixels in the group for (int j = 0; j < grouping; j++) { - uint16_t indexSet = i + ((reverse) ? -j : j); + unsigned indexSet = i + ((reverse) ? -j : j); if (indexSet >= start && indexSet < stop) { if (mirror) { //set the corresponding mirrored pixel - uint16_t indexMir = stop - indexSet + start - 1; + unsigned indexMir = stop - indexSet + start - 1; indexMir += offset; // offset/phase if (indexMir >= stop) indexMir -= len; // wrap - strip.setPixelColor(indexMir, col); +#ifndef WLED_DISABLE_MODE_BLEND + if (_modeBlend) tmpCol = color_blend(strip.getPixelColor(indexMir), col, 0xFFFFU - progress(), true); +#endif + strip.setPixelColor(indexMir, tmpCol); } indexSet += offset; // offset/phase if (indexSet >= stop) indexSet -= len; // wrap - strip.setPixelColor(indexSet, col); +#ifndef WLED_DISABLE_MODE_BLEND + if (_modeBlend) tmpCol = color_blend(strip.getPixelColor(indexSet), col, 0xFFFFU - progress(), true); +#endif + strip.setPixelColor(indexSet, tmpCol); } } } @@ -676,7 +807,7 @@ void Segment::setPixelColor(float i, uint32_t col, bool aa) } } -uint32_t Segment::getPixelColor(int i) +uint32_t IRAM_ATTR Segment::getPixelColor(int i) { if (!isActive()) return 0; // not active #ifndef WLED_DISABLE_2D @@ -733,10 +864,11 @@ uint8_t Segment::differs(Segment& b) const { if (startY != b.startY) d |= SEG_DIFFERS_BOUNDS; if (stopY != b.stopY) d |= SEG_DIFFERS_BOUNDS; - //bit pattern: (msb first) set:2, sound:1, mapping:3, transposed, mirrorY, reverseY, [transitional, reset,] paused, mirrored, on, reverse, [selected] - if ((options & 0b1111111110011110U) != (b.options & 0b1111111110011110U)) d |= SEG_DIFFERS_OPT; + //bit pattern: (msb first) + // set:2, sound:2, mapping:3, transposed, mirrorY, reverseY, [reset,] paused, mirrored, on, reverse, [selected] + if ((options & 0b1111111111011110U) != (b.options & 0b1111111111011110U)) d |= SEG_DIFFERS_OPT; if ((options & 0x0001U) != (b.options & 0x0001U)) d |= SEG_DIFFERS_SEL; - for (uint8_t i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL; + for (unsigned i = 0; i < NUM_COLORS; i++) if (colors[i] != b.colors[i]) d |= SEG_DIFFERS_COL; return d; } @@ -754,8 +886,7 @@ void Segment::refreshLightCapabilities() { if (start < Segment::maxWidth * Segment::maxHeight) { // we are withing 2D matrix (includes 1D segments) for (int y = startY; y < stopY; y++) for (int x = start; x < stop; x++) { - uint16_t index = x + Segment::maxWidth * y; - if (index < strip.customMappingSize) index = strip.customMappingTable[index]; // convert logical address to physical + uint16_t index = strip.getMappedPixelIndex(x + Segment::maxWidth * y); // convert logical address to physical if (index < 0xFFFFU) { if (segStartIdx > index) segStartIdx = index; if (segStopIdx < index) segStopIdx = index; @@ -768,8 +899,8 @@ void Segment::refreshLightCapabilities() { segStopIdx = stop; } - for (uint8_t b = 0; b < busses.getNumBusses(); b++) { - Bus *bus = busses.getBus(b); + for (unsigned b = 0; b < BusManager::getNumBusses(); b++) { + Bus *bus = BusManager::getBus(b); if (bus == nullptr || bus->getLength()==0) break; if (!bus->isOk()) continue; if (bus->getStart() >= segStopIdx) continue; @@ -798,43 +929,12 @@ void Segment::fill(uint32_t c) { if (!isActive()) return; // not active const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); const uint16_t rows = virtualHeight(); // will be 1 for 1D - for(uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { + for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) { if (is2D()) setPixelColorXY(x, y, c); else setPixelColor(x, c); } } -// Blends the specified color with the existing pixel color. -void Segment::blendPixelColor(int n, uint32_t color, uint8_t blend) { - setPixelColor(n, color_blend(getPixelColor(n), color, blend)); -} - -// Adds the specified color with the existing pixel color perserving color balance. -void Segment::addPixelColor(int n, uint32_t color, bool fast) { - if (!isActive()) return; // not active - uint32_t col = getPixelColor(n); - uint8_t r = R(col); - uint8_t g = G(col); - uint8_t b = B(col); - uint8_t w = W(col); - if (fast) { - r = qadd8(r, R(color)); - g = qadd8(g, G(color)); - b = qadd8(b, B(color)); - w = qadd8(w, W(color)); - col = RGBW32(r,g,b,w); - } else { - col = color_add(col, color); - } - setPixelColor(n, col); -} - -void Segment::fadePixelColor(uint16_t n, uint8_t fade) { - if (!isActive()) return; // not active - CRGB pix = CRGB(getPixelColor(n)).nscale8_video(fade); - setPixelColor(n, pix); -} - /* * fade out function, higher rate = quicker fade */ @@ -844,7 +944,7 @@ void Segment::fade_out(uint8_t rate) { const uint16_t rows = virtualHeight(); // will be 1 for 1D rate = (255-rate) >> 1; - float mappedRate = float(rate) +1.1; + float mappedRate = float(rate) +1.1f; uint32_t color = colors[1]; // SEGCOLOR(1); // target color int w2 = W(color); @@ -852,7 +952,7 @@ void Segment::fade_out(uint8_t rate) { int g2 = G(color); int b2 = B(color); - for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { + for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) { color = is2D() ? getPixelColorXY(x, y) : getPixelColor(x); int w1 = W(color); int r1 = R(color); @@ -881,49 +981,40 @@ void Segment::fadeToBlackBy(uint8_t fadeBy) { const uint16_t cols = is2D() ? virtualWidth() : virtualLength(); const uint16_t rows = virtualHeight(); // will be 1 for 1D - for (uint16_t y = 0; y < rows; y++) for (uint16_t x = 0; x < cols; x++) { - if (is2D()) setPixelColorXY(x, y, CRGB(getPixelColorXY(x,y)).nscale8(255-fadeBy)); - else setPixelColor(x, CRGB(getPixelColor(x)).nscale8(255-fadeBy)); + for (int y = 0; y < rows; y++) for (int x = 0; x < cols; x++) { + if (is2D()) setPixelColorXY(x, y, color_fade(getPixelColorXY(x,y), 255-fadeBy)); + else setPixelColor(x, color_fade(getPixelColor(x), 255-fadeBy)); } } /* * blurs segment content, source: FastLED colorutils.cpp */ -void Segment::blur(uint8_t blur_amount) -{ +void Segment::blur(uint8_t blur_amount) { if (!isActive() || blur_amount == 0) return; // optimization: 0 means "don't blur" #ifndef WLED_DISABLE_2D if (is2D()) { // compatibility with 2D - const uint_fast16_t cols = virtualWidth(); - const uint_fast16_t rows = virtualHeight(); - for (uint_fast16_t i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows - for (uint_fast16_t k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns + const unsigned cols = virtualWidth(); + const unsigned rows = virtualHeight(); + for (unsigned i = 0; i < rows; i++) blurRow(i, blur_amount); // blur all rows + for (unsigned k = 0; k < cols; k++) blurCol(k, blur_amount); // blur all columns return; } #endif uint8_t keep = 255 - blur_amount; uint8_t seep = blur_amount >> 1; - CRGB carryover = CRGB::Black; - uint_fast16_t vlength = virtualLength(); - for(uint_fast16_t i = 0; i < vlength; i++) - { - CRGB cur = CRGB(getPixelColor(i)); - CRGB part = cur; - CRGB before = cur; // remember color before blur - part.nscale8(seep); - cur.nscale8(keep); - cur += carryover; - if(i > 0) { + uint32_t carryover = BLACK; + unsigned vlength = virtualLength(); + for (unsigned i = 0; i < vlength; i++) { + uint32_t cur = getPixelColor(i); + uint32_t part = color_fade(cur, seep); + cur = color_add(color_fade(cur, keep), carryover, true); + if (i > 0) { uint32_t c = getPixelColor(i-1); - uint8_t r = R(c); - uint8_t g = G(c); - uint8_t b = B(c); - setPixelColor((uint16_t)(i-1), qadd8(r, part.red), qadd8(g, part.green), qadd8(b, part.blue)); + setPixelColor(i-1, color_add(c, part, true)); } - if (before != cur) // optimization: only set pixel if color has changed - setPixelColor((uint16_t)i,cur.red, cur.green, cur.blue); + setPixelColor(i, cur); carryover = part; } } @@ -935,33 +1026,19 @@ void Segment::blur(uint8_t blur_amount) */ uint32_t Segment::color_wheel(uint8_t pos) { if (palette) return color_from_palette(pos, false, true, 0); + uint8_t w = W(currentColor(0)); pos = 255 - pos; - if(pos < 85) { - return ((uint32_t)(255 - pos * 3) << 16) | ((uint32_t)(0) << 8) | (pos * 3); + if (pos < 85) { + return RGBW32((255 - pos * 3), 0, (pos * 3), w); } else if(pos < 170) { pos -= 85; - return ((uint32_t)(0) << 16) | ((uint32_t)(pos * 3) << 8) | (255 - pos * 3); + return RGBW32(0, (pos * 3), (255 - pos * 3), w); } else { pos -= 170; - return ((uint32_t)(pos * 3) << 16) | ((uint32_t)(255 - pos * 3) << 8) | (0); + return RGBW32((pos * 3), (255 - pos * 3), 0, w); } } -/* - * Returns a new, random wheel index with a minimum distance of 42 from pos. - */ -uint8_t Segment::get_random_wheel_index(uint8_t pos) { - uint8_t r = 0, x = 0, y = 0, d = 0; - - while(d < 42) { - r = random8(); - x = abs(pos - r); - y = 255 - x; - d = MIN(x, y); - } - return r; -} - /* * Gets a single color from the currently selected palette. * @param i Palette Index (if mapping is true, the full palette will be _virtualSegmentLength long, if false, 255). Will wrap around automatically. @@ -971,26 +1048,20 @@ uint8_t Segment::get_random_wheel_index(uint8_t pos) { * @param pbri Value to scale the brightness of the returned color by. Default is 255. (no scaling) * @returns Single color from palette */ -uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) -{ +uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_t mcol, uint8_t pbri) { + uint32_t color = gamma32(currentColor(mcol)); + // default palette or no RGB support on segment - if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) { - uint32_t color = currentColor(mcol, colors[mcol]); - color = gamma32(color); - if (pbri == 255) return color; - return RGBW32(scale8_video(R(color),pbri), scale8_video(G(color),pbri), scale8_video(B(color),pbri), scale8_video(W(color),pbri)); - } + if ((palette == 0 && mcol < NUM_COLORS) || !_isRGB) return (pbri == 255) ? color : color_fade(color, pbri, true); uint8_t paletteIndex = i; if (mapping && virtualLength() > 1) paletteIndex = (i*255)/(virtualLength() -1); - if (!wrap) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" - CRGB fastled_col; + if (!wrap && strip.paletteBlend != 3) paletteIndex = scale8(paletteIndex, 240); //cut off blend at palette "end" CRGBPalette16 curPal; - if (transitional && _t) curPal = _t->_palT; - else loadPalette(curPal, palette); - fastled_col = ColorFromPalette(curPal, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global + curPal = currentPalette(curPal, palette); + CRGB fastled_col = ColorFromPalette(curPal, paletteIndex, pbri, (strip.paletteBlend == 3)? NOBLEND:LINEARBLEND); // NOTE: paletteBlend should be global - return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, 0); + return RGBW32(fastled_col.r, fastled_col.g, fastled_col.b, W(color)); } @@ -999,8 +1070,7 @@ uint32_t Segment::color_from_palette(uint16_t i, bool mapping, bool wrap, uint8_ /////////////////////////////////////////////////////////////////////////////// //do not call this method from system context (network callback) -void WS2812FX::finalizeInit(void) -{ +void WS2812FX::finalizeInit(void) { //reset segment runtimes for (segment &seg : _segments) { seg.markForReset(); @@ -1015,26 +1085,26 @@ void WS2812FX::finalizeInit(void) _hasWhiteChannel = _isOffRefreshRequired = false; //if busses failed to load, add default (fresh install, FS issue, ...) - if (busses.getNumBusses() == 0) { + if (BusManager::getNumBusses() == 0) { DEBUG_PRINTLN(F("No busses, init default")); const uint8_t defDataPins[] = {DATA_PINS}; const uint16_t defCounts[] = {PIXEL_COUNTS}; const uint8_t defNumBusses = ((sizeof defDataPins) / (sizeof defDataPins[0])); const uint8_t defNumCounts = ((sizeof defCounts) / (sizeof defCounts[0])); uint16_t prevLen = 0; - for (uint8_t i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) { + for (int i = 0; i < defNumBusses && i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) { uint8_t defPin[] = {defDataPins[i]}; uint16_t start = prevLen; uint16_t count = defCounts[(i < defNumCounts) ? i : defNumCounts -1]; prevLen += count; BusConfig defCfg = BusConfig(DEFAULT_LED_TYPE, defPin, start, count, DEFAULT_LED_COLOR_ORDER, false, 0, RGBW_MODE_MANUAL_ONLY); - if (busses.add(defCfg) == -1) break; + if (BusManager::add(defCfg) == -1) break; } } _length = 0; - for (uint8_t i=0; igetStart() + bus->getLength() > MAX_LEDS) break; //RGBW mode is enabled if at least one of the strips is RGBW @@ -1052,64 +1122,79 @@ void WS2812FX::finalizeInit(void) #endif } - if (isMatrix) setUpMatrix(); - else { - Segment::maxWidth = _length; - Segment::maxHeight = 1; - } + Segment::maxWidth = _length; + Segment::maxHeight = 1; //segments are created in makeAutoSegments(); DEBUG_PRINTLN(F("Loading custom palettes")); loadCustomPalettes(); // (re)load all custom palettes DEBUG_PRINTLN(F("Loading custom ledmaps")); - deserializeMap(); // (re)load default ledmap + deserializeMap(); // (re)load default ledmap (will also setUpMatrix() if ledmap does not exist) } void WS2812FX::service() { unsigned long nowUp = millis(); // Be aware, millis() rolls over every 49 days now = nowUp + timebase; - if (nowUp - _lastShow < MIN_SHOW_DELAY) return; + if (nowUp - _lastShow < MIN_SHOW_DELAY || _suspend) return; bool doShow = false; _isServicing = true; _segment_index = 0; + Segment::handleRandomPalette(); // move it into for loop when each segment has individual random palette for (segment &seg : _segments) { + if (_suspend) return; // immediately stop processing segments if suspend requested during service() + // process transition (mode changes in the middle of transition) seg.handleTransition(); // reset the segment runtime data if needed seg.resetIfRequired(); + if (!seg.isActive()) continue; + // last condition ensures all solid segments are updated at the same time - if (seg.isActive() && (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC))) + if (nowUp > seg.next_time || _triggered || (doShow && seg.mode == FX_MODE_STATIC)) { doShow = true; uint16_t delay = FRAMETIME; if (!seg.freeze) { //only run effect function if not frozen - _virtualSegmentLength = seg.virtualLength(); - _colors_t[0] = seg.currentColor(0, seg.colors[0]); - _colors_t[1] = seg.currentColor(1, seg.colors[1]); - _colors_t[2] = seg.currentColor(2, seg.colors[2]); - seg.currentPalette(_currentPalette, seg.palette); - - if (!cctFromRgb || correctWB) busses.setSegmentCCT(seg.currentBri(seg.cct, true), correctWB); - for (uint8_t c = 0; c < NUM_COLORS; c++) _colors_t[c] = gamma32(_colors_t[c]); - - // effect blending (execute previous effect) - // actual code may be a bit more involved as effects have runtime data including allocated memory - //if (seg.transitional && seg._modeP) (*_mode[seg._modeP])(progress()); - delay = (*_mode[seg.currentMode(seg.mode)])(); - if (seg.mode != FX_MODE_HALLOWEEN_EYES) seg.call++; - if (seg.transitional && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition + _virtualSegmentLength = seg.virtualLength(); //SEGLEN + _colors_t[0] = gamma32(seg.currentColor(0)); + _colors_t[1] = gamma32(seg.currentColor(1)); + _colors_t[2] = gamma32(seg.currentColor(2)); + seg.currentPalette(_currentPalette, seg.palette); // we need to pass reference + if (!cctFromRgb || correctWB) BusManager::setSegmentCCT(seg.currentBri(true), correctWB); + // Effect blending + // When two effects are being blended, each may have different segment data, this + // data needs to be saved first and then restored before running previous mode. + // The blending will largely depend on the effect behaviour since actual output (LEDs) may be + // overwritten by later effect. To enable seamless blending for every effect, additional LED buffer + // would need to be allocated for each effect and then blended together for each pixel. + [[maybe_unused]] uint8_t tmpMode = seg.currentMode(); // this will return old mode while in transition + delay = (*_mode[seg.mode])(); // run new/current mode +#ifndef WLED_DISABLE_MODE_BLEND + if (modeBlending && seg.mode != tmpMode) { + Segment::tmpsegd_t _tmpSegData; + Segment::modeBlend(true); // set semaphore + seg.swapSegenv(_tmpSegData); // temporarily store new mode state (and swap it with transitional state) + _virtualSegmentLength = seg.virtualLength(); // update SEGLEN (mapping may have changed) + uint16_t d2 = (*_mode[tmpMode])(); // run old mode + seg.restoreSegenv(_tmpSegData); // restore mode state (will also update transitional state) + delay = MIN(delay,d2); // use shortest delay + Segment::modeBlend(false); // unset semaphore + } +#endif + seg.call++; + if (seg.isInTransition() && delay > FRAMETIME) delay = FRAMETIME; // force faster updates during transition } seg.next_time = nowUp + delay; } - if (_segment_index == _queuedChangesSegId) setUpSegmentFromQueuedChanges(); +// if (_segment_index == _queuedChangesSegId) setUpSegmentFromQueuedChanges(); _segment_index++; } _virtualSegmentLength = 0; - busses.setSegmentCCT(-1); + BusManager::setSegmentCCT(-1); _isServicing = false; _triggered = false; @@ -1125,98 +1210,16 @@ void WS2812FX::service() { #endif } -void IRAM_ATTR WS2812FX::setPixelColor(int i, uint32_t col) -{ - if (i < customMappingSize) i = customMappingTable[i]; +void IRAM_ATTR WS2812FX::setPixelColor(unsigned i, uint32_t col) { + i = getMappedPixelIndex(i); if (i >= _length) return; - busses.setPixelColor(i, col); + BusManager::setPixelColor(i, col); } -uint32_t WS2812FX::getPixelColor(uint16_t i) -{ - if (i < customMappingSize) i = customMappingTable[i]; +uint32_t IRAM_ATTR WS2812FX::getPixelColor(uint16_t i) { + i = getMappedPixelIndex(i); if (i >= _length) return 0; - return busses.getPixelColor(i); -} - - -//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 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 - -uint8_t WS2812FX::estimateCurrentAndLimitBri() { - //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) - bool useWackyWS2815PowerModel = false; - byte actualMilliampsPerLed = milliampsPerLed; - - if (ablMilliampsMax < 150 || actualMilliampsPerLed == 0) { //0 mA per LED and too low numbers turn off calculation - currentMilliamps = 0; - return _brightness; - } - - if (milliampsPerLed == 255) { - useWackyWS2815PowerModel = true; - actualMilliampsPerLed = 12; // from testing an actual strip - } - - size_t powerBudget = (ablMilliampsMax - MA_FOR_ESP); //100mA for ESP power - - size_t pLen = 0; //getLengthPhysical(); - size_t powerSum = 0; - for (uint_fast8_t bNum = 0; bNum < busses.getNumBusses(); bNum++) { - Bus *bus = busses.getBus(bNum); - if (!IS_DIGITAL(bus->getType())) continue; //exclude non-digital network busses - uint16_t len = bus->getLength(); - pLen += len; - uint32_t busPowerSum = 0; - for (uint_fast16_t i = 0; i < len; i++) { //sum up the usage of each LED - uint32_t c = bus->getPixelColor(i); // always returns original or restored color without brightness scaling - byte r = R(c), g = G(c), b = B(c), w = W(c); - - if(useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation - busPowerSum += (MAX(MAX(r,g),b)) * 3; - } else { - busPowerSum += (r + g + b + w); - } - } - - if (bus->hasWhite()) { //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less - busPowerSum *= 3; - busPowerSum >>= 2; //same as /= 4 - } - powerSum += busPowerSum; - } - - if (powerBudget > pLen) { //each LED uses about 1mA in standby, exclude that from power budget - powerBudget -= pLen; - } else { - powerBudget = 0; - } - - // powerSum has all the values of channels summed (max would be pLen*765 as white is excluded) so convert to milliAmps - powerSum = (powerSum * actualMilliampsPerLed) / 765; - - uint8_t newBri = _brightness; - if (powerSum * _brightness / 255 > powerBudget) { //scale brightness down to stay in current limit - float scale = (float)(powerBudget * 255) / (float)(powerSum * _brightness); - uint16_t scaleI = scale * 255; - uint8_t scaleB = (scaleI > 255) ? 255 : scaleI; - newBri = scale8(_brightness, scaleB) + 1; - } - currentMilliamps = (powerSum * newBri) / 255; - currentMilliamps += MA_FOR_ESP; //add power of ESP back to estimate - currentMilliamps += pLen; //add standby power (1mA/LED) back to estimate - return newBri; + return BusManager::getPixelColor(i); } void WS2812FX::show(void) { @@ -1224,44 +1227,17 @@ void WS2812FX::show(void) { show_callback callback = _callback; if (callback) callback(); - #ifdef WLED_DEBUG - static unsigned long sumMicros = 0, sumCurrent = 0; - static size_t calls = 0; - unsigned long microsStart = micros(); - #endif - - uint8_t newBri = estimateCurrentAndLimitBri(); - busses.setBrightness(newBri); // "repaints" all pixels if brightness changed - - #ifdef WLED_DEBUG - sumCurrent += micros() - microsStart; - #endif - // some buses send asynchronously and this method will return before // all of the data has been sent. // See https://github.com/Makuna/NeoPixelBus/wiki/ESP32-NeoMethods#neoesp32rmt-methods - busses.show(); + BusManager::show(); - // restore bus brightness to its original value - // this is done right after show, so this is only OK if LED updates are completed before show() returns - // or async show has a separate buffer (ESP32 RMT and I2S are ok) - if (newBri < _brightness) busses.setBrightness(_brightness); - - #ifdef WLED_DEBUG - sumMicros += micros() - microsStart; - if (++calls == 100) { - DEBUG_PRINTF("%d show calls: %lu[us] avg: %lu[us] (current: %lu[us] avg: %lu[us])\n", calls, sumMicros, sumMicros/calls, sumCurrent, sumCurrent/calls); - sumMicros = sumCurrent = 0; - calls = 0; - } - #endif - - unsigned long now = millis(); - size_t diff = now - _lastShow; + unsigned long showNow = millis(); + size_t diff = showNow - _lastShow; size_t fpsCurr = 200; if (diff > 0) fpsCurr = 1000 / diff; _cumulativeFps = (3 * _cumulativeFps + fpsCurr +2) >> 2; // "+2" for proper rounding (2/4 = 0.5) - _lastShow = now; + _lastShow = showNow; } /** @@ -1269,7 +1245,7 @@ void WS2812FX::show(void) { * On some hardware (ESP32), strip updates are done asynchronously. */ bool WS2812FX::isUpdating() { - return !busses.canAllShow(); + return !BusManager::canAllShow(); } /** @@ -1292,9 +1268,7 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) { if (m >= getModeCount()) m = getModeCount() - 1; if (_segments[segid].mode != m) { - _segments[segid].startTransition(_transitionDur); // set effect transitions - //_segments[segid].markForReset(); - _segments[segid].mode = m; + _segments[segid].setMode(m); // do not load defaults } } @@ -1330,7 +1304,7 @@ void WS2812FX::setBrightness(uint8_t b, bool direct) { } // setting brightness with NeoPixelBusLg has no effect on already painted pixels, // so we need to force an update to existing buffer - busses.setBrightness(b); + BusManager::setBrightness(b); if (!direct) { unsigned long t = millis(); if (_segments[0].next_time > t + 22 && t - _lastShow > MIN_SHOW_DELAY) trigger(); //apply brightness change immediately if no refresh soon @@ -1345,8 +1319,7 @@ uint8_t WS2812FX::getActiveSegsLightCapabilities(bool selectedOnly) { return totalLC; } -uint8_t WS2812FX::getFirstSelectedSegId(void) -{ +uint8_t WS2812FX::getFirstSelectedSegId(void) { size_t i = 0; for (segment &seg : _segments) { if (seg.isActive() && seg.isSelected()) return i; @@ -1387,8 +1360,8 @@ uint16_t WS2812FX::getLengthTotal(void) { uint16_t WS2812FX::getLengthPhysical(void) { uint16_t len = 0; - for (size_t b = 0; b < busses.getNumBusses(); b++) { - Bus *bus = busses.getBus(b); + for (size_t b = 0; b < BusManager::getNumBusses(); b++) { + Bus *bus = BusManager::getBus(b); if (bus->getType() >= TYPE_NET_DDP_RGB) continue; //exclude non-physical network busses len += bus->getLength(); } @@ -1399,8 +1372,8 @@ uint16_t WS2812FX::getLengthPhysical(void) { //returns if there is an RGBW bus (supports RGB and White, not only white) //not influenced by auto-white mode, also true if white slider does not affect output white channel bool WS2812FX::hasRGBWBus(void) { - for (size_t b = 0; b < busses.getNumBusses(); b++) { - Bus *bus = busses.getBus(b); + for (size_t b = 0; b < BusManager::getNumBusses(); b++) { + Bus *bus = BusManager::getBus(b); if (bus == nullptr || bus->getLength()==0) break; if (bus->hasRGB() && bus->hasWhite()) return true; } @@ -1409,8 +1382,8 @@ bool WS2812FX::hasRGBWBus(void) { bool WS2812FX::hasCCTBus(void) { if (cctFromRgb && !correctWB) return false; - for (size_t b = 0; b < busses.getNumBusses(); b++) { - Bus *bus = busses.getBus(b); + for (size_t b = 0; b < BusManager::getNumBusses(); b++) { + Bus *bus = BusManager::getBus(b); if (bus == nullptr || bus->getLength()==0) break; switch (bus->getType()) { case TYPE_ANALOG_5CH: @@ -1421,18 +1394,18 @@ bool WS2812FX::hasCCTBus(void) { return false; } -void WS2812FX::purgeSegments(bool force) { +void WS2812FX::purgeSegments() { // remove all inactive segments (from the back) int deleted = 0; if (_segments.size() <= 1) return; for (size_t i = _segments.size()-1; i > 0; i--) - if (_segments[i].stop == 0 || force) { + if (_segments[i].stop == 0) { deleted++; _segments.erase(_segments.begin() + i); } if (deleted) { _segments.shrink_to_fit(); - if (_mainSegment >= _segments.size()) setMainSegmentId(0); + setMainSegmentId(0); } } @@ -1447,7 +1420,7 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group appendSegment(Segment(0, strip.getLengthTotal())); segId = getSegmentsNum()-1; // segments are added at the end of list } - +/* if (_queuedChangesSegId == segId) _queuedChangesSegId = 255; // cancel queued change if already queued for this segment if (segId < getMaxSegments() && segId == getCurrSegmentId() && isServicing()) { // queue change to prevent concurrent access @@ -1456,22 +1429,22 @@ void WS2812FX::setSegment(uint8_t segId, uint16_t i1, uint16_t i2, uint8_t group _qStart = i1; _qStop = i2; _qStartY = startY; _qStopY = stopY; _qGrouping = grouping; _qSpacing = spacing; _qOffset = offset; _queuedChangesSegId = segId; + DEBUG_PRINT(F("Segment queued: ")); DEBUG_PRINTLN(segId); return; // queued changes are applied immediately after effect function returns } - +*/ + suspend(); _segments[segId].setUp(i1, i2, grouping, spacing, offset, startY, stopY); + resume(); + if (segId > 0 && segId == getSegmentsNum()-1 && i2 <= i1) _segments.pop_back(); // if last segment was deleted remove it from vector } - +/* void WS2812FX::setUpSegmentFromQueuedChanges() { if (_queuedChangesSegId >= getSegmentsNum()) return; - getSegment(_queuedChangesSegId).setUp(_qStart, _qStop, _qGrouping, _qSpacing, _qOffset, _qStartY, _qStopY); + _segments[_queuedChangesSegId].setUp(_qStart, _qStop, _qGrouping, _qSpacing, _qOffset, _qStartY, _qStopY); _queuedChangesSegId = 255; } - -void WS2812FX::restartRuntime() { - for (segment &seg : _segments) seg.markForReset(); -} - +*/ void WS2812FX::resetSegments() { _segments.clear(); // destructs all Segment as part of clearing #ifndef WLED_DISABLE_2D @@ -1498,8 +1471,8 @@ void WS2812FX::makeAutoSegments(bool forceReset) { } #endif - for (size_t i = s; i < busses.getNumBusses(); i++) { - Bus* b = busses.getBus(i); + for (size_t i = s; i < BusManager::getNumBusses(); i++) { + Bus* b = BusManager::getBus(i); segStarts[s] = b->getStart(); segStops[s] = segStarts[s] + b->getLength(); @@ -1588,8 +1561,8 @@ void WS2812FX::fixInvalidSegments() { bool WS2812FX::checkSegmentAlignment() { bool aligned = false; for (segment &seg : _segments) { - for (uint8_t b = 0; bgetStart() && seg.stop == bus->getStart() + bus->getLength()) aligned = true; } if (seg.start == 0 && seg.stop == _length) aligned = true; @@ -1611,17 +1584,8 @@ uint8_t WS2812FX::setPixelSegment(uint8_t n) { } void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col) { - if (i2 >= i) - { - for (uint16_t x = i; x <= i2; x++) setPixelColor(x, col); - } else - { - for (uint16_t x = i2; x <= i; x++) setPixelColor(x, col); - } -} - -void WS2812FX::setTransitionMode(bool t) { - for (segment &seg : _segments) seg.startTransition(t ? _transitionDur : 0); + if (i2 < i) std::swap(i,i2); + for (unsigned x = i; x <= i2; x++) setPixelColor(x, col); } #ifdef WLED_DEBUG @@ -1652,7 +1616,7 @@ void WS2812FX::loadCustomPalettes() { if (readObjectFromFile(fileName, nullptr, &pDoc)) { JsonArray pal = pDoc[F("palette")]; - if (!pal.isNull() && pal.size()>4) { // not an empty palette (at least 2 entries) + if (!pal.isNull() && pal.size()>3) { // not an empty palette (at least 2 entries) if (pal[0].is() && pal[1].is()) { // we have an array of index & hex strings size_t palSize = MIN(pal.size(), 36); @@ -1661,7 +1625,7 @@ void WS2812FX::loadCustomPalettes() { uint8_t rgbw[] = {0,0,0,0}; tcp[ j ] = (uint8_t) pal[ i ].as(); // index colorFromHexString(rgbw, pal[i+1].as()); // will catch non-string entires - for (size_t c=0; c<3; c++) tcp[j+1+c] = rgbw[c]; // only use RGB component + for (size_t c=0; c<3; c++) tcp[j+1+c] = gamma8(rgbw[c]); // only use RGB component DEBUG_PRINTF("%d(%d) : %d %d %d\n", i, int(tcp[j]), int(tcp[j+1]), int(tcp[j+2]), int(tcp[j+3])); } } else { @@ -1669,13 +1633,15 @@ void WS2812FX::loadCustomPalettes() { palSize -= palSize % 4; // make sure size is multiple of 4 for (size_t i=0; i()<256; i+=4) { tcp[ i ] = (uint8_t) pal[ i ].as(); // index - tcp[i+1] = (uint8_t) pal[i+1].as(); // R - tcp[i+2] = (uint8_t) pal[i+2].as(); // G - tcp[i+3] = (uint8_t) pal[i+3].as(); // B + tcp[i+1] = gamma8((uint8_t) pal[i+1].as()); // R + tcp[i+2] = gamma8((uint8_t) pal[i+2].as()); // G + tcp[i+3] = gamma8((uint8_t) pal[i+3].as()); // B DEBUG_PRINTF("%d(%d) : %d %d %d\n", i, int(tcp[i]), int(tcp[i+1]), int(tcp[i+2]), int(tcp[i+3])); } } customPalettes.push_back(targetPalette.loadDynamicGradientPalette(tcp)); + } else { + DEBUG_PRINTLN(F("Wrong palette format.")); } } } else { @@ -1691,49 +1657,47 @@ bool WS2812FX::deserializeMap(uint8_t n) { char fileName[32]; strcpy_P(fileName, PSTR("/ledmap")); if (n) sprintf(fileName +7, "%d", n); - strcat(fileName, ".json"); + strcat_P(fileName, PSTR(".json")); bool isFile = WLED_FS.exists(fileName); - if (!isFile) { - // erase custom mapping if selecting nonexistent ledmap.json (n==0) - if (!isMatrix && !n && customMappingTable != nullptr) { - customMappingSize = 0; - delete[] customMappingTable; - customMappingTable = nullptr; - } + customMappingSize = 0; // prevent use of mapping if anything goes wrong + + if (!isFile && n==0 && isMatrix) { + setUpMatrix(); return false; } - if (!requestJSONBufferLock(7)) return false; + if (!isFile || !requestJSONBufferLock(7)) return false; // this will trigger setUpMatrix() when called from wled.cpp - if (!readObjectFromFile(fileName, nullptr, &doc)) { + if (!readObjectFromFile(fileName, nullptr, pDoc)) { + DEBUG_PRINT(F("ERROR Invalid ledmap in ")); DEBUG_PRINTLN(fileName); releaseJSONBufferLock(); - return false; //if file does not exist just exit + return false; // if file does not load properly then exit } - DEBUG_PRINT(F("Reading LED map from ")); - DEBUG_PRINTLN(fileName); + DEBUG_PRINT(F("Reading LED map from ")); DEBUG_PRINTLN(fileName); - // erase old custom ledmap - if (customMappingTable != nullptr) { - customMappingSize = 0; - delete[] customMappingTable; - customMappingTable = nullptr; - } + if (customMappingTable == nullptr) customMappingTable = new uint16_t[getLengthTotal()]; - JsonArray map = doc[F("map")]; + JsonObject root = pDoc->as(); + JsonArray map = root[F("map")]; if (!map.isNull() && map.size()) { // not an empty map - customMappingSize = map.size(); - customMappingTable = new uint16_t[customMappingSize]; - for (uint16_t i=0; i COL_ORDER_MAX) { + // upper nibble contains W swap information + if ((colorOrder & 0x0F) > COL_ORDER_MAX) { return; } _mappings[_count].start = start; @@ -63,12 +64,13 @@ void ColorOrderMap::add(uint16_t start, uint16_t len, uint8_t colorOrder) { } uint8_t IRAM_ATTR ColorOrderMap::getPixelColorOrder(uint16_t pix, uint8_t defaultColorOrder) const { - if (_count == 0) return defaultColorOrder; - // upper nibble containd W swap information - uint8_t swapW = defaultColorOrder >> 4; - for (uint8_t i = 0; i < _count; i++) { - if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) { - return _mappings[i].colorOrder | (swapW << 4); + if (_count > 0) { + // upper nibble contains W swap information + // when ColorOrderMap's upper nibble contains value >0 then swap information is used from it, otherwise global swap is used + for (unsigned i = 0; i < _count; i++) { + if (pix >= _mappings[i].start && pix < (_mappings[i].start + _mappings[i].len)) { + return _mappings[i].colorOrder | ((_mappings[i].colorOrder >> 4) ? 0 : (defaultColorOrder & 0xF0)); + } } } return defaultColorOrder; @@ -77,7 +79,7 @@ uint8_t IRAM_ATTR ColorOrderMap::getPixelColorOrder(uint16_t pix, uint8_t defaul uint32_t Bus::autoWhiteCalc(uint32_t c) { uint8_t aWM = _autoWhiteMode; - if (_gAWM < 255) aWM = _gAWM; + if (_gAWM < AW_GLOBAL_DISABLED) aWM = _gAWM; if (aWM == RGBW_MODE_MANUAL_ONLY) return c; uint8_t w = W(c); //ignore auto-white calculation if w>0 and mode DUAL (DUAL behaves as BRIGHTER if w==0) @@ -101,6 +103,8 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com) : Bus(bc.type, bc.start, bc.autoWhite, bc.count, bc.reversed, (bc.refreshReq || bc.type == TYPE_TM1814)) , _skip(bc.skipAmount) //sacrificial pixels , _colorOrder(bc.colorOrder) +, _milliAmpsPerLed(bc.milliAmpsPerLed) +, _milliAmpsMax(bc.milliAmpsMax) , _colorOrderMap(com) { if (!IS_DIGITAL(bc.type) || !bc.count) return; @@ -118,17 +122,92 @@ BusDigital::BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com) _iType = PolyBus::getI(bc.type, _pins, nr); if (_iType == I_NONE) return; if (bc.doubleBuffer && !allocData(bc.count * (Bus::hasWhite(_type) + 3*Bus::hasRGB(_type)))) return; //warning: hardcoded channel count - _buffering = bc.doubleBuffer; + //_buffering = bc.doubleBuffer; uint16_t lenToCreate = bc.count; if (bc.type == TYPE_WS2812_1CH_X3) lenToCreate = NUM_ICS_WS2812_1CH_3X(bc.count); // only needs a third of "RGB" LEDs for NeoPixelBus _busPtr = PolyBus::create(_iType, _pins, lenToCreate + _skip, nr, _frequencykHz); _valid = (_busPtr != nullptr); - DEBUG_PRINTF("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u)\n", _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], _pins[1], _iType); + DEBUG_PRINTF("%successfully inited strip %u (len %u) with type %u and pins %u,%u (itype %u). mA=%d/%d\n", _valid?"S":"Uns", nr, bc.count, bc.type, _pins[0], _pins[1], _iType, _milliAmpsPerLed, _milliAmpsMax); +} + +//fine tune power estimation constants for your setup +//you can set it to 0 if the ESP is powered by USB and the LEDs by external +#ifndef MA_FOR_ESP + #ifdef ESP8266 + #define MA_FOR_ESP 80 //how much mA does the ESP use (Wemos D1 about 80mA) + #else + #define MA_FOR_ESP 120 //how much mA does the ESP use (ESP32 about 120mA) + #endif +#endif + +//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 or houses! + +// To disable brightness limiter we either set output max current to 0 or single LED current to 0 +uint8_t BusDigital::estimateCurrentAndLimitBri() { + bool useWackyWS2815PowerModel = false; + byte actualMilliampsPerLed = _milliAmpsPerLed; + + if (_milliAmpsMax < MA_FOR_ESP/BusManager::getNumBusses() || actualMilliampsPerLed == 0) { //0 mA per LED and too low numbers turn off calculation + return _bri; + } + + if (_milliAmpsPerLed == 255) { + useWackyWS2815PowerModel = true; + actualMilliampsPerLed = 12; // from testing an actual strip + } + + size_t powerBudget = (_milliAmpsMax - MA_FOR_ESP/BusManager::getNumBusses()); //80/120mA for ESP power + if (powerBudget > getLength()) { //each LED uses about 1mA in standby, exclude that from power budget + powerBudget -= getLength(); + } else { + powerBudget = 0; + } + + uint32_t busPowerSum = 0; + for (unsigned i = 0; i < getLength(); i++) { //sum up the usage of each LED + uint32_t c = getPixelColor(i); // always returns original or restored color without brightness scaling + byte r = R(c), g = G(c), b = B(c), w = W(c); + + if (useWackyWS2815PowerModel) { //ignore white component on WS2815 power calculation + busPowerSum += (max(max(r,g),b)) * 3; + } else { + busPowerSum += (r + g + b + w); + } + } + + if (hasWhite()) { //RGBW led total output with white LEDs enabled is still 50mA, so each channel uses less + busPowerSum *= 3; + busPowerSum >>= 2; //same as /= 4 + } + + // powerSum has all the values of channels summed (max would be getLength()*765 as white is excluded) so convert to milliAmps + busPowerSum = (busPowerSum * actualMilliampsPerLed) / 765; + _milliAmpsTotal = busPowerSum * _bri / 255; + + uint8_t newBri = _bri; + if (busPowerSum * _bri / 255 > powerBudget) { //scale brightness down to stay in current limit + float scale = (float)(powerBudget * 255) / (float)(busPowerSum * _bri); + if (scale >= 1.0f) return _bri; + _milliAmpsTotal = ceilf((float)_milliAmpsTotal * scale); + uint8_t scaleB = min((int)(scale * 255), 255); + newBri = unsigned(_bri * scaleB) / 256 + 1; + } + return newBri; } void BusDigital::show() { + _milliAmpsTotal = 0; if (!_valid) return; - if (_buffering) { // should be _data != nullptr, but that causes ~20% FPS drop + + uint8_t newBri = estimateCurrentAndLimitBri(); // will fill _milliAmpsTotal + if (newBri < _bri) PolyBus::setBrightness(_busPtr, _iType, newBri); // limit brightness to stay within current limits + + if (_data) { // use _buffering this causes ~20% FPS drop size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type); for (size_t i=0; i<_len; i++) { size_t offset = i*channels; @@ -144,12 +223,30 @@ void BusDigital::show() { c = RGBW32(_data[offset],_data[offset+1],_data[offset+2],(Bus::hasWhite(_type)?_data[offset+3]:0)); } uint16_t pix = i; - if (_reversed) pix = _len - pix -1; - else pix += _skip; + if (_reversed) pix = _len - pix -1; + pix += _skip; PolyBus::setPixelColor(_busPtr, _iType, pix, c, co); } + #if !defined(STATUSLED) || STATUSLED>=0 + if (_skip) PolyBus::setPixelColor(_busPtr, _iType, 0, 0, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); // paint skipped pixels black + #endif + for (int i=1; i<_skip; i++) PolyBus::setPixelColor(_busPtr, _iType, i, 0, _colorOrderMap.getPixelColorOrder(_start, _colorOrder)); // paint skipped pixels black + } else { + if (newBri < _bri) { + uint16_t hwLen = _len; + if (_type == TYPE_WS2812_1CH_X3) hwLen = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus + for (unsigned i = 0; i < hwLen; i++) { + // use 0 as color order, actual order does not matter here as we just update the channel values as-is + uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, i, 0), _bri); + PolyBus::setPixelColor(_busPtr, _iType, i, c, 0); // repaint all pixels with new brightness + } + } } - PolyBus::show(_busPtr, _iType, !_buffering); // faster if buffer consistency is not important + PolyBus::show(_busPtr, _iType, !_data); // faster if buffer consistency is not important (use !_buffering this causes 20% FPS drop) + // restore bus brightness to its original value + // this is done right after show, so this is only OK if LED updates are completed before show() returns + // or async show has a separate buffer (ESP32 RMT and I2S are ok) + if (newBri < _bri) PolyBus::setBrightness(_busPtr, _iType, _bri); } bool BusDigital::canShow() { @@ -165,22 +262,8 @@ void BusDigital::setBrightness(uint8_t b) { if (_pins[0] == LED_BUILTIN || _pins[1] == LED_BUILTIN) reinit(); } #endif - uint8_t prevBri = _bri; Bus::setBrightness(b); PolyBus::setBrightness(_busPtr, _iType, b); - - if (_buffering) return; - - // must update/repaint every LED in the NeoPixelBus buffer to the new brightness - // the only case where repainting is unnecessary is when all pixels are set after the brightness change but before the next show - // (which we can't rely on) - uint16_t hwLen = _len; - if (_type == TYPE_WS2812_1CH_X3) hwLen = NUM_ICS_WS2812_1CH_3X(_len); // only needs a third of "RGB" LEDs for NeoPixelBus - for (uint_fast16_t i = 0; i < hwLen; i++) { - // use 0 as color order, actual order does not matter here as we just update the channel values as-is - uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, i, 0),prevBri); - PolyBus::setPixelColor(_busPtr, _iType, i, c, 0); - } } //If LEDs are skipped, it is possible to use the first as a status LED. @@ -196,7 +279,7 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) { if (!_valid) return; if (Bus::hasWhite(_type)) c = autoWhiteCalc(c); if (_cct >= 1900) c = colorBalanceFromKelvin(_cct, c); //color correction from CCT - if (_buffering) { // should be _data != nullptr, but that causes ~20% FPS drop + if (_data) { // use _buffering this causes ~20% FPS drop size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type); size_t offset = pix*channels; if (Bus::hasRGB(_type)) { @@ -206,8 +289,8 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) { } if (Bus::hasWhite(_type)) _data[offset] = W(c); } else { - if (_reversed) pix = _len - pix -1; - else pix += _skip; + if (_reversed) pix = _len - pix -1; + pix += _skip; uint8_t co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder); if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs uint16_t pOld = pix; @@ -224,9 +307,9 @@ void IRAM_ATTR BusDigital::setPixelColor(uint16_t pix, uint32_t c) { } // returns original color if global buffering is enabled, else returns lossly restored color from bus -uint32_t BusDigital::getPixelColor(uint16_t pix) { +uint32_t IRAM_ATTR BusDigital::getPixelColor(uint16_t pix) { if (!_valid) return 0; - if (_buffering) { // should be _data != nullptr, but that causes ~20% FPS drop + if (_data) { // use _buffering this causes ~20% FPS drop size_t channels = Bus::hasWhite(_type) + 3*Bus::hasRGB(_type); size_t offset = pix*channels; uint32_t c; @@ -237,8 +320,8 @@ uint32_t BusDigital::getPixelColor(uint16_t pix) { } return c; } else { - if (_reversed) pix = _len - pix -1; - else pix += _skip; + if (_reversed) pix = _len - pix -1; + pix += _skip; uint8_t co = _colorOrderMap.getPixelColorOrder(pix+_start, _colorOrder); uint32_t c = restoreColorLossy(PolyBus::getPixelColor(_busPtr, _iType, (_type==TYPE_WS2812_1CH_X3) ? IC_INDEX_WS2812_1CH_3X(pix) : pix, co),_bri); if (_type == TYPE_WS2812_1CH_X3) { // map to correct IC, each controls 3 LEDs @@ -257,7 +340,7 @@ uint32_t BusDigital::getPixelColor(uint16_t pix) { uint8_t BusDigital::getPins(uint8_t* pinArray) { uint8_t numPins = IS_2PIN(_type) ? 2 : 1; - for (uint8_t i = 0; i < numPins; i++) pinArray[i] = _pins[i]; + for (unsigned i = 0; i < numPins; i++) pinArray[i] = _pins[i]; return numPins; } @@ -301,7 +384,7 @@ BusPwm::BusPwm(BusConfig &bc) } #endif - for (uint8_t i = 0; i < numPins; i++) { + for (unsigned i = 0; i < numPins; i++) { uint8_t currentPin = bc.pins[i]; if (!pinManager.allocatePin(currentPin, true, PinOwner::BusPwm)) { deallocatePins(); return; @@ -380,7 +463,7 @@ uint32_t BusPwm::getPixelColor(uint16_t pix) { void BusPwm::show() { if (!_valid) return; uint8_t numPins = NUM_PWM_PINS(_type); - for (uint8_t i = 0; i < numPins; i++) { + for (unsigned i = 0; i < numPins; i++) { uint8_t scaled = (_data[i] * _bri) / 255; if (_reversed) scaled = 255 - scaled; #ifdef ESP8266 @@ -394,7 +477,7 @@ void BusPwm::show() { uint8_t BusPwm::getPins(uint8_t* pinArray) { if (!_valid) return 0; uint8_t numPins = NUM_PWM_PINS(_type); - for (uint8_t i = 0; i < numPins; i++) { + for (unsigned i = 0; i < numPins; i++) { pinArray[i] = _pins[i]; } return numPins; @@ -402,7 +485,7 @@ uint8_t BusPwm::getPins(uint8_t* pinArray) { void BusPwm::deallocatePins() { uint8_t numPins = NUM_PWM_PINS(_type); - for (uint8_t i = 0; i < numPins; i++) { + for (unsigned i = 0; i < numPins; i++) { pinManager.deallocatePin(_pins[i], PinOwner::BusPwm); if (!pinManager.isPinOk(_pins[i])) continue; #ifdef ESP8266 @@ -508,7 +591,7 @@ void BusNetwork::show() { } uint8_t BusNetwork::getPins(uint8_t* pinArray) { - for (uint8_t i = 0; i < 4; i++) { + for (unsigned i = 0; i < 4; i++) { pinArray[i] = _client[i]; } return 4; @@ -523,29 +606,34 @@ void BusNetwork::cleanup() { //utility to get the approx. memory usage of a given BusConfig uint32_t BusManager::memUsage(BusConfig &bc) { - uint8_t type = bc.type; + if (bc.type == TYPE_ONOFF || IS_PWM(bc.type)) return 5; + uint16_t len = bc.count + bc.skipAmount; - if (type > 15 && type < 32) { // digital types - if (type == TYPE_UCS8903 || type == TYPE_UCS8904) len *= 2; // 16-bit LEDs + uint16_t channels = 3; + uint16_t multiplier = 1; + if (IS_DIGITAL(bc.type)) { // digital types + if (IS_16BIT(bc.type)) len *= 2; // 16-bit LEDs #ifdef ESP8266 + if (bc.type > 28) channels = 4; //RGBW if (bc.pins[0] == 3) { //8266 DMA uses 5x the mem - if (type > 28) return len*20; //RGBW - return len*15; + multiplier = 5; } - if (type > 28) return len*4; //RGBW - return len*3; - #else //ESP32 RMT uses double buffer? - if (type > 28) return len*8; //RGBW - return len*6; + #else //ESP32 RMT uses double buffer, I2S uses 5x buffer + if (type > 28) channels = 4; //RGBW + multiplier = 2; #endif } - if (type > 31 && type < 48) return 5; - return len*3; //RGB + if (IS_VIRTUAL(bc.type)) { + switch (bc.type) { + case TYPE_NET_DDP_RGBW: channels = 4; break; + } + } + return len * channels * multiplier; //RGB } int BusManager::add(BusConfig &bc) { if (getNumBusses() - getNumVirtualBusses() >= WLED_MAX_BUSSES) return -1; - if (bc.type >= TYPE_NET_DDP_RGB && bc.type < 96) { + if (IS_VIRTUAL(bc.type)) { busses[numBusses] = new BusNetwork(bc); } else if (IS_DIGITAL(bc.type)) { busses[numBusses] = new BusDigital(bc, numBusses, colorOrderMap); @@ -562,24 +650,27 @@ void BusManager::removeAll() { DEBUG_PRINTLN(F("Removing all.")); //prevents crashes due to deleting busses while in use. while (!canAllShow()) yield(); - for (uint8_t i = 0; i < numBusses; i++) delete busses[i]; + for (unsigned i = 0; i < numBusses; i++) delete busses[i]; numBusses = 0; } void BusManager::show() { - for (uint8_t i = 0; i < numBusses; i++) { + _milliAmpsUsed = 0; + for (unsigned i = 0; i < numBusses; i++) { busses[i]->show(); + _milliAmpsUsed += busses[i]->getUsedCurrent(); } + if (_milliAmpsUsed) _milliAmpsUsed += MA_FOR_ESP; } void BusManager::setStatusPixel(uint32_t c) { - for (uint8_t i = 0; i < numBusses; i++) { + for (unsigned i = 0; i < numBusses; i++) { busses[i]->setStatusPixel(c); } } void IRAM_ATTR BusManager::setPixelColor(uint16_t pix, uint32_t c) { - for (uint8_t i = 0; i < numBusses; i++) { + for (unsigned i = 0; i < numBusses; i++) { Bus* b = busses[i]; uint16_t bstart = b->getStart(); if (pix < bstart || pix >= bstart + b->getLength()) continue; @@ -588,7 +679,7 @@ void IRAM_ATTR BusManager::setPixelColor(uint16_t pix, uint32_t c) { } void BusManager::setBrightness(uint8_t b) { - for (uint8_t i = 0; i < numBusses; i++) { + for (unsigned i = 0; i < numBusses; i++) { busses[i]->setBrightness(b); } } @@ -603,7 +694,7 @@ void BusManager::setSegmentCCT(int16_t cct, bool allowWBCorrection) { } uint32_t BusManager::getPixelColor(uint16_t pix) { - for (uint8_t i = 0; i < numBusses; i++) { + for (unsigned i = 0; i < numBusses; i++) { Bus* b = busses[i]; uint16_t bstart = b->getStart(); if (pix < bstart || pix >= bstart + b->getLength()) continue; @@ -613,7 +704,7 @@ uint32_t BusManager::getPixelColor(uint16_t pix) { } bool BusManager::canAllShow() { - for (uint8_t i = 0; i < numBusses; i++) { + for (unsigned i = 0; i < numBusses; i++) { if (!busses[i]->canShow()) return false; } return true; @@ -627,7 +718,7 @@ Bus* BusManager::getBus(uint8_t busNr) { //semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit()) uint16_t BusManager::getTotalLength() { uint16_t len = 0; - for (uint8_t i=0; igetLength(); + for (unsigned i=0; igetLength(); return len; } @@ -635,3 +726,11 @@ uint16_t BusManager::getTotalLength() { int16_t Bus::_cct = -1; uint8_t Bus::_cctBlend = 0; uint8_t Bus::_gAWM = 255; + +uint16_t BusDigital::_milliAmpsTotal = 0; + +uint8_t BusManager::numBusses = 0; +Bus* BusManager::busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES]; +ColorOrderMap BusManager::colorOrderMap = {}; +uint16_t BusManager::_milliAmpsUsed = 0; +uint16_t BusManager::_milliAmpsMax = ABL_MILLIAMPS_DEFAULT; \ No newline at end of file diff --git a/wled00/bus_manager.h b/wled00/bus_manager.h index 4249c880e..b2dbd50fa 100644 --- a/wled00/bus_manager.h +++ b/wled00/bus_manager.h @@ -35,8 +35,10 @@ struct BusConfig { uint8_t pins[5] = {LEDPIN, 255, 255, 255, 255}; uint16_t frequency; bool doubleBuffer; + uint8_t milliAmpsPerLed; + uint16_t milliAmpsMax; - BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw=RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz=0U, bool dblBfr=false) + BusConfig(uint8_t busType, uint8_t* ppins, uint16_t pstart, uint16_t len = 1, uint8_t pcolorOrder = COL_ORDER_GRB, bool rev = false, uint8_t skip = 0, byte aw=RGBW_MODE_MANUAL_ONLY, uint16_t clock_kHz=0U, bool dblBfr=false, uint8_t maPerLed=55, uint16_t maMax=ABL_MILLIAMPS_DEFAULT) : count(len) , start(pstart) , colorOrder(pcolorOrder) @@ -45,6 +47,8 @@ struct BusConfig { , autoWhite(aw) , frequency(clock_kHz) , doubleBuffer(dblBfr) + , milliAmpsPerLed(maPerLed) + , milliAmpsMax(maMax) { refreshReq = (bool) GET_BIT(busType,7); type = busType & 0x7F; // bit 7 may be/is hacked to include refresh info (1=refresh in off state, 0=no refresh) @@ -114,7 +118,7 @@ class Bus { , _needsRefresh(refresh) , _data(nullptr) // keep data access consistent across all types of buses { - _autoWhiteMode = Bus::hasWhite(_type) ? aw : RGBW_MODE_MANUAL_ONLY; + _autoWhiteMode = Bus::hasWhite(type) ? aw : RGBW_MODE_MANUAL_ONLY; }; virtual ~Bus() {} //throw the bus under the bus @@ -125,13 +129,15 @@ class Bus { virtual void setPixelColor(uint16_t pix, uint32_t c) = 0; virtual uint32_t getPixelColor(uint16_t pix) { return 0; } virtual void setBrightness(uint8_t b) { _bri = b; }; - virtual void cleanup() = 0; virtual uint8_t getPins(uint8_t* pinArray) { return 0; } virtual uint16_t getLength() { return _len; } - virtual void setColorOrder() {} + virtual void setColorOrder(uint8_t co) {} virtual uint8_t getColorOrder() { return COL_ORDER_RGB; } virtual uint8_t skippedLeds() { return 0; } virtual uint16_t getFrequency() { return 0U; } + virtual uint16_t getLEDCurrent() { return 0; } + virtual uint16_t getUsedCurrent() { return 0; } + virtual uint16_t getMaxCurrent() { return 0; } inline void setReversed(bool reversed) { _reversed = reversed; } inline uint16_t getStart() { return _start; } inline void setStart(uint16_t start) { _start = start; } @@ -148,7 +154,7 @@ class Bus { } virtual bool hasWhite(void) { return Bus::hasWhite(_type); } static bool hasWhite(uint8_t type) { - if ((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_SK6812_RGBW || type == TYPE_TM1814) return true; // digital types with white channel + if ((type >= TYPE_WS2812_1CH && type <= TYPE_WS2812_WWA) || type == TYPE_SK6812_RGBW || type == TYPE_TM1814 || type == TYPE_UCS8904) return true; // digital types with white channel if (type > TYPE_ONOFF && type <= TYPE_ANALOG_5CH && type != TYPE_ANALOG_3CH) return true; // analog types with white channel if (type == TYPE_NET_DDP_RGBW) return true; // network types with white channel return false; @@ -200,17 +206,21 @@ class BusDigital : public Bus { BusDigital(BusConfig &bc, uint8_t nr, const ColorOrderMap &com); ~BusDigital() { cleanup(); } - void show(); - bool canShow(); - void setBrightness(uint8_t b); - void setStatusPixel(uint32_t c); - void setPixelColor(uint16_t pix, uint32_t c); - void setColorOrder(uint8_t colorOrder); - uint32_t getPixelColor(uint16_t pix); - uint8_t getColorOrder() { return _colorOrder; } - uint8_t getPins(uint8_t* pinArray); - uint8_t skippedLeds() { return _skip; } - uint16_t getFrequency() { return _frequencykHz; } + void show() override; + bool canShow() override; + void setBrightness(uint8_t b) override; + void setStatusPixel(uint32_t c) override; + void setPixelColor(uint16_t pix, uint32_t c) override; + void setColorOrder(uint8_t colorOrder) override; + uint32_t getPixelColor(uint16_t pix) override; + uint8_t getColorOrder() override { return _colorOrder; } + uint8_t getPins(uint8_t* pinArray) override; + uint8_t skippedLeds() override { return _skip; } + uint16_t getFrequency() override { return _frequencykHz; } + uint8_t estimateCurrentAndLimitBri(); + uint16_t getLEDCurrent() override { return _milliAmpsPerLed; } + uint16_t getUsedCurrent() override { return _milliAmpsTotal; } + uint16_t getMaxCurrent() override { return _milliAmpsMax; } void reinit(); void cleanup(); @@ -220,9 +230,12 @@ class BusDigital : public Bus { uint8_t _pins[2]; uint8_t _iType; uint16_t _frequencykHz; + uint8_t _milliAmpsPerLed; + uint16_t _milliAmpsMax; void * _busPtr; const ColorOrderMap &_colorOrderMap; - bool _buffering; // temporary until we figure out why comparison "_data != nullptr" causes severe FPS drop + + static uint16_t _milliAmpsTotal; // is overwitten/recalculated on each show() inline uint32_t restoreColorLossy(uint32_t c, uint8_t restoreBri) { if (restoreBri < 255) { @@ -242,11 +255,11 @@ class BusPwm : public Bus { BusPwm(BusConfig &bc); ~BusPwm() { cleanup(); } - void setPixelColor(uint16_t pix, uint32_t c); - uint32_t getPixelColor(uint16_t pix); //does no index check - uint8_t getPins(uint8_t* pinArray); - uint16_t getFrequency() { return _frequency; } - void show(); + void setPixelColor(uint16_t pix, uint32_t c) override; + uint32_t getPixelColor(uint16_t pix) override; //does no index check + uint8_t getPins(uint8_t* pinArray) override; + uint16_t getFrequency() override { return _frequency; } + void show() override; void cleanup() { deallocatePins(); } private: @@ -266,10 +279,10 @@ class BusOnOff : public Bus { BusOnOff(BusConfig &bc); ~BusOnOff() { cleanup(); } - void setPixelColor(uint16_t pix, uint32_t c); - uint32_t getPixelColor(uint16_t pix); - uint8_t getPins(uint8_t* pinArray); - void show(); + void setPixelColor(uint16_t pix, uint32_t c) override; + uint32_t getPixelColor(uint16_t pix) override; + uint8_t getPins(uint8_t* pinArray) override; + void show() override; void cleanup() { pinManager.deallocatePin(_pin, PinOwner::BusOnOff); } private: @@ -283,13 +296,13 @@ class BusNetwork : public Bus { BusNetwork(BusConfig &bc); ~BusNetwork() { cleanup(); } - bool hasRGB() { return true; } - bool hasWhite() { return _rgbw; } - bool canShow() { return !_broadcastLock; } // this should be a return value from UDP routine if it is still sending data out - void setPixelColor(uint16_t pix, uint32_t c); - uint32_t getPixelColor(uint16_t pix); - uint8_t getPins(uint8_t* pinArray); - void show(); + bool hasRGB() override { return true; } + bool hasWhite() override { return _rgbw; } + bool canShow() override { return !_broadcastLock; } // this should be a return value from UDP routine if it is still sending data out + void setPixelColor(uint16_t pix, uint32_t c) override; + uint32_t getPixelColor(uint16_t pix) override; + uint8_t getPins(uint8_t* pinArray) override; + void show() override; void cleanup(); private: @@ -303,39 +316,44 @@ class BusNetwork : public Bus { class BusManager { public: - BusManager() : numBusses(0) {}; + BusManager() {}; //utility to get the approx. memory usage of a given BusConfig static uint32_t memUsage(BusConfig &bc); + static uint16_t currentMilliamps(void) { return _milliAmpsUsed; } + static uint16_t ablMilliampsMax(void) { return _milliAmpsMax; } - int add(BusConfig &bc); + static int add(BusConfig &bc); //do not call this method from system context (network callback) - void removeAll(); + static void removeAll(); - void show(); - bool canAllShow(); - void setStatusPixel(uint32_t c); - void setPixelColor(uint16_t pix, uint32_t c); - void setBrightness(uint8_t b); - void setSegmentCCT(int16_t cct, bool allowWBCorrection = false); - uint32_t getPixelColor(uint16_t pix); + static void show(); + static bool canAllShow(); + static void setStatusPixel(uint32_t c); + static void setPixelColor(uint16_t pix, uint32_t c); + static void setBrightness(uint8_t b); + static void setSegmentCCT(int16_t cct, bool allowWBCorrection = false); + static void setMilliampsMax(uint16_t max) { _milliAmpsMax = max;} + static uint32_t getPixelColor(uint16_t pix); - Bus* getBus(uint8_t busNr); + static Bus* getBus(uint8_t busNr); //semi-duplicate of strip.getLengthTotal() (though that just returns strip._length, calculated in finalizeInit()) - uint16_t getTotalLength(); - inline uint8_t getNumBusses() const { return numBusses; } + static uint16_t getTotalLength(); + static uint8_t getNumBusses() { return numBusses; } - inline void updateColorOrderMap(const ColorOrderMap &com) { memcpy(&colorOrderMap, &com, sizeof(ColorOrderMap)); } - inline const ColorOrderMap& getColorOrderMap() const { return colorOrderMap; } + static void updateColorOrderMap(const ColorOrderMap &com) { memcpy(&colorOrderMap, &com, sizeof(ColorOrderMap)); } + static const ColorOrderMap& getColorOrderMap() { return colorOrderMap; } private: - uint8_t numBusses; - Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES]; - ColorOrderMap colorOrderMap; + static uint8_t numBusses; + static Bus* busses[WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES]; + static ColorOrderMap colorOrderMap; + static uint16_t _milliAmpsUsed; + static uint16_t _milliAmpsMax; - inline uint8_t getNumVirtualBusses() { + static uint8_t getNumVirtualBusses() { int j = 0; for (int i=0; igetType() >= TYPE_NET_DDP_RGB && busses[i]->getType() < 96) j++; return j; diff --git a/wled00/button.cpp b/wled00/button.cpp index d45274a62..b1e7f2a79 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -21,6 +21,7 @@ void shortPressAction(uint8_t b) case 1: ++effectCurrent %= strip.getModeCount(); stateChanged = true; colorUpdated(CALL_MODE_BUTTON); break; } } else { + unloadPlaylist(); // applying a preset unloads the playlist applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET); } @@ -42,6 +43,7 @@ void longPressAction(uint8_t b) case 1: bri += 8; stateUpdated(CALL_MODE_BUTTON); buttonPressedTime[b] = millis(); break; // repeatable action } } else { + unloadPlaylist(); // applying a preset unloads the playlist applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET); } @@ -63,6 +65,7 @@ void doublePressAction(uint8_t b) case 1: ++effectPalette %= strip.getPaletteCount(); colorUpdated(CALL_MODE_BUTTON); break; } } else { + unloadPlaylist(); // applying a preset unloads the playlist applyPreset(macroDoublePress[b], CALL_MODE_BUTTON_PRESET); } @@ -94,8 +97,9 @@ bool isButtonPressed(uint8_t i) if (digitalRead(pin) == HIGH) return true; break; case BTN_TYPE_TOUCH: + case BTN_TYPE_TOUCH_SWITCH: #if defined(ARDUINO_ARCH_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) - if (touchRead(pin) <= touchThreshold) return true; + if (digitalPinToTouchChannel(btnPin[i]) >= 0 && touchRead(pin) <= touchThreshold) return true; #endif break; } @@ -106,6 +110,7 @@ void handleSwitch(uint8_t b) { // isButtonPressed() handles inverted/noninverted logic if (buttonPressedBefore[b] != isButtonPressed(b)) { + DEBUG_PRINT(F("Switch: State changed ")); DEBUG_PRINTLN(b); buttonPressedTime[b] = millis(); buttonPressedBefore[b] = !buttonPressedBefore[b]; } @@ -113,12 +118,15 @@ void handleSwitch(uint8_t b) if (buttonLongPressed[b] == buttonPressedBefore[b]) return; if (millis() - buttonPressedTime[b] > WLED_DEBOUNCE_THRESHOLD) { //fire edge event only after 50ms without change (debounce) + DEBUG_PRINT(F("Switch: Activating ")); DEBUG_PRINTLN(b); if (!buttonPressedBefore[b]) { // on -> off + DEBUG_PRINT(F("Switch: On -> Off ")); DEBUG_PRINTLN(b); if (macroButton[b]) applyPreset(macroButton[b], CALL_MODE_BUTTON_PRESET); else { //turn on if (!bri) {toggleOnOff(); stateUpdated(CALL_MODE_BUTTON);} } } else { // off -> on + DEBUG_PRINT(F("Switch: Off -> On ")); DEBUG_PRINTLN(b); if (macroLongPress[b]) applyPreset(macroLongPress[b], CALL_MODE_BUTTON_PRESET); else { //turn off if (bri) {toggleOnOff(); stateUpdated(CALL_MODE_BUTTON);} @@ -150,13 +158,18 @@ void handleAnalog(uint8_t b) static float filteredReading[WLED_MAX_BUTTONS] = {0.0f}; uint16_t rawReading; // raw value from analogRead, scaled to 12bit + DEBUG_PRINT(F("Analog: Reading button ")); DEBUG_PRINTLN(b); + #ifdef ESP8266 rawReading = analogRead(A0) << 2; // convert 10bit read to 12bit #else + if ((btnPin[b] < 0) || (digitalPinToAnalogChannel(btnPin[b]) < 0)) return; // pin must support analog ADC - newer esp32 frameworks throw lots of warnings otherwise rawReading = analogRead(btnPin[b]); // collect at full 12bit resolution #endif yield(); // keep WiFi task running - analog read may take several millis on ESP8266 + DEBUG_PRINT(F("Analog: Raw read = ")); DEBUG_PRINTLN(rawReading); + filteredReading[b] += POT_SMOOTHING * ((float(rawReading) / 16.0f) - filteredReading[b]); // filter raw input, and scale to [0..255] uint16_t aRead = max(min(int(filteredReading[b]), 255), 0); // squash into 8bit if(aRead <= POT_SENSITIVITY) aRead = 0; // make sure that 0 and 255 are used @@ -167,6 +180,8 @@ void handleAnalog(uint8_t b) // remove noise & reduce frequency of UI updates if (abs(int(aRead) - int(oldRead[b])) <= POT_SENSITIVITY) return; // no significant change in reading + DEBUG_PRINT(F("Analog: Filtered read = ")); DEBUG_PRINTLN(aRead); + // Unomment the next lines if you still see flickering related to potentiometer // This waits until strip finishes updating (why: strip was not updating at the start of handleButton() but may have started during analogRead()?) //unsigned long wait_started = millis(); @@ -179,13 +194,14 @@ void handleAnalog(uint8_t b) // if no macro for "short press" and "long press" is defined use brightness control if (!macroButton[b] && !macroLongPress[b]) { + DEBUG_PRINT(F("Analog: Action = ")); DEBUG_PRINTLN(macroDoublePress[b]); // if "double press" macro defines which option to change if (macroDoublePress[b] >= 250) { // global brightness if (aRead == 0) { briLast = bri; bri = 0; - } else{ + } else { bri = aRead; } } else if (macroDoublePress[b] == 249) { @@ -214,6 +230,7 @@ void handleAnalog(uint8_t b) updateInterfaces(CALL_MODE_BUTTON); } } else { + DEBUG_PRINTLN(F("Analog: No action")); //TODO: // we can either trigger a preset depending on the level (between short and long entries) // or use it for RGBW direct control @@ -248,7 +265,7 @@ void handleButton() } // button is not momentary, but switch. This is only suitable on pins whose on-boot state does not matter (NOT gpio0) - if (buttonType[b] == BTN_TYPE_SWITCH || buttonType[b] == BTN_TYPE_PIR_SENSOR) { + if (buttonType[b] == BTN_TYPE_SWITCH || buttonType[b] == BTN_TYPE_TOUCH_SWITCH || buttonType[b] == BTN_TYPE_PIR_SENSOR) { handleSwitch(b); continue; } @@ -262,7 +279,7 @@ void handleButton() shortPressAction(b); buttonPressedBefore[b] = true; buttonPressedTime[b] = now; // continually update (for debouncing to work in release handler) - return; + continue; } if (!buttonPressedBefore[b]) buttonPressedTime[b] = now; @@ -283,7 +300,7 @@ void handleButton() // released after rising-edge short press action if (macroButton[b] && macroButton[b] == macroLongPress[b] && macroButton[b] == macroDoublePress[b]) { if (dur > WLED_DEBOUNCE_THRESHOLD) buttonPressedBefore[b] = false; // debounce, blocks button for 50 ms once it has been released - return; + continue; } if (dur < WLED_DEBOUNCE_THRESHOLD) {buttonPressedBefore[b] = false; continue;} // too short "press", debounce @@ -330,10 +347,10 @@ void handleButton() void esp32RMTInvertIdle() { bool idle_out; - for (uint8_t u = 0; u < busses.getNumBusses(); u++) + for (uint8_t u = 0; u < BusManager::getNumBusses(); u++) { if (u > 7) return; // only 8 RMT channels, TODO: ESP32 variants have less RMT channels - Bus *bus = busses.getBus(u); + Bus *bus = BusManager::getBus(u); if (!bus || bus->getLength()==0 || !IS_DIGITAL(bus->getType()) || IS_2PIN(bus->getType())) continue; //assumes that bus number to rmt channel mapping stays 1:1 rmt_channel_t ch = static_cast(u); diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp old mode 100644 new mode 100755 index cafba6a0a..1234a1c5f --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -31,11 +31,16 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { getStringFromJson(cmDNS, id[F("mdns")], 33); getStringFromJson(serverDescription, id[F("name")], 33); getStringFromJson(alexaInvocationName, id[F("inv")], 33); -#ifdef WLED_ENABLE_SIMPLE_UI CJSON(simplifiedUI, id[F("sui")]); + + JsonObject nw = doc["nw"]; +#ifndef WLED_DISABLE_ESPNOW + CJSON(enableESPNow, nw[F("espnow")]); + getStringFromJson(linked_remote, nw[F("linked_remote")], 13); + linked_remote[12] = '\0'; #endif - JsonObject nw_ins_0 = doc["nw"]["ins"][0]; + JsonObject nw_ins_0 = nw["ins"][0]; getStringFromJson(clientSSID, nw_ins_0[F("ssid")], 33); //int nw_ins_0_pskl = nw_ins_0[F("pskl")]; //The WiFi PSK is normally not contained in the regular file for security reasons. @@ -74,17 +79,17 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { noWifiSleep = doc[F("wifi")][F("sleep")] | !noWifiSleep; // inverted noWifiSleep = !noWifiSleep; - //int wifi_phy = doc[F("wifi")][F("phy")]; //force phy mode n? + force802_3g = doc[F("wifi")][F("phy")] | force802_3g; //force phy mode g? JsonObject hw = doc[F("hw")]; // initialize LED pins and lengths prior to other HW (except for ethernet) JsonObject hw_led = hw["led"]; - uint8_t autoWhiteMode = RGBW_MODE_MANUAL_ONLY; - CJSON(strip.ablMilliampsMax, hw_led[F("maxpwr")]); - CJSON(strip.milliampsPerLed, hw_led[F("ledma")]); - Bus::setGlobalAWMode(hw_led[F("rgbwm")] | 255); + uint16_t total = hw_led[F("total")] | strip.getLengthTotal(); + uint16_t ablMilliampsMax = hw_led[F("maxpwr")] | BusManager::ablMilliampsMax(); + BusManager::setMilliampsMax(ablMilliampsMax); + Bus::setGlobalAWMode(hw_led[F("rgbwm")] | AW_GLOBAL_DISABLED); CJSON(correctWB, hw_led["cct"]); CJSON(cctFromRgb, hw_led[F("cr")]); CJSON(strip.cctBlending, hw_led[F("cb")]); @@ -133,7 +138,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (fromFS || !ins.isNull()) { uint8_t s = 0; // bus iterator - if (fromFS) busses.removeAll(); // can't safely manipulate busses directly in network callback + if (fromFS) BusManager::removeAll(); // can't safely manipulate busses directly in network callback uint32_t mem = 0, globalBufMem = 0; uint16_t maxlen = 0; bool busesChanged = false; @@ -150,7 +155,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { } uint16_t length = elm["len"] | 1; - uint8_t colorOrder = (int)elm[F("order")]; + uint8_t colorOrder = (int)elm[F("order")]; // contains white channel swap option in upper nibble uint8_t skipFirst = elm[F("skip")]; uint16_t start = elm["start"] | 0; if (length==0 || start + length > MAX_LEDS) continue; // zero length or we reached max. number of LEDs, just stop @@ -158,19 +163,26 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { bool reversed = elm["rev"]; bool refresh = elm["ref"] | false; uint16_t freqkHz = elm[F("freq")] | 0; // will be in kHz for DotStar and Hz for PWM (not yet implemented fully) + uint8_t AWmode = elm[F("rgbwm")] | RGBW_MODE_MANUAL_ONLY; + uint8_t maPerLed = elm[F("ledma")] | 55; + uint16_t maMax = elm[F("maxpwr")] | (ablMilliampsMax * length) / total; // rough (incorrect?) per strip ABL calculation when no config exists + // To disable brightness limiter we either set output max current to 0 or single LED current to 0 (we choose output max current) + if ((ledType > TYPE_TM1814 && ledType < TYPE_WS2801) || ledType >= TYPE_NET_DDP_RGB) { // analog and virtual + maPerLed = 0; + maMax = 0; + } ledType |= refresh << 7; // hack bit 7 to indicate strip requires off refresh - uint8_t AWmode = elm[F("rgbwm")] | autoWhiteMode; if (fromFS) { - BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer); + BusConfig bc = BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax); mem += BusManager::memUsage(bc); if (useGlobalLedBuffer && start + length > maxlen) { maxlen = start + length; globalBufMem = maxlen * 4; } - if (mem + globalBufMem <= MAX_LED_MEMORY) if (busses.add(bc) == -1) break; // finalization will be done in WLED::beginStrip() + if (mem + globalBufMem <= MAX_LED_MEMORY) if (BusManager::add(bc) == -1) break; // finalization will be done in WLED::beginStrip() } else { if (busConfigs[s] != nullptr) delete busConfigs[s]; - busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer); + busConfigs[s] = new BusConfig(ledType, pins, start, length, colorOrder, reversed, skipFirst, AWmode, freqkHz, useGlobalLedBuffer, maPerLed, maMax); busesChanged = true; } s++; @@ -178,7 +190,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { doInitBusses = busesChanged; // finalization done in beginStrip() } - if (hw_led["rev"]) busses.getBus(0)->setReversed(true); //set 0.11 global reversed setting for first bus + if (hw_led["rev"]) BusManager::getBus(0)->setReversed(true); //set 0.11 global reversed setting for first bus // read color order map configuration JsonArray hw_com = hw[F("com")]; @@ -193,7 +205,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { com.add(start, len, colorOrder); s++; } - busses.updateColorOrderMap(com); + BusManager::updateColorOrderMap(com); } // read multiple button configuration @@ -216,7 +228,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { if (((buttonType[s] == BTN_TYPE_ANALOG) || (buttonType[s] == BTN_TYPE_ANALOG_INVERTED)) && (digitalPinToAnalogChannel(btnPin[s]) < 0)) { // not an ADC analog pin - DEBUG_PRINTF("PIN ALLOC error: GPIO%d for analog button #%d is not an analog pin!\n", btnPin[s], s); + DEBUG_PRINT(F("PIN ALLOC error: GPIO")); DEBUG_PRINT(btnPin[s]); + DEBUG_PRINT(F("for analog button #")); DEBUG_PRINT(s); + DEBUG_PRINTLN(F(" is not an analog pin!")); btnPin[s] = -1; pinManager.deallocatePin(pin,PinOwner::Button); } @@ -357,8 +371,10 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { JsonObject light_tr = light["tr"]; CJSON(fadeTransition, light_tr["mode"]); + CJSON(modeBlending, light_tr["fx"]); int tdd = light_tr["dur"] | -1; if (tdd >= 0) transitionDelay = transitionDelayDefault = tdd * 100; + strip.setTransition(fadeTransition ? transitionDelayDefault : 0); CJSON(strip.paletteFade, light_tr["pal"]); CJSON(randomPaletteChangeTime, light_tr[F("rpc")]); @@ -382,6 +398,10 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(udpPort, if_sync[F("port0")]); // 21324 CJSON(udpPort2, if_sync[F("port1")]); // 65506 +#ifndef WLED_DISABLE_ESPNOW + CJSON(useESPNowSync, if_sync[F("espnow")]); +#endif + JsonObject if_sync_recv = if_sync["recv"]; CJSON(receiveNotificationBrightness, if_sync_recv["bri"]); CJSON(receiveNotificationColor, if_sync_recv["col"]); @@ -389,17 +409,14 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(receiveGroups, if_sync_recv["grp"]); CJSON(receiveSegmentOptions, if_sync_recv["seg"]); CJSON(receiveSegmentBounds, if_sync_recv["sb"]); - //! following line might be a problem if called after boot - receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects || receiveSegmentOptions); JsonObject if_sync_send = if_sync["send"]; - prev = notifyDirectDefault; - CJSON(notifyDirectDefault, if_sync_send[F("dir")]); - if (notifyDirectDefault != prev) notifyDirect = notifyDirectDefault; + CJSON(sendNotifications, if_sync_send["en"]); + sendNotificationsRT = sendNotifications; + CJSON(notifyDirect, if_sync_send[F("dir")]); CJSON(notifyButton, if_sync_send["btn"]); CJSON(notifyAlexa, if_sync_send["va"]); CJSON(notifyHue, if_sync_send["hue"]); - CJSON(notifyMacro, if_sync_send["macro"]); CJSON(syncGroups, if_sync_send["grp"]); if (if_sync_send[F("twice")]) udpNumRetries = 1; // import setting from 0.13 and earlier CJSON(udpNumRetries, if_sync_send["ret"]); @@ -409,8 +426,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { CJSON(nodeBroadcastEnabled, if_nodes[F("bcast")]); JsonObject if_live = interfaces["live"]; - CJSON(receiveDirect, if_live["en"]); + CJSON(receiveDirect, if_live["en"]); // UDP/Hyperion realtime CJSON(useMainSegmentOnly, if_live[F("mso")]); + CJSON(realtimeRespectLedMaps, if_live[F("rlm")]); CJSON(e131Port, if_live["port"]); // 5568 if (e131Port == DDP_DEFAULT_PORT) e131Port = E131_DEFAULT_PORT; // prevent double DDP port allocation CJSON(e131Multicast, if_live[F("mc")]); @@ -442,24 +460,17 @@ bool deserializeConfig(JsonObject doc, bool fromFS) { #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces["mqtt"]; CJSON(mqttEnabled, if_mqtt["en"]); - getStringFromJson(mqttServer, if_mqtt[F("broker")], 33); + getStringFromJson(mqttServer, if_mqtt[F("broker")], MQTT_MAX_SERVER_LEN+1); CJSON(mqttPort, if_mqtt["port"]); // 1883 getStringFromJson(mqttUser, if_mqtt[F("user")], 41); getStringFromJson(mqttPass, if_mqtt["psk"], 65); //normally not present due to security getStringFromJson(mqttClientID, if_mqtt[F("cid")], 41); - getStringFromJson(mqttDeviceTopic, if_mqtt[F("topics")][F("device")], 33); // "wled/test" - getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], 33); // "" + getStringFromJson(mqttDeviceTopic, if_mqtt[F("topics")][F("device")], MQTT_MAX_TOPIC_LEN+1); // "wled/test" + getStringFromJson(mqttGroupTopic, if_mqtt[F("topics")][F("group")], MQTT_MAX_TOPIC_LEN+1); // "" CJSON(retainMqttMsg, if_mqtt[F("rtn")]); #endif -#ifndef WLED_DISABLE_ESPNOW - JsonObject remote = doc["remote"]; - CJSON(enable_espnow_remote, remote[F("remote_enabled")]); - getStringFromJson(linked_remote, remote[F("linked_remote")], 13); -#endif - - #ifndef WLED_DISABLE_HUESYNC JsonObject if_hue = interfaces["hue"]; CJSON(huePollingEnabled, if_hue["en"]); @@ -598,7 +609,7 @@ void deserializeConfigFromFS() { DEBUG_PRINTLN(F("Reading settings from /cfg.json...")); - success = readObjectFromFile("/cfg.json", nullptr, &doc); + success = readObjectFromFile("/cfg.json", nullptr, pDoc); if (!success) { // if file does not exist, optionally try reading from EEPROM and then save defaults to FS releaseJSONBufferLock(); #ifdef WLED_ADD_EEPROM_SUPPORT @@ -619,7 +630,8 @@ void deserializeConfigFromFS() { // NOTE: This routine deserializes *and* applies the configuration // Therefore, must also initialize ethernet from this function - bool needsSave = deserializeConfig(doc.as(), true); + JsonObject root = pDoc->as(); + bool needsSave = deserializeConfig(root, true); releaseJSONBufferLock(); if (needsSave) serializeConfig(); // usermods required new parameters @@ -632,21 +644,25 @@ void serializeConfig() { if (!requestJSONBufferLock(2)) return; - JsonArray rev = doc.createNestedArray("rev"); + JsonObject root = pDoc->to(); + + JsonArray rev = root.createNestedArray("rev"); rev.add(1); //major settings revision rev.add(0); //minor settings revision - doc[F("vid")] = VERSION; + root[F("vid")] = VERSION; - JsonObject id = doc.createNestedObject("id"); + JsonObject id = root.createNestedObject("id"); id[F("mdns")] = cmDNS; id[F("name")] = serverDescription; id[F("inv")] = alexaInvocationName; -#ifdef WLED_ENABLE_SIMPLE_UI id[F("sui")] = simplifiedUI; -#endif - JsonObject nw = doc.createNestedObject("nw"); + JsonObject nw = root.createNestedObject("nw"); +#ifndef WLED_DISABLE_ESPNOW + nw[F("espnow")] = enableESPNow; + nw[F("linked_remote")] = linked_remote; +#endif JsonArray nw_ins = nw.createNestedArray("ins"); @@ -664,7 +680,7 @@ void serializeConfig() { nw_ins_0_sn.add(staticSubnet[i]); } - JsonObject ap = doc.createNestedObject("ap"); + JsonObject ap = root.createNestedObject("ap"); ap[F("ssid")] = apSSID; ap[F("pskl")] = strlen(apPass); ap[F("chan")] = apChannel; @@ -677,12 +693,12 @@ void serializeConfig() { ap_ip.add(2); ap_ip.add(1); - JsonObject wifi = doc.createNestedObject("wifi"); + JsonObject wifi = root.createNestedObject("wifi"); wifi[F("sleep")] = !noWifiSleep; - //wifi[F("phy")] = 1; + wifi[F("phy")] = force802_3g; #ifdef WLED_USE_ETHERNET - JsonObject ethernet = doc.createNestedObject("eth"); + JsonObject ethernet = root.createNestedObject("eth"); ethernet["type"] = ethernetType; if (ethernetType != WLED_ETH_NONE && ethernetType < WLED_NUM_ETH_TYPES) { JsonArray pins = ethernet.createNestedArray("pin"); @@ -705,12 +721,12 @@ void serializeConfig() { } #endif - JsonObject hw = doc.createNestedObject("hw"); + JsonObject hw = root.createNestedObject("hw"); JsonObject hw_led = hw.createNestedObject("led"); - hw_led[F("total")] = strip.getLengthTotal(); //no longer read, but provided for compatibility on downgrade - hw_led[F("maxpwr")] = strip.ablMilliampsMax; - hw_led[F("ledma")] = strip.milliampsPerLed; + hw_led[F("total")] = strip.getLengthTotal(); //provided for compatibility on downgrade and per-output ABL + hw_led[F("maxpwr")] = BusManager::ablMilliampsMax(); + hw_led[F("ledma")] = 0; // no longer used hw_led["cct"] = correctWB; hw_led[F("cr")] = cctFromRgb; hw_led[F("cb")] = strip.cctBlending; @@ -740,8 +756,8 @@ void serializeConfig() { JsonArray hw_led_ins = hw_led.createNestedArray("ins"); - for (uint8_t s = 0; s < busses.getNumBusses(); s++) { - Bus *bus = busses.getBus(s); + for (uint8_t s = 0; s < BusManager::getNumBusses(); s++) { + Bus *bus = BusManager::getBus(s); if (!bus || bus->getLength()==0) break; JsonObject ins = hw_led_ins.createNestedObject(); ins["start"] = bus->getStart(); @@ -757,10 +773,12 @@ void serializeConfig() { ins["ref"] = bus->isOffRefreshRequired(); ins[F("rgbwm")] = bus->getAutoWhiteMode(); ins[F("freq")] = bus->getFrequency(); + ins[F("maxpwr")] = bus->getMaxCurrent(); + ins[F("ledma")] = bus->getLEDCurrent(); } JsonArray hw_com = hw.createNestedArray(F("com")); - const ColorOrderMap& com = busses.getColorOrderMap(); + const ColorOrderMap& com = BusManager::getColorOrderMap(); for (uint8_t s = 0; s < com.count(); s++) { const ColorOrderMapEntry *entry = com.get(s); if (!entry) break; @@ -815,7 +833,7 @@ void serializeConfig() { //JsonObject hw_status = hw.createNestedObject("status"); //hw_status["pin"] = -1; - JsonObject light = doc.createNestedObject(F("light")); + JsonObject light = root.createNestedObject(F("light")); light[F("scale-bri")] = briMultiplier; light[F("pal-mode")] = strip.paletteBlend; light[F("aseg")] = autoSegments; @@ -827,6 +845,7 @@ void serializeConfig() { JsonObject light_tr = light.createNestedObject("tr"); light_tr["mode"] = fadeTransition; + light_tr["fx"] = modeBlending; light_tr["dur"] = transitionDelayDefault / 100; light_tr["pal"] = strip.paletteFade; light_tr[F("rpc")] = randomPaletteChangeTime; @@ -837,17 +856,21 @@ void serializeConfig() { light_nl[F("tbri")] = nightlightTargetBri; light_nl["macro"] = macroNl; - JsonObject def = doc.createNestedObject("def"); + JsonObject def = root.createNestedObject("def"); def["ps"] = bootPreset; def["on"] = turnOnAtBoot; def["bri"] = briS; - JsonObject interfaces = doc.createNestedObject("if"); + JsonObject interfaces = root.createNestedObject("if"); JsonObject if_sync = interfaces.createNestedObject("sync"); if_sync[F("port0")] = udpPort; if_sync[F("port1")] = udpPort2; +#ifndef WLED_DISABLE_ESPNOW + if_sync[F("espnow")] = useESPNowSync; +#endif + JsonObject if_sync_recv = if_sync.createNestedObject("recv"); if_sync_recv["bri"] = receiveNotificationBrightness; if_sync_recv["col"] = receiveNotificationColor; @@ -857,11 +880,11 @@ void serializeConfig() { if_sync_recv["sb"] = receiveSegmentBounds; JsonObject if_sync_send = if_sync.createNestedObject("send"); + if_sync_send["en"] = sendNotifications; if_sync_send[F("dir")] = notifyDirect; if_sync_send["btn"] = notifyButton; if_sync_send["va"] = notifyAlexa; if_sync_send["hue"] = notifyHue; - if_sync_send["macro"] = notifyMacro; if_sync_send["grp"] = syncGroups; if_sync_send["ret"] = udpNumRetries; @@ -870,8 +893,9 @@ void serializeConfig() { if_nodes[F("bcast")] = nodeBroadcastEnabled; JsonObject if_live = interfaces.createNestedObject("live"); - if_live["en"] = receiveDirect; + if_live["en"] = receiveDirect; // UDP/Hyperion realtime if_live[F("mso")] = useMainSegmentOnly; + if_live[F("rlm")] = realtimeRespectLedMaps; if_live["port"] = e131Port; if_live[F("mc")] = e131Multicast; @@ -888,6 +912,7 @@ void serializeConfig() { if_live[F("no-gc")] = arlsDisableGammaCorrection; if_live[F("offset")] = arlsOffset; +#ifndef WLED_DISABLE_ALEXA JsonObject if_va = interfaces.createNestedObject("va"); if_va[F("alexa")] = alexaEnabled; @@ -896,6 +921,7 @@ void serializeConfig() { if_va_macros.add(macroAlexaOff); if_va["p"] = alexaNumPresets; +#endif #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces.createNestedObject("mqtt"); @@ -912,13 +938,6 @@ void serializeConfig() { if_mqtt_topics[F("group")] = mqttGroupTopic; #endif -#ifndef WLED_DISABLE_ESPNOW - JsonObject remote = doc.createNestedObject(F("remote")); - remote[F("remote_enabled")] = enable_espnow_remote; - remote[F("linked_remote")] = linked_remote; -#endif - - #ifndef WLED_DISABLE_HUESYNC JsonObject if_hue = interfaces.createNestedObject("hue"); if_hue["en"] = huePollingEnabled; @@ -945,7 +964,7 @@ void serializeConfig() { if_ntp[F("ln")] = longitude; if_ntp[F("lt")] = latitude; - JsonObject ol = doc.createNestedObject("ol"); + JsonObject ol = root.createNestedObject("ol"); ol[F("clock")] = overlayCurrent; ol[F("cntdwn")] = countdownMode; @@ -955,7 +974,7 @@ void serializeConfig() { ol[F("o5m")] = analogClock5MinuteMarks; ol[F("osec")] = analogClockSecondsTrail; - JsonObject timers = doc.createNestedObject(F("timers")); + JsonObject timers = root.createNestedObject(F("timers")); JsonObject cntdwn = timers.createNestedObject(F("cntdwn")); JsonArray goal = cntdwn.createNestedArray(F("goal")); @@ -983,14 +1002,14 @@ void serializeConfig() { } } - JsonObject ota = doc.createNestedObject("ota"); + JsonObject ota = root.createNestedObject("ota"); ota[F("lock")] = otaLock; ota[F("lock-wifi")] = wifiLock; ota[F("pskl")] = strlen(otaPass); ota[F("aota")] = aOtaEnabled; #ifdef WLED_ENABLE_DMX - JsonObject dmx = doc.createNestedObject("dmx"); + JsonObject dmx = root.createNestedObject("dmx"); dmx[F("chan")] = DMXChannels; dmx[F("gap")] = DMXGap; dmx["start"] = DMXStart; @@ -1004,11 +1023,11 @@ void serializeConfig() { dmx[F("e131proxy")] = e131ProxyUniverse; #endif - JsonObject usermods_settings = doc.createNestedObject("um"); + JsonObject usermods_settings = root.createNestedObject("um"); usermods.addToConfig(usermods_settings); File f = WLED_FS.open("/cfg.json", "w"); - if (f) serializeJson(doc, f); + if (f) serializeJson(root, f); f.close(); releaseJSONBufferLock(); @@ -1021,19 +1040,21 @@ bool deserializeConfigSec() { if (!requestJSONBufferLock(3)) return false; - bool success = readObjectFromFile("/wsec.json", nullptr, &doc); + bool success = readObjectFromFile("/wsec.json", nullptr, pDoc); if (!success) { releaseJSONBufferLock(); return false; } - JsonObject nw_ins_0 = doc["nw"]["ins"][0]; + JsonObject root = pDoc->as(); + + JsonObject nw_ins_0 = root["nw"]["ins"][0]; getStringFromJson(clientPass, nw_ins_0["psk"], 65); - JsonObject ap = doc["ap"]; + JsonObject ap = root["ap"]; getStringFromJson(apPass, ap["psk"] , 65); - JsonObject interfaces = doc["if"]; + [[maybe_unused]] JsonObject interfaces = root["if"]; #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces["mqtt"]; @@ -1044,10 +1065,10 @@ bool deserializeConfigSec() { getStringFromJson(hueApiKey, interfaces["hue"][F("key")], 47); #endif - getStringFromJson(settingsPIN, doc["pin"], 5); + getStringFromJson(settingsPIN, root["pin"], 5); correctPIN = !strlen(settingsPIN); - JsonObject ota = doc["ota"]; + JsonObject ota = root["ota"]; getStringFromJson(otaPass, ota[F("pwd")], 33); CJSON(otaLock, ota[F("lock")]); CJSON(wifiLock, ota[F("lock-wifi")]); @@ -1062,17 +1083,19 @@ void serializeConfigSec() { if (!requestJSONBufferLock(4)) return; - JsonObject nw = doc.createNestedObject("nw"); + JsonObject root = pDoc->to(); + + JsonObject nw = root.createNestedObject("nw"); JsonArray nw_ins = nw.createNestedArray("ins"); JsonObject nw_ins_0 = nw_ins.createNestedObject(); nw_ins_0["psk"] = clientPass; - JsonObject ap = doc.createNestedObject("ap"); + JsonObject ap = root.createNestedObject("ap"); ap["psk"] = apPass; - JsonObject interfaces = doc.createNestedObject("if"); + [[maybe_unused]] JsonObject interfaces = root.createNestedObject("if"); #ifdef WLED_ENABLE_MQTT JsonObject if_mqtt = interfaces.createNestedObject("mqtt"); if_mqtt["psk"] = mqttPass; @@ -1082,16 +1105,16 @@ void serializeConfigSec() { if_hue[F("key")] = hueApiKey; #endif - doc["pin"] = settingsPIN; + root["pin"] = settingsPIN; - JsonObject ota = doc.createNestedObject("ota"); + JsonObject ota = root.createNestedObject("ota"); ota[F("pwd")] = otaPass; ota[F("lock")] = otaLock; ota[F("lock-wifi")] = wifiLock; ota[F("aota")] = aOtaEnabled; File f = WLED_FS.open("/wsec.json", "w"); - if (f) serializeJson(doc, f); + if (f) serializeJson(root, f); f.close(); releaseJSONBufferLock(); } diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 8c4baabb5..21c27d651 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -35,23 +35,59 @@ uint32_t color_blend(uint32_t color1, uint32_t color2, uint16_t blend, bool b16) * color add function that preserves ratio * idea: https://github.com/Aircoookie/WLED/pull/2465 by https://github.com/Proto-molecule */ -uint32_t color_add(uint32_t c1, uint32_t c2) +uint32_t color_add(uint32_t c1, uint32_t c2, bool fast) { - uint32_t r = R(c1) + R(c2); - uint32_t g = G(c1) + G(c2); - uint32_t b = B(c1) + B(c2); - uint32_t w = W(c1) + W(c2); - uint16_t max = r; - if (g > max) max = g; - if (b > max) max = b; - if (w > max) max = w; - if (max < 256) return RGBW32(r, g, b, w); - else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max); + if (fast) { + uint8_t r = R(c1); + uint8_t g = G(c1); + uint8_t b = B(c1); + uint8_t w = W(c1); + r = qadd8(r, R(c2)); + g = qadd8(g, G(c2)); + b = qadd8(b, B(c2)); + w = qadd8(w, W(c2)); + return RGBW32(r,g,b,w); + } else { + uint32_t r = R(c1) + R(c2); + uint32_t g = G(c1) + G(c2); + uint32_t b = B(c1) + B(c2); + uint32_t w = W(c1) + W(c2); + uint16_t max = r; + if (g > max) max = g; + if (b > max) max = b; + if (w > max) max = w; + if (max < 256) return RGBW32(r, g, b, w); + else return RGBW32(r * 255 / max, g * 255 / max, b * 255 / max, w * 255 / max); + } +} + +/* + * fades color toward black + * if using "video" method the resulting color will never become black unless it is already black + */ +uint32_t color_fade(uint32_t c1, uint8_t amount, bool video) +{ + uint8_t r = R(c1); + uint8_t g = G(c1); + uint8_t b = B(c1); + uint8_t w = W(c1); + if (video) { + r = scale8_video(r, amount); + g = scale8_video(g, amount); + b = scale8_video(b, amount); + w = scale8_video(w, amount); + } else { + r = scale8(r, amount); + g = scale8(g, amount); + b = scale8(b, amount); + w = scale8(w, amount); + } + return RGBW32(r, g, b, w); } void setRandomColor(byte* rgb) { - lastRandomIndex = strip.getMainSegment().get_random_wheel_index(lastRandomIndex); + lastRandomIndex = get_random_wheel_index(lastRandomIndex); colorHStoRGB(lastRandomIndex*256,255,rgb); } diff --git a/wled00/const.h b/wled00/const.h index aa256ebe0..4ef81b907 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -147,8 +147,10 @@ #define USERMOD_ID_SD_CARD 37 //Usermod "usermod_sd_card.h" #define USERMOD_ID_PWM_OUTPUTS 38 //Usermod "usermod_pwm_outputs.h #define USERMOD_ID_SHT 39 //Usermod "usermod_sht.h -#define USERMOD_ID_KLIPPER 40 // Usermod Klipper percentage +#define USERMOD_ID_KLIPPER 40 //Usermod Klipper percentage #define USERMOD_ID_WIREGUARD 41 //Usermod "wireguard.h" +#define USERMOD_ID_INTERNAL_TEMPERATURE 42 //Usermod "usermod_internal_temperature.h" +#define USERMOD_ID_ANIMARTRIX 44 //Usermod "usermod_v2_animartrix.h" //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot @@ -165,7 +167,7 @@ #define CALL_MODE_NO_NOTIFY 5 #define CALL_MODE_FX_CHANGED 6 //no longer used #define CALL_MODE_HUE 7 -#define CALL_MODE_PRESET_CYCLE 8 +#define CALL_MODE_PRESET_CYCLE 8 //no longer used #define CALL_MODE_BLYNK 9 //no longer used #define CALL_MODE_ALEXA 10 #define CALL_MODE_WS_SEND 11 //special call mode, not for notifier, updates websocket only @@ -223,7 +225,7 @@ #define TYPE_NONE 0 //light is not configured #define TYPE_RESERVED 1 //unused. Might indicate a "virtual" light -//Digital types (data pin only) (16-31) +//Digital types (data pin only) (16-39) #define TYPE_WS2812_1CH 18 //white-only chips (1 channel per IC) (unused) #define TYPE_WS2812_1CH_X3 19 //white-only chips (3 channels per IC) #define TYPE_WS2812_2CH_X3 20 //CCT chips (1st IC controls WW + CW of 1st zone and CW of 2nd zone, 2nd IC controls WW of 2nd zone and WW + CW of 3rd zone) @@ -233,11 +235,11 @@ #define TYPE_WS2811_400KHZ 24 //half-speed WS2812 protocol, used by very old WS2811 units #define TYPE_TM1829 25 #define TYPE_UCS8903 26 -#define TYPE_UCS8904 29 +#define TYPE_UCS8904 29 //first RGBW digital type (hardcoded in busmanager.cpp, memUsage()) #define TYPE_SK6812_RGBW 30 #define TYPE_TM1814 31 -//"Analog" types (PWM) (32-47) -#define TYPE_ONOFF 40 //binary output (relays etc.) +//"Analog" types (40-47) +#define TYPE_ONOFF 40 //binary output (relays etc.; NOT PWM) #define TYPE_ANALOG_1CH 41 //single channel PWM. Uses value of brightest RGBW channel #define TYPE_ANALOG_2CH 42 //analog WW + CW #define TYPE_ANALOG_3CH 43 //analog RGB @@ -255,10 +257,13 @@ #define TYPE_NET_ARTNET_RGB 82 //network ArtNet RGB bus (master broadcast bus, unused) #define TYPE_NET_DDP_RGBW 88 //network DDP RGBW bus (master broadcast bus) -#define IS_DIGITAL(t) ((t) & 0x10) //digital are 16-31 and 48-63 -#define IS_PWM(t) ((t) > 40 && (t) < 46) -#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only -#define IS_2PIN(t) ((t) > 47) +#define IS_TYPE_VALID(t) ((t) > 15 && (t) < 128) +#define IS_DIGITAL(t) (((t) > 15 && (t) < 40) || ((t) > 47 && (t) < 64)) //digital are 16-39 and 48-63 +#define IS_2PIN(t) ((t) > 47 && (t) < 64) +#define IS_16BIT(t) ((t) == TYPE_UCS8903 || (t) == TYPE_UCS8904) +#define IS_PWM(t) ((t) > 40 && (t) < 46) //does not include on/Off type +#define NUM_PWM_PINS(t) ((t) - 40) //for analog PWM 41-45 only +#define IS_VIRTUAL(t) ((t) >= 80 && (t) < 96) //this was a poor choice a better would be 96-111 //Color orders #define COL_ORDER_GRB 0 //GRB(w),defaut @@ -269,6 +274,10 @@ #define COL_ORDER_GBR 5 #define COL_ORDER_MAX 5 +//ESP-NOW +#define ESP_NOW_STATE_UNINIT 0 +#define ESP_NOW_STATE_ON 1 +#define ESP_NOW_STATE_ERROR 2 //Button type #define BTN_TYPE_NONE 0 @@ -280,6 +289,7 @@ #define BTN_TYPE_TOUCH 6 #define BTN_TYPE_ANALOG 7 #define BTN_TYPE_ANALOG_INVERTED 8 +#define BTN_TYPE_TOUCH_SWITCH 9 //Ethernet board types #define WLED_NUM_ETH_TYPES 11 @@ -312,10 +322,9 @@ #define SEG_OPTION_MIRROR 3 //Indicates that the effect will be mirrored within the segment #define SEG_OPTION_FREEZE 4 //Segment contents will not be refreshed #define SEG_OPTION_RESET 5 //Segment runtime requires reset -#define SEG_OPTION_TRANSITIONAL 6 -#define SEG_OPTION_REVERSED_Y 7 -#define SEG_OPTION_MIRROR_Y 8 -#define SEG_OPTION_TRANSPOSED 9 +#define SEG_OPTION_REVERSED_Y 6 +#define SEG_OPTION_MIRROR_Y 7 +#define SEG_OPTION_TRANSPOSED 8 //Segment differs return byte #define SEG_DIFFERS_BRI 0x01 // opacity @@ -337,13 +346,16 @@ // WLED Error modes #define ERR_NONE 0 // All good :) #define ERR_DENIED 1 // Permission denied -#define ERR_EEP_COMMIT 2 // Could not commit to EEPROM (wrong flash layout?) OBSOLETE +#define ERR_CONCURRENCY 2 // Conurrency (client active) #define ERR_NOBUF 3 // JSON buffer was not released in time, request cannot be handled at this time +#define ERR_NOT_IMPL 4 // Not implemented +#define ERR_NORAM 8 // effect RAM depleted #define ERR_JSON 9 // JSON parsing failed (input too large?) #define ERR_FS_BEGIN 10 // Could not init filesystem (no partition?) #define ERR_FS_QUOTA 11 // The FS is full or the maximum file size is reached #define ERR_FS_PLOAD 12 // It was attempted to load a preset that does not exist #define ERR_FS_IRLOAD 13 // It was attempted to load an IR JSON cmd, but the "ir.json" file does not exist +#define ERR_FS_RMLOAD 14 // It was attempted to load an remote JSON cmd, but the "remote.json" file does not exist #define ERR_FS_GENERAL 19 // A general unspecified filesystem error occured #define ERR_OVERTEMP 30 // An attached temperature sensor has measured above threshold temperature (not implemented) #define ERR_OVERCURRENT 31 // An attached current sensor has measured a current above the threshold (not implemented) @@ -442,7 +454,11 @@ #ifdef ESP8266 #define JSON_BUFFER_SIZE 10240 #else - #define JSON_BUFFER_SIZE 24576 + #if defined(ARDUINO_ARCH_ESP32S2) + #define JSON_BUFFER_SIZE 24576 + #else + #define JSON_BUFFER_SIZE 32767 + #endif #endif //#define MIN_HEAP_SIZE (8k for AsyncWebServer) diff --git a/wled00/data/cpal/cpal.htm b/wled00/data/cpal/cpal.htm index 5a8c801e5..852641ec3 100644 --- a/wled00/data/cpal/cpal.htm +++ b/wled00/data/cpal/cpal.htm @@ -1,6 +1,7 @@ + @@ -45,6 +46,7 @@ width: 7px; top: 50%; transform: translateY(-50%); + touch-action: none; } .color-picker-marker { height: 7px; @@ -94,9 +96,14 @@ line-height: 1; } .wrap { - width: 800px; + width: 100%; margin: 0 auto; } + @media (min-width: 800px) { + .wrap { + width: 800px; + } + } .palette { height: 20px; } @@ -136,6 +143,9 @@ .sendSpan, .editSpan{ cursor: pointer; } + h1 { + font-size: 1.6rem; + } @@ -191,6 +201,7 @@ var gradientLength = rect.width; var mOffs = Math.round((gradientLength / 256) / 2) - 5; var paletteArray = []; //Holds the palettes after load. + var paletteName = []; // Holds the names of the palettes after load. var svgSave = '' var svgEdit = '' @@ -349,24 +360,31 @@ var gradientLength = maxX - minX + 1; elmnt.onmousedown = dragMouseDown; + elmnt.ontouchstart = dragMouseDown; function dragMouseDown(e) { removeTrashcan(event) e = e || window.event; - e.preventDefault(); + var isTouch = e.type.startsWith('touch'); + if (!isTouch) e.preventDefault(); // get the mouse cursor position at startup: - mousePos = e.clientX; + mousePos = isTouch ? e.touches[0].clientX : e.clientX; d.onmouseup = closeDragElement; + d.ontouchcancel = closeDragElement; + d.ontouchend = closeDragElement; // call a function whenever the cursor moves: d.onmousemove = elementDrag; + d.ontouchmove = elementDrag; } function elementDrag(e) { e = e || window.event; - e.preventDefault(); + var isTouch = e.type.startsWith('touch'); + if (!isTouch) e.preventDefault(); // calculate the new cursor position: - posNew = mousePos - e.clientX; - mousePos = e.clientX; + var clientX = isTouch ? e.touches[0].clientX : e.clientX; + posNew = mousePos - clientX; + mousePos = clientX; mousePosInGradient = mousePos - (minX + 1) truePos = Math.round((mousePosInGradient/gradientLength)*256); @@ -393,7 +411,10 @@ function closeDragElement() { /* stop moving when mouse button is released:*/ d.onmouseup = null; + d.ontouchcancel = null; + d.ontouchend = null; d.onmousemove = null; + d.ontouchmove = null; } } @@ -500,8 +521,10 @@ if (hst.length > 0 ) { try { var arr = []; - const response = await fetch('http://'+hst+'/json/info'); - const json = await response.json(); + const responseInfo = await fetch('http://'+hst+'/json/info'); + const responsePalettes = await fetch('http://'+hst+'/json/palettes'); + const json = await responseInfo.json(); + paletteName = await responsePalettes.json(); cpalc = json.cpalcount; fetchPalettes(cpalc-1); } catch (error) { @@ -521,6 +544,7 @@ const json = await response.json(); paletteArray.push(json); } catch (error) { + cpalc--; //remove audio/dynamically generated palettes console.error(`Error fetching JSON from ${url}: `, error); } } @@ -540,6 +564,7 @@ alert("The cache of palettes are missig from your browser. You should probably return to the main page and let it load properly for the palettes cache to regenerate before returning here.","Missing cached palettes!") } else { for (const key in wledPalx.p) { + wledPalx.p[key].name = paletteName[key]; if (key > 245) { delete wledPalx.p[key]; continue; @@ -571,8 +596,11 @@ } const pArray = Object.entries(wledPalx.p).map(([key, value]) => ({ - [key]: value.flat() + [key]: value.flat(), + name: value.name })); + // Sort pArray by name + pArray.sort((a, b) => a.name.localeCompare(b.name)); paletteArray.push( ...pArray); } @@ -614,6 +642,9 @@ editSpan.id = `editSpan${i}`; editSpan.onclick = function() {loadForEdit(i)}; editSpan.setAttribute('title', `Copy slot ${i} palette to editor`); + if (paletteArray[i].name) { + editSpan.setAttribute('title', `Copy ${paletteArray[i].name} palette to editor`); + } editSpan.innerHTML = svgEdit; editSpan.classList.add("editSpan") diff --git a/wled00/data/index.css b/wled00/data/index.css index 049e6f03e..095de572a 100644 --- a/wled00/data/index.css +++ b/wled00/data/index.css @@ -20,8 +20,8 @@ --c-g: #2c1; --c-l: #48a; --c-y: #a90; - --t-b: 0.5; - --c-o: rgba(34, 34, 34, 0.9); + --t-b: .5; + --c-o: rgba(34, 34, 34, .9); --c-tb : rgba(34, 34, 34, var(--t-b)); --c-tba: rgba(102, 102, 102, var(--t-b)); --c-tbh: rgba(51, 51, 51, var(--t-b)); @@ -33,7 +33,8 @@ --bbp: 9px 0 7px 0; --bhd: none; --sgp: "block"; - --bmt: 0px; + --bmt: 0; + --sti: 42px; } html { @@ -88,7 +89,7 @@ a, a:visited { } button { - outline: none; + outline: 0; cursor: pointer; } @@ -219,7 +220,7 @@ button { .pop-c span { padding: 2px 6px; } - + .search-icon { position: absolute; top: 8px; @@ -238,7 +239,7 @@ button { .flr { color: var(--c-f); transform: rotate(0deg); - transition: transform 0.3s; + transition: transform .3s; position: absolute; top: 0; right: 0; @@ -258,13 +259,13 @@ button { #liveview { height: 4px; width: 100%; - border: 0px; + border: 0; } #liveview2D { height: 90%; width: 90%; - border: 0px; + border: 0; position: absolute; top: 50%; left: 50%; @@ -287,8 +288,8 @@ button { .tab button { background-color: transparent; float: left; - border: none; - transition: color 0.3s, background-color 0.3s; + border: 0; + transition: color .3s, background-color .3s; font-size: 17px; color: var(--c-c); min-width: 44px; @@ -301,7 +302,7 @@ button { .bot button { padding: var(--bbp); - width:25%; + width: 25%; margin: 0; } @@ -336,8 +337,9 @@ button { width: 100%; width: calc(100%/var(--n)); box-sizing: border-box; - border: 0px; - overflow: auto; + border: 0; + overflow-y: auto; + overflow-x: hidden; height: 100%; overscroll-behavior: none; padding: 0 4px; @@ -368,6 +370,16 @@ button { padding: 5px 0 0; } +/* Quick load magin for simplified UI */ +.simplified #pql { + margin-bottom: 8px; +} + +/* Button margin for simplified UI */ +.simplified #fx .btn, .simplified #palw .btn { + margin-top: 0; +} + .smooth { transition: transform calc(var(--f, 1)*.5s) ease-out } .tab-label { @@ -388,8 +400,8 @@ button { align-items: center; justify-content: center; z-index: 11; - opacity: 0.95; - transition: 0.7s; + opacity: .95; + transition: .7s; pointer-events: none; } @@ -399,7 +411,7 @@ button { position: sticky !important; top: 0; z-index: 2; - margin: 0 auto auto; + margin: 0 auto auto; } .staybot { @@ -411,6 +423,7 @@ button { position: sticky; bottom: 0; max-width: 300px; + z-index: 2; } #sliders .labels { @@ -456,65 +469,56 @@ button { padding: 4px 2px; position: relative; opacity: 1; - transition: opacity 0.5s linear, height 0.5s, transform 0.5s; + transition: opacity .5s linear, height .25s, transform .25s; } .filter { z-index: 1; - overflow: hidden; + /*overflow: visible;*/ + border-radius: 0 0 16px 16px; + max-width: 220px; + height: 54px; + line-height: 1.5; + padding-bottom: 8px; + pointer-events: none; } -/* Tooltip text */ -.slider .tooltiptext, .option .tooltiptext { +/* New tooltip */ +.tooltip { + position: absolute; + opacity: 0; visibility: hidden; + transition: opacity .25s ease, visibility .25s ease; background-color: var(--c-5); - /*border: 2px solid var(--c-2);*/ box-shadow: 4px 4px 10px 4px var(--c-1); color: var(--c-f); text-align: center; - padding: 4px 8px; + padding: 8px 16px; border-radius: 6px; - - /* Position the tooltip text */ - width: 160px; - position: absolute; z-index: 1; - bottom: 80%; - left: 50%; - margin-left: -92px; - - /* Ensure tooltip goes away when mouse leaves control */ pointer-events: none; +} - /* Fade in tooltip */ - opacity: 0; - transition: opacity 0.75s; -} -.option .tooltiptext { - bottom: 120%; -} -/* Tooltip arrow */ -.slider .tooltiptext::after, .option .tooltiptext::after { + .tooltip::after { content: ""; position: absolute; - top: 100%; - left: 50%; - margin-left: -5px; - border-width: 5px; - border-style: solid; + border: 8px solid; border-color: var(--c-5) transparent transparent transparent; -} -/* Show the tooltip text when you mouse over the tooltip container */ -.slider:hover .tooltiptext, .option .check:hover .tooltiptext { - visibility: visible; + top: 100%; + left: calc(50% - 8px); + z-index: 0; + } + +.tooltip.visible { opacity: 1; + visibility: visible; } .fade { visibility: hidden; /* hide it */ opacity: 0; /* make it transparent */ transform: scaleY(0); /* shrink content */ - height: 0px; /* force other elements to move */ + height: 0; /* force other elements to move */ padding: 0; /* remove empty space */ } @@ -542,24 +546,24 @@ button { #toast.show { opacity: 1; - animation: fadein 0.5s, fadein 0.5s 2.5s reverse; + animation: fadein .5s, fadein .5s 2.5s reverse; } #toast.error { opacity: 1; background-color: #b21; - animation: fadein 0.5s; + animation: fadein .5s; } .modal { - position:fixed; - left: 0px; - bottom: 0px; - right: 0px; + position: fixed; + left: 0; + bottom: 0; + right: 0; top: calc(var(--th) - 1px); background-color: var(--c-o); transform: translateY(100%); - transition: transform 0.4s; + transition: transform .4s; padding: 8px; font-size: 20px; overflow: auto; @@ -641,7 +645,7 @@ button { } #heart { - transition: color 0.9s; + transition: color .9s; font-size: 16px; color: #f00; } @@ -720,7 +724,7 @@ input[type=range] { } input[type=range]:focus { - outline: none; + outline: 0; } input[type=range]::-webkit-slider-runnable-track { width: 100%; @@ -743,7 +747,7 @@ input[type=range]::-moz-range-track { background-color: rgba(0, 0, 0, 0); } input[type=range]::-moz-range-thumb { - border: 0px solid rgba(0, 0, 0, 0); + border: 0 solid rgba(0, 0, 0, 0); height: 16px; width: 16px; border-radius: 50%; @@ -761,23 +765,27 @@ input[type=range]::-moz-range-thumb { } #Colors .sliderwrap { - margin: 4px 0 0; + margin: 2px 0 0; } -/* Dynamically hide brightness slider label */ +/* Dynamically hide labels */ .hd { display: var(--bhd); } +/* Do not hide quick load label in simplified mode on small screen widths */ +.simplified #pql .hd { + display: var(--bhd) !important; +} #briwrap { - min-width: 267px; + min-width: 300px; float: right; margin-top: var(--bmt); } #picker { margin-top: 8px !important; - max-width: 260px; + max-width: max-content; } /* buttons */ @@ -789,11 +797,11 @@ input[type=range]::-moz-range-thumb { color: var(--c-d); cursor: pointer; border-radius: 25px; - transition-duration: 0.3s; + transition-duration: .3s; -webkit-backface-visibility: hidden; - -webkit-transform:translate3d(0,0,0); + -webkit-transform: translate3d(0,0,0); backface-visibility: hidden; - transform:translate3d(0,0,0); + transform: translate3d(0,0,0); overflow: hidden; text-overflow: ellipsis; border: 1px solid var(--c-3); @@ -893,13 +901,13 @@ select { cursor: pointer; border: 0 solid var(--c-2); border-radius: 20px; - transition-duration: 0.5s; + transition-duration: .5s; -webkit-backface-visibility: hidden; - -webkit-transform:translate3d(0,0,0); - -webkit-appearance: none; - -moz-appearance: none; + -webkit-transform: translate3d(0,0,0); + -webkit-appearance: none; + -moz-appearance: none; backface-visibility: hidden; - transform:translate3d(0,0,0); + transform: translate3d(0,0,0); text-overflow: ellipsis; } #tt { @@ -917,15 +925,15 @@ div.sel-p { position: relative; } div.sel-p:after { - content: ""; - position: absolute; - right: 10px; - top: 22px; - width: 0; - height: 0; - border-left: 8px solid transparent; - border-right: 8px solid transparent; - border-top: 8px solid var(--c-f); + content: ""; + position: absolute; + right: 10px; + top: 22px; + width: 0; + height: 0; + border-left: 8px solid transparent; + border-right: 8px solid transparent; + border-top: 8px solid var(--c-f); } select.sel-ple { text-align: center; @@ -942,13 +950,13 @@ input[type=number], input[type=text] { background: var(--c-3); color: var(--c-f); - border: 0px solid var(--c-2); + border: 0 solid var(--c-2); border-radius: 10px; padding: 8px; /*margin: 6px 6px 6px 0;*/ font-size: 19px; - transition: background-color 0.2s; - outline: none; + transition: background-color .2s; + outline: 0; -webkit-appearance: textfield; -moz-appearance: textfield; appearance: textfield; @@ -988,7 +996,7 @@ textarea { height: 90px; border-radius: 5px; border: 2px solid var(--c-5); - outline: none; + outline: 0; resize: none; font-size: 19px; padding: 5px; @@ -1034,13 +1042,14 @@ textarea { /*padding: 1px 0 1px 20px;*/ display: var(--sgp); width: 100%; + position: relative; } .pname { top: 1px; } .plname { - top:0; + top: 0; } /* preset id number */ @@ -1120,8 +1129,8 @@ textarea { } .revchkl { - padding: 4px 0px 0px 35px; - margin-bottom: 0px; + padding: 4px 0 0 35px; + margin-bottom: 0; margin-top: 8px; } @@ -1217,9 +1226,9 @@ TD .checkmark, TD .radiomark { .seg, .pres { background-color: var(--c-2); /*color: var(--c-f);*/ /* seems to affect only the Add segment button, which should be same color as reset segments */ - border: 0px solid var(--c-f); + border: 0 solid var(--c-f); text-align: left; - transition: background-color 0.5s; + transition: background-color .5s; border-radius: 21px; } @@ -1236,14 +1245,19 @@ TD .checkmark, TD .radiomark { /* checkmark labels */ .filter .fchkl, .option .ochkl { display: inline-block; - min-width: 0.7em; - padding: 1px 4px 4px 32px; + min-width: .7em; + padding: 1px 4px 1px 32px; text-align: left; line-height: 24px; vertical-align: middle; -webkit-filter: grayscale(100%); /* Safari 6.0 - 9.0 */ filter: grayscale(100%); } +.filter .fchkl { + margin: 0 4px; + min-width: 20px; + pointer-events: auto; +} .lbl-l { font-size: 13px; @@ -1262,15 +1276,15 @@ TD .checkmark, TD .radiomark { /* list wrapper */ .list { position: relative; - transition: background-color 0.5s; - margin: auto auto 10px; + transition: background-color .5s; + margin: auto auto 10px; line-height: 24px; } /* list item */ .lstI { align-items: center; - cursor: pointer; + cursor: pointer; background-color: var(--c-2); overflow: hidden; position: -webkit-sticky; @@ -1285,6 +1299,12 @@ TD .checkmark, TD .radiomark { margin-top: 0; } +/* Simplify segments */ +.simplified #segcont .lstI { + margin-top: 4px; + min-height: unset; +} + /* selected item/element */ .selected { /* has to be after .lstI since !important is not ok */ background: var(--c-4); @@ -1292,7 +1312,7 @@ TD .checkmark, TD .radiomark { #segcont .seg:hover:not([class*="expanded"]), .lstI:hover:not([class*="expanded"]) { - background: var(--c-5); + background: var(--c-5); } .selected .checkmark, @@ -1312,7 +1332,7 @@ TD .checkmark, TD .radiomark { .lstI.sticky, .lstI.selected { z-index: 1; - box-shadow: 0px 0px 10px 4px var(--c-1); + box-shadow: 0 0 10px 4px var(--c-1); } #pcont .selected:not([class*="expanded"]) { @@ -1320,20 +1340,27 @@ TD .checkmark, TD .radiomark { top: 42px; } -#fxlist .lstI.selected { - top: 84px; -} - -#fxlist .lstI.sticky { - top: 42px; -} - +#fxlist .lstI.selected, #pallist .lstI.selected { - top: 84px; + top: calc(var(--sti) + 42px); } +dialog::backdrop { + backdrop-filter: blur(10px); + -webkit-backdrop-filter: blur(10px); +} +dialog { + max-height: 70%; + border: 0; + border-radius: 10px; + background: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.1)), var(--c-3); + box-shadow: 4px 4px 10px 4px var(--c-1); + color: var(--c-f); +} + +#fxlist .lstI.sticky, #pallist .lstI.sticky { - top: 42px; + top: var(--sti); } /* list item content */ @@ -1369,8 +1396,8 @@ TD .checkmark, TD .radiomark { display: block; width: 100%; box-sizing: border-box; - padding: 8px 40px 8px 44px; - margin: 5px auto 0; + padding: 8px 40px 8px 44px; + margin: 5px auto 0; text-align: left; border-radius: 21px; background: var(--c-2); @@ -1456,7 +1483,7 @@ TD .checkmark, TD .radiomark { } ::-webkit-scrollbar-thumb { background: var(--c-sb); - opacity: 0.2; + opacity: .2; border-radius: 5px; } ::-webkit-scrollbar-thumb:hover { @@ -1482,7 +1509,7 @@ TD .checkmark, TD .radiomark { @media all and (max-width: 335px) { .sliderbubble { - display: none; + display: none; } } @@ -1539,9 +1566,6 @@ TD .checkmark, TD .radiomark { max-width: 280px; font-size: 18px; } - #picker { - width: 230px; - } #putil .btn-s { width: 114px; } diff --git a/wled00/data/index.htm b/wled00/data/index.htm index 0cf48d6e6..ae685bdb9 100644 --- a/wled00/data/index.htm +++ b/wled00/data/index.htm @@ -7,52 +7,9 @@ WLED - - +
Loading WLED UI...
@@ -72,8 +29,8 @@

Brightness

-
- +
+
@@ -88,98 +45,91 @@
-
-
+
+
- Hue
-
+
- Saturation
-
+
- Value/Brightness
-
+
- Kelvin/Temperature
-
-
+
- Red channel
-
+
- Green channel
-
+
- Blue channel
- -
+
- White channel
- -
+
- White balance
-
-
-
-
-
-

-
-
-
-
-
R
+
+
+
+
+
+

+
+
+
+
+
R
- - - + + +

- +
+
+ + + +

Color palette

@@ -189,7 +139,7 @@
-
-
- - -

Effect mode

-
- +
+ - + +
+ + + + + + +
-
-
- - - - - - -
-
+
- Effect speed
-
+
- Effect intensity
-
+
- Custom 1
-
+
- Custom 2
-
+
- Custom 3
-

- Made with ❤︎ by Aircoookie and the WLED community + Made with ❤︎ by Aircoookie and the WLED community
+
+ + + + diff --git a/wled00/data/index.js b/wled00/data/index.js index 145ed2f22..ec8fcb23a 100644 --- a/wled00/data/index.js +++ b/wled00/data/index.js @@ -1,6 +1,6 @@ //page js var loc = false, locip, locproto = "http:"; -var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false, syncTglRecv = true; +var isOn = false, nlA = false, isLv = false, isInfo = false, isNodes = false, syncSend = false/*, syncTglRecv = true*/; var hasWhite = false, hasRGB = false, hasCCT = false; var nlDur = 60, nlTar = 0; var nlMode = false; @@ -12,8 +12,11 @@ var currentPreset = -1; var lastUpdate = 0; var segCount = 0, ledCount = 0, lowestUnused = 0, maxSeg = 0, lSeg = 0; var pcMode = false, pcModeA = false, lastw = 0, wW; +var simplifiedUI = false; var tr = 7; var d = document; +const ranges = RangeTouch.setup('input[type="range"]', {}); +var retry = false; var palettesData; var fxdata = []; var pJson = {}, eJson = {}, lJson = {}; @@ -22,23 +25,34 @@ var pN = "", pI = 0, pNum = 0; var pmt = 1, pmtLS = 0, pmtLast = 0; var lastinfo = {}; var isM = false, mw = 0, mh=0; -var ws, cpick, ranges, wsRpt=0; +var ws, wsRpt=0; var cfg = { - theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, + theme:{base:"dark", bg:{url:"", rnd: false, rndGrayscale: false, rndBlur: false}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}}, comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, - labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:false, - css:true, hdays:false, fxdef:true} + labels:true, pcmbot:false, pid:true, seglen:false, segpwr:false, segexp:false, + css:true, hdays:false, fxdef:true, on:0, off:0, idsort: false} }; +// [year, month (0 -> January, 11 -> December), day, duration in days, image url] var hol = [ - [0,11,24,4,"https://aircoookie.github.io/xmas.png"], // christmas - [0,2,17,1,"https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day - [2025,3,20,2,"https://aircoookie.github.io/easter.png"], - [2023,3,9,2,"https://aircoookie.github.io/easter.png"], - [2024,2,31,2,"https://aircoookie.github.io/easter.png"], - [0,6,4,1,"https://initiate.alphacoders.com/download/wallpaper/516792/images/jpg/510921363292536"], // 4th of July - [0,0,1,1,"https://initiate.alphacoders.com/download/wallpaper/1198800/images/jpg/2522807481585600"] // new year + [0, 11, 24, 4, "https://aircoookie.github.io/xmas.png"], // christmas + [0, 2, 17, 1, "https://images.alphacoders.com/491/491123.jpg"], // st. Patrick's day + [2025, 3, 20, 2, "https://aircoookie.github.io/easter.png"], // easter 2025 + [2024, 2, 31, 2, "https://aircoookie.github.io/easter.png"], // easter 2024 + [0, 6, 4, 1, "https://images.alphacoders.com/516/516792.jpg"], // 4th of July + [0, 0, 1, 1, "https://images.alphacoders.com/119/1198800.jpg"] // new year ]; +var cpick = new iro.ColorPicker("#picker", { + width: 260, + wheelLightness: false, + wheelAngle: 270, + wheelDirection: "clockwise", + layout: [{ + component: iro.ui.Wheel, + options: {} + }] +}); + function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson();} function sCol(na, col) {d.documentElement.style.setProperty(na, col);} function gId(c) {return d.getElementById(c);} @@ -74,6 +88,7 @@ function setCSL(cs) function applyCfg() { cTheme(cfg.theme.base === "light"); + gId("Colors").style.paddingTop = cfg.comp.colors.picker ? "0" : "28px"; var bg = cfg.theme.color.bg; if (bg) sCol('--c-1', bg); var l = cfg.comp.labels; @@ -109,6 +124,7 @@ function tglLabels() function tglRgb() { cfg.comp.colors.rgb = !cfg.comp.colors.rgb; + cfg.comp.colors.picker = !cfg.comp.colors.picker; applyCfg(); } @@ -160,19 +176,19 @@ function cTheme(light) { } } -function loadBg(iUrl) -{ - let bg = gId('bg'); - let img = d.createElement("img"); +function loadBg() { + const { url: iUrl, rnd: iRnd } = cfg.theme.bg; + const bg = gId('bg'); + const img = d.createElement("img"); img.src = iUrl; - if (iUrl == "" || iUrl==="https://picsum.photos/1920/1080") { - var today = new Date(); - for (var h of (hol||[])) { - var yr = h[0]==0 ? today.getFullYear() : h[0]; - var hs = new Date(yr,h[1],h[2]); - var he = new Date(hs); - he.setDate(he.getDate() + h[3]); - if (today>=hs && today<=he) img.src = h[4]; + if (!iUrl || iRnd) { + const today = new Date(); + for (const holiday of (hol || [])) { + const year = holiday[0] == 0 ? today.getFullYear() : holiday[0]; + const holidayStart = new Date(year, holiday[1], holiday[2]); + const holidayEnd = new Date(holidayStart); + holidayEnd.setDate(holidayEnd.getDate() + holiday[3]); + if (today >= holidayStart && today <= holidayEnd) img.src = holiday[4]; } } img.addEventListener('load', (e) => { @@ -180,7 +196,6 @@ function loadBg(iUrl) if (isNaN(a)) a = 0.6; bg.style.opacity = a; bg.style.backgroundImage = `url(${img.src})`; - img = null; gId('namelabel').style.color = "var(--c-c)"; // improve namelabel legibility on background image }); } @@ -217,13 +232,11 @@ function onLoad() // detect reverse proxy and/or HTTPS let pathn = l.pathname; let paths = pathn.slice(1,pathn.endsWith('/')?-1:undefined).split("/"); - //if (paths[0]==="sliders") paths.shift(); - //while (paths[0]==="") paths.shift(); locproto = l.protocol; locip = l.hostname + (l.port ? ":" + l.port : ""); if (paths.length > 0 && paths[0]!=="") { loc = true; - locip += "/" + paths[0]; + locip += "/" + paths.join('/'); } else if (locproto==="https:") { loc = true; } @@ -231,7 +244,9 @@ function onLoad() var sett = localStorage.getItem('wledUiCfg'); if (sett) cfg = mergeDeep(cfg, JSON.parse(sett)); + tooltip(); resetPUtil(); + initFilters(); if (localStorage.getItem('pcm') == "true" || (!/Mobi/.test(navigator.userAgent) && localStorage.getItem('pcm') == null)) togglePcMode(true); applyCfg(); @@ -251,40 +266,47 @@ function onLoad() console.log("No array of holidays in holidays.json. Defaults loaded."); }) .finally(()=>{ - loadBg(cfg.theme.bg.url); + loadBg(); }); } else - loadBg(cfg.theme.bg.url); - if (cfg.comp.css) loadSkinCSS('skinCss'); + loadBg(); selectSlot(0); updateTablinks(0); + cpick.on("input:end", () => {setColor(1);}); + cpick.on("color:change", () => {updatePSliders()}); pmtLS = localStorage.getItem('wledPmt'); // Load initial data + // Once we figure out why ESP8266 sometimes corrupts JSON responses if they are made in quick succession + // we can remove all setTimeout() throttling loadPalettes(()=>{ - // fill effect extra data array - loadFXData(()=>{ - // load and populate effects - loadFX(()=>{ + setTimeout(()=>{ // ESP8266 can't handle quick requests + // fill effect extra data array + loadFXData(()=>{ setTimeout(()=>{ // ESP8266 can't handle quick requests - loadPalettesData(()=>{ - requestJson();// will load presets and create WS + // load and populate effects + loadFX(()=>{ + setTimeout(()=>{ // ESP8266 can't handle quick requests + loadPalettesData(()=>{ + requestJson();// will load presets and create WS + if (cfg.comp.css) setTimeout(()=>{loadSkinCSS('skinCss')},100); + }); + },50); }); - },100); + },50); }); - }); + },50); }); resetUtil(); d.addEventListener("visibilitychange", handleVisibilityChange, false); //size(); gId("cv").style.opacity=0; - var sls = d.querySelectorAll('input[type="range"]'); - for (var sl of sls) { + d.querySelectorAll('input[type="range"]').forEach((sl)=>{ sl.addEventListener('touchstart', toggleBubble); sl.addEventListener('touchend', toggleBubble); - } + }); } function updateTablinks(tabI) @@ -307,7 +329,6 @@ function openTab(tabI, force = false) var timeout; function showToast(text, error = false) { - if (error) gId('connind').style.backgroundColor = "var(--c-r)"; var x = gId('toast'); //if (error) text += ''; x.innerHTML = text; @@ -320,6 +341,7 @@ function showToast(text, error = false) function showErrorToast() { + gId('connind').style.backgroundColor = "var(--c-r)"; showToast('Connection to light failed!', true); } @@ -426,18 +448,30 @@ function presetError(empty) if (hasBackup) { cn += `

`; if (empty) - cn += `However, there is backup preset data of a previous installation available.
- (Saving a preset will hide this and overwrite the backup)`; + cn += `However, there is backup preset data of a previous installation available.
(Saving a preset will hide this and overwrite the backup)`; else cn += `Here is a backup of the last known good state:`; - cn += `
- `; + cn += `
`; + cn += `
`; } cn += `
`; gId('pcont').innerHTML = cn; if (hasBackup) gId('bck').value = bckstr; } +function restore(txt) { + var req = new XMLHttpRequest(); + req.addEventListener('load', function(){showToast(this.responseText,this.status >= 400)}); + req.addEventListener('error', function(e){showToast(e.stack,true);}); + req.open("POST", getURL("/upload")); + var formData = new FormData(); + var b = new Blob([txt], {type: "application/json"}); + formData.append("data", b, '/presets.json'); + req.send(formData); + setTimeout(loadPresets, 2000); + return false; +} + function loadPresets(callback = null) { // 1st boot (because there is a callback) @@ -486,8 +520,13 @@ function loadPalettes(callback = null) .then((json)=>{ lJson = Object.entries(json); populatePalettes(); + retry = false; }) .catch((e)=>{ + if (!retry) { + retry = true; + setTimeout(loadPalettes, 500); // retry + } showToast(e, true); }) .finally(()=>{ @@ -508,9 +547,13 @@ function loadFX(callback = null) .then((json)=>{ eJson = Object.entries(json); populateEffects(); + retry = false; }) .catch((e)=>{ - //setTimeout(loadFX, 250); // retry + if (!retry) { + retry = true; + setTimeout(loadFX, 500); // retry + } showToast(e, true); }) .finally(()=>{ @@ -533,10 +576,14 @@ function loadFXData(callback = null) // add default value for Solid fxdata.shift() fxdata.unshift(";!;"); + retry = false; }) .catch((e)=>{ fxdata = []; - //setTimeout(loadFXData, 250); // retry + if (!retry) { + retry = true; + setTimeout(loadFXData, 500); // retry + } showToast(e, true); }) .finally(()=>{ @@ -566,8 +613,7 @@ function populatePresets(fromls) if (!pJson) {setTimeout(loadPresets,250); return;} delete pJson["0"]; var cn = ""; - var arr = Object.entries(pJson); - arr.sort(cmpP); + var arr = Object.entries(pJson).sort(cmpP); pQL = []; var is = []; pNum = 0; @@ -611,23 +657,24 @@ function parseInfo(i) { if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)"; // Minecraft easter egg if (i.live) name = "(Live) " + name; if (loc) name = "(L) " + name; - d.title = name; - ledCount = i.leds.count; - syncTglRecv = i.str; - maxSeg = i.leds.maxseg; - pmt = i.fs.pmt; + d.title = name; + simplifiedUI = i.simplifiedui; + ledCount = i.leds.count; + //syncTglRecv = i.str; + maxSeg = i.leds.maxseg; + pmt = i.fs.pmt; gId('buttonNodes').style.display = lastinfo.ndc > 0 ? null:"none"; // do we have a matrix set-up mw = i.leds.matrix ? i.leds.matrix.w : 0; mh = i.leds.matrix ? i.leds.matrix.h : 0; isM = mw>0 && mh>0; if (!isM) { - gId("filter0D").classList.remove('hide'); - gId("filter1D").classList.add('hide'); + //gId("filter0D").classList.remove('hide'); + //gId("filter1D").classList.add('hide'); gId("filter2D").classList.add('hide'); } else { - gId("filter0D").classList.add('hide'); - gId("filter1D").classList.remove('hide'); + //gId("filter0D").classList.add('hide'); + //gId("filter1D").classList.remove('hide'); gId("filter2D").classList.remove('hide'); } // if (i.noaudio) { @@ -672,8 +719,6 @@ function populateInfo(i) } } var vcn = "Kuuhaku"; - if (i.ver.startsWith("0.14.")) vcn = "Hoshi"; -// if (i.ver.includes("-bl")) vcn = "Supāku"; if (i.cn) vcn = i.cn; cn += `v${i.ver} "${vcn}"

@@ -683,6 +728,7 @@ ${i.opt&0x100?inforow("Debug","
`+ ``+ @@ -822,6 +869,7 @@ function populateSegments(s) } gId('segcont').innerHTML = cn; + gId("segcont").classList.remove("hide"); let noNewSegs = (lowestUnused >= maxSeg); resetUtil(noNewSegs); if (gId('selall')) gId('selall').checked = true; @@ -834,7 +882,9 @@ function populateSegments(s) } if (segCount < 2) { gId(`segd${lSeg}`).classList.add("hide"); - gId(`segp0`).classList.add("hide"); + if (parseInt(gId("seg0bri").value)==255) gId(`segp0`).classList.add("hide"); + // hide segment controls if there is only one segment in simplified UI + if (simplifiedUI) gId("segcont").classList.add("hide"); } if (!isM && !noNewSegs && (cfg.comp.seglen?parseInt(gId(`seg${lSeg}s`).value):0)+parseInt(gId(`seg${lSeg}e`).value) 1) ? "block":"none"; // rsbtn parent @@ -907,7 +957,7 @@ function populatePalettes() for (let pa of lJson) { html += generateListItemHtml( 'palette', - pa[0], + pa[0], pa[1], 'setPalette', `
` @@ -915,8 +965,9 @@ function populatePalettes() } gId('pallist').innerHTML=html; // append custom palettes (when loading for the 1st time) - if (!isEmpty(lastinfo) && lastinfo.cpalcount) { - for (let j = 0; j0) gId("rmPal").classList.remove("hide"); + else gId("rmPal").classList.add("hide"); } function redrawPalPrev() @@ -1073,7 +1126,7 @@ function updateTrail(e) { if (e==null) return; let sd = e.parentNode.getElementsByClassName('sliderdisplay')[0]; - if (sd && getComputedStyle(sd).getPropertyValue("--bg") !== "none") { + if (sd && getComputedStyle(sd).getPropertyValue("--bg").trim() !== "none") { // trim() for Safari var max = e.hasAttribute('max') ? e.attributes.max.value : 255; var perc = Math.round(e.value * 100 / max); if (perc < 50) perc += 2; @@ -1193,6 +1246,7 @@ function updateUI() gId('buttonPower').className = (isOn) ? 'active':''; gId('buttonNl').className = (nlA) ? 'active':''; gId('buttonSync').className = (syncSend) ? 'active':''; + gId('pxmb').style.display = (isM) ? "inline-block" : "none"; updateSelectedFx(); updateSelectedPalette(selectedPal); // must be after updateSelectedFx() to un-hide color slots for * palettes @@ -1208,7 +1262,7 @@ function updateUI() if (hasRGB) { updateTrail(gId('sliderR')); updateTrail(gId('sliderG')); - updateTrail(gId('sliderB')); + updateTrail(gId('sliderB')); } if (hasWhite) updateTrail(gId('sliderW')); @@ -1242,12 +1296,18 @@ function updateSelectedPalette(s) var selectedPalette = parent.querySelector(`.lstI[data-id="${s}"]`); if (selectedPalette) parent.querySelector(`.lstI[data-id="${s}"]`).classList.add('selected'); + // Display selected palette name on button in simplified UI + let selectedName = selectedPalette.querySelector(".lstIname").innerText; + if (simplifiedUI) { + gId("palwbtn").innerText = "Palette: " + selectedName; + } + // in case of special palettes (* Colors...), force show color selectors (if hidden by effect data) let cd = gId('csl').children; // color selectors if (s > 1 && s < 6) { cd[0].classList.remove('hide'); // * Color 1 if (s > 2) cd[1].classList.remove('hide'); // * Color 1 & 2 - if (s == 5) cd[2].classList.remove('hide'); // all colors + if (s > 3) cd[2].classList.remove('hide'); // all colors } else { for (let i of cd) if (i.dataset.hide == '1') i.classList.add('hide'); } @@ -1270,20 +1330,28 @@ function updateSelectedFx() selectedEffect.classList.add('selected'); setEffectParameters(selectedFx); // hide non-0D effects if segment only has 1 pixel (0D) - var fxs = parent.querySelectorAll('.lstI'); - for (const fx of fxs) { - if (!fx.dataset.opt) continue; - let opts = fx.dataset.opt.split(";"); - if (fx.dataset.id>0) { - if (segLmax==0) fx.classList.add('hide'); // none of the segments selected (hide all effects) - else { - if ((segLmax==1 && (!opts[3] || opts[3].indexOf("0")<0)) || (!isM && opts[3] && ((opts[3].indexOf("2")>=0 && opts[3].indexOf("1")<0)))) fx.classList.add('hide'); - else fx.classList.remove('hide'); + parent.querySelectorAll('.lstI').forEach((fx)=>{ + let ds = fx.dataset; + if (ds.opt) { + let opts = ds.opt.split(";"); + if (ds.id>0) { + if (segLmax==0) fx.classList.add('hide'); // none of the segments selected (hide all effects) + else { + if ((segLmax==1 && (!opts[3] || opts[3].indexOf("0")<0)) || (!isM && opts[3] && ((opts[3].indexOf("2")>=0 && opts[3].indexOf("1")<0)))) fx.classList.add('hide'); + else fx.classList.remove('hide'); + } } } - } - // hide 2D mapping and/or sound simulation options + }); var selectedName = selectedEffect.querySelector(".lstIname").innerText; + + // Display selected effect name on button in simplified UI + let selectedNameOnlyAscii = selectedName.replace(/[^\x00-\x7F]/g, ""); + if (simplifiedUI) { + gId("fxbtn").innerText = "Effect: " + selectedNameOnlyAscii; + } + + // hide 2D mapping and/or sound simulation options var segs = gId("segcont").querySelectorAll(`div[data-map="map2D"]`); for (const seg of segs) if (selectedName.indexOf("\u25A6")<0) seg.classList.remove('hide'); else seg.classList.add('hide'); var segs = gId("segcont").querySelectorAll(`div[data-snd="si"]`); @@ -1301,7 +1369,7 @@ function displayRover(i,s) function cmpP(a, b) { - if (!a[1].n) return (a[0] > b[0]); + if (cfg.comp.idsort || !a[1].n) return (parseInt(a[0]) > parseInt(b[0])); // sort playlists first, followed by presets with characters and last presets with special 1st character const c = a[1].n.charCodeAt(0); const d = b[1].n.charCodeAt(0); @@ -1403,7 +1471,7 @@ function readState(s,command=false) if (s.seg.length>2) d.querySelectorAll(".pop").forEach((e)=>{e.classList.remove("hide");}); - var cd = gId('csl').children; + var cd = gId('csl').querySelectorAll("button"); for (let e = cd.length-1; e >= 0; e--) { cd[e].dataset.r = i.col[e][0]; cd[e].dataset.g = i.col[e][1]; @@ -1424,25 +1492,31 @@ function readState(s,command=false) gId('checkO3').checked = !(!i.o3); if (s.error && s.error != 0) { - var errstr = ""; - switch (s.error) { - case 10: - errstr = "Could not mount filesystem!"; - break; - case 11: - errstr = "Not enough space to save preset!"; - break; - case 12: - errstr = "Preset not found."; - break; - case 13: - errstr = "Missing ir.json."; - break; - case 19: - errstr = "A filesystem error has occured."; - break; + var errstr = ""; + switch (s.error) { + case 8: + errstr = "Effect RAM depleted!"; + break; + case 9: + errstr = "JSON parsing error!"; + break; + case 10: + errstr = "Could not mount filesystem!"; + break; + case 11: + errstr = "Not enough space to save preset!"; + break; + case 12: + errstr = "Preset not found."; + break; + case 13: + errstr = "Missing ir.json."; + break; + case 19: + errstr = "A filesystem error has occured."; + break; } - showToast('Error ' + s.error + ": " + errstr, true); + showToast('Error ' + s.error + ": " + errstr, true); } selectedPal = i.pal; @@ -1484,46 +1558,49 @@ function setEffectParameters(idx) var paOnOff = (effectPars.length<3 || effectPars[2]=='')?[]:effectPars[2].split(","); // set html slider items on/off - let nSliders = 5; - for (let i=0; ii && slOnOff[i] != "")) { - if (slOnOff.length>i && slOnOff[i]!="!") label.innerHTML = slOnOff[i]; - else if (i==0) label.innerHTML = "Effect speed"; - else if (i==1) label.innerHTML = "Effect intensity"; - else label.innerHTML = "Custom" + (i-1); - slider.classList.remove('hide'); - } else { - slider.classList.add('hide'); - } - } - if (slOnOff.length>5) { // up to 3 checkboxes + let sliders = d.querySelectorAll("#sliders .sliderwrap"); + sliders.forEach((slider, i)=>{ + let text = slider.getAttribute("tooltip"); + if ((!controlDefined && i<((idx<128)?2:nSliders)) || (slOnOff.length>i && slOnOff[i]!="")) { + if (slOnOff.length>i && slOnOff[i]!="!") text = slOnOff[i]; + // restore overwritten default tooltips + if (i<2 && slOnOff[i]==="!") text = i==0 ? "Effect speed" : "Effect intensity"; + slider.setAttribute("tooltip", text); + slider.parentElement.classList.remove('hide'); + } else + slider.parentElement.classList.add('hide'); + }); + + if (slOnOff.length > 5) { // up to 3 checkboxes gId('fxopt').classList.remove('fade'); - for (let i = 0; i<3; i++) { + let checks = d.querySelectorAll("#sliders .ochkl"); + checks.forEach((check, i)=>{ + let text = check.getAttribute("tooltip"); if (5+i5+i && slOnOff[5+i]!="!") text = slOnOff[5+i]; + check.setAttribute("tooltip", text); + check.classList.remove('hide'); } else - gId('opt'+i).classList.add('hide'); - } - } else { - gId('fxopt').classList.add('fade'); - } + check.classList.add('hide'); + }); + } else gId('fxopt').classList.add('fade'); // set the bottom position of selected effect (sticky) as the top of sliders div - setInterval(()=>{ + function setSelectedEffectPosition() { + if (simplifiedUI) return; let top = parseInt(getComputedStyle(gId("sliders")).height); top += 5; let sel = d.querySelector('#fxlist .selected'); if (sel) sel.style.bottom = top + "px"; // we will need to remove this when unselected (in setFX()) - },750); + } + + setSelectedEffectPosition(); + setInterval(setSelectedEffectPosition,750); // set html color items on/off var cslLabel = ''; var sep = ''; var cslCnt = 0, oCsel = csel; - for (let i=0; i{ var btn = gId("csl" + i); // if no controlDefined or coOnOff has a value if (coOnOff.length>i && coOnOff[i] != "") { @@ -1553,12 +1630,16 @@ function setEffectParameters(idx) btn.dataset.hide = 1; btn.innerHTML = `${i+1}`; // name hidden buttons 1..3 for * palettes } - } + }); gId("cslLabel").innerHTML = cslLabel; + if (cslLabel!=="") gId("cslLabel").classList.remove("hide"); + else gId("cslLabel").classList.add("hide"); // set palette on/off var palw = gId("palw"); // wrapper var pall = gId("pall"); // label + var icon = ' '; + var text = 'Color palette'; // if not controlDefined or palette has a value if (hasRGB && ((!controlDefined) || (paOnOff.length>0 && paOnOff[0]!="" && isNaN(paOnOff[0])))) { palw.style.display = "inline-block"; @@ -1568,13 +1649,17 @@ function setEffectParameters(idx) var v = Math.max(0,Math.min(255,parseInt(paOnOff[0].substr(dPos+1)))); paOnOff[0] = paOnOff[0].substring(0,dPos); } - if (paOnOff.length>0 && paOnOff[0] != "!") pall.innerHTML = paOnOff[0]; - else pall.innerHTML = ' Color palette'; + if (paOnOff.length>0 && paOnOff[0] != "!") text = paOnOff[0]; } else { // disable palette list - pall.innerHTML = ' Color palette not used'; + text += ' not used'; palw.style.display = "none"; + // Close palette dialog if not available + if (gId("palw").lastElementChild.tagName == "DIALOG") { + gId("palw").lastElementChild.close(); + } } + pall.innerHTML = icon + text; // not all color selectors shown, hide palettes created from color selectors // NOTE: this will disallow user to select "* Color ..." palettes which may be undesirable in some cases or for some users //for (let e of (gId('pallist').querySelectorAll('.lstI')||[])) { @@ -1638,6 +1723,7 @@ function requestJson(command=null) parseInfo(i); populatePalettes(i); if (isInfo) populateInfo(i); + if (simplifiedUI) simplifyUI(); } var s = json.state ? json.state : json; readState(s); @@ -1650,8 +1736,13 @@ function requestJson(command=null) }); },25); reqsLegal = true; + retry = false; }) .catch((e)=>{ + if (!retry) { + retry = true; + setTimeout(requestJson,500); + } showToast(e, true); }); } @@ -1665,6 +1756,8 @@ function togglePower() obj.seg = []; obj.seg[0] = {"id": lastinfo.liveseg, "frz": false}; } + if (cfg.comp.on >0 && isOn) obj = {"ps": cfg.comp.on }; // don't use setPreset() + if (cfg.comp.off>0 && !isOn) obj = {"ps": cfg.comp.off}; // don't use setPreset() requestJson(obj); } @@ -1687,7 +1780,7 @@ function toggleSync() if (syncSend) showToast('Other lights in the network will now sync to this one.'); else showToast('This light and other lights in the network will no longer sync.'); var obj = {"udpn": {"send": syncSend}}; - if (syncTglRecv) obj.udpn.recv = syncSend; + //if (syncTglRecv) obj.udpn.recv = syncSend; requestJson(obj); } @@ -1699,7 +1792,7 @@ function toggleLiveview() let wsOn = ws && ws.readyState === WebSocket.OPEN; var lvID = "liveview"; - if (isM && wsOn) { + if (isM && wsOn) { lvID += "2D"; if (isLv) gId('klv2D').innerHTML = ``; gId('mlv2D').style.transform = (isLv) ? "translateY(0px)":"translateY(100%)"; @@ -1792,12 +1885,12 @@ function makePlSel(el, incPl=false) { var plSelContent = ""; delete pJson["0"]; // remove filler preset - var arr = Object.entries(pJson); - for (var a of arr) { + Object.entries(pJson).sort(cmpP).forEach((a)=>{ var n = a[1].n ? a[1].n : "Preset " + a[0]; - if (!incPl && a[1].playlist && a[1].playlist.ps) continue; // remove playlists, sub-playlists not yet supported - plSelContent += `` - } + if (cfg.comp.idsort) n = a[0] + ' ' + n; + if (!(!incPl && a[1].playlist && a[1].playlist.ps)) // skip playlists, sub-playlists not yet supported + plSelContent += ``; + }); return plSelContent; } @@ -1806,21 +1899,19 @@ function refreshPlE(p) var plEDiv = gId(`ple${p}`); if (!plEDiv) return; var content = "
Playlist entries
"; - for (var i = 0; i < plJson[p].ps.length; i++) { - content += makePlEntry(p,i); - } + plJson[p].ps.forEach((e,i)=>{content += makePlEntry(p,i);}); + content += `
`; plEDiv.innerHTML = content; var dels = plEDiv.getElementsByClassName("btn-pl-del"); if (dels.length < 2) dels[0].style.display = "none"; - var sels = gId(`seg${p+100}`).getElementsByClassName("sel"); - for (var i of sels) { + d.querySelectorAll(`#seg${p+100} .sel`).forEach((i)=>{ if (i.dataset.val) { if (parseInt(i.dataset.val) > 0) i.value = i.dataset.val; else plJson[p].ps[i.dataset.index] = parseInt(i.value); } - } + }); } // p: preset ID, i: ps index @@ -1886,7 +1977,7 @@ function makeP(i,pl) end: 0 }; var rep = plJson[i].repeat ? plJson[i].repeat : 0; - content = + content = `
`; -} - -function pName(i) -{ - var n = "Preset " + i; - if (pJson && pJson[i] && pJson[i].n) n = pJson[i].n; - return n; -} - -function isPlaylist(i) -{ - return pJson[i].playlist && pJson[i].playlist.ps; -} - -function papiVal(i) -{ - if (!pJson || !pJson[i]) return ""; - var o = Object.assign({},pJson[i]); - if (o.win) return o.win; - delete o.n; delete o.p; delete o.ql; - return JSON.stringify(o); -} - -function qlName(i) -{ - if (!pJson || !pJson[i] || !pJson[i].ql) return ""; - return pJson[i].ql; -} - -function cpBck() -{ - var copyText = gId("bck"); - - copyText.select(); - copyText.setSelectionRange(0, 999999); - d.execCommand("copy"); - showToast("Copied to clipboard!"); -} - -function loadPresets(callback = null) -{ - //1st boot (because there is a callback) - if (callback && pmt == pmtLS && pmt > 0) { - //we have a copy of the presets in local storage and don't need to fetch another one - pJson = JSON.parse(localStorage.getItem("wledP")); - populatePresets(); - pmtLast = pmt; - callback(); - return; - } - - //afterwards - if (!callback && pmt == pmtLast) return; - - pmtLast = pmt; - - fetch(getURL('/presets.json'), { - method: 'get' - }) - .then(res => { - if (!res.ok) showErrorToast(); - return res.json(); - }) - .then(json => { - clearErrorToast(); - pJson = json; - populatePresets(); - }) - .catch(function (error) { - showToast(error, true); - console.log(error); - }) - .finally(()=>{ - if (callback) setTimeout(callback,99); - }); -} - -function loadPalettes(callback = null) -{ - fetch(getURL('/json/palettes'), { - method: 'get' - }) - .then(res => { - if (!res.ok) showErrorToast(); - return res.json(); - }) - .then(json => { - clearErrorToast(); - lJson = Object.entries(json); - populatePalettes(); - }) - .catch(function (error) { - showToast(error, true); - }) - .finally(()=>{ - if (callback) callback(); - }); -} - -function loadFX(callback = null) -{ - fetch(getURL('/json/effects'), { - method: 'get' - }) - .then(res => { - if (!res.ok) showErrorToast(); - return res.json(); - }) - .then(json => { - clearErrorToast(); - eJson = Object.entries(json); - populateEffects(); - }) - .catch(function (error) { - showToast(error, true); - }) - .finally(()=>{ - if (callback) callback(); - }); -} - -function loadFXData(callback = null) -{ - fetch(getURL('/json/fxdata'), { - method: 'get' - }) - .then(res => { - if (!res.ok) showErrorToast(); - return res.json(); - }) - .then(json => { - clearErrorToast(); - fxdata = json||[]; - // add default value for Solid - fxdata.shift() - fxdata.unshift("@;!;"); - }) - .catch(function (error) { - fxdata = []; - showToast(error, true); - }) - .finally(()=>{ - if (callback) callback(); - updateUI(); - }); -} - -var pQL = []; -function populateQL() -{ - var cn = ""; - if (pQL.length > 0) { - pQL.sort((a,b) => (a[0]>b[0])); - for (var key of (pQL||[])) { - cn += ``; - } - } - gId('pql').innerHTML = cn; -} - -function populatePresets() -{ - if (!pJson) {pJson={};return}; - delete pJson["0"]; - var cn = ""; //`

All presets

`; - var arr = Object.entries(pJson); - arr.sort(cmpP); - pQL = []; - var is = []; - pNum = 0; - for (var key of (arr||[])) - { - if (!isObj(key[1])) continue; - let i = parseInt(key[0]); - var qll = key[1].ql; - if (qll) pQL.push([i, qll, pName(i)]); - is.push(i); - - cn += `
`; - //if (cfg.comp.pid) cn += `
${i}
`; - cn += `${isPlaylist(i)?"":""}${pName(i)}
`; - pNum++; - } - gId('pcont').innerHTML = cn; - updatePA(); - populateQL(); -} - -function parseInfo() { - var li = lastinfo; - var name = li.name; - gId('namelabel').innerHTML = name; -// if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)"; - if (li.live) name = "(Live) " + name; - if (loc) name = "(L) " + name; - d.title = name; - isRgbw = li.leds.wv; - ledCount = li.leds.count; - syncTglRecv = li.str; - maxSeg = li.leds.maxseg; - pmt = li.fs.pmt; - cct = li.leds.cct; -} - -function populateInfo(i) -{ - var cn=""; - var heap = i.freeheap/1000; - heap = heap.toFixed(1); - var pwr = i.leds.pwr; - var pwru = "Not calculated"; - if (pwr > 1000) {pwr /= 1000; pwr = pwr.toFixed((pwr > 10) ? 0 : 1); pwru = pwr + " A";} - else if (pwr > 0) {pwr = 50 * Math.round(pwr/50); pwru = pwr + " mA";} - var urows=""; - if (i.u) { - for (const [k, val] of Object.entries(i.u)) { - if (val[1]) - urows += inforow(k,val[0],val[1]); - else - urows += inforow(k,val); - } - } - var vcn = "Kuuhaku"; - if (i.ver.startsWith("0.14.")) vcn = "Hoshi"; - if (i.ver.includes("-bl")) vcn = "Supāku"; - if (i.cn) vcn = i.cn; - - cn += `v${i.ver} "${vcn}"

${key}${val}${unit}
-${urows} -${inforow("Build",i.vid)} -${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")} -${inforow("Uptime",getRuntimeStr(i.uptime))} -${inforow("Free heap",heap," kB")} -${i.psram?inforow("Free PSRAM",(i.psram/1024).toFixed(1)," kB"):""} -${inforow("Estimated current",pwru)} -${inforow("Average FPS",i.leds.fps)} -${inforow("MAC address",i.mac)} -${inforow("Filesystem",i.fs.u + "/" + i.fs.t + " kB (" +Math.round(i.fs.u*100/i.fs.t) + "%)")} -${inforow("Environment",i.arch + " " + i.core + " (" + i.lwip + ")")} -
`; - gId('kv').innerHTML = cn; -} - -function populateSegments(s) -{ - var cn = ""; - segCount = (s.seg||[]).length; - lowestUnused = 0; lSeg = 0; - - if (segCount > 1) { - for (var y = 0; y < segCount && y<4; y++) - { - var inst=s.seg[y]; - let i = parseInt(inst.id); - powered[i] = inst.on; - if (i == lowestUnused) lowestUnused = i+1; - if (i > lSeg) lSeg = i; - - cn += -`
${(inst.n&&inst.n!=='')?inst.n:('Segment '+y)}
-
- -
- -
- -
-
- -
-
`; - } - //if (gId('buttonBri').className !== 'active') tglBri(true); - } else { - //tglBri(false); - } - //gId('buttonBri').style.display = (segCount > 1) ? "block" : "none"; - gId('segcont').innerHTML = cn; - for (var i = 0; i < segCount && i<4; i++) updateTrail(gId(`seg${i}bri`)); -} - -function btype(b) -{ - switch (b) { - case 2: - case 32: return "ESP32"; - case 1: - case 82: return "ESP8266"; - } - return "?"; -} - -function bname(o) -{ - if (o.name=="WLED") return o.ip; - return o.name; -} - -function populateNodes(i,n) -{ - var cn=""; - var urows=""; - var nnodes = 0; - if (n.nodes) { - n.nodes.sort((a,b) => (a.name).localeCompare(b.name)); - for (var x=0;x${bname(o)}`; - urows += inforow(url,`${btype(o.type)}
${o.vid==0?"N/A":o.vid}`); - nnodes++; - } - } - } - if (i.ndc < 0) cn += `Instance List is disabled.`; - else if (nnodes == 0) cn += `No other instances found.`; - cn += ` - ${urows} - ${inforow("Current instance:",i.name)} -
`; - gId('kn').innerHTML = cn; -} - -function loadNodes() -{ - fetch(getURL('/json/nodes'), { - method: 'get' - }) - .then(res => { - if (!res.ok) showToast('Could not load Node list!', true); - return res.json(); - }) - .then(json => { - clearErrorToast(); - populateNodes(lastinfo, json); - }) - .catch(function (error) { - showToast(error, true); - console.log(error); - }); -} - -function populateEffects() -{ - var effects = eJson; - var html = ""; - - effects.shift(); //remove solid - for (let i = 0; i < effects.length; i++) effects[i] = {id: effects[i][0], name:effects[i][1]}; - effects.sort((a,b) => (a.name).localeCompare(b.name)); - effects.unshift({ - "id": 0, - "name": "Solid@;!;0" - }); - - for (let i = 0; i < effects.length; i++) { - // WLEDSR: add slider and color control to setEffect (used by requestjson) - if (effects[i].name.indexOf("RSVD") < 0) { - var posAt = effects[i].name.indexOf("@"); - var extra = ''; - if (posAt > 0) - extra = effects[i].name.substr(posAt); - else - posAt = 999; - html += generateListItemHtml( - 'fx', - effects[i].id, - effects[i].name.substr(0,posAt), - 'setEffect', - '','', - extra - ); - } - } - gId('fxlist').innerHTML=html; -} - -function populatePalettes() -{ - var palettes = lJson; - palettes.shift(); //remove default - for (let i = 0; i < palettes.length; i++) { - palettes[i] = { - "id": palettes[i][0], - "name": palettes[i][1] - }; - } - palettes.sort((a,b) => (a.name).localeCompare(b.name)); - palettes.unshift({ - "id": 0, - "name": "Default", - }); - var html = ""; - for (let i = 0; i < palettes.length; i++) { - html += generateListItemHtml( - 'palette', - palettes[i].id, - palettes[i].name, - 'setPalette', - `
` - ); - } - gId('pallist').innerHTML=html; -} - -function redrawPalPrev() -{ - let palettes = d.querySelectorAll('#pallist .lstI'); - for (let i = 0; i < palettes.length; i++) { - let id = palettes[i].dataset.id; - let lstPrev = palettes[i].querySelector('.lstIprev'); - if (lstPrev) { - lstPrev.style = genPalPrevCss(id); - } - } -} - -function genPalPrevCss(id) -{ - if (!palettesData) return; - - var paletteData = palettesData[id]; - var previewCss = ""; - - if (!paletteData) return 'display: none'; - - // We need at least two colors for a gradient - if (paletteData.length == 1) { - paletteData[1] = paletteData[0]; - if (Array.isArray(paletteData[1])) { - paletteData[1][0] = 255; - } - } - - var gradient = []; - for (let j = 0; j < paletteData.length; j++) { - const element = paletteData[j]; - let r; - let g; - let b; - let index = false; - if (Array.isArray(element)) { - index = element[0]/255*100; - r = element[1]; - g = element[2]; - b = element[3]; - } else if (element == 'r') { - r = Math.random() * 255; - g = Math.random() * 255; - b = Math.random() * 255; - } else { - if (selColors) { - let e = element[1] - 1; - r = selColors[e][0]; - g = selColors[e][1]; - b = selColors[e][2]; - } - } - if (index === false) { - index = j / paletteData.length * 100; - } - - gradient.push(`rgb(${r},${g},${b}) ${index}%`); - } - - return `background: linear-gradient(to right,${gradient.join()});`; -} - -function generateOptionItemHtml(id, name) -{ - return ``; -} - -function generateListItemHtml(listName, id, name, clickAction, extraHtml = '', extraClass = '', extraPar = '') -{ - return `
-
- - ${name} - -
- ${extraHtml} -
`; -} - -//update the 'sliderdisplay' background div of a slider for a visual indication of slider position -function updateTrail(e) -{ - if (e==null) return; - var max = e.hasAttribute('max') ? e.attributes.max.value : 255; - var perc = e.value * 100 / max; - perc = parseInt(perc); - if (perc < 50) perc += 2; - var val = `linear-gradient(90deg, var(--c-f) ${perc}%, var(--c-4) ${perc}%)`; - e.parentNode.getElementsByClassName('sliderdisplay')[0].style.background = val; - var b = e.parentNode.parentNode.getElementsByTagName('output')[0]; - if (b) b.innerHTML = e.value; -} - -//rangetouch slider function -function toggleBubble(e) -{ - var b = e.target.parentNode.parentNode.getElementsByTagName('output')[0]; - b.classList.toggle('sliderbubbleshow'); -} - -function updatePA() -{ - var ps = gEBCN("pres"); - for (let i = 0; i < ps.length; i++) { - ps[i].classList.remove('selected');; - } - ps = gEBCN("psts"); - for (let i = 0; i < ps.length; i++) { - ps[i].classList.remove('selected');; - } - if (currentPreset > 0) { - var acv = gId(`p${currentPreset}o`); - if (acv) acv.classList.add('selected'); - acv = gId(`p${currentPreset}qlb`); - if (acv) acv.classList.add('selected'); - } -} - -function updateUI() -{ - gId('buttonPower').className = (isOn) ? "active":""; - - var sel = 0; - if (lJson && lJson.length) { - for (var i=0; i b[0]); - // playlists follow presets - var name = (a[1].playlist ? '~' : ' ') + a[1].n; - return name.localeCompare((b[1].playlist ? '~' : ' ') + b[1].n, undefined, {numeric: true}); -} - -function makeWS() { - if (ws) return; - let url = loc ? getURL('/ws').replace("http","ws") : "ws://"+window.location.hostname+"/ws"; - ws = new WebSocket(url); - ws.onmessage = (e)=>{ - var json = JSON.parse(e.data); - if (json.leds) return; //liveview packet - clearTimeout(jsonTimeout); - jsonTimeout = null; - lastUpdate = new Date(); - clearErrorToast(); - gId('connind').style.backgroundColor = "var(--c-l)"; - // json object should contain json.info AND json.state (but may not) - var i = json.info; - if (i) { - lastinfo = i; - parseInfo(); - if (isInfo) populateInfo(i); - } else - i = lastinfo; - var s = json.state ? json.state : json; - readState(s); - }; - ws.onclose = (e)=>{ - gId('connind').style.backgroundColor = "var(--c-r)"; - ws = null; - if (lastinfo.ws > -1) setTimeout(makeWS,500); - } - ws.onopen = (e)=>{ - ws.send("{'v':true}"); - reqsLegal = true; - clearErrorToast(); - } -} - -function readState(s,command=false) -{ - if (!s) return false; - - isOn = s.on; - gId('sliderBri').value= s.bri; - nlA = s.nl.on; - nlDur = s.nl.dur; - nlTar = s.nl.tbri; - nlFade = s.nl.fade; - syncSend = s.udpn.send; - if (s.pl<0) currentPreset = s.ps; - else currentPreset = s.pl; - tr = s.transition/10; - - var selc=0; var ind=0; - populateSegments(s); - for (let i = 0; i < (s.seg||[]).length; i++) - { - if(s.seg[i].sel) {selc = ind; break;} ind++; - } - var i=s.seg[selc]; - if (!i) { - showToast('No Segments!', true); - updateUI(); - return; - } - - selColors = i.col; - var cd = gId('csl').children; - for (let e = cd.length-1; e >= 0; e--) - { - var r,g,b,w; - r = i.col[e][0]; - g = i.col[e][1]; - b = i.col[e][2]; - if (isRgbw) w = i.col[e][3]; - cd[e].style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")"; - if (isRgbw) whites[e] = parseInt(w); - selectSlot(csel); - } - gId('sliderW').value = whites[csel]; - if (i.cct && i.cct>=0) gId("sliderA").value = i.cct; - - gId('sliderSpeed').value = i.sx; - gId('sliderIntensity').value = i.ix; -/* - gId('sliderC1').value = i.f1x ? i.f1x : 0; - gId('sliderC2').value = i.f2x ? i.f2x : 0; - gId('sliderC3').value = i.f3x ? i.f3x : 0; -*/ - if (s.error && s.error != 0) { - var errstr = ""; - switch (s.error) { - case 10: - errstr = "Could not mount filesystem!"; - break; - case 11: - errstr = "Not enough space to save preset!"; - break; - case 12: - errstr = "Preset not found."; - break; - case 13: - errstr = "Missing IR.json."; - break; - case 19: - errstr = "A filesystem error has occured."; - break; - } - showToast('Error ' + s.error + ": " + errstr, true); - } - - selectedPal = i.pal; - selectedFx = i.fx; - updateUI(); -} - -var jsonTimeout; -var reqsLegal = false; - -function requestJson(command=null) -{ - gId('connind').style.backgroundColor = "var(--c-r)"; - if (command && !reqsLegal) return; //stop post requests from chrome onchange event on page restore - if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000); - var req = null; - var useWs = (ws && ws.readyState === WebSocket.OPEN); - var type = command ? 'post':'get'; - if (command) { - if (useWs || !command.ps) command.v = true; // force complete /json/si API response - command.time = Math.floor(Date.now() / 1000); - req = JSON.stringify(command); - if (req.length > 1000) useWs = false; //do not send very long requests over websocket - }; - - if (useWs) { - ws.send(req?req:'{"v":true}'); - return; - } else if (command && command.ps) { //refresh UI if we don't use WS (async loading of presets) - setTimeout(requestJson,200); - } - - fetch(getURL('/json/si'), { - method: type, - headers: { - "Content-type": "application/json; charset=UTF-8" - }, - body: req - }) - .then(res => { - if (!res.ok) showErrorToast(); - return res.json(); - }) - .then(json => { - clearTimeout(jsonTimeout); - jsonTimeout = null; - lastUpdate = new Date(); - clearErrorToast(); - gId('connind').style.backgroundColor = "var(--c-g)"; - if (!json) { showToast('Empty response', true); return; } - if (json.success) return; - if (json.info) { - lastinfo = json.info; - parseInfo(); - if (isInfo) populateInfo(lastinfo); - } - var s = json.state ? json.state : json; - readState(s); - reqsLegal = true; - }) - .catch(function (error) { - showToast(error, true); - console.log(error); - }); -} - -function togglePower() -{ - isOn = !isOn; - var obj = {"on": isOn}; - requestJson(obj); -} - -function toggleInfo() -{ - if (isNodes) toggleNodes(); - isInfo = !isInfo; - if (isInfo) requestJson(); - gId('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)"; - gId('buttonI').className = (isInfo) ? "active":""; -} - -function toggleNodes() -{ - if (isInfo) toggleInfo(); - isNodes = !isNodes; - if (isNodes) loadNodes(); - gId('nodes').style.transform = (isNodes) ? "translateY(0px)":"translateY(100%)"; - gId('buttonNodes').className = (isNodes) ? "active":""; -} -/* -function tglBri(b=null) -{ - if (b===null) b = gId(`briwrap`).style.display === "block"; - gId('briwrap').style.display = !b ? "block":"none"; - gId('buttonBri').className = !b ? "active":""; - size(); -} -*/ -function tglCP() -{ - var p = gId('buttonCP').className === "active"; - gId('buttonCP').className = !p ? "active":""; - gId('picker').style.display = !p ? "block":"none"; - gId('vwrap').style.display = !p ? "block":"none"; - gId('rgbwrap').style.display = !p ? "block":"none"; - var csl = gId('Slots').style.display === "block"; - gId('Slots').style.display = !csl ? "block":"none"; - //var ps = gId(`Presets`).style.display === "block"; - //gId('Presets').style.display = !ps ? "block":"none"; -} - -function tglCs(i) -{ - var pss = gId(`p${i}cstgl`).checked; - gId(`p${i}o1`).style.display = pss? "block" : "none"; - gId(`p${i}o2`).style.display = !pss? "block" : "none"; -} - -function selSeg(s) -{ - var sel = gId(`seg${s}sel`).checked; - var obj = {"seg": {"id": s, "sel": sel}}; - requestJson(obj); -} - -function tglPalDropdown() -{ - var p = gId('palDropdown').style; - p.display = (p.display==='block'?'none':'block'); - gId('fxDropdown').style.display = 'none'; - if (p.display==='block') - gId('palDropdown').scrollIntoView({ - behavior: 'smooth', - block: 'center', - }); -} - -function tglFxDropdown() -{ - var p = gId('fxDropdown').style; - p.display = (p.display==='block'?'none':'block'); - gId('palDropdown').style.display = 'none'; - if (p.display==='block') - gId('fxDropdown').scrollIntoView({ - behavior: 'smooth', - block: 'center', - }); -} - -function setSegPwr(s) -{ - var obj = {"seg": {"id": s, "on": !powered[s]}}; - requestJson(obj); -} - -function setSegBri(s) -{ - var obj = {"seg": {"id": s, "bri": parseInt(gId(`seg${s}bri`).value)}}; - requestJson(obj); -} - -function setEffect(ind = 0) -{ - tglFxDropdown(); - var obj = {"seg": {"fx": parseInt(ind), "fxdef":true}}; // fxdef sets effect parameters to default values, TODO add client setting - requestJson(obj); -} - -function setPalette(paletteId = null) -{ - tglPalDropdown(); - var obj = {"seg": {"pal": paletteId}}; - requestJson(obj); -} - -function setBri() -{ - var obj = {"bri": parseInt(gId('sliderBri').value)}; - requestJson(obj); -} - -function setSpeed() -{ - var obj = {"seg": {"sx": parseInt(gId('sliderSpeed').value)}}; - requestJson(obj); -} - -function setIntensity() -{ - var obj = {"seg": {"ix": parseInt(gId('sliderIntensity').value)}}; - requestJson(obj); -} - -function setLor(i) -{ - var obj = {"lor": i}; - requestJson(obj); -} - -function setPreset(i) -{ - var obj = {"ps": i}; - if (isPlaylist(i)) obj.on = true; - showToast("Loading preset " + pName(i) +" (" + i + ")"); - requestJson(obj); -} - -function selectSlot(b) -{ - csel = b; - var cd = gId('csl').children; - for (let i = 0; i < cd.length; i++) cd[i].classList.remove('xxs-w'); - cd[b].classList.add('xxs-w'); - setPicker(cd[b].style.backgroundColor); - gId('sliderW').value = whites[b]; - redrawPalPrev(); - updatePSliders(); -} - -var lasth = 0; -function pC(col) -{ - if (col == "rnd") { - col = {h: 0, s: 0, v: 100}; - col.s = Math.floor((Math.random() * 50) + 50); - do { - col.h = Math.floor(Math.random() * 360); - } while (Math.abs(col.h - lasth) < 50); - lasth = col.h; - } - setPicker(col); - setColor(0); -} - -function updatePSliders() { - //update RGB sliders - var col = cpick.color.rgb; - gId('sliderR').value = col.r; - gId('sliderG').value = col.g; - gId('sliderB').value = col.b; - - //update hex field - var str = cpick.color.hexString.substring(1); - var w = whites[csel]; - if (w > 0) str += w.toString(16); - - //update value slider - var v = gId('sliderV'); - v.value = cpick.color.value; - //background color as if color had full value - var hsv = {"h":cpick.color.hue,"s":cpick.color.saturation,"v":100}; - var c = iro.Color.hsvToRgb(hsv); - var cs = 'rgb('+c.r+','+c.g+','+c.b+')'; - v.nextElementSibling.style.backgroundImage = `linear-gradient(90deg, #000 0%, ${cs})`; - - //update Kelvin slider - gId('sliderK').value = cpick.color.kelvin; -} - -function setPicker(rgb) { - var c = new iro.Color(rgb); - if (c.value > 0) cpick.color.set(c); - else cpick.color.setChannel('hsv', 'v', 0); -} - -function fromV() -{ - cpick.color.setChannel('hsv', 'v', d.getElementById('sliderV').value); -} - -function fromK() -{ - cpick.color.set({ kelvin: d.getElementById('sliderK').value }); -} - -function fromRgb() -{ - var r = gId('sliderR').value; - var g = gId('sliderG').value; - var b = gId('sliderB').value; - setPicker(`rgb(${r},${g},${b})`); - setColor(0); -} - -// sets color from picker: 0=all, 1=leaving picker/HSV, 2=ignore white channel -function setColor(sr) -{ - var cd = gId('csl').children; // color slots - if (sr == 1 && cd[csel].style.backgroundColor == 'rgb(0, 0, 0)') cpick.color.setChannel('hsv', 'v', 100); - cd[csel].style.backgroundColor = cpick.color.rgbString; - if (sr != 2) whites[csel] = parseInt(gId('sliderW').value); - var col = cpick.color.rgb; - var obj = {"seg": {"col": [[col.r, col.g, col.b, whites[csel]],[],[]]}}; - if (sr==1 || gId(`picker`).style.display !== "block") obj.seg.fx = 0; - if (csel == 1) { - obj = {"seg": {"col": [[],[col.r, col.g, col.b, whites[csel]],[]]}}; - } else if (csel == 2) { - obj = {"seg": {"col": [[],[],[col.r, col.g, col.b, whites[csel]]]}}; - } - requestJson(obj); -} - -function setBalance(b) -{ - var obj = {"seg": {"cct": parseInt(b)}}; - requestJson(obj); -} - -var hc = 0; -setInterval(()=>{if (!isInfo) return; hc+=18; if (hc>300) hc=0; if (hc>200)hc=306; if (hc==144) hc+=36; if (hc==108) hc+=18; -gId('heart').style.color = `hsl(${hc}, 100%, 50%)`;}, 910); - -function openGH() { window.open("https://github.com/Aircoookie/WLED/wiki"); } - -var cnfr = false; -function cnfReset() -{ - if (!cnfr) { - var bt = gId('resetbtn'); - bt.style.color = "#f00"; - bt.innerHTML = "Confirm Reboot"; - cnfr = true; return; - } - window.location.href = "/reset"; -} - -function loadPalettesData(callback = null) -{ - if (palettesData) return; - const lsKey = "wledPalx"; - var palettesDataJson = localStorage.getItem(lsKey); - if (palettesDataJson) { - try { - palettesDataJson = JSON.parse(palettesDataJson); - if (palettesDataJson && palettesDataJson.vid == lastinfo.vid) { - palettesData = palettesDataJson.p; - if (callback) callback(); //redrawPalPrev() - return; - } - } catch (e) {} - } - - palettesData = {}; - getPalettesData(0, ()=>{ - localStorage.setItem(lsKey, JSON.stringify({ - p: palettesData, - vid: lastinfo.vid - })); - if (callback) setTimeout(callback, 99); //redrawPalPrev() - }); -} - -function getPalettesData(page, callback) -{ - fetch(getURL(`/json/palx?page=${page}`), { - method: 'get', - headers: { - "Content-type": "application/json; charset=UTF-8" - } - }) - .then((res)=>{ - if (!res.ok) showErrorToast(); - return res.json(); - }) - .then((json)=>{ - palettesData = Object.assign({}, palettesData, json.p); - if (page < json.m) setTimeout(()=>{ getPalettesData(page + 1, callback); }, 50); - else callback(); - }) - .catch((e)=>{ - showToast(e, true); - }); -} - -function search(f,l=null) -{ - f.nextElementSibling.style.display=(f.value!=='')?'block':'none'; - if (!l) return; - var el = gId(l).querySelectorAll('.lstI'); - for (i = 0; i < el.length; i++) { - var it = el[i]; - var itT = it.querySelector('.lstIname').innerText.toUpperCase(); - it.style.display = itT.indexOf(f.value.toUpperCase())>-1?'':'none'; - } -} - -function clean(c) -{ - c.style.display='none'; - var i=c.previousElementSibling; - i.value=''; - i.focus(); - i.dispatchEvent(new Event('input')); -} - -function unfocusSliders() -{ - gId("sliderBri").blur(); - gId("sliderSpeed").blur(); - gId("sliderIntensity").blur(); -} - -//sliding UI -const _C = d.querySelector('.container'), N = 1; - -let iSlide = 0, x0 = null, scrollS = 0, locked = false, w; - -function unify(e) { return e.changedTouches ? e.changedTouches[0] : e; } - -function hasIroClass(classList) -{ - for (var i = 0; i < classList.length; i++) { - var element = classList[i]; - if (element.startsWith('Iro')) return true; - } - return false; -} -//required by rangetouch.js -function lock(e) -{ - var l = e.target.classList; - var pl = e.target.parentElement.classList; - - if (l.contains('noslide') || hasIroClass(l) || hasIroClass(pl)) return; - - x0 = unify(e).clientX; - scrollS = gEBCN("tabcontent")[iSlide].scrollTop; - - _C.classList.toggle('smooth', !(locked = true)); -} -//required by rangetouch.js -function move(e) -{ - if(!locked) return; - var clientX = unify(e).clientX; - var dx = clientX - x0; - var s = Math.sign(dx); - var f = +(s*dx/w).toFixed(2); - - if((clientX != 0) && - (iSlide > 0 || s < 0) && (iSlide < N - 1 || s > 0) && - f > 0.12 && - gEBCN("tabcontent")[iSlide].scrollTop == scrollS) - { - _C.style.setProperty('--i', iSlide -= s); - f = 1 - f; - updateTablinks(iSlide); - } - _C.style.setProperty('--f', f); - _C.classList.toggle('smooth', !(locked = false)); - x0 = null; -} - -function size() -{ - var h = gId('top').clientHeight; - sCol('--th', h + "px"); - sCol("--tp", h - (gId(`briwrap`).style.display === "block" ? 0 : gId(`briwrap`).clientTop) + "px"); - sCol("--bh", "0px"); -} - -function mergeDeep(target, ...sources) -{ - if (!sources.length) return target; - const source = sources.shift(); - - if (isObj(target) && isObj(source)) { - for (const key in source) { - if (isObj(source[key])) { - if (!target[key]) Object.assign(target, { [key]: {} }); - mergeDeep(target[key], source[key]); - } else { - Object.assign(target, { [key]: source[key] }); - } - } - } - return mergeDeep(target, ...sources); -} - -size(); -window.addEventListener('resize', size, false); - -_C.addEventListener('mousedown', lock, false); -_C.addEventListener('touchstart', lock, false); - -_C.addEventListener('mouseout', move, false); -_C.addEventListener('mouseup', move, false); -_C.addEventListener('touchend', move, false); diff --git a/wled00/data/style.css b/wled00/data/style.css index 5daca929a..52b26a825 100644 --- a/wled00/data/style.css +++ b/wled00/data/style.css @@ -16,6 +16,9 @@ hr { hr.sml { width: 260px; } +h4 { + margin: 0; +} a, a:hover { color: #28f; text-decoration: none; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index df793a5a7..586f533e4 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -65,7 +65,8 @@ class NeoGammaWLEDMethod { #define gamma32(c) NeoGammaWLEDMethod::Correct32(c) #define gamma8(c) NeoGammaWLEDMethod::rawGamma8(c) uint32_t color_blend(uint32_t,uint32_t,uint16_t,bool b16=false); -uint32_t color_add(uint32_t,uint32_t); +uint32_t color_add(uint32_t,uint32_t, bool fast=false); +uint32_t color_fade(uint32_t c1, uint8_t amount, bool video=false); inline uint32_t colorFromRgbw(byte* rgbw) { return uint32_t((byte(rgbw[3]) << 24) | (byte(rgbw[0]) << 16) | (byte(rgbw[1]) << 8) | (byte(rgbw[2]))); } void colorHStoRGB(uint16_t hue, byte sat, byte* rgb); //hue, sat to rgb void colorKtoRGB(uint16_t kelvin, byte* rgb); @@ -229,7 +230,7 @@ void deletePreset(byte index); bool getPresetName(byte index, String& name); //remote.cpp -void handleRemote(); +void handleRemote(uint8_t *data, size_t len); //set.cpp bool isAsterisksOnly(const char* str, byte maxLen); @@ -245,6 +246,9 @@ void handleNotifications(); void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w); void refreshNodeList(); void sendSysInfoUDP(); +#ifndef WLED_DISABLE_ESPNOW +void espNowReceiveCB(uint8_t* address, uint8_t* data, uint8_t len, signed int rssi, bool broadcast); +#endif //network.cpp int getSignalQuality(int rssi); @@ -348,6 +352,7 @@ void userLoop(); int getNumVal(const String* req, uint16_t pos); void parseNumber(const char* str, byte* val, byte minv=0, byte maxv=255); bool getVal(JsonVariant elem, byte* val, byte minv=0, byte maxv=255); +bool getBoolVal(JsonVariant elem, bool dflt); bool updateVal(const char* req, const char* key, byte* val, byte minv=0, byte maxv=255); bool oappend(const char* txt); // append new c string to temp buffer efficiently bool oappendi(int i); // append new number to temp buffer efficiently @@ -364,6 +369,23 @@ void checkSettingsPIN(const char *pin); uint16_t crc16(const unsigned char* data_p, size_t length); um_data_t* simulateSound(uint8_t simulationId); void enumerateLedmaps(); +uint8_t get_random_wheel_index(uint8_t pos); + +// RAII guard class for the JSON Buffer lock +// Modeled after std::lock_guard +class JSONBufferGuard { + bool holding_lock; + public: + inline JSONBufferGuard(uint8_t module=255) : holding_lock(requestJSONBufferLock(module)) {}; + inline ~JSONBufferGuard() { if (holding_lock) releaseJSONBufferLock(); }; + inline JSONBufferGuard(const JSONBufferGuard&) = delete; // Noncopyable + inline JSONBufferGuard& operator=(const JSONBufferGuard&) = delete; + inline JSONBufferGuard(JSONBufferGuard&& r) : holding_lock(r.holding_lock) { r.holding_lock = false; }; // but movable + inline JSONBufferGuard& operator=(JSONBufferGuard&& r) { holding_lock |= r.holding_lock; r.holding_lock = false; return *this; }; + inline bool owns_lock() const { return holding_lock; } + explicit inline operator bool() const { return owns_lock(); }; + inline void release() { if (holding_lock) releaseJSONBufferLock(); holding_lock = false; } +}; #ifdef WLED_ADD_EEPROM_SUPPORT //wled_eeprom.cpp @@ -404,10 +426,10 @@ bool isIp(String str); void createEditHandler(bool enable); bool captivePortal(AsyncWebServerRequest *request); void initServer(); -void serveIndexOrWelcome(AsyncWebServerRequest *request); void serveIndex(AsyncWebServerRequest* request); String msgProcessor(const String& var); void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl="", byte optionT=255); +void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t error); String dmxProcessor(const String& var); void serveSettings(AsyncWebServerRequest* request, bool post = false); void serveSettingsJS(AsyncWebServerRequest* request); diff --git a/wled00/html_cpal.h b/wled00/html_cpal.h deleted file mode 100644 index a20096397..000000000 --- a/wled00/html_cpal.h +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Binary array for the Web UI. - * gzip is used for smaller size and improved speeds. - * - * Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui - * to find out how to easily modify the web UI source! - */ - -// Autogenerated from wled00/data/cpal/cpal.htm, do not edit!! -const uint16_t PAGE_cpal_L = 4721; -const uint8_t PAGE_cpal[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xbd, 0x3b, 0x7f, 0x73, 0xdb, 0xb6, - 0x92, 0xff, 0xe7, 0x53, 0x20, 0x4c, 0x5f, 0x42, 0xd6, 0x14, 0x45, 0xd2, 0xb6, 0x64, 0x4b, 0xa2, - 0x3b, 0xa9, 0x93, 0x77, 0xce, 0x8d, 0xdd, 0x64, 0x5e, 0x7c, 0x6e, 0x7b, 0x3e, 0xbf, 0x31, 0x4d, - 0x42, 0x12, 0x1b, 0x8a, 0xe0, 0x03, 0x21, 0xd9, 0xae, 0xac, 0xef, 0x7e, 0xbb, 0x00, 0x48, 0x91, - 0x94, 0xe4, 0x24, 0xd7, 0x37, 0xd7, 0xf1, 0x44, 0x20, 0xb0, 0x58, 0xec, 0x2e, 0xf6, 0x17, 0x16, - 0xe8, 0xe8, 0xe5, 0xbb, 0x8f, 0xa7, 0x97, 0xbf, 0x7f, 0x7a, 0x4f, 0xa6, 0x62, 0x96, 0x9e, 0x90, - 0x51, 0xf9, 0x43, 0xc3, 0x18, 0x7e, 0x66, 0x54, 0x84, 0x30, 0x22, 0xf2, 0x0e, 0xfd, 0xd7, 0x3c, - 0x59, 0x04, 0xc6, 0x69, 0x18, 0x4d, 0x69, 0xe7, 0x94, 0x65, 0x82, 0xb3, 0xd4, 0x20, 0x2f, 0x22, - 0x68, 0xd1, 0x4c, 0x04, 0x46, 0xc6, 0x3a, 0x11, 0x8e, 0xd9, 0x04, 0x5a, 0x85, 0x60, 0x1c, 0x5a, - 0xb3, 0x79, 0x21, 0x3a, 0x9c, 0x2e, 0xc2, 0x34, 0x89, 0x43, 0x41, 0x8d, 0x6d, 0x08, 0x3f, 0xf1, - 0x70, 0x32, 0x0b, 0xb7, 0x61, 0xda, 0x0a, 0xfe, 0xfe, 0x21, 0x4f, 0x38, 0x2d, 0x0c, 0x52, 0x81, - 0xbb, 0x08, 0x27, 0x12, 0x91, 0xd2, 0x93, 0x17, 0xbf, 0x9e, 0xbf, 0x7f, 0x47, 0x4e, 0x61, 0x55, - 0x36, 0x23, 0x9f, 0xc2, 0x94, 0x0a, 0x41, 0xc9, 0xfb, 0x38, 0x01, 0x6a, 0x46, 0x5d, 0x05, 0x42, - 0x46, 0x45, 0xc4, 0x93, 0x5c, 0x10, 0xf1, 0x98, 0xd3, 0xc0, 0x10, 0xf4, 0x41, 0x74, 0xff, 0x08, - 0x17, 0xa1, 0xea, 0x35, 0x4e, 0x5e, 0x8c, 0xe7, 0x59, 0x24, 0x12, 0x96, 0x91, 0xc9, 0x87, 0xd8, - 0xa4, 0xd6, 0x92, 0x53, 0x31, 0xe7, 0x19, 0x89, 0x9d, 0x09, 0x15, 0xef, 0x53, 0x3a, 0x83, 0x35, - 0x7f, 0x7e, 0x94, 0x43, 0xab, 0x0a, 0x34, 0x7a, 0xdf, 0x80, 0x8c, 0x38, 0x05, 0x6e, 0x35, 0x30, - 0x02, 0x2e, 0x42, 0x4e, 0xe2, 0x20, 0x66, 0xd1, 0x1c, 0x7b, 0x5e, 0x8c, 0xba, 0x6a, 0x35, 0x24, - 0x46, 0x3c, 0x22, 0xdd, 0x77, 0x2c, 0x7e, 0x5c, 0x8e, 0x81, 0xa3, 0xce, 0x38, 0x9c, 0x25, 0xe9, - 0xe3, 0xe0, 0x2d, 0x4f, 0xc2, 0xd4, 0x2e, 0xc2, 0xac, 0xe8, 0x14, 0x94, 0x27, 0xe3, 0xe1, 0x5d, - 0x18, 0x7d, 0x99, 0x70, 0x36, 0xcf, 0xe2, 0x4e, 0xc4, 0x52, 0xc6, 0x07, 0xaf, 0x3c, 0xcf, 0x1b, - 0xca, 0x29, 0x45, 0xf2, 0x27, 0x1d, 0x78, 0xbd, 0xfc, 0x61, 0xa8, 0x47, 0xe2, 0x38, 0x1e, 0xce, - 0x42, 0x3e, 0x49, 0xb2, 0x81, 0x4b, 0x3c, 0x17, 0x06, 0xd2, 0x24, 0xa3, 0x9d, 0x29, 0x4d, 0x26, - 0x53, 0x31, 0x70, 0x0e, 0x57, 0xaf, 0xf2, 0x90, 0x03, 0x21, 0x1d, 0x94, 0x61, 0x08, 0x43, 0x7c, - 0x99, 0xb3, 0x22, 0x41, 0x56, 0x06, 0x9c, 0xa6, 0xa1, 0x48, 0x16, 0x74, 0x78, 0x9f, 0xc4, 0x62, - 0x3a, 0xf0, 0x5c, 0xf7, 0x6f, 0x43, 0x3d, 0xd1, 0x07, 0x4c, 0xab, 0x57, 0x77, 0x4c, 0x80, 0x74, - 0x4f, 0x37, 0x67, 0x86, 0x77, 0x05, 0x4b, 0xe7, 0x82, 0xea, 0xa5, 0x3b, 0x82, 0xe5, 0x83, 0x43, - 0x39, 0x65, 0xc2, 0xc3, 0x38, 0xc1, 0xf5, 0xee, 0xd8, 0xc3, 0x72, 0x13, 0x2f, 0xb6, 0x57, 0x8e, - 0xa4, 0xbd, 0x03, 0x73, 0xbf, 0x50, 0x6e, 0xeb, 0xaf, 0x3c, 0x89, 0xe0, 0x4b, 0x77, 0x6e, 0x59, - 0xe9, 0x8e, 0xf1, 0x18, 0xc6, 0x11, 0xfd, 0xbc, 0x18, 0xec, 0x03, 0xa3, 0x1b, 0x62, 0x2a, 0x92, - 0x74, 0x41, 0xb9, 0x86, 0x1c, 0xf8, 0xf9, 0x03, 0x81, 0xb9, 0x49, 0x4c, 0xf8, 0xe4, 0x2e, 0x34, - 0x7b, 0x47, 0xb6, 0xfa, 0x73, 0x0e, 0xad, 0xe1, 0x9f, 0x9d, 0x24, 0x8b, 0xe9, 0xc3, 0xc0, 0x6f, - 0xd2, 0xb2, 0xd4, 0x54, 0xee, 0xa3, 0x1c, 0x15, 0xf1, 0x7d, 0x68, 0x29, 0xee, 0xfe, 0x36, 0x14, - 0x1c, 0xf6, 0x68, 0xcc, 0xf8, 0x6c, 0x20, 0x5b, 0x20, 0x3c, 0xfa, 0xbb, 0xd9, 0x81, 0x11, 0x6b, - 0xb5, 0x95, 0x09, 0x8d, 0xad, 0xbf, 0x81, 0xcc, 0x3b, 0x44, 0x29, 0xc4, 0x14, 0x94, 0x96, 0xee, - 0xe6, 0x58, 0x4f, 0x3f, 0xac, 0xa6, 0x63, 0xeb, 0x1b, 0xc4, 0xf0, 0x6a, 0x3c, 0x1e, 0x97, 0x42, - 0xd8, 0xaf, 0x84, 0xf0, 0xea, 0xf8, 0xce, 0x3f, 0xf2, 0x8f, 0xe4, 0xfa, 0xbe, 0x0f, 0xdc, 0x6c, - 0xc8, 0x40, 0x11, 0xbf, 0x9b, 0x10, 0xaf, 0x22, 0xc4, 0xab, 0x08, 0x91, 0xcd, 0x92, 0xa5, 0x0a, - 0xa5, 0x57, 0x92, 0x59, 0x53, 0xdf, 0xad, 0x4a, 0xbd, 0x72, 0xee, 0xe6, 0xa0, 0x62, 0x59, 0x94, - 0x86, 0x45, 0xb1, 0xcc, 0xc3, 0x38, 0x4e, 0xb2, 0xc9, 0xc0, 0xad, 0x34, 0x7a, 0x08, 0xfb, 0x29, - 0x92, 0x28, 0x4c, 0x3b, 0xe0, 0x56, 0x26, 0xd9, 0x40, 0x29, 0xe4, 0x0e, 0x5c, 0x6d, 0x75, 0x25, - 0x45, 0x1e, 0x66, 0xcb, 0x38, 0x29, 0xf2, 0x34, 0x7c, 0x1c, 0x24, 0x99, 0x34, 0x8c, 0x71, 0x4a, - 0x1f, 0x86, 0x12, 0x59, 0x27, 0x11, 0x74, 0x56, 0x0c, 0x22, 0x50, 0x56, 0x50, 0x9a, 0x9a, 0xe8, - 0x6a, 0x86, 0x06, 0x3a, 0xd4, 0x26, 0x61, 0x96, 0xc4, 0x71, 0x4a, 0x57, 0xaf, 0x92, 0x6c, 0xcc, - 0x2a, 0xe4, 0x86, 0x31, 0x44, 0xef, 0xa2, 0x41, 0xbe, 0x8a, 0x72, 0xd3, 0x02, 0x6b, 0x76, 0xb4, - 0x61, 0xc4, 0x20, 0xa5, 0x7b, 0x1e, 0xe6, 0xda, 0x9a, 0x8e, 0x5c, 0x1c, 0xaf, 0x4c, 0x3e, 0x9c, - 0x0b, 0xb6, 0x72, 0x72, 0xe5, 0xff, 0x96, 0x75, 0xeb, 0x2d, 0x3b, 0xff, 0x43, 0x5b, 0x64, 0xb1, - 0x44, 0xde, 0x61, 0x6f, 0x6a, 0x40, 0x9b, 0xea, 0x54, 0x4d, 0x2b, 0x2e, 0x40, 0x88, 0xcb, 0x96, - 0x7d, 0xd7, 0x3c, 0x85, 0x04, 0xbc, 0x64, 0x79, 0xb9, 0xe6, 0x38, 0x51, 0x3e, 0x06, 0x56, 0xfa, - 0x8b, 0xb2, 0x68, 0xf1, 0x0e, 0xcb, 0x94, 0x2c, 0x7c, 0x92, 0xae, 0xac, 0x92, 0xfa, 0xae, 0xbd, - 0xdc, 0x42, 0x51, 0x5b, 0xbe, 0xff, 0x56, 0x0a, 0x95, 0x0e, 0x17, 0xef, 0x92, 0xc5, 0x56, 0x6d, - 0xd3, 0x6b, 0xa7, 0x74, 0xdc, 0x30, 0x66, 0xb9, 0x47, 0x14, 0x02, 0xd6, 0x67, 0x50, 0x53, 0xdb, - 0x29, 0x68, 0x16, 0x63, 0x6b, 0x19, 0xcd, 0x79, 0x01, 0x94, 0xe4, 0x2c, 0x41, 0xba, 0x56, 0x18, - 0x41, 0x64, 0xe0, 0x20, 0xa3, 0xae, 0x0e, 0xd4, 0x18, 0x41, 0xe0, 0x27, 0x4e, 0x16, 0x24, 0x89, - 0x03, 0x03, 0x95, 0x03, 0x62, 0x24, 0x9a, 0x90, 0xfe, 0xd0, 0x83, 0x2f, 0xe4, 0xc4, 0xc0, 0x68, - 0xc8, 0xeb, 0x0f, 0x88, 0x98, 0xc9, 0xf8, 0xb1, 0x94, 0x8c, 0x66, 0x1f, 0xa7, 0x4c, 0xbd, 0xed, - 0x33, 0x36, 0x25, 0x8c, 0xd0, 0xc5, 0x62, 0x52, 0x81, 0x2b, 0x8e, 0xf6, 0x31, 0x2c, 0x95, 0x1e, - 0xb4, 0x57, 0x29, 0x69, 0x87, 0xcb, 0x1e, 0xe8, 0x30, 0xc8, 0x22, 0xa1, 0xf7, 0x3f, 0xb3, 0x07, - 0x08, 0xe4, 0xc4, 0x25, 0xfb, 0x3e, 0xfc, 0x19, 0x27, 0xa3, 0x3c, 0x14, 0x53, 0xf2, 0x62, 0x9c, - 0xa4, 0x69, 0x60, 0xbc, 0x72, 0xdd, 0x7d, 0xd8, 0x02, 0x03, 0x42, 0xa8, 0x71, 0xd1, 0x23, 0xbe, - 0x3f, 0x3d, 0x5a, 0x1c, 0x9c, 0xf5, 0xfe, 0xbc, 0xf0, 0x0e, 0x88, 0x77, 0x30, 0x3d, 0x58, 0x1c, - 0x4d, 0x3b, 0x07, 0xf0, 0x75, 0x04, 0xb1, 0xae, 0xfa, 0xf2, 0x7d, 0xd2, 0x43, 0xb8, 0x69, 0xe7, - 0xe8, 0x4f, 0xa3, 0x7b, 0x02, 0x02, 0x5b, 0x4c, 0x4e, 0x5e, 0x00, 0x89, 0x20, 0x4e, 0x29, 0x21, - 0x94, 0x9b, 0x71, 0xf2, 0x5c, 0xc2, 0x80, 0xa0, 0x52, 0xc2, 0x1e, 0xfe, 0x0b, 0xc2, 0x2b, 0x45, - 0x88, 0xd3, 0xdb, 0x11, 0xd4, 0xa8, 0x09, 0xbf, 0x1e, 0xef, 0x80, 0x17, 0x3d, 0xb5, 0x8e, 0xe1, - 0xfb, 0x36, 0xa1, 0xc4, 0x5b, 0x5a, 0x21, 0x26, 0x4b, 0x6a, 0x67, 0xeb, 0x76, 0xd9, 0x82, 0x04, - 0x33, 0xac, 0x14, 0x40, 0x7f, 0x02, 0xff, 0xa7, 0x73, 0x8e, 0x74, 0xa7, 0x8f, 0x24, 0xc9, 0xc8, - 0xbc, 0xa0, 0x24, 0x52, 0xbc, 0x97, 0x88, 0x48, 0x8b, 0xda, 0xbf, 0x4e, 0x34, 0xfa, 0x44, 0xb9, - 0x72, 0x0a, 0xa1, 0x84, 0x40, 0xb2, 0x24, 0xa6, 0x94, 0x94, 0x12, 0x22, 0x54, 0xca, 0x9a, 0x08, - 0x46, 0xc0, 0xcf, 0x93, 0x8c, 0xde, 0x13, 0x69, 0x73, 0xa4, 0x80, 0xf0, 0x04, 0x79, 0x00, 0x02, - 0xab, 0x19, 0xb2, 0x9b, 0xc6, 0x04, 0x44, 0x4a, 0xee, 0x68, 0xca, 0xee, 0x65, 0xaf, 0x02, 0xc3, - 0xe9, 0xd1, 0x34, 0xcc, 0x26, 0x94, 0x24, 0xa2, 0x50, 0xa0, 0x8e, 0x5e, 0x10, 0xa1, 0x9a, 0xf3, - 0x20, 0x1c, 0x81, 0xeb, 0xc6, 0x55, 0xcd, 0x30, 0x8b, 0x31, 0x8f, 0x1c, 0x27, 0x7c, 0x66, 0x21, - 0x12, 0x15, 0x7d, 0x1d, 0xf2, 0x31, 0x8b, 0x28, 0x19, 0x27, 0x59, 0x52, 0x4c, 0x69, 0x6c, 0x83, - 0x14, 0x4b, 0x4c, 0x21, 0xe7, 0x88, 0x21, 0x42, 0x36, 0x18, 0x99, 0xe7, 0x29, 0x0b, 0x63, 0x40, - 0x08, 0x6d, 0x1c, 0x8d, 0x69, 0x91, 0xe0, 0x5a, 0x45, 0xca, 0x84, 0x43, 0x2e, 0x99, 0xe4, 0x8e, - 0xd0, 0x87, 0x04, 0x64, 0x94, 0x4d, 0x4a, 0x19, 0xd7, 0xf1, 0xe5, 0x34, 0x8b, 0x92, 0x54, 0x22, - 0x74, 0xc8, 0x8b, 0x2d, 0x42, 0xff, 0x7e, 0x99, 0x4b, 0xed, 0x2c, 0x04, 0x38, 0xa5, 0xe8, 0x53, - 0xa5, 0x2f, 0x5f, 0x51, 0x17, 0x04, 0xdf, 0xa9, 0x32, 0x6f, 0x17, 0x61, 0x92, 0x86, 0x77, 0x29, - 0x48, 0x5b, 0x62, 0xfd, 0x9a, 0xae, 0xc8, 0x9f, 0x51, 0x57, 0x3b, 0x24, 0x9d, 0x6d, 0xbf, 0xd8, - 0x95, 0x6e, 0x63, 0x6a, 0x5c, 0x6a, 0x03, 0x7a, 0x01, 0xcc, 0xba, 0x9b, 0x06, 0x64, 0xd9, 0x11, - 0xac, 0x18, 0x05, 0x1d, 0xcf, 0xce, 0x1f, 0x4e, 0x59, 0x1a, 0x2c, 0x57, 0xb6, 0xd0, 0xbf, 0x9c, - 0x46, 0x22, 0xa8, 0x4d, 0xc7, 0x24, 0xfd, 0x67, 0xcc, 0x01, 0x40, 0xde, 0xb0, 0xff, 0xd0, 0xf9, - 0x0f, 0x80, 0x30, 0x2d, 0xbb, 0x84, 0x39, 0xa7, 0xd9, 0x44, 0x4c, 0x03, 0x9c, 0xe7, 0x48, 0x0f, - 0x65, 0xcf, 0x3e, 0x8e, 0xc7, 0x45, 0x70, 0x01, 0xfe, 0xc6, 0x91, 0xd9, 0x83, 0xd9, 0x04, 0xed, - 0xfa, 0x87, 0xbd, 0xae, 0x6f, 0x75, 0x0e, 0x6d, 0xcd, 0xf6, 0x5b, 0xce, 0xc3, 0xc7, 0xe0, 0xfa, - 0xc6, 0x06, 0x87, 0xf2, 0x39, 0x5c, 0xd0, 0xe0, 0x8d, 0x74, 0x7b, 0x0d, 0xaf, 0xe7, 0x1f, 0xae, - 0xbd, 0x1e, 0xb6, 0x5b, 0x4e, 0xce, 0x3f, 0x80, 0xbf, 0xd2, 0xc9, 0x49, 0x1f, 0x87, 0x21, 0x46, - 0xba, 0x37, 0xdf, 0xb7, 0x3d, 0xff, 0xad, 0xe7, 0xda, 0x1e, 0x02, 0xc2, 0x0f, 0xf1, 0x7c, 0xdb, - 0x6f, 0xf6, 0x6c, 0x05, 0x69, 0x42, 0x20, 0xc8, 0x45, 0x1f, 0xfe, 0x39, 0x87, 0x31, 0xaf, 0x7f, - 0xe5, 0x1d, 0x9c, 0x79, 0xbd, 0x2b, 0xcf, 0x3d, 0xf3, 0xfc, 0xab, 0xfe, 0x39, 0x0e, 0xfc, 0x77, - 0xe5, 0x14, 0xdf, 0x20, 0x27, 0xe8, 0xf3, 0xfe, 0xbd, 0x9c, 0x20, 0x51, 0xa7, 0x3d, 0xe7, 0xa0, - 0x6f, 0xfb, 0x40, 0x31, 0x36, 0x24, 0xe1, 0xa7, 0x48, 0x8f, 0x73, 0xb8, 0x4f, 0xd4, 0x90, 0xaf, - 0xf8, 0x3b, 0x95, 0x7d, 0xf8, 0xe9, 0x97, 0xe3, 0xbe, 0x82, 0xd6, 0x53, 0xf5, 0xb8, 0x84, 0xbe, - 0xf0, 0x0e, 0x1d, 0xcf, 0xee, 0x3b, 0x6e, 0xff, 0x14, 0x5a, 0xfe, 0x81, 0x6c, 0x12, 0x68, 0xee, - 0x1f, 0x41, 0xd3, 0xf3, 0xb1, 0x79, 0x08, 0x2d, 0x7f, 0xff, 0xdc, 0xeb, 0x39, 0xfd, 0xbe, 0x7d, - 0xe4, 0x1c, 0xc2, 0x02, 0xf0, 0xd3, 0x87, 0xb1, 0xbe, 0x7d, 0x2c, 0xc1, 0xe5, 0xc8, 0xb1, 0xe3, - 0x1f, 0x9d, 0x03, 0x38, 0x34, 0x3d, 0x57, 0xb6, 0xf7, 0x01, 0x08, 0x20, 0x71, 0xee, 0x01, 0x36, - 0x11, 0xcd, 0x29, 0x34, 0x8f, 0x7c, 0x8d, 0xfb, 0xc0, 0x39, 0xee, 0x55, 0x2b, 0x2a, 0x32, 0x2e, - 0x60, 0x96, 0xb7, 0x0f, 0xb3, 0x8e, 0x3c, 0x44, 0xe6, 0x1d, 0x23, 0xb2, 0xa3, 0xfe, 0xf9, 0x31, - 0xf6, 0xc2, 0x42, 0xc7, 0xfb, 0x67, 0x08, 0x76, 0x85, 0x68, 0xfa, 0xe7, 0x6b, 0xe0, 0xda, 0x1e, - 0x0c, 0xab, 0xb3, 0x24, 0xa8, 0xe6, 0xc7, 0xb1, 0x89, 0xa7, 0xc9, 0xff, 0x37, 0xd5, 0xae, 0x1d, - 0x64, 0xd3, 0xe4, 0xcb, 0xc7, 0xac, 0x4c, 0xad, 0xd4, 0xa1, 0x76, 0xc6, 0x16, 0xf4, 0x92, 0x87, - 0xc5, 0x34, 0x0a, 0x33, 0xe8, 0xb1, 0xc1, 0x51, 0x9f, 0x9a, 0x35, 0xa4, 0xd4, 0x61, 0xb0, 0x0c, - 0x15, 0xbf, 0x75, 0x9b, 0xe8, 0x7f, 0x04, 0xf4, 0x56, 0xed, 0x90, 0x2c, 0xe7, 0x51, 0x1b, 0x4e, - 0xec, 0x86, 0xb5, 0x04, 0x53, 0x22, 0x1c, 0x4d, 0x9a, 0x05, 0x2f, 0x3d, 0xc8, 0xb3, 0xb2, 0x42, - 0x90, 0xb0, 0xc1, 0xee, 0xbf, 0xe6, 0x94, 0x3f, 0x7e, 0x06, 0x87, 0x1c, 0x81, 0xab, 0x7e, 0x9b, - 0xa6, 0xa6, 0xd1, 0x38, 0x96, 0x19, 0xd6, 0x30, 0x19, 0x9b, 0xa1, 0x03, 0x47, 0xaf, 0xf7, 0x61, - 0x34, 0x35, 0x4d, 0x61, 0x73, 0x2b, 0x38, 0x59, 0x0a, 0x94, 0xd3, 0x5b, 0x21, 0x78, 0x02, 0x19, - 0x18, 0x35, 0x8d, 0x38, 0x14, 0x61, 0x47, 0xf0, 0x39, 0x85, 0x8c, 0xcd, 0xb0, 0x82, 0x80, 0xbe, - 0x7e, 0x6d, 0xc2, 0x9a, 0xae, 0xb5, 0x02, 0x4e, 0x9c, 0x54, 0x52, 0x7a, 0xe2, 0xf5, 0xcb, 0x5e, - 0x9b, 0x59, 0xea, 0x18, 0x8f, 0xd8, 0xe9, 0x89, 0xfb, 0xfa, 0x35, 0x1d, 0xf9, 0x87, 0x87, 0x16, - 0x2c, 0x63, 0xa2, 0xab, 0xca, 0x02, 0x6f, 0x98, 0x8d, 0x02, 0xaf, 0xf7, 0xfa, 0x35, 0x1f, 0x41, - 0x73, 0x6f, 0xcf, 0x92, 0x1e, 0x4b, 0x92, 0x76, 0xa1, 0x28, 0xdb, 0xcb, 0xac, 0xa7, 0x27, 0x93, - 0x07, 0x99, 0x35, 0xa4, 0x29, 0x84, 0x58, 0x1e, 0xd0, 0xa1, 0x61, 0x04, 0x81, 0x80, 0x45, 0x80, - 0xfb, 0x57, 0xc6, 0x9e, 0xe9, 0xf5, 0xfa, 0xfd, 0xbe, 0xef, 0x1d, 0xfe, 0xa8, 0xe4, 0x08, 0x71, - 0x88, 0xcd, 0x4c, 0x6b, 0x34, 0x72, 0x2d, 0x47, 0xb0, 0xcf, 0x40, 0x7c, 0x36, 0x01, 0x18, 0x0b, - 0xf2, 0xdc, 0xf8, 0xb3, 0x08, 0xb9, 0x30, 0x7b, 0xb6, 0xe1, 0x1a, 0x96, 0xa5, 0x25, 0x95, 0x06, - 0xd1, 0x7b, 0xd3, 0xc0, 0xfc, 0x04, 0xc4, 0x90, 0x3a, 0xd2, 0x65, 0xff, 0x12, 0xce, 0xc0, 0x6a, - 0x1b, 0x22, 0xb2, 0x53, 0x07, 0xbd, 0x7b, 0x83, 0x36, 0xbe, 0x5e, 0xc0, 0x82, 0xf1, 0x62, 0xb7, - 0xb0, 0x6c, 0xfa, 0x0c, 0x00, 0xe0, 0x34, 0x6c, 0xb1, 0x03, 0x40, 0xe9, 0x83, 0xa1, 0xf4, 0x0f, - 0x61, 0x60, 0xeb, 0xdf, 0x2f, 0x50, 0x31, 0x20, 0x12, 0x52, 0x48, 0x96, 0x40, 0x5e, 0x18, 0x02, - 0x0d, 0x1b, 0x72, 0x8f, 0xfc, 0xef, 0x73, 0x0e, 0xa1, 0x90, 0x7f, 0xe2, 0x2c, 0x97, 0xf8, 0xd0, - 0xfd, 0x38, 0x98, 0x18, 0x3f, 0xaf, 0xb9, 0x3f, 0x52, 0x6b, 0x4f, 0x2e, 0xb0, 0x67, 0x80, 0x5b, - 0xd2, 0x82, 0x49, 0xa4, 0x60, 0x92, 0x2c, 0x9f, 0x0b, 0x54, 0x10, 0x47, 0x45, 0x1d, 0x29, 0x00, - 0xc3, 0x4e, 0x9c, 0x45, 0x98, 0xce, 0x69, 0x20, 0xa0, 0xb5, 0x21, 0x32, 0x75, 0xd0, 0x45, 0xa0, - 0x4a, 0x64, 0x9f, 0x54, 0x57, 0x53, 0x64, 0xc9, 0x16, 0x66, 0xd4, 0x7a, 0xf6, 0x3c, 0xc7, 0x22, - 0x57, 0x69, 0x3c, 0xdb, 0x41, 0x35, 0xdf, 0x51, 0x7e, 0x9a, 0x7e, 0x29, 0x77, 0xb3, 0xa8, 0xef, - 0x66, 0xb1, 0x8b, 0xb4, 0x6a, 0x53, 0x8b, 0x36, 0x85, 0x5b, 0xb7, 0xb6, 0x78, 0x66, 0x71, 0x96, - 0xe2, 0xea, 0x00, 0x52, 0x93, 0x75, 0x5d, 0xf0, 0x40, 0xf9, 0x8e, 0x11, 0x4d, 0x71, 0x5c, 0xa7, - 0x98, 0xa3, 0x95, 0x70, 0xb4, 0x12, 0xd0, 0xef, 0xb8, 0x4e, 0x7e, 0xa3, 0x98, 0x61, 0xd8, 0xb1, - 0x24, 0x5c, 0x75, 0x6e, 0xa5, 0x39, 0xde, 0x4d, 0x33, 0x05, 0xd3, 0x56, 0x33, 0x4f, 0x91, 0x71, - 0x2c, 0xaa, 0x21, 0xfc, 0x0e, 0x32, 0xd7, 0x7a, 0xb4, 0xae, 0x0a, 0xc8, 0x79, 0x81, 0xd6, 0x81, - 0x8a, 0xf7, 0x5d, 0xe3, 0x75, 0x4f, 0x14, 0xe6, 0x90, 0xa6, 0xc5, 0xa7, 0xd3, 0x24, 0x8d, 0xcd, - 0xc4, 0xda, 0x39, 0x94, 0xee, 0x1e, 0x02, 0x23, 0x70, 0x5f, 0x06, 0xfc, 0xf5, 0x6b, 0x10, 0x92, - 0xfc, 0xdd, 0x05, 0x18, 0x5b, 0x76, 0x5d, 0x9c, 0xb3, 0xf0, 0x0b, 0xbd, 0xa0, 0xef, 0x78, 0x38, - 0x31, 0xd1, 0xcb, 0xa0, 0x39, 0x5b, 0xb0, 0x6f, 0x54, 0x5c, 0x32, 0x96, 0x8a, 0x24, 0x57, 0x52, - 0xac, 0x8f, 0x35, 0x75, 0xd0, 0xac, 0xb9, 0xdf, 0xf6, 0xc8, 0x52, 0x6d, 0x25, 0xfd, 0x4e, 0xa7, - 0xbb, 0x91, 0x82, 0xd1, 0x0d, 0x17, 0xac, 0x10, 0x33, 0x99, 0xca, 0xd1, 0x6b, 0x7e, 0x03, 0x94, - 0x39, 0x9c, 0x42, 0xfe, 0x1a, 0xd1, 0xa6, 0xa3, 0xb4, 0x1b, 0x76, 0x66, 0x59, 0x4a, 0xf6, 0xc3, - 0xef, 0x9b, 0xa7, 0xfb, 0x60, 0xf6, 0xf6, 0x1d, 0x65, 0xb6, 0xc4, 0xf5, 0xfc, 0xe0, 0x33, 0x4e, - 0x8e, 0x59, 0x55, 0x78, 0x92, 0xb0, 0xcf, 0x85, 0x17, 0x3b, 0xfb, 0x8a, 0xcf, 0x0a, 0xb5, 0x00, - 0xaf, 0xb3, 0x1b, 0x58, 0x1b, 0x45, 0x78, 0x1d, 0x42, 0x6b, 0xb5, 0x56, 0x1d, 0x65, 0x0c, 0x81, - 0x81, 0xa5, 0x82, 0x90, 0x77, 0xca, 0x6e, 0x13, 0x8e, 0x18, 0xf2, 0xcc, 0x6c, 0xd8, 0x1f, 0xef, - 0xfe, 0xc0, 0x10, 0x0f, 0x9d, 0x3c, 0xa1, 0x85, 0x29, 0xf1, 0x59, 0xeb, 0x4d, 0xb8, 0x86, 0x10, - 0x7b, 0x83, 0xdb, 0xd0, 0xc4, 0xb8, 0x17, 0xdc, 0xda, 0xe4, 0x87, 0xa5, 0x58, 0xc1, 0x3f, 0x74, - 0x95, 0x3f, 0xdc, 0x6e, 0xac, 0xb9, 0x17, 0x18, 0x96, 0xd1, 0x50, 0xe1, 0xb6, 0xcc, 0x82, 0xe6, - 0x84, 0xb5, 0x6e, 0xb5, 0xdc, 0x38, 0xe6, 0x0d, 0xd4, 0xc1, 0x4e, 0xfc, 0x0a, 0x27, 0x21, 0x02, - 0xd5, 0x75, 0x51, 0x79, 0xa0, 0xed, 0xe9, 0xc5, 0x96, 0x89, 0xb6, 0xd4, 0x08, 0xa7, 0xe0, 0x91, - 0xae, 0xa9, 0x37, 0x34, 0xa3, 0x52, 0x0a, 0xd4, 0x01, 0xe9, 0x2e, 0x1a, 0x4b, 0xe5, 0x3b, 0x56, - 0x5a, 0x48, 0x1f, 0xfd, 0x2c, 0x99, 0x35, 0xf3, 0x03, 0x04, 0x18, 0xfe, 0x45, 0xe0, 0xda, 0xfc, - 0x9b, 0xb2, 0x32, 0x16, 0x70, 0x47, 0x6e, 0x98, 0x1d, 0x42, 0x4b, 0x7a, 0xd5, 0x2c, 0x60, 0x9d, - 0x70, 0xcf, 0x5b, 0xa7, 0x7a, 0xa9, 0xc9, 0xad, 0x25, 0x24, 0x0a, 0xfc, 0xe9, 0xe9, 0x1e, 0x4e, - 0xa5, 0xec, 0xde, 0x51, 0x54, 0x39, 0x39, 0x97, 0x8d, 0x77, 0x74, 0x1c, 0xce, 0x53, 0xc4, 0x26, - 0x3a, 0x1c, 0x59, 0x83, 0xbe, 0xdf, 0x20, 0x81, 0x5a, 0xb7, 0x67, 0x0c, 0xce, 0xf0, 0x9f, 0x58, - 0xf1, 0xa1, 0xca, 0xd9, 0x02, 0xd1, 0x31, 0x61, 0x11, 0x98, 0x02, 0x4a, 0x09, 0x23, 0x75, 0x85, - 0xdc, 0x84, 0xee, 0x66, 0x32, 0x4b, 0xb3, 0x59, 0x1a, 0x5f, 0x6a, 0x78, 0xfa, 0xbc, 0x86, 0x6b, - 0xb4, 0xe8, 0xa4, 0x74, 0x53, 0xb9, 0xaa, 0x35, 0x86, 0x97, 0x81, 0x1e, 0xc0, 0x74, 0x47, 0x83, - 0xf4, 0x0e, 0x7e, 0x12, 0xd3, 0xa4, 0xf8, 0x28, 0x13, 0x83, 0xc0, 0x1d, 0x94, 0x58, 0xbc, 0x63, - 0xbf, 0x3e, 0xd0, 0x1f, 0xd4, 0x3e, 0xf6, 0xe5, 0xe6, 0x6c, 0x4b, 0x06, 0x32, 0x69, 0x4b, 0x1a, - 0x47, 0x3d, 0x0b, 0xd0, 0x8a, 0xf2, 0x7f, 0xf2, 0x1b, 0x72, 0x91, 0xfa, 0x8a, 0x5f, 0x45, 0xd6, - 0x88, 0x64, 0x7f, 0x01, 0x4f, 0xcb, 0x09, 0xee, 0x42, 0x43, 0x9f, 0x4d, 0xd6, 0x4a, 0x69, 0x6c, - 0x46, 0x07, 0xba, 0x19, 0x15, 0x6a, 0x3a, 0x9e, 0x40, 0x24, 0x88, 0x1d, 0x96, 0x49, 0xdd, 0x98, - 0xe7, 0x41, 0x36, 0x4f, 0x53, 0xbb, 0xea, 0x40, 0x93, 0x91, 0x5d, 0x2b, 0x5a, 0x76, 0x81, 0x9a, - 0x66, 0x41, 0x39, 0x7d, 0xb7, 0x61, 0x99, 0x34, 0xa0, 0x5f, 0x57, 0x6b, 0xe0, 0xb0, 0x54, 0xe5, - 0x3a, 0x11, 0x49, 0x8b, 0x82, 0x74, 0x55, 0xf3, 0x35, 0x9b, 0xfc, 0x2d, 0xdb, 0xa2, 0x91, 0x57, - 0x7d, 0x86, 0x7d, 0x0b, 0xae, 0xee, 0x59, 0x6d, 0x5e, 0x91, 0x01, 0x79, 0x06, 0x06, 0xfd, 0xbf, - 0xb5, 0xba, 0xad, 0x49, 0xab, 0x99, 0x82, 0x68, 0x97, 0x80, 0xb9, 0x50, 0x9c, 0x2c, 0x20, 0x38, - 0xa2, 0xf6, 0xbe, 0xab, 0x69, 0x45, 0x50, 0x77, 0x5a, 0x36, 0x8e, 0x9e, 0xae, 0x77, 0x5e, 0xc6, - 0xc7, 0xf6, 0x8c, 0x86, 0x9a, 0xa8, 0xd5, 0x4a, 0x0d, 0x01, 0xdd, 0x58, 0xa3, 0xa8, 0xeb, 0xf0, - 0xf7, 0x22, 0xaa, 0x54, 0xad, 0x8d, 0xee, 0x5b, 0x11, 0xed, 0xd0, 0x5c, 0x9b, 0x43, 0x1e, 0x43, - 0xb9, 0x32, 0xdf, 0xdf, 0x02, 0xcf, 0xd5, 0x1d, 0xbf, 0x35, 0xc4, 0xb0, 0xcb, 0x63, 0x3a, 0x0f, - 0x9d, 0xc6, 0x7c, 0x3d, 0xf9, 0xf7, 0x6f, 0x9b, 0xfc, 0xb8, 0x07, 0x67, 0x6a, 0x21, 0x13, 0x4c, - 0x81, 0x9a, 0x68, 0xe0, 0x47, 0x06, 0x19, 0xe4, 0xd9, 0xe5, 0xc5, 0xb9, 0x2e, 0x6c, 0x6c, 0xa9, - 0x5c, 0x90, 0x87, 0x59, 0x9a, 0x15, 0x81, 0x81, 0x37, 0xcc, 0x83, 0x6e, 0xf7, 0xfe, 0xfe, 0xde, - 0xb9, 0xdf, 0x77, 0x18, 0x9f, 0x74, 0x7d, 0xd7, 0x75, 0xf1, 0x68, 0x6e, 0x10, 0x79, 0x96, 0x0e, - 0x0c, 0xbc, 0xff, 0x33, 0x88, 0x2a, 0x85, 0xe8, 0x2f, 0x5d, 0xf7, 0xd0, 0x05, 0x13, 0x2c, 0x7f, - 0x0c, 0x5e, 0x1d, 0x1d, 0xc1, 0x44, 0x77, 0x08, 0x9d, 0x9c, 0x7d, 0xa1, 0x03, 0x02, 0x1d, 0xf8, - 0x5f, 0xd9, 0xd1, 0x51, 0x65, 0x15, 0xd2, 0xc1, 0x4b, 0x04, 0xdd, 0x15, 0x03, 0xbd, 0x21, 0x56, - 0x95, 0x06, 0xc4, 0x75, 0x3c, 0x9b, 0x1c, 0x0d, 0x55, 0xa9, 0xfb, 0xd8, 0xde, 0xbf, 0x3a, 0x38, - 0x3b, 0xb8, 0xea, 0x9d, 0x1d, 0x5e, 0x79, 0xc7, 0x6f, 0x7d, 0xdb, 0x97, 0xe5, 0x1d, 0x97, 0xf4, - 0x6d, 0xdf, 0x3b, 0xf3, 0xfa, 0xb5, 0x1e, 0x2c, 0x39, 0x1c, 0x03, 0xa0, 0xef, 0xc2, 0x0c, 0xef, - 0xf0, 0x6a, 0xff, 0xec, 0xf8, 0xa2, 0x6f, 0xf7, 0xce, 0xb0, 0xf4, 0x73, 0x7c, 0xd6, 0xbf, 0xea, - 0x01, 0xb2, 0xa3, 0x2b, 0xaf, 0x7f, 0xe6, 0x79, 0x57, 0x47, 0x30, 0x86, 0x05, 0x08, 0xf9, 0x79, - 0x08, 0x9f, 0xde, 0x7e, 0xbd, 0x18, 0x24, 0xb4, 0xcf, 0x29, 0x6f, 0x38, 0x02, 0xa3, 0xbc, 0xf3, - 0x33, 0xaa, 0x31, 0xe9, 0x9c, 0xf4, 0xe6, 0x2a, 0xc7, 0x5b, 0x8e, 0x40, 0x30, 0xd5, 0x03, 0xbf, - 0xab, 0x81, 0xd8, 0xc1, 0x42, 0x60, 0x23, 0xc9, 0x05, 0xef, 0x20, 0x9e, 0xcf, 0xf4, 0x85, 0xa3, - 0xca, 0xeb, 0xbf, 0xb0, 0x98, 0x3a, 0xca, 0xbf, 0xac, 0xa7, 0xb6, 0xf5, 0x73, 0x17, 0x68, 0x0b, - 0x6e, 0x87, 0xf1, 0x3c, 0x37, 0x7d, 0x03, 0xd8, 0x6a, 0xdb, 0xf0, 0x57, 0x67, 0xef, 0x58, 0xfb, - 0x1b, 0x57, 0xdd, 0x92, 0xcf, 0x6f, 0x4f, 0x90, 0x9e, 0x39, 0x39, 0x35, 0xdd, 0xf3, 0x57, 0x32, - 0x9e, 0x8d, 0x74, 0x6c, 0x29, 0xad, 0x49, 0x55, 0x65, 0x95, 0x61, 0x21, 0x06, 0x11, 0x72, 0x30, - 0x44, 0x0c, 0xf4, 0xd0, 0x83, 0x89, 0x80, 0xfc, 0x31, 0xe5, 0xef, 0x4e, 0xd6, 0x70, 0x10, 0x29, - 0x55, 0x9d, 0xdf, 0x44, 0x6c, 0x3d, 0x8f, 0x9b, 0x7e, 0xf9, 0xb5, 0x7e, 0x68, 0x41, 0x82, 0xe4, - 0xbd, 0x16, 0x46, 0x11, 0xf9, 0x25, 0x2f, 0x74, 0xac, 0x61, 0x59, 0x8e, 0xfa, 0x15, 0x0d, 0x6d, - 0xd4, 0x73, 0xdd, 0x9f, 0x4a, 0xdd, 0xd4, 0x45, 0x74, 0x7c, 0x60, 0x92, 0x51, 0x63, 0xb0, 0xd1, - 0xad, 0xee, 0xe7, 0x8c, 0xda, 0x9a, 0x61, 0x1a, 0xfd, 0xe7, 0xe7, 0x8f, 0xbf, 0x98, 0xaa, 0x5e, - 0x45, 0x83, 0x37, 0xcb, 0xb2, 0x84, 0x6e, 0x0c, 0xae, 0xdf, 0x0c, 0xf5, 0x83, 0x8f, 0x56, 0x42, - 0x2e, 0x5a, 0xf9, 0x38, 0x9c, 0x8a, 0x64, 0x3e, 0x2e, 0x30, 0x67, 0x32, 0x29, 0xa4, 0xd9, 0x36, - 0x0a, 0x11, 0x12, 0x72, 0x4c, 0xc7, 0x6d, 0xe3, 0x87, 0x25, 0x77, 0x0a, 0x60, 0x9f, 0x9a, 0x9e, - 0xb5, 0x32, 0x30, 0x2f, 0x47, 0x98, 0x9b, 0x15, 0x98, 0x42, 0x2d, 0x4c, 0x67, 0x60, 0x8c, 0xa0, - 0x09, 0xff, 0x25, 0xaf, 0x1c, 0x70, 0x63, 0xd4, 0xe5, 0x83, 0x24, 0x6f, 0x4d, 0xa7, 0x7d, 0xdb, - 0xd5, 0x04, 0x62, 0x96, 0xef, 0xfc, 0x51, 0xb0, 0xec, 0xb6, 0x71, 0x06, 0xac, 0xe6, 0xc0, 0x29, - 0x41, 0xc5, 0x2f, 0x1e, 0xe0, 0xad, 0xcb, 0x6f, 0x17, 0xe7, 0x67, 0xe0, 0x03, 0xff, 0x41, 0xe1, - 0x04, 0x58, 0x08, 0xc8, 0x5e, 0xb1, 0xf3, 0xe7, 0x94, 0xdd, 0xc1, 0x79, 0xe2, 0xc6, 0x5e, 0x62, - 0x1d, 0x65, 0x60, 0x80, 0x11, 0xa7, 0x78, 0x75, 0x02, 0xa8, 0xba, 0x88, 0xda, 0x58, 0xc1, 0xe9, - 0x7f, 0x8b, 0xe6, 0xe1, 0x22, 0x86, 0x6d, 0x96, 0x67, 0x41, 0x86, 0x1e, 0x83, 0x4d, 0xa4, 0x72, - 0xc3, 0xee, 0x17, 0x39, 0xf4, 0xd1, 0x4b, 0xfa, 0x20, 0x6c, 0x83, 0x74, 0x88, 0x21, 0x6d, 0xc3, - 0xc1, 0xbb, 0x85, 0x39, 0x16, 0x8b, 0x18, 0x70, 0xf3, 0x19, 0x4e, 0x9f, 0xe1, 0xa4, 0xd4, 0x9f, - 0x0f, 0x82, 0xce, 0x60, 0xb3, 0x53, 0x1a, 0x7f, 0x0a, 0x53, 0xbc, 0x0f, 0xd0, 0x59, 0x05, 0x82, - 0x22, 0x2d, 0xce, 0x94, 0xd3, 0x71, 0x60, 0x74, 0x81, 0x1c, 0x7b, 0x1b, 0x39, 0x94, 0x73, 0x2c, - 0xff, 0xd0, 0x16, 0x39, 0xc6, 0x7b, 0xec, 0x1f, 0x10, 0x59, 0xe8, 0x6a, 0x0c, 0x90, 0xcf, 0x92, - 0x98, 0x41, 0x9b, 0x36, 0x4c, 0x3d, 0x92, 0x19, 0x65, 0x73, 0x61, 0x4a, 0xe6, 0x56, 0xb6, 0x47, - 0xf7, 0x2d, 0xb9, 0x2a, 0x03, 0xf7, 0x66, 0x1a, 0x9f, 0x3e, 0x7e, 0xbe, 0x84, 0xdd, 0xed, 0x2a, - 0x39, 0x83, 0x32, 0xa2, 0x80, 0x43, 0x29, 0xcb, 0xbf, 0x33, 0x3e, 0x7b, 0x07, 0x89, 0x45, 0xa9, - 0x34, 0xa1, 0x76, 0x89, 0x2a, 0xdd, 0x80, 0x63, 0x26, 0x56, 0xd3, 0xb8, 0xbc, 0xf1, 0x35, 0x43, - 0xcb, 0x7e, 0xe9, 0xad, 0xc2, 0xe2, 0x31, 0x8b, 0xc8, 0xfa, 0x39, 0x12, 0x15, 0x1f, 0xb2, 0x31, - 0x03, 0x5d, 0x4c, 0xc6, 0xe6, 0xb4, 0x10, 0xc1, 0x9a, 0x7d, 0x06, 0x3b, 0x06, 0x3d, 0x65, 0x35, - 0xd3, 0xb5, 0x04, 0x7f, 0xac, 0x2c, 0x25, 0xbc, 0x0f, 0x13, 0x41, 0xc6, 0x54, 0x80, 0x32, 0x96, - 0x71, 0xce, 0xd8, 0x03, 0xf0, 0x3d, 0x43, 0x6e, 0x62, 0x57, 0x5e, 0xd0, 0xa1, 0x15, 0x29, 0x48, - 0x2a, 0xb5, 0xc6, 0xb4, 0x86, 0x72, 0x4a, 0x79, 0x85, 0x64, 0x9a, 0xea, 0x12, 0x46, 0x38, 0xf2, - 0x17, 0x42, 0xb0, 0xb0, 0x3a, 0xa0, 0xaf, 0x40, 0x02, 0xe0, 0xa5, 0x56, 0x25, 0x59, 0x29, 0x6c, - 0x2c, 0xcf, 0xc8, 0xd2, 0x67, 0xb3, 0xd7, 0x00, 0x9b, 0xce, 0x98, 0x20, 0x49, 0x0c, 0xfb, 0x93, - 0x8c, 0x1f, 0x09, 0x52, 0x0e, 0x19, 0x56, 0x8b, 0xd3, 0xe6, 0xc2, 0x80, 0xbb, 0x7e, 0xf3, 0xa2, - 0x99, 0x0c, 0xdc, 0x21, 0x96, 0x64, 0xd1, 0x2c, 0xe1, 0x3c, 0x31, 0x14, 0xa3, 0x80, 0x0e, 0xc5, - 0xde, 0xde, 0xda, 0x41, 0xdc, 0x6a, 0x56, 0x7f, 0x58, 0x02, 0xab, 0xab, 0xb5, 0x55, 0x08, 0x6d, - 0x15, 0xc3, 0xb5, 0x8c, 0x44, 0x43, 0x46, 0xa0, 0x0c, 0x5c, 0x77, 0x88, 0x52, 0x14, 0x0d, 0x02, - 0xf2, 0x79, 0x31, 0x85, 0x83, 0x9b, 0x66, 0x5d, 0xb4, 0x59, 0xbf, 0x95, 0x6a, 0xa5, 0x90, 0xe1, - 0xad, 0x1f, 0x5a, 0x1b, 0x19, 0x73, 0x36, 0x93, 0x07, 0xef, 0x01, 0xb9, 0x85, 0x8d, 0x5e, 0xad, - 0xb6, 0xb0, 0x34, 0xf2, 0xc0, 0x3f, 0x6c, 0xae, 0x54, 0x72, 0x3f, 0xb8, 0x76, 0xed, 0x7e, 0xf9, - 0x07, 0x47, 0xae, 0xea, 0xe3, 0x66, 0x55, 0x56, 0x28, 0x44, 0x80, 0x8b, 0xa1, 0x03, 0x2e, 0xa8, - 0xd9, 0x30, 0x24, 0x54, 0x9e, 0x96, 0x15, 0xc9, 0xfa, 0x39, 0x50, 0x8f, 0x62, 0xd4, 0x42, 0xc3, - 0x3b, 0x61, 0x08, 0xbd, 0x52, 0xc3, 0xe8, 0x89, 0x7f, 0x70, 0x68, 0xe9, 0x9a, 0x1b, 0xf6, 0x82, - 0x1f, 0xc0, 0x65, 0x44, 0x92, 0xcd, 0xe9, 0x4a, 0x4d, 0xe0, 0x81, 0xee, 0xc7, 0x6d, 0xc0, 0xf2, - 0xf9, 0xb0, 0x8e, 0x8c, 0x8d, 0x09, 0x97, 0xa8, 0x5e, 0x2a, 0x6e, 0x92, 0x42, 0xfe, 0x82, 0x80, - 0x9f, 0x9e, 0x0e, 0x5e, 0x06, 0x01, 0xd5, 0x7c, 0x5b, 0x4b, 0x79, 0x07, 0x70, 0xc7, 0x69, 0xf8, - 0x65, 0xb5, 0x46, 0x20, 0x10, 0x01, 0xb5, 0x60, 0xbe, 0x91, 0xcd, 0x67, 0x77, 0x90, 0x61, 0x42, - 0xbc, 0x01, 0x37, 0x04, 0xbd, 0xe2, 0xe9, 0x49, 0x8c, 0x5c, 0xf8, 0xe7, 0x04, 0xe4, 0xf0, 0xf4, - 0xf4, 0xf2, 0x17, 0x39, 0x0e, 0x0b, 0x7c, 0xc8, 0x04, 0x9d, 0x80, 0xc9, 0x0b, 0xab, 0x81, 0x74, - 0x85, 0x44, 0xb0, 0xaf, 0x30, 0x03, 0xc7, 0xf4, 0x6b, 0xae, 0x49, 0xea, 0x78, 0x37, 0x28, 0x1d, - 0x59, 0xad, 0x0b, 0xc2, 0x6b, 0xf7, 0x66, 0xad, 0x57, 0xd7, 0x8e, 0xe3, 0x84, 0x37, 0x43, 0x0a, - 0x9d, 0x01, 0xee, 0x02, 0x57, 0xbb, 0x04, 0x0a, 0xbf, 0x2a, 0x41, 0xda, 0xf1, 0x00, 0x24, 0xea, - 0xcc, 0xc2, 0x7c, 0x5d, 0x9a, 0x31, 0x97, 0xb0, 0x3e, 0xc4, 0x9f, 0x71, 0x1a, 0xca, 0x90, 0xbe, - 0x4d, 0xc1, 0x60, 0x99, 0xd2, 0x88, 0x60, 0x8c, 0x0b, 0xd3, 0xb8, 0xc4, 0x5b, 0x70, 0x7c, 0x17, - 0x89, 0x82, 0xa9, 0xee, 0x60, 0x21, 0xd8, 0x92, 0x59, 0x52, 0x14, 0xc9, 0x44, 0x29, 0xd9, 0x23, - 0x9b, 0x73, 0x72, 0xc7, 0xd9, 0x7d, 0x01, 0x12, 0x21, 0xbf, 0xb3, 0x39, 0x29, 0xa6, 0x6c, 0x9e, - 0xc6, 0x24, 0xe7, 0xec, 0x2e, 0xbc, 0x4b, 0x1f, 0x89, 0x76, 0x40, 0xfa, 0xce, 0x7a, 0x16, 0xc2, - 0xa6, 0x43, 0x2a, 0x00, 0xcb, 0x64, 0x31, 0xc1, 0x8d, 0x04, 0xc5, 0x97, 0xd7, 0xda, 0x30, 0x21, - 0xa7, 0x1c, 0x26, 0x8c, 0xf1, 0x82, 0x1e, 0x2f, 0xab, 0xcb, 0x35, 0x15, 0x15, 0x58, 0x91, 0x02, - 0x69, 0x83, 0x8b, 0x85, 0xb8, 0x44, 0xee, 0x28, 0x80, 0x51, 0x8d, 0x1c, 0xf5, 0x7e, 0x4a, 0x39, - 0x75, 0xc0, 0x19, 0x5e, 0x20, 0x71, 0xf0, 0x2d, 0x27, 0xc5, 0x15, 0x92, 0x97, 0xe0, 0x1d, 0xcb, - 0xc9, 0xda, 0xd6, 0xdf, 0x25, 0x8b, 0xa2, 0x9e, 0x8c, 0x6c, 0x1d, 0xae, 0x36, 0x62, 0xe3, 0x41, - 0xe6, 0xfa, 0x79, 0x04, 0x3a, 0xb3, 0xcd, 0xe1, 0xd6, 0x9d, 0x38, 0x9a, 0xb9, 0x92, 0x37, 0xca, - 0x0d, 0x0e, 0xe8, 0x11, 0xa6, 0x29, 0x90, 0xba, 0x40, 0xec, 0x4e, 0x52, 0x81, 0x07, 0xcb, 0xe0, - 0x44, 0x1e, 0xdb, 0x67, 0xd2, 0xd0, 0xbb, 0xff, 0xd4, 0xf8, 0xff, 0x27, 0xfe, 0xa1, 0x0b, 0x5b, - 0xd6, 0xd2, 0x54, 0x6e, 0xb5, 0x33, 0xd5, 0xca, 0x41, 0x71, 0x70, 0x50, 0x7c, 0xb4, 0xc5, 0xe2, - 0x87, 0x7c, 0xed, 0xb1, 0x58, 0x50, 0x07, 0xb8, 0xe6, 0x37, 0x76, 0x18, 0xb4, 0x5f, 0x92, 0xea, - 0x53, 0x66, 0xe8, 0xd4, 0x1e, 0x83, 0x18, 0x7b, 0xdc, 0x0e, 0x55, 0xd1, 0x1d, 0x23, 0x1e, 0x86, - 0xbf, 0x4a, 0x12, 0x46, 0xe9, 0x18, 0xb2, 0x52, 0x27, 0xbf, 0xd0, 0xc7, 0xc2, 0x64, 0x16, 0x28, - 0x2f, 0x60, 0xc1, 0xc0, 0x03, 0x21, 0x0d, 0x2b, 0xbc, 0xf2, 0xf8, 0xa1, 0xbc, 0x47, 0x21, 0x6b, - 0x7b, 0xe0, 0x9d, 0x4d, 0x76, 0x9d, 0xdd, 0xac, 0x6f, 0x9c, 0x76, 0x10, 0x93, 0xd6, 0x89, 0x29, - 0xf3, 0x54, 0x20, 0xaa, 0xba, 0x90, 0xd9, 0x31, 0x4f, 0xdd, 0xb3, 0xac, 0x5f, 0x49, 0x21, 0x1f, - 0x49, 0x9b, 0x8f, 0xda, 0xf0, 0xfa, 0xb2, 0x64, 0x03, 0x61, 0x75, 0x73, 0x22, 0x9f, 0x32, 0xe8, - 0x27, 0x53, 0x88, 0xaf, 0x70, 0xf0, 0x15, 0x21, 0x24, 0x96, 0xeb, 0x7a, 0x05, 0x38, 0xa4, 0x66, - 0x26, 0x05, 0x8e, 0x1c, 0x2f, 0x03, 0xb6, 0x95, 0x0f, 0x8c, 0xcf, 0x14, 0xdf, 0x87, 0xa8, 0x17, - 0x33, 0xb5, 0x97, 0x2a, 0xf8, 0xbc, 0x83, 0x00, 0x7e, 0xbc, 0x41, 0x59, 0x9f, 0x31, 0xf5, 0x73, - 0x00, 0xbb, 0x68, 0x33, 0x51, 0x51, 0x54, 0xb2, 0x10, 0xed, 0x64, 0x21, 0x92, 0x2c, 0x94, 0xef, - 0xbf, 0x90, 0x85, 0x68, 0x1b, 0x0b, 0x48, 0x38, 0xe4, 0x13, 0x78, 0x67, 0x2f, 0xe9, 0x8f, 0x76, - 0x94, 0x3f, 0x4e, 0x59, 0xfe, 0xa8, 0xa8, 0x85, 0x1c, 0x73, 0x55, 0x9a, 0x1e, 0xb2, 0xa0, 0x98, - 0xb9, 0x85, 0xbc, 0xa7, 0xc9, 0x01, 0xa2, 0x84, 0xbe, 0x16, 0x07, 0x15, 0x41, 0x78, 0xaf, 0xb2, - 0x5d, 0xd5, 0xaa, 0x07, 0x85, 0xa8, 0x12, 0xa0, 0xf3, 0x79, 0x60, 0x18, 0x95, 0x01, 0x50, 0x30, - 0x00, 0x3a, 0x42, 0x75, 0x2a, 0x15, 0x1f, 0x32, 0x5c, 0xdf, 0xaa, 0xc2, 0x2f, 0x8e, 0xa0, 0x47, - 0x46, 0x5f, 0xaf, 0xd4, 0x0f, 0x6f, 0x4b, 0x95, 0xaf, 0x57, 0x63, 0x7b, 0xde, 0x8d, 0x95, 0x43, - 0xc6, 0xfc, 0xea, 0x87, 0x65, 0xd5, 0x81, 0x95, 0x6c, 0xd1, 0x05, 0x1f, 0xfc, 0xa3, 0xe7, 0xba, - 0xab, 0xbf, 0xd9, 0xe4, 0x56, 0x5e, 0xb7, 0x2e, 0x11, 0x4e, 0xbe, 0xee, 0xad, 0xc3, 0x62, 0xed, - 0x5b, 0x7f, 0xf9, 0x8d, 0xaf, 0x7d, 0xfc, 0xf2, 0xac, 0x0d, 0x5c, 0x98, 0x84, 0xfb, 0x10, 0xa7, - 0x83, 0x5c, 0x27, 0xe7, 0xae, 0xdd, 0xf1, 0xb7, 0xdd, 0x2b, 0x7d, 0x98, 0x81, 0xf3, 0x0c, 0x6e, - 0x77, 0xd5, 0xeb, 0x71, 0xa9, 0x7c, 0x65, 0xdd, 0x96, 0x46, 0xaa, 0x6e, 0xc6, 0x36, 0xde, 0x2f, - 0x82, 0xb6, 0x95, 0x46, 0x1b, 0x04, 0xd9, 0x4f, 0x49, 0xeb, 0xfa, 0x68, 0x10, 0xe9, 0x75, 0xd5, - 0xf3, 0xb9, 0x73, 0x3c, 0x7f, 0x1b, 0xf2, 0x3d, 0x86, 0xcd, 0x5f, 0x06, 0x32, 0x25, 0x7b, 0xfd, - 0xba, 0x39, 0x29, 0xc2, 0xfb, 0xed, 0xd6, 0xfd, 0x54, 0xd8, 0xbe, 0xcb, 0x6a, 0x2c, 0x4a, 0x1b, - 0xa3, 0xa1, 0x05, 0x11, 0xaa, 0xd9, 0x51, 0xab, 0xc2, 0xd5, 0x55, 0x90, 0x62, 0x05, 0x71, 0xe3, - 0xe6, 0xe8, 0x8d, 0xbc, 0x15, 0xbd, 0x4e, 0xe2, 0x7f, 0x36, 0xaf, 0x53, 0x6f, 0xde, 0xac, 0x0f, - 0x47, 0x98, 0x92, 0xd3, 0x5d, 0x07, 0x46, 0x7d, 0xc5, 0xb7, 0x89, 0x18, 0x8d, 0xa5, 0x86, 0x57, - 0x57, 0xa3, 0x6e, 0x6c, 0xd2, 0x1a, 0x68, 0xd4, 0x79, 0x1b, 0xc3, 0x8d, 0x32, 0xd6, 0x77, 0x11, - 0x34, 0x54, 0x19, 0x67, 0x2d, 0xcf, 0x9a, 0xd4, 0x42, 0x8f, 0xb1, 0x47, 0xad, 0x6d, 0xc5, 0xc4, - 0xd2, 0xc3, 0x1a, 0x96, 0xd5, 0x32, 0x0a, 0xb1, 0xcd, 0x22, 0x20, 0xaf, 0xaa, 0xb2, 0xaa, 0xad, - 0x46, 0x21, 0x94, 0x45, 0x30, 0xf9, 0x98, 0x40, 0x7d, 0x28, 0xdd, 0x67, 0x01, 0x68, 0xfe, 0x25, - 0x3b, 0xa3, 0x0f, 0xa6, 0xea, 0xb6, 0x85, 0xd4, 0x78, 0xf9, 0xb3, 0x7f, 0x63, 0x29, 0xad, 0x96, - 0x2f, 0x31, 0xb8, 0xcd, 0xaa, 0x93, 0x54, 0x11, 0x71, 0x06, 0x92, 0x75, 0x6d, 0xb7, 0xbe, 0xc7, - 0x15, 0x2a, 0x48, 0x5b, 0x6c, 0xbe, 0x0e, 0x54, 0x26, 0x1d, 0x8d, 0xbc, 0x1e, 0xa4, 0x60, 0xa3, - 0xa3, 0x27, 0xde, 0x7c, 0xb0, 0xa0, 0x4f, 0x37, 0x48, 0x96, 0xe1, 0x1a, 0x58, 0x37, 0x04, 0x37, - 0x67, 0xf6, 0x3a, 0xac, 0xcc, 0xf5, 0xf6, 0xd8, 0xaa, 0x3a, 0xc8, 0x94, 0xab, 0xef, 0x3a, 0x40, - 0xe2, 0x91, 0xff, 0x19, 0x20, 0x38, 0x49, 0x26, 0x7f, 0xd2, 0x12, 0xac, 0x71, 0xa3, 0xba, 0xf3, - 0xe6, 0xbb, 0xf1, 0xbc, 0x45, 0x3f, 0x65, 0x71, 0xf5, 0x2f, 0x3e, 0xf3, 0xd8, 0xa8, 0xb7, 0xd4, - 0xff, 0x5f, 0x8d, 0xae, 0xfa, 0x5f, 0x63, 0xfe, 0x17, 0x66, 0xba, 0xb1, 0x98, 0x32, 0x33, 0x00, - 0x00 -}; diff --git a/wled00/html_other.h b/wled00/html_other.h deleted file mode 100644 index 5821b42b6..000000000 --- a/wled00/html_other.h +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * More web UI HTML source arrays. - * This file is auto generated, please don't make any changes manually. - * Instead, see https://kno.wled.ge/advanced/custom-features/#changing-web-ui - * to find out how to easily modify the web UI source! - */ - -// Autogenerated from wled00/data/usermod.htm, do not edit!! -const uint16_t PAGE_usermod_length = 81; -const uint8_t PAGE_usermod[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xb3, 0x51, 0x74, 0xf1, 0x77, 0x0e, - 0x89, 0x0c, 0x70, 0x55, 0xc8, 0x28, 0xc9, 0xcd, 0xb1, 0xb3, 0x81, 0x90, 0x49, 0xf9, 0x29, 0x95, - 0x76, 0x7e, 0xf9, 0x0a, 0xa5, 0xc5, 0xa9, 0x45, 0xb9, 0xf9, 0x29, 0x0a, 0xc9, 0xa5, 0xc5, 0x25, - 0xf9, 0xb9, 0x0a, 0xe5, 0xa9, 0x49, 0x0a, 0x05, 0x89, 0xe9, 0xa9, 0x0a, 0xc5, 0xa9, 0x25, 0x7a, - 0x36, 0xfa, 0x60, 0x55, 0x36, 0xfa, 0x60, 0x2d, 0x00, 0x1e, 0x93, 0x65, 0xc7, 0x48, 0x00, 0x00, - 0x00 -}; - - -// Autogenerated from wled00/data/msg.htm, do not edit!! -const char PAGE_msg[] PROGMEM = R"=====( -WLED Message

%MSG%)====="; - - -#ifdef WLED_ENABLE_DMX - -// Autogenerated from wled00/data/dmxmap.htm, do not edit!! -const char PAGE_dmxmap[] PROGMEM = R"=====( -DMX Map
...
)====="; - - -#else -const char PAGE_dmxmap[] PROGMEM = R"=====()====="; -#endif - -// Autogenerated from wled00/data/update.htm, do not edit!! -const uint16_t PAGE_update_length = 616; -const uint8_t PAGE_update[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x75, 0x53, 0x4d, 0x6f, 0xd4, 0x30, - 0x10, 0xbd, 0xe7, 0x57, 0x18, 0x9f, 0x76, 0x25, 0xd6, 0x2e, 0x1f, 0x17, 0x4a, 0x92, 0x42, 0x69, - 0x85, 0x2a, 0x21, 0xb5, 0x52, 0x5b, 0x10, 0x27, 0xe4, 0xd8, 0x93, 0x8d, 0x59, 0xc7, 0x4e, 0xed, - 0xc9, 0xae, 0x56, 0xa8, 0xff, 0x9d, 0x89, 0xb3, 0x5b, 0x10, 0x1f, 0x97, 0x28, 0xce, 0xbc, 0x79, - 0x9e, 0x79, 0xef, 0xa5, 0x7c, 0x76, 0x71, 0xfd, 0xe1, 0xee, 0xeb, 0xcd, 0x25, 0xeb, 0xb0, 0x77, - 0x75, 0x79, 0x78, 0x82, 0x32, 0x75, 0xd9, 0x03, 0x2a, 0xa6, 0x83, 0x47, 0xf0, 0x58, 0xf1, 0x9d, - 0x35, 0xd8, 0x55, 0x06, 0xb6, 0x56, 0xc3, 0x2a, 0x1f, 0x38, 0xf3, 0xaa, 0x87, 0x8a, 0x6f, 0x2d, - 0xec, 0x86, 0x10, 0x91, 0xd7, 0x45, 0x89, 0x16, 0x1d, 0xd4, 0x5f, 0x3e, 0x5d, 0x5e, 0xb0, 0xfb, - 0xc1, 0x28, 0x84, 0x52, 0xce, 0x9f, 0xca, 0xa4, 0xa3, 0x1d, 0xb0, 0x2e, 0xda, 0xd1, 0x6b, 0xb4, - 0xc1, 0xb3, 0xf3, 0xc5, 0xf2, 0xc7, 0xce, 0x7a, 0x13, 0x76, 0xa2, 0xb3, 0x09, 0x43, 0xdc, 0x8b, - 0x46, 0xe9, 0xcd, 0x62, 0xf9, 0xf8, 0x04, 0xb9, 0x27, 0x88, 0x09, 0x7a, 0xec, 0x69, 0x02, 0xb1, - 0x06, 0xbc, 0x74, 0x30, 0xbd, 0x9e, 0xef, 0xaf, 0xcc, 0x82, 0x8f, 0x2d, 0x5f, 0x8a, 0x84, 0x7b, - 0x07, 0xc2, 0xd8, 0x34, 0x38, 0xb5, 0xaf, 0xb8, 0x0f, 0x1e, 0xf8, 0xf3, 0xff, 0xb6, 0xf4, 0x69, - 0xfd, 0x77, 0x4f, 0xe3, 0x82, 0xde, 0xf0, 0xc7, 0xa2, 0x94, 0x87, 0x11, 0x0f, 0xa3, 0xb2, 0x14, - 0x75, 0xc5, 0x65, 0x02, 0x44, 0xeb, 0xd7, 0x49, 0x26, 0xf1, 0x3d, 0x9d, 0x0d, 0xd5, 0x1b, 0x5e, - 0xff, 0x86, 0x9c, 0xa8, 0xea, 0xe2, 0x9d, 0xed, 0x27, 0x01, 0xd8, 0x18, 0xdd, 0x82, 0xcf, 0xf4, - 0x3a, 0x25, 0xbe, 0x7c, 0x4b, 0xc8, 0x8c, 0x28, 0xe5, 0x2c, 0x69, 0x13, 0xcc, 0x9e, 0x05, 0xef, - 0x82, 0x32, 0x15, 0xff, 0x08, 0xf8, 0x79, 0xb1, 0x24, 0xba, 0xee, 0x65, 0x5d, 0x64, 0xc9, 0x6e, - 0x43, 0x8b, 0x3b, 0x15, 0xe1, 0x49, 0x3b, 0xaa, 0x94, 0x6d, 0x88, 0x3d, 0x23, 0x2f, 0xba, 0x40, - 0x3d, 0x37, 0xd7, 0xb7, 0x77, 0x9c, 0xa9, 0x2c, 0x4f, 0xc5, 0x85, 0x1c, 0x33, 0x90, 0x33, 0x4b, - 0x35, 0x12, 0x84, 0x15, 0x40, 0xd2, 0xed, 0x07, 0x72, 0xa5, 0x1f, 0x1d, 0xda, 0x41, 0x45, 0x94, - 0x13, 0xc1, 0x8a, 0x60, 0x8a, 0xd3, 0xd5, 0x69, 0x6c, 0x7a, 0x4b, 0x76, 0xde, 0x4f, 0x37, 0x5f, - 0xf9, 0x84, 0xca, 0x39, 0x30, 0x6c, 0x0b, 0x31, 0x11, 0xe5, 0x29, 0x2b, 0xd3, 0xa0, 0x3c, 0x2b, - 0xb4, 0x53, 0x29, 0x55, 0x3c, 0xd9, 0x81, 0xd7, 0x27, 0xe2, 0xc5, 0x6b, 0x71, 0xb2, 0x6a, 0x5e, - 0xd1, 0x36, 0x54, 0xa4, 0x2d, 0x62, 0x7d, 0x11, 0x76, 0x79, 0x0b, 0x86, 0x1d, 0x30, 0x47, 0x23, - 0x24, 0x64, 0x8d, 0xf5, 0x2a, 0xee, 0x89, 0x42, 0xb1, 0xa2, 0x8b, 0xd0, 0x56, 0xbc, 0x43, 0x1c, - 0xd2, 0xa9, 0x94, 0x6b, 0x8b, 0xdd, 0xd8, 0x08, 0x1d, 0x7a, 0xf9, 0xde, 0x46, 0x1d, 0x42, 0xd8, - 0x58, 0x90, 0xd3, 0xca, 0x32, 0x82, 0x03, 0x95, 0x20, 0x71, 0x86, 0x2a, 0x92, 0x5f, 0x15, 0xff, - 0xd6, 0x38, 0xe5, 0x37, 0x24, 0x8b, 0xed, 0xd7, 0xac, 0xc8, 0x26, 0x1c, 0x79, 0xe8, 0x8b, 0x48, - 0x9d, 0x05, 0x67, 0x92, 0xb0, 0xe1, 0x40, 0x7b, 0xa4, 0xf8, 0x93, 0x5a, 0xa4, 0xed, 0xfa, 0x2c, - 0xcb, 0x5f, 0xb5, 0x34, 0xe1, 0x2a, 0x3d, 0x8c, 0x24, 0xed, 0x14, 0x52, 0xa9, 0xf2, 0x0e, 0xa5, - 0xf5, 0xc3, 0x88, 0x6c, 0x96, 0xab, 0xb5, 0x0e, 0x8e, 0x81, 0x3e, 0x8a, 0x1a, 0xe1, 0x61, 0xb4, - 0x11, 0xcc, 0x8c, 0x6e, 0x46, 0x44, 0xca, 0xe4, 0x0c, 0x9f, 0x65, 0x24, 0xb2, 0xd9, 0xa9, 0x67, - 0xa5, 0x9c, 0xcb, 0xff, 0x80, 0xce, 0x87, 0x49, 0x7b, 0xed, 0xac, 0xde, 0x54, 0xfc, 0x7c, 0x92, - 0xfe, 0x9c, 0xa2, 0xfe, 0xab, 0x29, 0x7b, 0x54, 0x97, 0xc6, 0x6e, 0x8b, 0x6c, 0xe5, 0x14, 0x54, - 0xa2, 0xa9, 0x33, 0x3b, 0xa5, 0x4f, 0x08, 0x41, 0xe0, 0x4c, 0x7e, 0x93, 0x97, 0x65, 0x26, 0x30, - 0x1f, 0x90, 0x69, 0x17, 0xe8, 0x10, 0x22, 0xcd, 0xda, 0x46, 0x48, 0x5d, 0xf6, 0x63, 0x50, 0x6b, - 0x60, 0xa7, 0xcb, 0x52, 0x12, 0xdf, 0xb4, 0xee, 0x94, 0xba, 0x29, 0x82, 0xd3, 0xbf, 0xfd, 0x13, - 0x46, 0x22, 0xf9, 0xe1, 0xf1, 0x03, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/welcome.htm, do not edit!! -const uint16_t PAGE_welcome_length = 1531; -const uint8_t PAGE_welcome[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x95, 0x56, 0x5b, 0x93, 0xaa, 0x3a, - 0x16, 0x7e, 0xef, 0x5f, 0xc1, 0x76, 0x6a, 0xea, 0x3c, 0xb8, 0xbb, 0xb9, 0x89, 0xa8, 0x6d, 0xf7, - 0x19, 0xc5, 0x4b, 0x7b, 0x03, 0x6f, 0x78, 0x7b, 0x0b, 0x10, 0x20, 0x08, 0x04, 0x93, 0x80, 0x97, - 0xae, 0xfe, 0xef, 0x27, 0xe8, 0xee, 0xa9, 0x7d, 0xea, 0x3c, 0x4c, 0x4d, 0x2c, 0x21, 0xf9, 0x92, - 0xb5, 0xd6, 0xb7, 0x92, 0xb8, 0x3e, 0xdb, 0x3f, 0x7a, 0x96, 0xb1, 0xde, 0xcf, 0xfb, 0x42, 0xc8, - 0x92, 0xf8, 0xbd, 0xfd, 0xeb, 0x09, 0x81, 0xf7, 0xde, 0x4e, 0x20, 0x03, 0x82, 0x1b, 0x02, 0x42, - 0x21, 0x7b, 0xab, 0xe4, 0xcc, 0x7f, 0x6e, 0x54, 0x7e, 0xa1, 0x4f, 0x2e, 0x4e, 0x19, 0x4c, 0x39, - 0x7c, 0x46, 0x1e, 0x0b, 0xdf, 0x3c, 0x58, 0x20, 0x17, 0x3e, 0xdf, 0x07, 0x15, 0x21, 0x05, 0x09, - 0x7c, 0xab, 0x14, 0x08, 0x9e, 0x33, 0x4c, 0xd8, 0xb7, 0xcd, 0x03, 0x65, 0x21, 0x4c, 0xe0, 0xb3, - 0x8b, 0x63, 0x4c, 0x2a, 0xbf, 0xb9, 0xf9, 0x97, 0x72, 0x6f, 0x7c, 0x2d, 0x43, 0x2c, 0x86, 0xef, - 0x5b, 0x18, 0xbb, 0x38, 0x81, 0x3f, 0xda, 0xe2, 0x63, 0xdc, 0xa6, 0xec, 0xca, 0x5f, 0x4f, 0x0e, - 0xf6, 0xae, 0x9f, 0x3e, 0xb7, 0x7a, 0xf6, 0x41, 0x82, 0xe2, 0x6b, 0x6b, 0x03, 0x89, 0x07, 0x52, - 0xf0, 0xf3, 0x03, 0xc6, 0x05, 0x64, 0xc8, 0x05, 0x3f, 0x29, 0x48, 0xe9, 0x33, 0x85, 0x04, 0xf9, - 0xaf, 0x0c, 0x5e, 0xd8, 0x33, 0x88, 0x51, 0x90, 0xb6, 0x5c, 0x1e, 0x06, 0x92, 0x57, 0x07, 0xb8, - 0xc7, 0x80, 0xe0, 0x3c, 0xf5, 0x1e, 0x1c, 0x5a, 0x65, 0xe0, 0xd7, 0x04, 0x90, 0x00, 0xa5, 0x2d, - 0xe9, 0xf5, 0x17, 0xe6, 0xfb, 0xfe, 0x97, 0x93, 0x33, 0x86, 0xd3, 0x4f, 0x9c, 0xb3, 0x18, 0xa5, - 0xb0, 0x9c, 0xcb, 0x09, 0xe5, 0x93, 0x19, 0x46, 0x77, 0x4f, 0x19, 0xf0, 0x3c, 0x94, 0x06, 0xad, - 0x46, 0x76, 0xf9, 0xb6, 0x97, 0x25, 0xde, 0xbf, 0xef, 0x41, 0x4b, 0x51, 0xcb, 0xfe, 0x3d, 0x3e, - 0x23, 0x9c, 0x90, 0x8f, 0x49, 0xd2, 0xca, 0xb3, 0x0c, 0x12, 0x17, 0x50, 0xf8, 0xfa, 0x7b, 0x06, - 0xe1, 0x37, 0xf3, 0x07, 0x4a, 0xd1, 0x0d, 0xb6, 0xe4, 0x26, 0xb7, 0xfe, 0x27, 0x57, 0x55, 0x55, - 0x7f, 0xa3, 0xf8, 0xea, 0x60, 0xe2, 0x41, 0xd2, 0x92, 0x04, 0x8a, 0x63, 0xe4, 0x09, 0xbf, 0x61, - 0xcf, 0x04, 0x78, 0x28, 0xa7, 0x2d, 0x45, 0xcb, 0x2e, 0x5f, 0x28, 0x09, 0x3e, 0x1f, 0xac, 0x9a, - 0x9a, 0x74, 0x67, 0x7b, 0x79, 0x9c, 0x54, 0xab, 0xa1, 0xfc, 0xfb, 0x15, 0x25, 0x20, 0x80, 0xcf, - 0x04, 0xa6, 0xdc, 0xac, 0xcc, 0x27, 0x43, 0x17, 0x18, 0x03, 0x06, 0xbd, 0x7f, 0xcc, 0xb8, 0x04, - 0xd1, 0xec, 0x19, 0x7a, 0x01, 0xa4, 0xdf, 0x19, 0xd7, 0x8a, 0x50, 0x90, 0xca, 0xcf, 0x2b, 0x48, - 0xf9, 0x72, 0x86, 0x70, 0xda, 0xf2, 0x91, 0x20, 0xd3, 0xaf, 0xff, 0x1c, 0xe1, 0xd5, 0x27, 0xfc, - 0xc8, 0xa9, 0xe0, 0xa3, 0x4f, 0x9f, 0xe0, 0xe4, 0x13, 0x67, 0xc0, 0x45, 0xec, 0xda, 0x92, 0xbe, - 0x18, 0xfe, 0xef, 0x40, 0xfe, 0xfa, 0x7a, 0x49, 0x00, 0x4a, 0x3f, 0xff, 0xee, 0xe0, 0x45, 0xa3, - 0xc2, 0x8b, 0x4e, 0x05, 0x07, 0xb3, 0xf0, 0xeb, 0xa9, 0x2d, 0x3e, 0x8e, 0xbf, 0x2d, 0x3e, 0x6e, - 0x66, 0x79, 0x0b, 0xde, 0xdb, 0x3c, 0x2f, 0x01, 0xc4, 0xfc, 0xf2, 0xf0, 0x8b, 0x44, 0x89, 0xfb, - 0x56, 0xf1, 0x00, 0x03, 0xad, 0x3b, 0x6b, 0x31, 0x4b, 0x03, 0xbe, 0x7f, 0x14, 0xd6, 0x6b, 0x3f, - 0xd1, 0xa6, 0x6b, 0x2d, 0xcf, 0xd2, 0x64, 0x18, 0xe0, 0x0e, 0x6f, 0xe6, 0xca, 0x0e, 0xfb, 0x76, - 0xc0, 0x7b, 0x43, 0xa9, 0x1c, 0xfb, 0x46, 0x67, 0xc6, 0x5f, 0x3d, 0x70, 0x9b, 0x5a, 0x79, 0x09, - 0x74, 0x76, 0xe6, 0x6a, 0x29, 0x8d, 0x3a, 0x84, 0xd6, 0xdc, 0xfa, 0xa2, 0x04, 0x96, 0xe9, 0xc2, - 0x96, 0xbb, 0x9d, 0x8e, 0x71, 0x89, 0xce, 0x45, 0x63, 0xbf, 0xb0, 0x39, 0xd6, 0x9d, 0xda, 0xfd, - 0x8b, 0xbd, 0xbc, 0xcf, 0x77, 0x1b, 0x72, 0x60, 0xd8, 0xe2, 0x6d, 0x72, 0x12, 0x45, 0x31, 0xc1, - 0x3a, 0xdd, 0xce, 0xcc, 0x86, 0x63, 0x55, 0x0f, 0xa3, 0x3d, 0x3b, 0x80, 0xce, 0xbc, 0x49, 0x3a, - 0xf3, 0xea, 0xc7, 0x8c, 0x1a, 0x68, 0x58, 0x5d, 0x77, 0x46, 0x56, 0x3a, 0x5b, 0x49, 0x93, 0x93, - 0x69, 0xeb, 0x93, 0x79, 0x3a, 0xb5, 0x0f, 0x16, 0x39, 0xd5, 0x0b, 0x6e, 0x59, 0x33, 0x3a, 0xc1, - 0x30, 0xc4, 0x60, 0x5a, 0x15, 0x8b, 0xba, 0x11, 0xe0, 0xfe, 0x65, 0xb6, 0xbe, 0x13, 0x8a, 0x93, - 0x9a, 0xd5, 0x28, 0x3b, 0x07, 0x6f, 0x30, 0xb6, 0x6c, 0xf1, 0x7f, 0xb4, 0x73, 0xa7, 0x6b, 0x76, - 0x4e, 0x6a, 0x69, 0x60, 0xec, 0xba, 0xa3, 0xed, 0xae, 0xcc, 0x4f, 0xef, 0xf1, 0x87, 0x75, 0x3e, - 0x7f, 0x7c, 0x38, 0xf5, 0xf0, 0x58, 0x4e, 0x99, 0x52, 0xdc, 0x5f, 0x6c, 0x96, 0xa3, 0x95, 0xae, - 0x6e, 0xa2, 0xcd, 0xd4, 0x98, 0x75, 0x3b, 0xfd, 0xfd, 0x88, 0x34, 0x8c, 0xfd, 0xe4, 0x48, 0xbc, - 0x48, 0xf5, 0xe5, 0xb1, 0xaa, 0xdf, 0xc0, 0x6e, 0x60, 0x64, 0x6b, 0xab, 0x9a, 0x21, 0xd0, 0x0b, - 0x9c, 0xf9, 0x89, 0x5f, 0xcc, 0xe6, 0x66, 0x21, 0x9d, 0xae, 0xa4, 0x98, 0x44, 0xb5, 0x53, 0x3d, - 0x91, 0x0e, 0x44, 0x0e, 0xab, 0x33, 0xfd, 0x32, 0x90, 0x6f, 0xcb, 0x24, 0xdd, 0xde, 0x4e, 0x9b, - 0xa6, 0x28, 0x79, 0x4a, 0xc4, 0xd8, 0x10, 0x33, 0x4b, 0xce, 0x8b, 0xa6, 0x67, 0x5b, 0xce, 0x19, - 0x46, 0x1a, 0x3e, 0x65, 0xba, 0x7f, 0xdb, 0x6e, 0xe6, 0x71, 0x23, 0xad, 0x37, 0x41, 0x46, 0x6e, - 0xd8, 0xb2, 0x6d, 0xc7, 0x29, 0xbc, 0x91, 0xb3, 0x51, 0xad, 0xe9, 0x19, 0xb1, 0x9d, 0x5b, 0x2f, - 0x56, 0x43, 0xd9, 0xd3, 0x93, 0xc6, 0x48, 0xf5, 0xe1, 0xaa, 0x6f, 0x4a, 0x91, 0x62, 0x40, 0xd3, - 0xb1, 0xf6, 0xb5, 0xd9, 0x05, 0x05, 0x91, 0x35, 0x35, 0xdc, 0x1a, 0x3d, 0xd0, 0xf5, 0x46, 0x89, - 0x65, 0xd7, 0xb8, 0x5e, 0x6b, 0xe7, 0xd1, 0x68, 0x3a, 0x9d, 0x46, 0x9d, 0x0b, 0xbb, 0x1e, 0x63, - 0x76, 0x52, 0x88, 0xb3, 0xb6, 0xab, 0x27, 0x24, 0xc9, 0xa6, 0x46, 0x76, 0xa6, 0xa5, 0xc4, 0x10, - 0x0c, 0xac, 0x25, 0x46, 0x11, 0x50, 0x62, 0x6d, 0x36, 0xd3, 0x80, 0xa4, 0x00, 0xb7, 0xb9, 0x07, - 0x72, 0x7d, 0x75, 0xd4, 0x58, 0x00, 0xe6, 0xc4, 0xce, 0xa2, 0x43, 0xee, 0x48, 0xdd, 0x69, 0x7d, - 0x7f, 0x5a, 0x5d, 0x26, 0x67, 0xe7, 0x43, 0xd7, 0x77, 0xb6, 0x9d, 0xac, 0x8e, 0xe3, 0xdd, 0x2a, - 0x6e, 0x2c, 0x18, 0x98, 0xe5, 0xd7, 0x71, 0x78, 0xd2, 0x12, 0x30, 0xd5, 0xd2, 0xf5, 0x64, 0x93, - 0x1d, 0x0c, 0x59, 0xdd, 0x24, 0x6c, 0x96, 0xad, 0x07, 0x6b, 0x25, 0xa8, 0x15, 0xe3, 0x68, 0x9d, - 0x0f, 0xfd, 0xd9, 0xed, 0xb6, 0xf3, 0x19, 0xb2, 0x0f, 0x69, 0xe8, 0xb1, 0xc0, 0x91, 0x2f, 0xd8, - 0x2f, 0xae, 0xd9, 0x12, 0xa7, 0xda, 0x3a, 0x32, 0xd3, 0xcb, 0xde, 0x6c, 0xde, 0xc6, 0xb8, 0x3e, - 0xd1, 0x48, 0xbe, 0x1a, 0xdd, 0x16, 0x6c, 0x98, 0x6f, 0x0e, 0xa9, 0x74, 0x69, 0xca, 0x64, 0x52, - 0x78, 0x1f, 0xdd, 0x22, 0x51, 0x9b, 0x7d, 0x7d, 0x75, 0x3d, 0xd4, 0xae, 0x52, 0x7d, 0x78, 0x6b, - 0x74, 0x7b, 0xdd, 0xc1, 0xe4, 0x46, 0x77, 0x49, 0xe8, 0x9e, 0xaf, 0x3e, 0x1d, 0x1e, 0x9a, 0x9b, - 0xcc, 0x09, 0x31, 0x32, 0x50, 0x0a, 0x2e, 0x73, 0x33, 0x19, 0x6e, 0x93, 0xed, 0x96, 0x98, 0xb6, - 0x12, 0x75, 0xa5, 0x53, 0xfd, 0xa3, 0xb0, 0x42, 0x53, 0x1e, 0xdb, 0xcc, 0x40, 0x97, 0x05, 0xcb, - 0x94, 0x40, 0x93, 0x0f, 0x1b, 0x7b, 0x37, 0x9a, 0xaf, 0x94, 0xe5, 0xac, 0xd3, 0xab, 0x56, 0xd7, - 0x4a, 0xba, 0x17, 0x7b, 0xa4, 0x17, 0x59, 0xb3, 0x9e, 0x55, 0x3b, 0x1b, 0x7a, 0x94, 0x98, 0xfb, - 0x48, 0xf5, 0x74, 0x35, 0x25, 0xbb, 0x3c, 0x68, 0xec, 0x59, 0x33, 0x37, 0xbb, 0x8d, 0x8b, 0x69, - 0xcb, 0xee, 0xc4, 0xdc, 0x6d, 0x63, 0x7b, 0x60, 0xee, 0x8c, 0x68, 0x23, 0x67, 0x87, 0x70, 0xb8, - 0xee, 0x37, 0xd4, 0x44, 0x29, 0xb6, 0xfe, 0xde, 0x17, 0xcd, 0x61, 0x54, 0xeb, 0x06, 0xf2, 0x2d, - 0xd7, 0xc6, 0x3d, 0x55, 0x9c, 0xa5, 0x1f, 0xda, 0x61, 0xeb, 0x4f, 0xad, 0x23, 0x75, 0x38, 0xa5, - 0x61, 0x14, 0xec, 0x66, 0xa6, 0x26, 0x1a, 0xca, 0x70, 0xb7, 0x1f, 0x0e, 0x06, 0xdb, 0xa6, 0x99, - 0xf0, 0xfa, 0x5d, 0xdf, 0xe5, 0x4c, 0x1a, 0x26, 0xd5, 0x31, 0x05, 0x57, 0x23, 0x6a, 0xdc, 0xa4, - 0x34, 0x8c, 0x86, 0xc5, 0x7e, 0x7c, 0xdb, 0xf8, 0x35, 0xb0, 0xba, 0x71, 0x26, 0x94, 0x54, 0x73, - 0x7d, 0xa1, 0x8c, 0x47, 0x1e, 0xde, 0xa9, 0x7b, 0x6b, 0x11, 0x59, 0x34, 0x4e, 0xe8, 0x56, 0x8e, - 0xc6, 0xaa, 0xac, 0x48, 0x69, 0xbf, 0x19, 0xf8, 0x58, 0x6f, 0x86, 0x6b, 0x60, 0x7a, 0x2e, 0x3d, - 0x6d, 0x96, 0x75, 0x59, 0x8a, 0x0b, 0xab, 0xa6, 0x67, 0x71, 0x0c, 0x60, 0x73, 0x09, 0x0f, 0x0d, - 0x49, 0xbb, 0x4d, 0xb0, 0x02, 0x54, 0x04, 0xf6, 0x9a, 0xab, 0x6b, 0xd9, 0x3a, 0xd9, 0x18, 0x9d, - 0xba, 0x37, 0xd6, 0x3e, 0x74, 0x53, 0xa2, 0x44, 0x04, 0x74, 0x7e, 0xee, 0xc2, 0xd0, 0xd1, 0x91, - 0xdf, 0x0f, 0x73, 0xba, 0xbc, 0xff, 0xb4, 0xfa, 0xf1, 0x60, 0x7d, 0x5c, 0xe5, 0x8b, 0xc4, 0x30, - 0x2a, 0xef, 0x4f, 0x6d, 0x0f, 0x15, 0x82, 0x1b, 0x03, 0x4a, 0xdf, 0x2a, 0x65, 0x51, 0xe2, 0x72, - 0x14, 0xca, 0xdf, 0x5a, 0x24, 0x30, 0x2c, 0x6c, 0xa7, 0xfd, 0x1e, 0xd7, 0x24, 0x0e, 0xb6, 0x43, - 0xf5, 0xfd, 0x69, 0x1d, 0x82, 0xf4, 0x28, 0x5c, 0x71, 0x2e, 0xf0, 0xfa, 0x2e, 0xa0, 0x94, 0x32, - 0x10, 0x73, 0xb5, 0x08, 0x84, 0xe4, 0x2a, 0x80, 0x2c, 0x8b, 0x79, 0x51, 0x2f, 0x2b, 0x5a, 0x69, - 0xa1, 0xf2, 0xaa, 0xf5, 0x6e, 0x72, 0x3d, 0x10, 0x28, 0x83, 0x19, 0x6d, 0xb5, 0x45, 0x87, 0x23, - 0xe4, 0xfe, 0x7d, 0x32, 0x70, 0x9a, 0x42, 0x97, 0x09, 0x5c, 0x1c, 0x85, 0x04, 0x7b, 0x79, 0x7c, - 0x0f, 0xc6, 0xfd, 0x12, 0x21, 0xc6, 0x2e, 0x88, 0x85, 0x2d, 0x1a, 0x20, 0x21, 0x84, 0x84, 0x0b, - 0xe2, 0xdd, 0xe6, 0xae, 0x4d, 0xc2, 0x13, 0x4e, 0x5d, 0x1e, 0xe3, 0xf8, 0xf6, 0xc7, 0x19, 0xa5, - 0x1e, 0x3e, 0xbf, 0x94, 0x8b, 0xcb, 0x80, 0x2f, 0x21, 0x81, 0xfe, 0x5b, 0xe5, 0x45, 0xe4, 0xca, - 0xcd, 0x38, 0x1f, 0x2a, 0x9e, 0x91, 0x8f, 0x2a, 0x7f, 0xbc, 0xdf, 0xfd, 0x7c, 0x83, 0x9c, 0xc2, - 0xdd, 0xcf, 0x83, 0x07, 0x7a, 0x7f, 0x1a, 0xe7, 0x94, 0x73, 0x20, 0xd7, 0x32, 0x03, 0x16, 0x22, - 0x2a, 0x70, 0xf1, 0xe3, 0x59, 0x09, 0x9d, 0x79, 0xc9, 0x0a, 0xfe, 0xd9, 0x16, 0xd1, 0xfb, 0xff, - 0x17, 0xff, 0x4f, 0xca, 0x85, 0x09, 0x12, 0xca, 0x43, 0xaf, 0xf1, 0x3d, 0xbd, 0x52, 0xf1, 0x09, - 0x8e, 0xe9, 0x8f, 0xbf, 0x47, 0x17, 0xf9, 0xce, 0xf3, 0xfd, 0x17, 0x1f, 0x95, 0x5d, 0xbc, 0xff, - 0x0d, 0xf9, 0x0b, 0x5c, 0xd5, 0x96, 0x6f, 0x9c, 0x08, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/liveview.htm, do not edit!! -const uint16_t PAGE_liveview_length = 962; -const uint8_t PAGE_liveview[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x9d, 0x55, 0x6d, 0x6f, 0xdb, 0x36, - 0x10, 0xfe, 0x9e, 0x5f, 0xa1, 0x32, 0x6b, 0x4a, 0xc2, 0xb2, 0x2c, 0xbb, 0xaf, 0xb3, 0x4c, 0x07, - 0xed, 0x9a, 0x0f, 0x03, 0x82, 0x25, 0x40, 0x32, 0x04, 0x43, 0x10, 0xa0, 0xb4, 0x74, 0xb6, 0xd8, - 0x50, 0xa4, 0x40, 0x52, 0xf6, 0x0c, 0x55, 0xff, 0x7d, 0x47, 0xc9, 0x71, 0xb0, 0xa1, 0xd8, 0xd0, - 0xf9, 0x83, 0x2c, 0x92, 0x77, 0xc7, 0xbb, 0xe7, 0xb9, 0xe7, 0xb4, 0x78, 0xf1, 0xf9, 0xea, 0x97, - 0xdb, 0x3f, 0xae, 0x2f, 0xa2, 0xd2, 0x57, 0x6a, 0xb9, 0x38, 0x3c, 0x41, 0x14, 0xcb, 0x45, 0x05, - 0x5e, 0x44, 0x5a, 0x54, 0xc0, 0xc9, 0x56, 0xc2, 0xae, 0x36, 0xd6, 0x93, 0xe8, 0x24, 0x37, 0xda, - 0x83, 0xf6, 0x9c, 0xec, 0x64, 0xe1, 0x4b, 0x5e, 0xc0, 0x56, 0xe6, 0x30, 0xee, 0x17, 0xb1, 0xd4, - 0xd2, 0x4b, 0xa1, 0xc6, 0x2e, 0x17, 0x0a, 0xf8, 0x34, 0xae, 0x70, 0xa3, 0x6a, 0xaa, 0xa7, 0x35, - 0x39, 0xc4, 0x3c, 0xc9, 0x4b, 0x61, 0x1d, 0x60, 0x8c, 0xc6, 0xaf, 0xc7, 0x1f, 0xc8, 0xdf, 0xae, - 0xf2, 0x25, 0x54, 0x30, 0xce, 0x8d, 0x32, 0x96, 0x44, 0xc7, 0xcb, 0x4e, 0x67, 0xfd, 0x0f, 0x4d, - 0xbd, 0xf4, 0x0a, 0x96, 0x27, 0x77, 0x97, 0x17, 0x9f, 0xa3, 0x4b, 0xb9, 0x85, 0xe8, 0xda, 0x42, - 0x48, 0x6f, 0x31, 0x19, 0x4e, 0x16, 0xce, 0xef, 0x83, 0xc1, 0xca, 0x14, 0xfb, 0xb6, 0x12, 0x76, - 0x23, 0xf5, 0x3c, 0xed, 0x4e, 0x73, 0xa1, 0xb7, 0xed, 0x4a, 0xe4, 0x8f, 0x1b, 0x6b, 0x1a, 0x5d, - 0xcc, 0x4f, 0xd3, 0x34, 0xcd, 0xd6, 0x52, 0x79, 0xb0, 0xf3, 0x95, 0x95, 0x9b, 0xd2, 0x6b, 0x70, - 0x8e, 0x4e, 0xdf, 0xbf, 0x7d, 0xc9, 0xb2, 0xbe, 0x9a, 0xf9, 0x34, 0x4d, 0x5f, 0x66, 0x25, 0x84, - 0xb3, 0xe1, 0xbd, 0x36, 0x0e, 0xeb, 0x33, 0x7a, 0x2e, 0x56, 0xce, 0xa8, 0xc6, 0x43, 0x77, 0xb2, - 0x98, 0x0c, 0xd7, 0x2d, 0x5c, 0x6e, 0x65, 0xed, 0x97, 0x27, 0x5b, 0x61, 0xa3, 0x9d, 0x8b, 0x7d, - 0x65, 0x1a, 0xcf, 0x75, 0xa3, 0x54, 0xb6, 0x6e, 0x74, 0x1e, 0xbc, 0xa2, 0xa6, 0x2e, 0x84, 0x07, - 0xca, 0x5a, 0xb9, 0xa6, 0x85, 0xc9, 0x9b, 0x0a, 0x2b, 0x4b, 0x4a, 0x59, 0x14, 0xa0, 0x99, 0x05, - 0xdf, 0x58, 0x1d, 0xe5, 0x0a, 0x84, 0xbd, 0x95, 0x15, 0xa0, 0x37, 0xed, 0x63, 0xb0, 0x78, 0x6b, - 0x64, 0x31, 0xbc, 0x73, 0xc4, 0xec, 0xe9, 0x70, 0x08, 0x16, 0xcf, 0xde, 0xa6, 0x8c, 0x65, 0x6b, - 0xf0, 0x79, 0x49, 0x49, 0x32, 0xf9, 0xea, 0x8c, 0x9e, 0x28, 0x44, 0x85, 0xb0, 0x04, 0x81, 0xd4, - 0x14, 0xf8, 0x92, 0x42, 0x62, 0x1e, 0xbf, 0x7d, 0xa3, 0xdf, 0x8b, 0xfd, 0x2f, 0x61, 0x31, 0x6e, - 0x0c, 0x49, 0x08, 0x48, 0x19, 0x7b, 0x8e, 0xd6, 0x86, 0x02, 0x91, 0x10, 0x25, 0x35, 0x86, 0x1b, - 0x6f, 0xac, 0x28, 0x24, 0xd6, 0x41, 0x7f, 0x4e, 0x0b, 0xd8, 0xc4, 0x24, 0xd6, 0x1c, 0x12, 0x05, - 0x85, 0xc3, 0x87, 0xde, 0xf8, 0x32, 0x5b, 0x1b, 0x4b, 0x25, 0x4f, 0x33, 0xb9, 0xd0, 0x99, 0x1c, - 0x8d, 0x58, 0xef, 0x6f, 0x0e, 0x46, 0xf7, 0xf2, 0x21, 0x33, 0x07, 0xcb, 0xe5, 0xbb, 0xb3, 0x33, - 0x6a, 0xb8, 0x49, 0x5c, 0xb3, 0x72, 0xde, 0x4a, 0xbd, 0xa1, 0x33, 0x4c, 0xc1, 0x8f, 0x90, 0x7c, - 0x32, 0x32, 0x31, 0x06, 0x18, 0x4f, 0xd1, 0x24, 0x6c, 0xc4, 0x84, 0x75, 0xe1, 0x9f, 0x91, 0xf8, - 0x08, 0xe4, 0x06, 0xfc, 0x85, 0x82, 0xf0, 0xfa, 0x69, 0xff, 0x6b, 0x41, 0x49, 0x20, 0x1c, 0x51, - 0xe8, 0xe9, 0x49, 0x9e, 0x89, 0xe7, 0x3e, 0xfe, 0x11, 0x20, 0xde, 0xa4, 0xac, 0x63, 0x49, 0x2e, - 0x02, 0xbe, 0xf4, 0x89, 0x49, 0x0a, 0xac, 0xfd, 0x61, 0x34, 0x3b, 0xc6, 0xba, 0x63, 0x2b, 0xdc, - 0x0c, 0x5d, 0xb0, 0x93, 0xba, 0x30, 0xbb, 0x44, 0x19, 0xbc, 0x00, 0xb7, 0x93, 0xd2, 0xc2, 0x3a, - 0xc1, 0x3d, 0xf8, 0xf3, 0x6a, 0x4d, 0xc9, 0xf9, 0xce, 0x11, 0xb6, 0x4c, 0x59, 0xeb, 0xed, 0xbe, - 0xdd, 0x39, 0xee, 0x4d, 0x9d, 0x1c, 0x3c, 0x76, 0xae, 0x1b, 0x72, 0xc2, 0x4c, 0xba, 0x10, 0xc8, - 0x9d, 0x9d, 0xed, 0x5c, 0x62, 0x51, 0xb7, 0xfb, 0x1b, 0x8f, 0x77, 0x72, 0xce, 0xef, 0x60, 0x75, - 0x63, 0xf2, 0x47, 0xf0, 0xc9, 0xd5, 0xf5, 0xc5, 0x6f, 0x0c, 0x8f, 0x1d, 0x68, 0x04, 0xa6, 0x7d, - 0xa5, 0xb6, 0xaf, 0xe6, 0xde, 0x36, 0xd0, 0x11, 0x96, 0x81, 0x72, 0xd0, 0x2a, 0xf0, 0x11, 0xf0, - 0x7f, 0x64, 0x13, 0x7b, 0x64, 0xa9, 0x16, 0xbe, 0x0c, 0xba, 0x44, 0x5e, 0x7d, 0xe2, 0x14, 0x4a, - 0x9d, 0x4e, 0x63, 0x9f, 0x60, 0x20, 0x77, 0x27, 0x3d, 0xf6, 0xdc, 0x84, 0xb0, 0xf3, 0xf1, 0x74, - 0x1e, 0x9a, 0x34, 0x4a, 0x11, 0xee, 0x5a, 0x49, 0xdf, 0xef, 0xc6, 0x12, 0xdd, 0x0d, 0x2a, 0x4b, - 0x6a, 0xcc, 0xab, 0x56, 0x02, 0x5d, 0x49, 0xe9, 0x7d, 0x8d, 0xec, 0x85, 0xc2, 0x32, 0xfd, 0x44, - 0x7c, 0x60, 0x55, 0x22, 0x9b, 0x13, 0x32, 0xd2, 0xf7, 0xe9, 0x03, 0x8b, 0xb1, 0x1c, 0xae, 0x61, - 0x17, 0x1d, 0x2b, 0xc0, 0x63, 0x32, 0x09, 0x4e, 0x2c, 0x31, 0xda, 0xd4, 0xa0, 0xf9, 0x91, 0x0a, - 0xd6, 0x7e, 0xbf, 0xb0, 0xae, 0xc3, 0xfd, 0x95, 0xd4, 0xc2, 0xee, 0x6f, 0xf7, 0x35, 0xce, 0x15, - 0x61, 0xad, 0xd8, 0xaf, 0x9a, 0xf5, 0x1a, 0x2c, 0x89, 0xf1, 0x4c, 0x14, 0xc5, 0xc5, 0x16, 0xbb, - 0xe5, 0x52, 0x3a, 0x1c, 0x31, 0x60, 0x29, 0xa9, 0x70, 0x00, 0x88, 0x0d, 0x90, 0x38, 0xb4, 0x79, - 0xc0, 0x1c, 0x81, 0x25, 0xf7, 0x66, 0xf5, 0x15, 0x72, 0x1f, 0x7d, 0x0c, 0xee, 0x9f, 0x7a, 0xf7, - 0x07, 0x82, 0xe8, 0x7a, 0x73, 0xd3, 0x37, 0x29, 0xf6, 0x86, 0x52, 0x28, 0x31, 0x24, 0x5a, 0x30, - 0x76, 0x40, 0x32, 0x24, 0xff, 0xbb, 0xd4, 0xfe, 0x43, 0xef, 0x45, 0x21, 0xdc, 0x33, 0x58, 0x64, - 0x18, 0xf3, 0xfd, 0xbb, 0x17, 0x1c, 0x42, 0xa1, 0x83, 0xe8, 0xb3, 0xe0, 0xf3, 0x9f, 0x8a, 0x0a, - 0x48, 0xc5, 0x86, 0xcf, 0x38, 0xba, 0x4e, 0x1f, 0xce, 0xdf, 0xcc, 0x67, 0x07, 0x69, 0x99, 0x83, - 0xb4, 0xf8, 0x6b, 0x86, 0x92, 0xf8, 0x62, 0x37, 0x2b, 0xfa, 0x53, 0x0b, 0xa8, 0xac, 0x2e, 0xee, - 0xff, 0x47, 0xd3, 0xe3, 0xdb, 0xec, 0xa1, 0x63, 0x5f, 0x7a, 0x21, 0xbd, 0x7e, 0x16, 0x52, 0xf6, - 0xbf, 0x85, 0xd4, 0x3d, 0xf7, 0x20, 0xce, 0x69, 0x9c, 0x88, 0x90, 0x80, 0xb5, 0x98, 0x14, 0xb9, - 0x06, 0x78, 0x8c, 0xee, 0x6e, 0xa2, 0x7e, 0x39, 0x47, 0x40, 0x91, 0x0e, 0xd6, 0x85, 0x56, 0x3b, - 0x0e, 0xc1, 0x7e, 0x74, 0x0e, 0x33, 0x73, 0x31, 0x19, 0xbe, 0x37, 0x61, 0x62, 0x47, 0x46, 0x2b, - 0x23, 0x0a, 0x4e, 0x50, 0x21, 0x38, 0xec, 0x0b, 0xb9, 0x8d, 0x24, 0xae, 0xfa, 0x1c, 0xd0, 0x10, - 0xd7, 0xf8, 0x0c, 0x86, 0xc1, 0x2b, 0x7c, 0xab, 0xfe, 0x02, 0x51, 0x65, 0x4f, 0x41, 0xc1, 0x06, - 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/liveviewws2D.htm, do not edit!! -const uint16_t PAGE_liveviewws2D_length = 870; -const uint8_t PAGE_liveviewws2D[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x6d, 0x54, 0x6d, 0x6f, 0xdb, 0x36, - 0x10, 0xfe, 0xee, 0x5f, 0xa1, 0x70, 0x43, 0x2a, 0xc6, 0xb2, 0x64, 0xbb, 0xed, 0x96, 0xc5, 0xa2, - 0x87, 0x35, 0x0d, 0xb0, 0x02, 0xd9, 0x6a, 0x20, 0x19, 0x82, 0x21, 0x30, 0x50, 0x5a, 0x3a, 0x5b, - 0x5c, 0x25, 0xd2, 0x20, 0xcf, 0x96, 0x35, 0x47, 0xff, 0x7d, 0x47, 0xc9, 0xc9, 0x32, 0x74, 0xfe, - 0x20, 0x93, 0xf7, 0xf2, 0xdc, 0xdb, 0x73, 0x4c, 0xcf, 0x3e, 0x7e, 0xbe, 0xbe, 0xff, 0x73, 0x71, - 0x13, 0x14, 0x58, 0x95, 0xf3, 0xf4, 0xf4, 0x05, 0x99, 0xcf, 0xd3, 0x0a, 0x50, 0x06, 0x5a, 0x56, - 0x20, 0xd8, 0x5e, 0x41, 0xbd, 0x35, 0x16, 0x59, 0x30, 0xc8, 0x8c, 0x46, 0xd0, 0x28, 0x58, 0xad, - 0x72, 0x2c, 0x44, 0x0e, 0x7b, 0x95, 0xc1, 0xa8, 0xbb, 0x44, 0x4a, 0x2b, 0x54, 0xb2, 0x1c, 0xb9, - 0x4c, 0x96, 0x20, 0x26, 0x51, 0x45, 0x82, 0x6a, 0x57, 0x3d, 0xdf, 0xd9, 0x09, 0x73, 0x90, 0x15, - 0xd2, 0x3a, 0x20, 0x8c, 0x1d, 0xae, 0x47, 0x97, 0xec, 0x3f, 0xa1, 0xb0, 0x80, 0x0a, 0x46, 0x99, - 0x29, 0x8d, 0x65, 0xc1, 0x4b, 0xb0, 0xef, 0xa6, 0xdd, 0x8f, 0x4c, 0x51, 0x61, 0x09, 0xf3, 0xc1, - 0xc3, 0xed, 0xcd, 0xc7, 0xe0, 0x56, 0xed, 0x21, 0x58, 0x58, 0xf0, 0xe9, 0xa5, 0x49, 0xaf, 0x49, - 0x1d, 0x36, 0xf4, 0xb7, 0x32, 0x79, 0x73, 0xac, 0xa4, 0xdd, 0x28, 0x7d, 0x35, 0x6e, 0xd3, 0xa4, - 0x97, 0xa6, 0x49, 0x5f, 0x9a, 0xd7, 0xce, 0xd3, 0x4c, 0xea, 0xbd, 0x74, 0xc1, 0x40, 0xe5, 0x82, - 0xf9, 0x33, 0xa1, 0x27, 0xbd, 0x8c, 0x50, 0x32, 0xab, 0xb6, 0x38, 0x1f, 0xec, 0xa5, 0x0d, 0x32, - 0x91, 0x9b, 0x6c, 0x57, 0x51, 0x22, 0xf1, 0x06, 0xf0, 0xa6, 0x04, 0x7f, 0xfc, 0xd0, 0x7c, 0xca, - 0xc3, 0xde, 0x8d, 0x47, 0x25, 0xe4, 0x4e, 0x30, 0x16, 0x61, 0x61, 0x0d, 0x52, 0x16, 0xb9, 0x38, - 0x9b, 0xcc, 0xd6, 0x3b, 0x9d, 0xa1, 0x32, 0x3a, 0xa0, 0x52, 0xaf, 0x3b, 0xd8, 0x90, 0x1f, 0xb3, - 0xb8, 0xef, 0x5b, 0xfc, 0xd3, 0xe5, 0x45, 0xad, 0x74, 0x6e, 0xea, 0x58, 0x69, 0x0d, 0xf6, 0xa1, - 0x6b, 0x60, 0x16, 0x17, 0xa0, 0x36, 0x05, 0x7e, 0xa3, 0xfe, 0xb5, 0x13, 0xb7, 0xaf, 0x90, 0x66, - 0x5d, 0x66, 0x78, 0x10, 0x99, 0x4f, 0xea, 0xda, 0x37, 0xea, 0x80, 0x21, 0x9b, 0xe6, 0x8c, 0xcf, - 0xd4, 0x3a, 0x24, 0x0d, 0x3f, 0x7a, 0x93, 0xda, 0xcd, 0xd0, 0x36, 0xc7, 0xda, 0x09, 0x34, 0xdb, - 0xf8, 0x84, 0x59, 0xbb, 0x36, 0x93, 0x98, 0x15, 0x21, 0xf2, 0x63, 0x4b, 0xd6, 0xb5, 0x3b, 0x3f, - 0xaf, 0x5d, 0x6c, 0xa9, 0x39, 0xcd, 0x1d, 0x4a, 0x04, 0x21, 0xc4, 0x03, 0xac, 0xee, 0x4c, 0xf6, - 0x15, 0x30, 0xfe, 0xbc, 0xb8, 0xf9, 0x9d, 0x93, 0xda, 0x81, 0xa6, 0x92, 0x8f, 0x6f, 0xca, 0xfd, - 0x9b, 0x2b, 0xb4, 0x3b, 0x68, 0x29, 0x14, 0x94, 0x0e, 0x8e, 0x25, 0x60, 0x80, 0xe2, 0x84, 0x5d, - 0x1a, 0x82, 0xa6, 0xb2, 0x23, 0x10, 0x18, 0x6f, 0x25, 0x16, 0x7e, 0xae, 0x91, 0x15, 0x10, 0xbb, - 0x92, 0xa8, 0x12, 0x4e, 0x22, 0x88, 0x09, 0xc8, 0x3d, 0x28, 0x2c, 0x42, 0x96, 0x30, 0xfe, 0xf3, - 0x68, 0x72, 0xb5, 0x37, 0x2a, 0x0f, 0xc6, 0x3c, 0x76, 0xdb, 0x52, 0x61, 0x27, 0x8d, 0x34, 0xb9, - 0x1b, 0xab, 0x68, 0x80, 0x94, 0xd7, 0xb6, 0x94, 0xe4, 0xca, 0x0a, 0xc4, 0x2d, 0x8b, 0x58, 0xed, - 0x28, 0xb2, 0x8d, 0x4b, 0xd0, 0x1b, 0x2c, 0xe6, 0x93, 0xf3, 0xf3, 0x50, 0x0f, 0x05, 0x39, 0x0d, - 0xed, 0xe3, 0x78, 0xc9, 0x23, 0x2a, 0x47, 0x68, 0xa8, 0x83, 0x97, 0x0a, 0x48, 0xcd, 0x12, 0xef, - 0xc4, 0x63, 0xa3, 0xcd, 0x16, 0xb4, 0x08, 0xb9, 0x98, 0x1f, 0xff, 0xbf, 0xa4, 0xb6, 0x25, 0xf9, - 0x4a, 0x69, 0x69, 0x9b, 0xfb, 0x66, 0x4b, 0x8c, 0x94, 0xd6, 0xca, 0x66, 0xb5, 0x5b, 0xaf, 0xc1, - 0xb2, 0x88, 0x74, 0x32, 0xcf, 0x6f, 0xf6, 0xc4, 0x80, 0x5b, 0xe5, 0x88, 0x9c, 0x60, 0x43, 0x56, - 0x81, 0x73, 0x72, 0x03, 0x34, 0x7f, 0x42, 0xf5, 0xdd, 0xa6, 0x96, 0xb2, 0x47, 0xb3, 0xfa, 0x0b, - 0x32, 0x0c, 0x7e, 0xf1, 0xee, 0x1f, 0x3a, 0xf7, 0x25, 0xa3, 0xbe, 0xa2, 0xb9, 0x43, 0xab, 0xf4, - 0x26, 0xa6, 0xa5, 0x28, 0x43, 0x8c, 0x73, 0x89, 0x92, 0xf3, 0x53, 0x0f, 0x7d, 0xda, 0x7f, 0x28, - 0x8d, 0x97, 0x9d, 0x57, 0x08, 0x3e, 0x4e, 0x6f, 0xe1, 0x87, 0xfa, 0xe3, 0x0f, 0x67, 0x02, 0xa9, - 0xc4, 0xa7, 0xa7, 0xa9, 0x3f, 0x4c, 0xe8, 0x70, 0xe6, 0x07, 0x6d, 0x01, 0x77, 0x56, 0xcf, 0x3c, - 0x84, 0x25, 0xf9, 0x74, 0xe9, 0x9b, 0xf7, 0xf8, 0x76, 0x19, 0x49, 0xf1, 0x1b, 0x0d, 0x20, 0xa6, - 0x3d, 0x0c, 0x4f, 0xc4, 0x4b, 0xec, 0x0b, 0xc9, 0x12, 0xcd, 0x23, 0xd5, 0x1b, 0xac, 0x4b, 0x63, - 0x6c, 0xf8, 0x6c, 0x33, 0x92, 0x17, 0x96, 0x27, 0xd3, 0x9e, 0x62, 0x20, 0xde, 0xcd, 0xd6, 0xa4, - 0x6c, 0x44, 0xfc, 0x7e, 0xd6, 0xa4, 0x7a, 0xd6, 0x0c, 0x87, 0xdc, 0x0b, 0x0e, 0x5e, 0x70, 0x48, - 0xed, 0xec, 0x40, 0x02, 0xca, 0x22, 0x5e, 0xab, 0xb2, 0xbc, 0xf3, 0x6b, 0x26, 0xbe, 0xd8, 0xcd, - 0x2a, 0xfc, 0xfe, 0x88, 0x8f, 0xb0, 0x6c, 0xa3, 0xee, 0x7f, 0x38, 0x79, 0x39, 0x4d, 0x97, 0x2d, - 0xff, 0x12, 0x79, 0x87, 0x15, 0xd0, 0x70, 0x17, 0x14, 0x3f, 0xe4, 0xdd, 0x5d, 0xda, 0x2c, 0x3c, - 0x5c, 0xc8, 0xa1, 0x8a, 0x9a, 0x0b, 0x19, 0xc5, 0xef, 0xe8, 0x33, 0x8e, 0xa6, 0x17, 0x5d, 0x86, - 0x8b, 0x4f, 0xbd, 0x8d, 0x0f, 0x42, 0xe6, 0x30, 0x14, 0x6f, 0xdb, 0x7f, 0x39, 0x4c, 0xef, 0x84, - 0x33, 0x25, 0xf1, 0xca, 0x5a, 0xca, 0x8c, 0x2d, 0x00, 0xbe, 0x06, 0x0f, 0x77, 0x41, 0x77, 0xbd, - 0xa2, 0xb1, 0xd0, 0x50, 0x79, 0x7b, 0xe2, 0xe7, 0xb7, 0xe3, 0xb3, 0xe0, 0xd4, 0xdf, 0xcf, 0xd3, - 0x7b, 0xde, 0xe0, 0xa7, 0xa7, 0xf0, 0xd5, 0xb6, 0xbd, 0xde, 0xec, 0x71, 0x44, 0x8a, 0x7b, 0x55, - 0x81, 0xd9, 0x61, 0xd8, 0x11, 0xe9, 0xf5, 0xda, 0xb7, 0xd1, 0xf4, 0xfd, 0x98, 0xf3, 0x96, 0x0f, - 0xe8, 0xd1, 0xe9, 0x1f, 0x91, 0x34, 0xe9, 0xdf, 0x9b, 0xa4, 0x7b, 0x5d, 0xff, 0x01, 0x47, 0xe8, - 0xd7, 0x03, 0x73, 0x05, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/404.htm, do not edit!! -const uint16_t PAGE_404_length = 870; -const uint8_t PAGE_404[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x65, 0x54, 0x5b, 0x73, 0xaa, 0x3a, - 0x14, 0x7e, 0xef, 0xaf, 0xe0, 0xb8, 0x67, 0xcf, 0x7e, 0x68, 0x15, 0x54, 0xac, 0x8a, 0xe8, 0x19, - 0x40, 0x14, 0x7b, 0xf1, 0x4e, 0xad, 0x7d, 0x0b, 0x24, 0x42, 0x2a, 0x10, 0x9a, 0x04, 0xc5, 0x76, - 0xfa, 0xdf, 0x4f, 0x80, 0x76, 0x4e, 0x67, 0xf6, 0x9a, 0x81, 0x95, 0x7c, 0x2b, 0xeb, 0xbe, 0x12, - 0xfd, 0x9f, 0xf1, 0xc2, 0xda, 0xee, 0x97, 0xb6, 0x14, 0xf2, 0x38, 0x1a, 0xe9, 0x5f, 0x7f, 0x04, - 0xe0, 0x48, 0x8f, 0x11, 0x07, 0x92, 0x1f, 0x02, 0xca, 0x10, 0x1f, 0xd6, 0x32, 0x7e, 0xa8, 0xf7, - 0x6a, 0x5f, 0xe8, 0x95, 0x4f, 0x12, 0x8e, 0x12, 0x01, 0x9f, 0x31, 0xe4, 0xe1, 0x10, 0xa2, 0x13, - 0xf6, 0x51, 0xbd, 0xdc, 0xd4, 0xa4, 0x04, 0xc4, 0x68, 0x58, 0x3b, 0x61, 0x74, 0x4e, 0x09, 0xe5, - 0xdf, 0x3a, 0x15, 0xca, 0x43, 0x14, 0xa3, 0xba, 0x4f, 0x22, 0x42, 0x6b, 0x3f, 0xcc, 0xfc, 0x6a, - 0x95, 0x24, 0xce, 0x72, 0xcc, 0x23, 0x34, 0x9a, 0x13, 0x2e, 0x1d, 0x48, 0x96, 0x40, 0x5d, 0xae, - 0x00, 0x9d, 0xf1, 0x8b, 0x60, 0x57, 0x1e, 0x81, 0x97, 0x8f, 0x83, 0x50, 0xab, 0x1f, 0x40, 0x8c, - 0xa3, 0x8b, 0xf6, 0x84, 0x28, 0x04, 0x09, 0xb8, 0x71, 0x50, 0x74, 0x42, 0x1c, 0xfb, 0xe0, 0x86, - 0x81, 0x84, 0xd5, 0x19, 0xa2, 0xf8, 0x30, 0xe0, 0x28, 0xe7, 0x75, 0x10, 0xe1, 0x20, 0xd1, 0x7c, - 0xe1, 0x07, 0xd1, 0x81, 0x07, 0xfc, 0x63, 0x40, 0x0b, 0xcb, 0x55, 0x10, 0x5a, 0xe1, 0x79, 0x10, - 0x03, 0x1a, 0xe0, 0x44, 0x53, 0x06, 0x5f, 0xd8, 0xe1, 0x70, 0xf8, 0xc4, 0x71, 0xf0, 0x51, 0x26, - 0xa4, 0xa9, 0x8a, 0x92, 0xe6, 0xe2, 0x4c, 0x5e, 0x25, 0xa8, 0x75, 0x94, 0xdf, 0x03, 0x1c, 0x83, - 0x00, 0xd5, 0x29, 0x4a, 0xa0, 0x70, 0x94, 0x04, 0x5a, 0x8a, 0x73, 0x14, 0x01, 0x8e, 0xe0, 0x5f, - 0x12, 0x9f, 0x62, 0x96, 0xd6, 0x11, 0x0c, 0x10, 0xfb, 0xf6, 0xd3, 0xea, 0xa4, 0xb9, 0xa4, 0x48, - 0xf5, 0xa6, 0x52, 0xf0, 0x4f, 0x2f, 0xe3, 0x9c, 0x24, 0x1f, 0x24, 0xe3, 0x11, 0x4e, 0x50, 0x11, - 0x45, 0x46, 0x99, 0x08, 0x23, 0x25, 0xb8, 0x8c, 0x39, 0x05, 0x10, 0x16, 0x96, 0x7a, 0x65, 0x14, - 0xa5, 0x85, 0x42, 0x73, 0x50, 0x45, 0xd3, 0x6a, 0x17, 0xeb, 0x32, 0x53, 0x4e, 0x45, 0xea, 0x07, - 0x42, 0x63, 0x2d, 0x4b, 0x53, 0x44, 0x7d, 0xc0, 0xd0, 0xe0, 0x67, 0xad, 0xc2, 0xef, 0x1a, 0x55, - 0x28, 0xc3, 0xef, 0x48, 0x6b, 0xf6, 0x85, 0xf6, 0xdf, 0x55, 0x69, 0xb7, 0xdb, 0x3f, 0x8a, 0x31, - 0xf0, 0x08, 0x15, 0xe9, 0x68, 0x8a, 0xc4, 0x48, 0x84, 0xa1, 0xf4, 0x03, 0xab, 0x53, 0x00, 0x71, - 0xc6, 0xca, 0x9c, 0x3e, 0xaf, 0x74, 0xb9, 0xea, 0x93, 0x2e, 0x57, 0x33, 0x54, 0xb4, 0x6b, 0xa4, - 0x8b, 0x52, 0x4a, 0x20, 0x12, 0x6d, 0x16, 0x2d, 0x67, 0xd4, 0x1f, 0xd6, 0x20, 0xe0, 0x40, 0x2b, - 0x0b, 0x25, 0xa7, 0x49, 0x20, 0xdc, 0x33, 0x74, 0xab, 0xde, 0xe0, 0x27, 0x73, 0xb1, 0x3e, 0x2b, - 0xf7, 0xd3, 0x80, 0x18, 0x82, 0xe6, 0x1b, 0x37, 0xb4, 0xdd, 0x40, 0xac, 0xac, 0x62, 0x6b, 0x04, - 0x96, 0xf1, 0x28, 0x98, 0x69, 0xa7, 0x33, 0x3a, 0x2d, 0x91, 0xe7, 0xf9, 0x66, 0xad, 0xcc, 0x0c, - 0xca, 0x54, 0xff, 0x76, 0x55, 0x00, 0xeb, 0x64, 0xe5, 0x36, 0x4d, 0xa1, 0x90, 0xbf, 0x9e, 0x4f, - 0xbd, 0xfd, 0xca, 0x2d, 0x40, 0xcf, 0xb5, 0x73, 0x77, 0x5d, 0xca, 0xcd, 0x5e, 0x33, 0xb0, 0x5c, - 0xf9, 0xfd, 0xfe, 0x4d, 0x2e, 0xa8, 0xef, 0xed, 0x9a, 0xc4, 0x32, 0x82, 0x69, 0x48, 0x40, 0x21, - 0x9e, 0x2e, 0x1f, 0x9e, 0x7b, 0xa5, 0xe5, 0x3b, 0x38, 0xb9, 0x5b, 0xb8, 0xf2, 0xff, 0x64, 0x4c, - 0xe6, 0x4b, 0x64, 0xce, 0x4a, 0x99, 0x6f, 0x87, 0x2f, 0xfe, 0xd9, 0x30, 0xc6, 0xac, 0xd8, 0x76, - 0x0d, 0x63, 0x47, 0x77, 0x78, 0x75, 0x2c, 0x02, 0x85, 0x1b, 0x77, 0x6d, 0x3e, 0x8d, 0xc3, 0x65, - 0xee, 0xf7, 0xbd, 0x31, 0x71, 0x03, 0xdb, 0x98, 0xaf, 0x90, 0xb7, 0x94, 0x27, 0x6e, 0xe6, 0x3c, - 0xbe, 0x9a, 0xd3, 0xbd, 0x6c, 0x5e, 0xb7, 0xed, 0xfd, 0xba, 0xbb, 0x76, 0x94, 0x37, 0x4b, 0x7e, - 0x31, 0xfd, 0x5b, 0xe7, 0x6c, 0x45, 0xaf, 0x81, 0xb3, 0xb8, 0xce, 0x5f, 0x66, 0x4f, 0x9b, 0x59, - 0x8b, 0xed, 0x03, 0x07, 0x4c, 0xbb, 0xb6, 0xb9, 0x0b, 0x7b, 0xaf, 0x3b, 0x92, 0x6f, 0xa9, 0x65, - 0x4e, 0xe0, 0xf8, 0xee, 0xda, 0x1c, 0xab, 0x91, 0x37, 0x73, 0x72, 0xc3, 0x7f, 0xef, 0x19, 0x4b, - 0xe3, 0xe9, 0x61, 0xcb, 0xe8, 0x8b, 0xad, 0xa2, 0xd5, 0xb8, 0xf3, 0xf6, 0xce, 0xdb, 0xbe, 0x31, - 0xd9, 0xee, 0xc9, 0xd1, 0x52, 0xf7, 0xd6, 0xbc, 0x3f, 0xbd, 0x78, 0x41, 0xa6, 0x5e, 0x8c, 0x15, - 0x37, 0x27, 0x0f, 0xab, 0x67, 0x27, 0x73, 0x0c, 0xd3, 0xe8, 0xde, 0x3d, 0xa2, 0x85, 0x6d, 0xc9, - 0xb6, 0xb2, 0xeb, 0x64, 0x97, 0x7e, 0x70, 0x52, 0x4f, 0xa4, 0xb3, 0x72, 0xee, 0x5b, 0xb8, 0x7b, - 0x79, 0x6b, 0x59, 0x3d, 0xd7, 0x30, 0x1f, 0x55, 0x27, 0x7e, 0xb8, 0xb6, 0x36, 0xdb, 0x67, 0x6b, - 0x3b, 0x69, 0x8e, 0xa9, 0xf5, 0x7c, 0x7b, 0x3d, 0x4d, 0xfb, 0xef, 0x66, 0x07, 0x96, 0xd9, 0x1a, - 0x76, 0x34, 0xd9, 0x1e, 0x37, 0xd9, 0x2a, 0xb6, 0xac, 0xda, 0xe8, 0x4a, 0x0f, 0x9b, 0x23, 0x55, - 0x51, 0xa5, 0xe2, 0xbe, 0x4e, 0xaa, 0xfb, 0x2a, 0x10, 0xdd, 0x1b, 0x19, 0x47, 0x14, 0x63, 0x09, - 0x12, 0xc4, 0xa4, 0x44, 0xc8, 0x8e, 0x09, 0x39, 0x4b, 0xe7, 0x10, 0x51, 0x24, 0x5d, 0x48, 0x26, - 0x01, 0xc1, 0x8b, 0x01, 0x41, 0xb0, 0xd1, 0x68, 0xe8, 0xb2, 0x27, 0x34, 0x68, 0xf9, 0x5d, 0xe9, - 0xd5, 0x65, 0x90, 0x48, 0xe2, 0x47, 0xd8, 0x3f, 0x0e, 0xff, 0x9c, 0x71, 0x02, 0xc9, 0xb9, 0x11, - 0x11, 0x1f, 0x70, 0x4c, 0x92, 0x46, 0x48, 0xd1, 0x61, 0x58, 0x6b, 0x34, 0xe4, 0x7f, 0x99, 0x98, - 0x44, 0x44, 0x59, 0xed, 0xcf, 0xc8, 0x14, 0xe3, 0x2b, 0x71, 0x22, 0x15, 0xcf, 0x09, 0x25, 0x11, - 0x13, 0x16, 0x4b, 0x2b, 0xc2, 0x9c, 0x5c, 0x4d, 0xa0, 0x5c, 0x3e, 0x6c, 0xff, 0x01, 0xd9, 0xa5, - 0x2c, 0x90, 0xee, 0x04, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/favicon.ico, do not edit!! -const uint16_t favicon_length = 954; -const uint8_t favicon[] PROGMEM = { - 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x86, 0x00, - 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, - 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, - 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00, 0x4d, 0x49, 0x44, 0x41, 0x54, 0x38, - 0x8d, 0x63, 0xfc, 0xff, 0xff, 0x3f, 0x03, 0xb1, 0x80, 0xd1, 0x9e, 0x01, 0x43, 0x31, 0x13, 0xd1, - 0xba, 0x71, 0x00, 0x8a, 0x0d, 0x60, 0x21, 0xa4, 0x00, 0xd9, 0xd9, 0xff, 0x0f, 0x32, 0x30, 0x52, - 0xdd, 0x05, 0xb4, 0xf1, 0x02, 0xb6, 0xd0, 0xa6, 0x99, 0x0b, 0x68, 0x1f, 0x0b, 0xd8, 0x42, 0x9e, - 0xaa, 0x2e, 0xa0, 0xd8, 0x00, 0x46, 0x06, 0x3b, 0xcc, 0xcc, 0x40, 0xc8, 0xd9, 0x54, 0x75, 0x01, - 0xe5, 0x5e, 0x20, 0x25, 0x3b, 0x63, 0x03, 0x00, 0x3e, 0xb7, 0x11, 0x5a, 0x8d, 0x1c, 0x07, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - - -// Autogenerated from wled00/data/iro.js, do not edit!! -const uint16_t iroJs_length = 9992; -const uint8_t iroJs[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xc5, 0x7d, 0x79, 0x77, 0xe3, 0x36, - 0x96, 0xef, 0xff, 0x73, 0xce, 0x7c, 0x07, 0x99, 0x49, 0x7c, 0x48, 0x0b, 0xa2, 0x25, 0x79, 0xa9, - 0x32, 0x55, 0x1c, 0x9d, 0xa4, 0xb2, 0x55, 0x77, 0x2a, 0x95, 0x49, 0x55, 0xa7, 0xa7, 0xa3, 0x28, - 0x39, 0x14, 0x05, 0x49, 0x2c, 0xd3, 0xa4, 0xc2, 0x45, 0xb6, 0x63, 0xe9, 0xbb, 0xbf, 0xdf, 0xc5, - 0x42, 0x82, 0x5a, 0x6c, 0x27, 0x6f, 0xfa, 0xbd, 0x93, 0x94, 0x08, 0x62, 0xb9, 0x00, 0x2e, 0xee, - 0x0e, 0x80, 0x3e, 0x3d, 0x39, 0xfa, 0xcf, 0xff, 0x68, 0x9d, 0xb4, 0xa2, 0x2c, 0x75, 0x3f, 0xe6, - 0xad, 0xd5, 0x85, 0x7b, 0xe1, 0xf6, 0x45, 0x4e, 0xbf, 0xdb, 0xbb, 0xec, 0xf4, 0xbb, 0xfd, 0x5e, - 0xeb, 0x6f, 0xc1, 0x0d, 0xcf, 0x5b, 0x5f, 0x06, 0x49, 0xc4, 0x63, 0x51, 0xf4, 0x5d, 0x14, 0xf2, - 0x24, 0xe7, 0xd3, 0x56, 0x99, 0x4c, 0x79, 0xd6, 0x7a, 0xfb, 0xc3, 0x77, 0xad, 0xbe, 0xdb, 0x15, - 0x45, 0xf3, 0xa8, 0x58, 0x94, 0x13, 0x37, 0x4c, 0x6f, 0x4e, 0x3f, 0x06, 0xd4, 0xee, 0x54, 0x42, - 0xa6, 0xc2, 0xd3, 0xff, 0xfc, 0x8f, 0xa3, 0x59, 0x99, 0x84, 0x45, 0x94, 0x26, 0x76, 0xc1, 0x12, - 0xe7, 0xc1, 0x4a, 0x27, 0x1f, 0x79, 0x58, 0x58, 0xbe, 0x5f, 0xdc, 0x2f, 0x79, 0x3a, 0x6b, 0xf1, - 0xbb, 0x65, 0x9a, 0x15, 0xf9, 0xf1, 0xb1, 0x45, 0xa0, 0x67, 0x51, 0xc2, 0xa7, 0xd6, 0x91, 0x2e, - 0xbc, 0x49, 0xa7, 0x65, 0xcc, 0x87, 0xf2, 0xe1, 0xaa, 0xaa, 0x7e, 0x62, 0x3b, 0x9e, 0xa5, 0xc1, - 0xd6, 0x90, 0x64, 0xeb, 0xe3, 0x63, 0xf9, 0x74, 0x83, 0x9b, 0xe9, 0x50, 0x26, 0xed, 0xc4, 0xf1, - 0xec, 0xc2, 0x2f, 0xd6, 0xeb, 0x9c, 0xc7, 0x33, 0xc7, 0xc5, 0xf8, 0x08, 0xc6, 0xc6, 0x2e, 0x16, - 0x51, 0xce, 0xaa, 0xf1, 0x61, 0x70, 0x65, 0xce, 0x5b, 0x79, 0x91, 0x45, 0x18, 0xe0, 0x60, 0x15, - 0x64, 0xad, 0x1b, 0x96, 0xb3, 0x84, 0x45, 0x2c, 0x65, 0x77, 0xfe, 0xc3, 0x86, 0x7d, 0xf4, 0x47, - 0x63, 0x96, 0xf9, 0xa7, 0x41, 0x18, 0x15, 0x6b, 0x7e, 0x67, 0x0f, 0xbd, 0x7c, 0x3d, 0x5f, 0x27, - 0xeb, 0xe5, 0xfa, 0x53, 0x67, 0x9d, 0x2d, 0x17, 0xeb, 0x79, 0x16, 0x4d, 0xd7, 0xe9, 0x6d, 0xbe, - 0xbe, 0x49, 0xc2, 0x75, 0x52, 0xdc, 0xae, 0xd1, 0xfb, 0x28, 0x5c, 0x8c, 0xd7, 0x7f, 0xa4, 0xe9, - 0xfa, 0xd7, 0x34, 0x9b, 0xae, 0x7f, 0xed, 0x74, 0x4e, 0xa3, 0x81, 0xee, 0xb3, 0xf5, 0x56, 0x62, - 0x65, 0x96, 0x66, 0x36, 0xf5, 0x17, 0xb5, 0xa2, 0xa4, 0x95, 0x38, 0xc5, 0x28, 0x1a, 0xfb, 0x09, - 0x7e, 0x06, 0x19, 0x2f, 0xca, 0x2c, 0x69, 0x15, 0x9b, 0xaa, 0xc5, 0xbd, 0x5d, 0x38, 0x0f, 0x54, - 0x37, 0xf1, 0x0b, 0x77, 0x19, 0x64, 0x3c, 0x29, 0xbe, 0x4f, 0xa7, 0x7c, 0x90, 0x1c, 0x1f, 0x27, - 0x6e, 0xc6, 0x6f, 0xd2, 0x15, 0x7f, 0xbd, 0x88, 0xe2, 0x29, 0xaa, 0xd5, 0x8d, 0x16, 0xd4, 0x0d, - 0x8b, 0x64, 0xc3, 0x8c, 0x71, 0x56, 0x62, 0x4a, 0xb1, 0x1f, 0x64, 0xf3, 0xf2, 0x06, 0x00, 0xf2, - 0x41, 0x34, 0xb3, 0x13, 0xff, 0xad, 0x8d, 0x39, 0x26, 0x0e, 0x3b, 0x7b, 0x55, 0x15, 0xb8, 0x31, - 0x4f, 0xe6, 0xc5, 0xc2, 0xa1, 0x01, 0x46, 0x3e, 0x46, 0x84, 0xe9, 0x9f, 0x0d, 0xb2, 0x9d, 0x0a, - 0x83, 0xac, 0xdd, 0x76, 0x22, 0x77, 0x59, 0xe6, 0x0b, 0x3b, 0x1e, 0x65, 0x63, 0x47, 0x40, 0x2c, - 0xe3, 0xf8, 0xc8, 0x8f, 0x8e, 0x8f, 0xed, 0xc4, 0x0d, 0x69, 0x4c, 0x18, 0xac, 0x1f, 0x39, 0x4c, - 0xe6, 0x17, 0x18, 0xb0, 0x4c, 0xb8, 0x58, 0xa6, 0xa0, 0x8c, 0x8b, 0x1f, 0xb2, 0x74, 0x99, 0x8b, - 0xae, 0x38, 0xe1, 0x61, 0x2b, 0x7f, 0x95, 0x46, 0xd3, 0x56, 0xd7, 0xf7, 0x81, 0x18, 0x3e, 0x26, - 0x98, 0x78, 0x6c, 0xb5, 0x45, 0x8e, 0xa3, 0x51, 0x86, 0x25, 0x76, 0xaf, 0xf9, 0xbd, 0xea, 0xcc, - 0x2e, 0x7d, 0xc2, 0xce, 0xcc, 0x21, 0xf2, 0x88, 0x79, 0xc1, 0x5b, 0xe2, 0x55, 0x95, 0xa6, 0x46, - 0x2e, 0xb5, 0x09, 0x05, 0xba, 0x52, 0x56, 0x1a, 0x28, 0x94, 0x79, 0x11, 0xcb, 0x24, 0x12, 0xb9, - 0xff, 0x40, 0x64, 0xe7, 0x15, 0x6c, 0x49, 0x3d, 0x7b, 0x09, 0x43, 0x43, 0x0f, 0xc5, 0x7c, 0xe6, - 0x65, 0x2c, 0xf1, 0x08, 0x30, 0x8b, 0xe4, 0x83, 0x7b, 0x5d, 0x96, 0xca, 0x64, 0x2c, 0x1f, 0xa1, - 0x7a, 0xa4, 0x09, 0xa8, 0xad, 0x0c, 0x8b, 0x34, 0xf3, 0xe4, 0xf4, 0x36, 0x7a, 0xf8, 0x37, 0xee, - 0x2a, 0xc1, 0xb2, 0x1e, 0x1f, 0xab, 0x84, 0xcd, 0x1d, 0xc6, 0xeb, 0xd1, 0xbc, 0x23, 0x2a, 0xd0, - 0xc4, 0x51, 0x21, 0xb7, 0x2e, 0x7f, 0x23, 0xe9, 0x8a, 0x08, 0xdc, 0x15, 0x03, 0xf4, 0x0b, 0x26, - 0x5e, 0xd0, 0x65, 0xc1, 0xef, 0x0a, 0xdf, 0xa8, 0x7b, 0x2b, 0xeb, 0xaa, 0x05, 0x03, 0x7e, 0x9d, - 0x0a, 0x70, 0x34, 0x44, 0xa1, 0x1b, 0x31, 0xfc, 0x73, 0x13, 0x37, 0x02, 0x83, 0xde, 0xbd, 0x9b, - 0xa1, 0xeb, 0x76, 0xcf, 0x11, 0x33, 0x18, 0x54, 0x84, 0x3b, 0x48, 0x5e, 0x15, 0xa8, 0xa2, 0xa8, - 0x21, 0x21, 0x6a, 0xd0, 0x04, 0x00, 0xc2, 0x41, 0xd1, 0x28, 0x19, 0x3b, 0x7a, 0xc5, 0x23, 0x37, - 0xd5, 0x7d, 0x20, 0xa9, 0xa6, 0xbc, 0x87, 0xa3, 0x0b, 0x97, 0x12, 0x34, 0x06, 0xd9, 0x5d, 0x3d, - 0xe6, 0xa0, 0xe2, 0x02, 0x16, 0xd5, 0xa4, 0x46, 0x4c, 0xee, 0x46, 0x4e, 0x4d, 0x58, 0xa1, 0x64, - 0xad, 0xc2, 0x4d, 0xe9, 0xc5, 0x9d, 0x04, 0x39, 0xf7, 0x05, 0xe6, 0x13, 0xbf, 0xfb, 0xa7, 0x47, - 0xfc, 0xd0, 0x00, 0x43, 0x03, 0x9f, 0x64, 0x3c, 0xb8, 0xde, 0xa8, 0x99, 0xd0, 0x90, 0x36, 0xf5, - 0x08, 0x39, 0x8d, 0xd0, 0x3e, 0x2a, 0xdc, 0x19, 0x68, 0x15, 0xbf, 0xfe, 0x51, 0x17, 0xd0, 0x7a, - 0xa0, 0xdf, 0x5c, 0xb2, 0x49, 0xe1, 0xac, 0xd7, 0xd1, 0x91, 0xef, 0xdf, 0x80, 0x84, 0x27, 0x29, - 0x9a, 0xf1, 0x1f, 0x39, 0x09, 0xd7, 0x28, 0x99, 0xa3, 0x22, 0x86, 0xb0, 0xa7, 0x80, 0xd9, 0x7b, - 0x32, 0xd7, 0xeb, 0xc4, 0xb1, 0x4b, 0xc7, 0xa0, 0xd5, 0xd2, 0x96, 0xc8, 0x51, 0x14, 0xab, 0xf9, - 0x5d, 0xac, 0x56, 0xee, 0xe6, 0x10, 0xa2, 0x76, 0x53, 0x2a, 0xab, 0x29, 0x24, 0xee, 0xd4, 0xe5, - 0x9d, 0x82, 0x7e, 0x37, 0xce, 0xa0, 0xa0, 0x91, 0xa6, 0x4b, 0xdb, 0x19, 0x38, 0x72, 0x16, 0x99, - 0x1f, 0xf9, 0x92, 0x4c, 0x59, 0xe9, 0xdb, 0xdc, 0x87, 0xc8, 0x28, 0x1c, 0x77, 0xea, 0xb8, 0x29, - 0x23, 0x6e, 0x5b, 0x42, 0xa2, 0x24, 0x6e, 0xc9, 0xf0, 0xcf, 0x3f, 0xea, 0xb1, 0x54, 0x4c, 0x42, - 0x08, 0xcc, 0x6b, 0x3b, 0xc5, 0x18, 0x84, 0x78, 0x01, 0x19, 0x27, 0xee, 0x2d, 0x93, 0x60, 0x30, - 0xfb, 0xd4, 0x4d, 0x6f, 0x13, 0x9e, 0xbd, 0xff, 0xe9, 0x9b, 0xaf, 0x62, 0x4e, 0x12, 0x85, 0x49, - 0xce, 0x61, 0x31, 0x93, 0xd4, 0x58, 0x62, 0xf9, 0xb9, 0xe3, 0x95, 0x0e, 0x9b, 0xda, 0x11, 0x35, - 0xcf, 0x8e, 0xfc, 0xf2, 0xf8, 0x38, 0x40, 0xa6, 0x39, 0xe5, 0xf7, 0x36, 0x4d, 0xb5, 0xa8, 0x27, - 0xcb, 0x72, 0x89, 0x83, 0x90, 0x05, 0x6c, 0xc6, 0x16, 0x6c, 0xc5, 0xa6, 0x6c, 0xce, 0x26, 0x24, - 0x76, 0xb0, 0xb6, 0xeb, 0xf5, 0x47, 0xb6, 0xf4, 0x27, 0x7a, 0xf5, 0xb1, 0xf2, 0xe8, 0xea, 0x0e, - 0x23, 0x8e, 0x7d, 0xb9, 0xe0, 0xe5, 0xb0, 0x1c, 0x75, 0xc7, 0xde, 0x92, 0x88, 0x8f, 0x75, 0x25, - 0xf9, 0x39, 0x2c, 0xf4, 0xbb, 0x0c, 0x9c, 0xe0, 0x7f, 0x6e, 0xe3, 0xb7, 0xd6, 0x1c, 0x45, 0xc5, - 0x3d, 0x20, 0x3a, 0x91, 0x06, 0x19, 0xfa, 0xc4, 0x36, 0x44, 0x27, 0xbc, 0xdd, 0x53, 0x73, 0xf1, - 0xed, 0x99, 0x3f, 0x19, 0x85, 0x63, 0xac, 0xfc, 0x8c, 0x86, 0x01, 0x91, 0xe1, 0xfb, 0x33, 0x7a, - 0xd0, 0x1b, 0xd1, 0xba, 0x4f, 0xef, 0x94, 0x70, 0xa8, 0x9e, 0xc2, 0xf6, 0x80, 0xc7, 0xd0, 0x4b, - 0xb4, 0x78, 0x01, 0xc8, 0x36, 0x78, 0xb5, 0x1c, 0x04, 0xa0, 0x56, 0xea, 0x46, 0xc0, 0x0b, 0x88, - 0x4c, 0x1f, 0x07, 0xf6, 0x40, 0xb5, 0x34, 0x34, 0x49, 0xb5, 0x33, 0x31, 0xd1, 0x0d, 0x80, 0x2c, - 0xb0, 0x3e, 0x09, 0x50, 0x37, 0xf3, 0x67, 0xeb, 0xf5, 0x5d, 0x85, 0x41, 0x29, 0xaf, 0x80, 0x46, - 0x86, 0x6e, 0x0b, 0x25, 0x3c, 0x67, 0xf4, 0x3c, 0xf2, 0x03, 0x60, 0x6a, 0xee, 0x83, 0xf2, 0x46, - 0x63, 0x47, 0x52, 0x73, 0x80, 0xc9, 0x86, 0xeb, 0xf5, 0x82, 0x15, 0x5a, 0xbe, 0x2f, 0x0c, 0x91, - 0x32, 0x45, 0xfd, 0x29, 0x72, 0xb4, 0xe8, 0x77, 0x63, 0x67, 0x41, 0xbf, 0x68, 0x24, 0x11, 0x2e, - 0xa7, 0x88, 0xfa, 0xa5, 0x4f, 0xa3, 0x58, 0x1c, 0xf9, 0x31, 0xc8, 0x5a, 0xb4, 0x5d, 0x18, 0x5a, - 0x0e, 0x3c, 0xe8, 0x55, 0x40, 0x51, 0x23, 0x36, 0xca, 0x8e, 0x48, 0x72, 0x25, 0x6e, 0xb0, 0x5c, - 0x82, 0x31, 0xa4, 0x0a, 0x5c, 0x38, 0x02, 0xae, 0x54, 0xaf, 0x7e, 0xcc, 0x08, 0x7d, 0x48, 0xac, - 0xdc, 0x04, 0x22, 0xf0, 0x7d, 0x34, 0x89, 0x25, 0xaf, 0x49, 0x8c, 0xfa, 0x7d, 0x12, 0x00, 0x2b, - 0x74, 0xe8, 0x08, 0x0c, 0xb5, 0x8a, 0x01, 0x89, 0xbc, 0x9c, 0x67, 0xc5, 0x17, 0x1c, 0x10, 0xb8, - 0xbd, 0x60, 0xb1, 0xb3, 0xb1, 0xd2, 0xa5, 0x12, 0x52, 0x91, 0xc0, 0xad, 0xd0, 0x6e, 0xab, 0x20, - 0x2e, 0xb9, 0x6f, 0x59, 0xce, 0x26, 0xc6, 0x78, 0x0d, 0xe8, 0x6c, 0x8f, 0x54, 0xab, 0xda, 0x45, - 0x98, 0xfc, 0x02, 0x32, 0x43, 0x71, 0x5f, 0xd8, 0x6e, 0xb3, 0x62, 0xe3, 0x80, 0xc0, 0x52, 0x7f, - 0xaa, 0x30, 0x05, 0x4a, 0xaf, 0x21, 0x1c, 0x35, 0x21, 0x08, 0x4d, 0x19, 0xfa, 0xa5, 0x26, 0xe2, - 0xb0, 0xd3, 0x19, 0x38, 0xaa, 0x19, 0x88, 0xe7, 0xf8, 0xf8, 0xde, 0xa6, 0xa7, 0x33, 0x90, 0xf5, - 0x96, 0x66, 0x85, 0x89, 0xa8, 0xf0, 0xbd, 0x4d, 0x4f, 0x26, 0x48, 0x92, 0x78, 0x60, 0xae, 0x40, - 0x76, 0x07, 0xe1, 0xab, 0x79, 0x05, 0x16, 0xb4, 0xf6, 0x95, 0x3d, 0xa7, 0x8a, 0xf3, 0x51, 0xbb, - 0x5d, 0x3d, 0x0c, 0xe6, 0xfb, 0x5c, 0x9b, 0x17, 0xd5, 0xda, 0x44, 0x8a, 0xf9, 0x1d, 0x45, 0xf9, - 0xb0, 0xbd, 0xac, 0x49, 0x9a, 0xc6, 0x3c, 0x30, 0xc5, 0xbb, 0x03, 0xa3, 0x45, 0x19, 0x0d, 0x89, - 0x68, 0xe8, 0x38, 0x15, 0x21, 0x7c, 0x9e, 0x65, 0xc1, 0xbd, 0x1b, 0xe5, 0xe2, 0x09, 0x0e, 0x73, - 0xb4, 0xaa, 0xc9, 0x30, 0xbc, 0x0c, 0xa2, 0xdb, 0x30, 0x3c, 0xd0, 0x3f, 0x6c, 0x0e, 0x31, 0x04, - 0xd5, 0x5e, 0x01, 0x1d, 0x26, 0xf6, 0x1e, 0x26, 0x3d, 0x38, 0x1c, 0x2d, 0x06, 0x89, 0x20, 0x51, - 0xd7, 0x22, 0x53, 0x30, 0x99, 0x1b, 0x35, 0xd0, 0x2c, 0x29, 0x6f, 0x26, 0x3c, 0xdb, 0xd3, 0x2a, - 0x14, 0xb0, 0x99, 0x12, 0x60, 0x62, 0x36, 0x83, 0xba, 0x43, 0x37, 0x95, 0xaa, 0xc4, 0x17, 0x5a, - 0x49, 0x2b, 0xd8, 0x81, 0x34, 0xe4, 0x60, 0x5b, 0x88, 0x15, 0x05, 0x3b, 0x08, 0x65, 0xcd, 0x8a, - 0xca, 0x74, 0xa9, 0xec, 0x99, 0x44, 0x28, 0x1f, 0xb0, 0xe5, 0x86, 0x90, 0xe1, 0x15, 0x55, 0x41, - 0x54, 0xaf, 0xc3, 0x4c, 0xaf, 0x83, 0xd5, 0xb1, 0x84, 0xa1, 0xd4, 0x1d, 0x0f, 0x0b, 0x37, 0xe7, - 0xc2, 0x3a, 0x02, 0x1d, 0xdf, 0x93, 0x90, 0x44, 0x5b, 0x68, 0x36, 0x7f, 0x67, 0x22, 0x58, 0xb2, - 0x23, 0x52, 0x4f, 0x99, 0x5b, 0xf0, 0xbc, 0x80, 0xcd, 0x3c, 0x8c, 0xda, 0xd6, 0xf2, 0xce, 0xf2, - 0xd4, 0x8a, 0x0e, 0x2d, 0xcb, 0x33, 0xfa, 0xfa, 0xd1, 0xae, 0xb4, 0x8b, 0x14, 0xb4, 0x4a, 0xea, - 0xb2, 0x50, 0xa0, 0x0e, 0xe3, 0xa7, 0x21, 0x40, 0x45, 0xf0, 0xa1, 0x15, 0xc6, 0x41, 0x9e, 0x7f, - 0x0f, 0xdf, 0x40, 0x8c, 0x4a, 0xbd, 0x03, 0xb0, 0xa7, 0x52, 0x46, 0xae, 0xa8, 0xe5, 0x25, 0x90, - 0x90, 0x96, 0xb6, 0x6a, 0x44, 0x71, 0x4d, 0x18, 0x58, 0x95, 0xfb, 0x58, 0x42, 0x72, 0x84, 0xc0, - 0xc0, 0x0c, 0x29, 0x87, 0xed, 0x2c, 0x57, 0xe4, 0x94, 0x6e, 0x98, 0xe7, 0x1f, 0xc8, 0xde, 0x89, - 0xa4, 0x24, 0xd8, 0xb7, 0xaa, 0x19, 0x68, 0xb5, 0xae, 0x68, 0x59, 0x50, 0x58, 0x52, 0xda, 0x67, - 0x82, 0xe6, 0x52, 0xb2, 0x45, 0x33, 0x07, 0xe8, 0x11, 0xa9, 0x08, 0xb2, 0xdb, 0xa6, 0xb9, 0x82, - 0xdb, 0x69, 0xa6, 0x91, 0xa8, 0x14, 0x8b, 0x22, 0x07, 0xa0, 0xa2, 0x51, 0x3c, 0x26, 0x2c, 0xe2, - 0x21, 0x6b, 0x42, 0x99, 0x21, 0xed, 0x6c, 0xa8, 0x7f, 0x2b, 0xd5, 0xeb, 0x02, 0xbe, 0x96, 0x13, - 0x1b, 0xf5, 0xc6, 0x43, 0x1b, 0x3e, 0xcd, 0x91, 0x40, 0x16, 0x59, 0xa5, 0xcb, 0x38, 0x08, 0xb9, - 0x7d, 0xfa, 0x3a, 0x58, 0x62, 0x7d, 0xf9, 0xa7, 0xa7, 0xd4, 0x13, 0xf8, 0xc8, 0xb7, 0xc1, 0x99, - 0x89, 0x5b, 0xa4, 0xdf, 0xa5, 0xb7, 0x3c, 0x7b, 0x0d, 0x1b, 0xc4, 0x76, 0x1c, 0x32, 0x93, 0x87, - 0xb0, 0x26, 0x1d, 0x37, 0x8f, 0xe1, 0xa2, 0xd9, 0x7d, 0x88, 0x8f, 0xa1, 0x9d, 0xad, 0xd7, 0x85, - 0x1b, 0x4c, 0xa7, 0x5f, 0xad, 0x20, 0x1b, 0xbf, 0x8b, 0xf2, 0x82, 0x43, 0xc5, 0x62, 0xed, 0x57, - 0x42, 0x9a, 0x83, 0xd6, 0xd6, 0x6b, 0xfa, 0x85, 0x4b, 0xe3, 0x38, 0x44, 0x0b, 0x44, 0x13, 0xca, - 0x77, 0xd8, 0xd7, 0x04, 0xde, 0x56, 0x8c, 0x1c, 0x8b, 0x24, 0x2c, 0xc6, 0x5d, 0x04, 0x73, 0xb1, - 0x4a, 0xea, 0x15, 0xd3, 0xbf, 0x51, 0xe9, 0x23, 0x48, 0xb5, 0x44, 0x98, 0xee, 0x43, 0x41, 0x63, - 0x26, 0xe5, 0x78, 0xfb, 0xe4, 0x18, 0x9a, 0x4f, 0x83, 0x64, 0xce, 0xb3, 0xb4, 0xcc, 0xe3, 0xfb, - 0xf7, 0xbc, 0x78, 0x93, 0xa0, 0xdb, 0x6f, 0x3f, 0xbc, 0xfd, 0x4e, 0x41, 0xb4, 0x77, 0xf1, 0xf2, - 0xeb, 0x1d, 0x04, 0xeb, 0xb5, 0x37, 0x94, 0x78, 0x19, 0xaa, 0x3e, 0xd6, 0x6b, 0x41, 0xbc, 0xd1, - 0x50, 0x4f, 0xe4, 0xf3, 0x02, 0xcb, 0x3c, 0x29, 0x0b, 0xfe, 0xfd, 0x7b, 0xdb, 0x5a, 0x14, 0xc5, - 0xd2, 0x3b, 0x3d, 0xbd, 0xbd, 0xbd, 0x75, 0x6f, 0xcf, 0xdc, 0x34, 0x9b, 0x9f, 0xf6, 0xae, 0xae, - 0xae, 0x4e, 0x05, 0x24, 0x8b, 0x6d, 0x23, 0xd5, 0x13, 0x3c, 0xf3, 0xd7, 0x01, 0x10, 0x8f, 0x3d, - 0x39, 0x2c, 0x72, 0x4a, 0x9b, 0xfd, 0x08, 0xe6, 0x34, 0xa4, 0xea, 0xca, 0xb4, 0xf1, 0xc9, 0x76, - 0x2f, 0x46, 0x52, 0x4c, 0x8c, 0x61, 0x05, 0x72, 0x5a, 0xa7, 0xa1, 0x7a, 0x92, 0x7d, 0x6c, 0xba, - 0x7b, 0xd7, 0xf6, 0x96, 0xe5, 0x47, 0x6c, 0x29, 0xb9, 0xb4, 0x61, 0x0c, 0xb1, 0x25, 0xbb, 0x67, - 0xb7, 0xec, 0x9a, 0xc8, 0x0a, 0x70, 0x89, 0x9c, 0x2b, 0xc3, 0x2c, 0x71, 0x0d, 0xef, 0xa4, 0x21, - 0x19, 0x61, 0x0e, 0xa0, 0x5f, 0xd2, 0x9b, 0x98, 0xc3, 0xa0, 0xc8, 0xee, 0xa5, 0x52, 0xde, 0xa3, - 0xe9, 0xae, 0x85, 0xc8, 0x5d, 0x92, 0x6d, 0x28, 0xc4, 0xda, 0xbd, 0x8f, 0xb6, 0xd7, 0xda, 0x07, - 0xf9, 0x40, 0x3a, 0xec, 0xf8, 0x38, 0x1b, 0x05, 0x2e, 0x94, 0xca, 0xad, 0x1f, 0x0c, 0xef, 0x87, - 0xf7, 0xb2, 0xa6, 0x54, 0xa8, 0x5e, 0xe0, 0x46, 0x70, 0xa6, 0x22, 0x37, 0x1c, 0x4e, 0xc8, 0x74, - 0xc2, 0x90, 0xa0, 0x74, 0x43, 0x38, 0xf0, 0x64, 0xe7, 0x78, 0xb6, 0x85, 0xba, 0x45, 0x4a, 0x7d, - 0x59, 0xa0, 0xb9, 0xeb, 0xe3, 0xe3, 0x6b, 0xb7, 0xca, 0x01, 0xba, 0xc9, 0x3c, 0x1e, 0x52, 0x1b, - 0xb4, 0xe4, 0xb7, 0x40, 0xca, 0x92, 0xdd, 0x3a, 0x9e, 0x5d, 0xe7, 0xbc, 0x11, 0x39, 0x6c, 0x66, - 0xce, 0xd4, 0xbf, 0x66, 0x33, 0xd5, 0xd6, 0xff, 0xc3, 0x61, 0xb0, 0xa5, 0xee, 0xdd, 0xbc, 0x9c, - 0xd8, 0x33, 0xaa, 0x27, 0x3d, 0xa9, 0x25, 0x52, 0x79, 0x11, 0x14, 0x1c, 0x5c, 0xa4, 0x52, 0xc4, - 0x49, 0x12, 0x8e, 0x70, 0xae, 0x6e, 0x91, 0xbe, 0xf5, 0x33, 0xb6, 0xc0, 0x38, 0xc9, 0xf0, 0xc7, - 0xeb, 0x8d, 0xa1, 0x0c, 0x67, 0xee, 0x47, 0x50, 0x36, 0x7e, 0x7d, 0xd5, 0x5c, 0xdb, 0x45, 0xd7, - 0xee, 0x9c, 0x17, 0x5f, 0xc2, 0xa8, 0x5f, 0xf1, 0xe9, 0x7b, 0x2a, 0xf8, 0x3a, 0x4b, 0x6f, 0x84, - 0x67, 0x7b, 0x7c, 0xfc, 0x56, 0x34, 0xd0, 0x2d, 0x86, 0xf4, 0x22, 0x0c, 0x6a, 0x24, 0x1c, 0x0f, - 0x3f, 0xec, 0x70, 0x63, 0x7b, 0x29, 0x6a, 0x39, 0x6c, 0xe1, 0xc8, 0x01, 0x3c, 0xd6, 0x8f, 0x1c, - 0x09, 0xcd, 0xe5, 0x66, 0x99, 0x26, 0x20, 0xae, 0x7f, 0x46, 0x71, 0xfc, 0x16, 0x1e, 0x47, 0x41, - 0xd6, 0xdf, 0x6e, 0xae, 0xad, 0x07, 0x6f, 0x14, 0x7e, 0x19, 0x4d, 0x55, 0x8b, 0x54, 0x2a, 0xe2, - 0x99, 0x53, 0x89, 0xdf, 0xe7, 0x8d, 0x00, 0xd6, 0xdd, 0x81, 0xa1, 0xfc, 0xc8, 0x43, 0x8e, 0x56, - 0xaa, 0xee, 0x23, 0x85, 0x72, 0x71, 0x8f, 0x0c, 0x38, 0xf9, 0x22, 0x2d, 0xe3, 0xe9, 0x6b, 0xdd, - 0xe0, 0x1f, 0xcb, 0x29, 0x3a, 0x56, 0x5a, 0xef, 0x40, 0xa9, 0x44, 0x1d, 0x00, 0x49, 0x47, 0x72, - 0x87, 0x04, 0x68, 0x2d, 0x99, 0x58, 0xe4, 0x1e, 0x43, 0xe9, 0x14, 0x3a, 0x09, 0x7a, 0x5a, 0x76, - 0x98, 0x0f, 0xf3, 0x23, 0xb2, 0x12, 0xd3, 0x61, 0xee, 0xe1, 0x57, 0xba, 0xfc, 0x09, 0xbc, 0x07, - 0xf2, 0x1d, 0xa4, 0x25, 0x9f, 0xd4, 0x0e, 0x28, 0x99, 0xf4, 0x78, 0x85, 0x9d, 0x2e, 0x2c, 0x4a, - 0x4a, 0x80, 0xce, 0xc1, 0x60, 0xca, 0x18, 0xdd, 0xec, 0xc5, 0x86, 0x9e, 0xc3, 0xde, 0xec, 0x6a, - 0xf0, 0x1b, 0x69, 0x00, 0xab, 0xd1, 0xb3, 0xa9, 0xa6, 0xa2, 0x2d, 0x92, 0xdd, 0x37, 0x37, 0xc1, - 0xec, 0x6f, 0x15, 0xb3, 0xeb, 0x99, 0x8a, 0x89, 0x52, 0x03, 0xbf, 0xc0, 0x44, 0x34, 0xbf, 0x68, - 0xec, 0xb0, 0x1d, 0xe8, 0x8e, 0x98, 0xf6, 0xe7, 0xca, 0x43, 0x82, 0xf3, 0x10, 0x28, 0xff, 0xe4, - 0x9d, 0x5e, 0xed, 0x80, 0x0c, 0x9e, 0x61, 0xa0, 0xb8, 0x5f, 0x6b, 0x7e, 0x2f, 0xa8, 0x89, 0x0b, - 0xf4, 0x22, 0x8c, 0xfa, 0xd7, 0x12, 0xa4, 0x70, 0x47, 0xdf, 0xda, 0x82, 0x05, 0x32, 0x1a, 0xd8, - 0x56, 0x39, 0xc4, 0x38, 0xe8, 0x5d, 0xfb, 0x10, 0xa2, 0xf8, 0x7d, 0x12, 0x2c, 0xb1, 0xc8, 0xca, - 0x9a, 0x97, 0x28, 0x02, 0x0b, 0xcf, 0x0f, 0x97, 0xda, 0x90, 0x93, 0x00, 0xf3, 0x7e, 0x4b, 0x9c, - 0x92, 0x30, 0x45, 0x8f, 0x32, 0x9a, 0xe0, 0xa6, 0x03, 0x42, 0xc1, 0x8d, 0x76, 0x95, 0x35, 0x73, - 0x57, 0x28, 0x74, 0x18, 0xe4, 0x5b, 0x10, 0xc7, 0xc4, 0x04, 0xd5, 0x80, 0x56, 0xf5, 0xc8, 0x4c, - 0xae, 0xd1, 0x83, 0xda, 0x97, 0x6b, 0x0b, 0xa1, 0xed, 0xb0, 0x89, 0x00, 0x7f, 0x8d, 0x96, 0x91, - 0xb4, 0x53, 0x84, 0x65, 0x21, 0xec, 0x43, 0xd3, 0xa9, 0x37, 0xc5, 0xbf, 0x14, 0xfd, 0x18, 0xb6, - 0xf4, 0x85, 0x41, 0x80, 0x72, 0xa1, 0x56, 0x5a, 0x32, 0x93, 0xe4, 0x87, 0xff, 0x92, 0xaf, 0xe6, - 0xc2, 0x26, 0x11, 0xab, 0xb3, 0x5e, 0x73, 0x6d, 0xbc, 0x6b, 0x16, 0x2a, 0x85, 0xad, 0x93, 0x83, - 0x74, 0xf3, 0x57, 0x95, 0xdb, 0x91, 0x37, 0x22, 0x27, 0xf0, 0x47, 0x46, 0x39, 0x39, 0xa4, 0x8a, - 0xd1, 0x15, 0xb0, 0xe1, 0x19, 0x92, 0xa1, 0x4b, 0x91, 0x2c, 0x12, 0xfb, 0x5e, 0xe8, 0xc6, 0x29, - 0x90, 0x42, 0x76, 0x44, 0x55, 0x07, 0x3c, 0x56, 0xf8, 0x21, 0xa3, 0xf6, 0xd2, 0x27, 0x94, 0x8e, - 0x6a, 0x6d, 0x43, 0x1b, 0x06, 0xbc, 0x6e, 0xa2, 0xf4, 0xd2, 0x34, 0x0d, 0x45, 0x38, 0xd2, 0x0d, - 0xd1, 0xa4, 0xe0, 0x64, 0xc8, 0x91, 0x4b, 0x68, 0xaf, 0x28, 0x8a, 0xc1, 0x87, 0x5b, 0xc5, 0x2a, - 0xd2, 0xb0, 0x5f, 0xaf, 0xf7, 0xbb, 0xdd, 0xee, 0x29, 0x21, 0x82, 0xa9, 0x2e, 0xbc, 0xfd, 0xad, - 0x6d, 0x55, 0xcc, 0x4a, 0xe9, 0x48, 0x1b, 0x1a, 0xb2, 0x9e, 0x35, 0xfc, 0x58, 0x7f, 0xa5, 0x70, - 0x21, 0x9c, 0x39, 0x78, 0x64, 0xa5, 0x11, 0x47, 0x1b, 0x2b, 0x4b, 0xb3, 0x70, 0xb1, 0xc2, 0x81, - 0xbf, 0x82, 0xdd, 0x70, 0x24, 0x9d, 0x27, 0xa3, 0x85, 0xff, 0x51, 0x1a, 0x77, 0x92, 0x8a, 0x54, - 0xb4, 0x8f, 0xa6, 0x07, 0xcb, 0x0c, 0xec, 0x67, 0x57, 0xeb, 0x09, 0xef, 0xdd, 0x71, 0x0f, 0xd8, - 0x53, 0xf0, 0xee, 0x57, 0x07, 0xcb, 0x62, 0xd2, 0x64, 0xeb, 0x75, 0x40, 0xcb, 0x36, 0x03, 0x77, - 0x92, 0x3c, 0x79, 0x47, 0x4c, 0xf9, 0x4e, 0x18, 0x8a, 0x91, 0xae, 0xe8, 0xcf, 0x44, 0x09, 0x6c, - 0x73, 0xb2, 0x48, 0x77, 0xa9, 0x4d, 0x39, 0x02, 0xc2, 0xe1, 0x2c, 0xa5, 0x45, 0x2c, 0x1e, 0xc9, - 0x7a, 0x4d, 0xee, 0x42, 0xa9, 0x62, 0x3b, 0xa3, 0x72, 0x0c, 0x9e, 0xad, 0x6b, 0x25, 0x0e, 0xdf, - 0xeb, 0xe6, 0x26, 0xa8, 0x88, 0xbe, 0x84, 0x2d, 0x40, 0x74, 0x59, 0x0a, 0xa7, 0x80, 0x87, 0xd7, - 0x7c, 0xaa, 0x5e, 0x09, 0x94, 0x30, 0xa2, 0xa9, 0xa2, 0xea, 0x82, 0xa0, 0xab, 0x2e, 0xe0, 0x2a, - 0xc1, 0xd4, 0x59, 0x80, 0x0d, 0x62, 0x29, 0x82, 0x92, 0x2d, 0x01, 0xc3, 0x30, 0xeb, 0x9a, 0xbb, - 0xc9, 0x94, 0xe5, 0xd1, 0x3c, 0x79, 0x27, 0xb7, 0x28, 0x8e, 0xf4, 0x32, 0x1e, 0x1f, 0x4b, 0x3e, - 0xba, 0x23, 0x30, 0x84, 0x2b, 0x35, 0x24, 0x0c, 0x1d, 0x8b, 0x5b, 0x59, 0x4c, 0x2b, 0x69, 0xb5, - 0x20, 0x47, 0x26, 0x8e, 0xc8, 0xd7, 0x53, 0x59, 0xb6, 0x4a, 0x29, 0x93, 0x58, 0xd5, 0x20, 0xc3, - 0x58, 0x25, 0x1d, 0x56, 0x4d, 0x6d, 0x07, 0xac, 0x2a, 0x20, 0xc0, 0x2a, 0x29, 0x40, 0x57, 0xd9, - 0x76, 0x95, 0xae, 0x2b, 0x93, 0xf8, 0x2b, 0x36, 0x76, 0x44, 0x1e, 0xa3, 0x21, 0x0a, 0x42, 0x47, - 0x9a, 0x6f, 0xd3, 0x68, 0x36, 0x43, 0x25, 0x29, 0xd6, 0x37, 0x61, 0x50, 0x84, 0x14, 0x90, 0x7c, - 0xb8, 0x71, 0x53, 0xe5, 0x42, 0x6e, 0x6a, 0xb7, 0xb3, 0xb6, 0x2b, 0xa7, 0x5b, 0xbb, 0x15, 0x03, - 0x8a, 0x93, 0xea, 0x10, 0x21, 0xec, 0xc0, 0x68, 0xd7, 0x04, 0xb0, 0x77, 0xa0, 0x47, 0xee, 0xd4, - 0xd9, 0xdc, 0xb8, 0x21, 0x85, 0xb6, 0x43, 0xea, 0xbd, 0x02, 0xff, 0x95, 0x76, 0x5f, 0x09, 0xd6, - 0xbe, 0x70, 0xf0, 0xb0, 0x90, 0x56, 0x73, 0x58, 0x66, 0x14, 0xf5, 0xf1, 0x93, 0x1d, 0xd8, 0x66, - 0x04, 0xf6, 0xfb, 0x9d, 0x4d, 0x0f, 0x12, 0x73, 0x37, 0x6e, 0x99, 0xdc, 0x48, 0xe3, 0xa4, 0x4a, - 0x02, 0x00, 0x83, 0x3a, 0xd1, 0x41, 0xae, 0xaf, 0xec, 0x4c, 0x39, 0xf1, 0x30, 0xe5, 0x41, 0x73, - 0x87, 0x02, 0xd3, 0xa0, 0x84, 0x48, 0xe9, 0x7a, 0x48, 0x4f, 0x38, 0xe7, 0x84, 0x73, 0xe1, 0xa6, - 0xc7, 0x7e, 0x15, 0x04, 0x40, 0x59, 0x26, 0x7c, 0x7e, 0x21, 0xbd, 0xb2, 0x2d, 0x3d, 0x2d, 0xfb, - 0x17, 0xc8, 0xdb, 0x5f, 0xb4, 0x8b, 0x3f, 0x60, 0x2c, 0x93, 0xba, 0x27, 0x83, 0x02, 0xd6, 0x41, - 0x3c, 0xea, 0x23, 0x11, 0xe2, 0xb9, 0x84, 0x78, 0x2e, 0x5f, 0x65, 0x5a, 0x3c, 0x97, 0x10, 0xcf, - 0x19, 0xd8, 0x81, 0xa2, 0x3d, 0xf4, 0x94, 0x51, 0x12, 0x39, 0x32, 0x4e, 0x31, 0x22, 0x6e, 0xac, - 0xc0, 0x1f, 0x1a, 0x65, 0xa6, 0xdb, 0x61, 0x58, 0xc7, 0x12, 0xc5, 0x55, 0xf5, 0xf9, 0x16, 0x3d, - 0xa0, 0xe7, 0xe8, 0x55, 0x65, 0xd1, 0x44, 0x14, 0xa4, 0x94, 0x11, 0x1b, 0xb9, 0x97, 0xe5, 0xf2, - 0x04, 0x82, 0x34, 0x0b, 0x26, 0x31, 0x8d, 0xbd, 0x7e, 0x21, 0x27, 0x89, 0xd1, 0xf4, 0x93, 0x59, - 0x34, 0x2f, 0x65, 0x39, 0x8c, 0xe6, 0x9a, 0xcb, 0xc8, 0x43, 0xcf, 0xdc, 0xdb, 0x2c, 0x2a, 0x54, - 0x99, 0xc3, 0x24, 0x8f, 0xba, 0x72, 0x83, 0xaf, 0x0a, 0x6f, 0x14, 0x00, 0x43, 0x91, 0x93, 0xcc, - 0xa4, 0x83, 0x89, 0xad, 0xe7, 0x63, 0x4f, 0x7c, 0xd5, 0x2e, 0xc8, 0x73, 0x30, 0x3a, 0x14, 0xad, - 0x11, 0x1d, 0xd2, 0xd3, 0x48, 0xea, 0x7d, 0x31, 0x16, 0xf9, 0x3d, 0x4c, 0x69, 0x67, 0xb7, 0x6b, - 0x7b, 0x6a, 0xba, 0x29, 0x97, 0xb1, 0x02, 0xd5, 0x49, 0xed, 0x8c, 0x2c, 0x82, 0xfc, 0xdd, 0x6d, - 0xa2, 0x87, 0x29, 0x05, 0x39, 0xc9, 0x4b, 0xe2, 0x5d, 0xda, 0xc6, 0xca, 0x68, 0xe7, 0x6a, 0x53, - 0x6d, 0xf6, 0x39, 0x14, 0xc5, 0x8c, 0xef, 0xe5, 0xfe, 0x64, 0xd5, 0x39, 0xb8, 0x86, 0x36, 0x21, - 0xdf, 0x18, 0x70, 0xe1, 0x3e, 0xbe, 0x97, 0x76, 0x46, 0x23, 0x9c, 0x2f, 0x17, 0x43, 0x2c, 0xde, - 0x47, 0x12, 0x15, 0x94, 0x10, 0xf6, 0xc8, 0xf1, 0xb1, 0xcc, 0x24, 0xb1, 0x2e, 0x12, 0xd2, 0x87, - 0xa8, 0x2b, 0x38, 0xce, 0x60, 0x1f, 0xb9, 0xc3, 0x48, 0xa6, 0xbd, 0x15, 0x3b, 0x62, 0xf5, 0x8e, - 0x92, 0xe3, 0xac, 0xd7, 0x6f, 0x29, 0xc7, 0xd8, 0xd0, 0x13, 0xa5, 0x42, 0x22, 0x51, 0x42, 0x6c, - 0x03, 0x24, 0x2a, 0xf7, 0x46, 0x85, 0xe4, 0x1c, 0xc6, 0x45, 0x29, 0x3c, 0xdd, 0xc6, 0x54, 0x80, - 0xc2, 0x50, 0x99, 0x5d, 0xbe, 0xb9, 0x2a, 0x35, 0xc8, 0x26, 0x20, 0x74, 0xab, 0x3b, 0xe9, 0x1e, - 0x00, 0xa9, 0xdc, 0xb8, 0x77, 0x2c, 0xa7, 0x6d, 0x88, 0xc4, 0xdf, 0x33, 0x33, 0x2c, 0xc9, 0x4d, - 0x94, 0xf3, 0xa1, 0x7a, 0x1a, 0x8d, 0x8b, 0x05, 0x4f, 0xdc, 0x09, 0x54, 0xb5, 0xad, 0xcb, 0x32, - 0x9e, 0xa7, 0xf1, 0x4a, 0x04, 0x08, 0x80, 0xf7, 0x0f, 0xd1, 0x0d, 0x4f, 0x4b, 0xf0, 0xc3, 0xde, - 0x7d, 0x9a, 0x9b, 0x1d, 0x6b, 0xac, 0xa6, 0xaf, 0x6c, 0x40, 0x8a, 0x28, 0x1a, 0x90, 0xd5, 0x04, - 0xbe, 0x85, 0x3f, 0x0a, 0x3a, 0x38, 0xca, 0xdc, 0x48, 0xca, 0x50, 0x29, 0x24, 0x2a, 0x96, 0xd3, - 0xb6, 0x57, 0x23, 0x73, 0x9f, 0xf7, 0xf4, 0x55, 0x96, 0x91, 0xa3, 0x5e, 0xd1, 0x84, 0xfd, 0xbc, - 0x16, 0x14, 0x4d, 0xdc, 0x72, 0xce, 0xb2, 0x86, 0x18, 0x7f, 0x4d, 0xe2, 0xc7, 0x21, 0x4b, 0x3e, - 0x4a, 0x4a, 0x3e, 0xd8, 0x53, 0x48, 0x1b, 0x5f, 0x8a, 0x76, 0xa9, 0xd7, 0x6b, 0x3f, 0xd3, 0x42, - 0x8b, 0xb6, 0x20, 0x21, 0xa5, 0x8b, 0x45, 0x96, 0xde, 0x82, 0xae, 0x59, 0xea, 0xdf, 0x89, 0x90, - 0x67, 0xe1, 0x5b, 0xf6, 0xd0, 0x1b, 0x75, 0x7e, 0xf9, 0xa5, 0x3d, 0x1e, 0xfe, 0xf2, 0xcb, 0xf4, - 0xe4, 0x97, 0x5f, 0x5c, 0x3c, 0xda, 0x9f, 0x0d, 0x9d, 0x75, 0xa3, 0x80, 0x72, 0x2c, 0x16, 0xfb, - 0xd6, 0xe8, 0x97, 0x5f, 0xf2, 0xf5, 0x2f, 0xbf, 0xd8, 0xe3, 0xb6, 0x6d, 0xb5, 0x8b, 0xb6, 0xe5, - 0x8c, 0x18, 0x5e, 0xf3, 0x43, 0xaf, 0x48, 0x03, 0xa6, 0x33, 0xb4, 0xd8, 0xf2, 0x4f, 0xb7, 0x3d, - 0x08, 0xea, 0x37, 0x11, 0x35, 0xf8, 0x91, 0xcf, 0xbf, 0xba, 0x5b, 0xda, 0x56, 0x36, 0x9f, 0x58, - 0x6d, 0x18, 0x04, 0xdf, 0x6e, 0xe7, 0x06, 0x56, 0x7b, 0xe9, 0xb0, 0x1f, 0x1a, 0xd9, 0x8b, 0x3c, - 0x16, 0x95, 0x3f, 0xdd, 0xce, 0x95, 0x95, 0x3f, 0xf8, 0xd6, 0xaf, 0x98, 0xf7, 0x27, 0xc3, 0x75, - 0xf7, 0x8e, 0x26, 0xfc, 0x4f, 0xe0, 0x67, 0xd4, 0xed, 0x5c, 0x05, 0x9d, 0xd9, 0xe7, 0x9d, 0xaf, - 0xc7, 0x0f, 0xbd, 0x0d, 0x32, 0x5f, 0x6f, 0x65, 0xf6, 0x29, 0xf3, 0x4b, 0x13, 0xe0, 0x87, 0xf6, - 0x3f, 0xc5, 0x7f, 0xd6, 0xa7, 0x96, 0xc3, 0xbe, 0xde, 0x57, 0xa2, 0xca, 0xbe, 0x6b, 0x96, 0xbd, - 0x16, 0xff, 0x89, 0x92, 0x2f, 0xf6, 0x95, 0xa8, 0xb2, 0xdf, 0xfd, 0xb7, 0x41, 0xb1, 0x80, 0xe5, - 0x3e, 0x67, 0xdf, 0xc8, 0x24, 0x6c, 0xc9, 0x64, 0xca, 0x7e, 0x96, 0x2f, 0xb3, 0x38, 0x4d, 0xb3, - 0xfa, 0x68, 0xc3, 0xdf, 0xb6, 0x74, 0x89, 0xa8, 0x73, 0x13, 0x25, 0xb6, 0x4c, 0x04, 0x77, 0x42, - 0x56, 0x35, 0xf4, 0xc9, 0xdf, 0x4d, 0xf1, 0xd5, 0xe9, 0xbd, 0x2a, 0x2a, 0x53, 0xd9, 0xfa, 0x0c, - 0xfd, 0x67, 0xfe, 0x32, 0xc8, 0x72, 0xfe, 0x75, 0x9c, 0x06, 0xa4, 0xb2, 0xab, 0x00, 0xf8, 0x30, - 0x39, 0xed, 0x75, 0xbb, 0x27, 0x99, 0x97, 0xd5, 0xa0, 0xfe, 0xdb, 0x08, 0x9e, 0x89, 0x56, 0x6f, - 0x48, 0xcd, 0xb3, 0xde, 0xa5, 0xd1, 0xdd, 0x3f, 0x1a, 0x9b, 0xe8, 0x45, 0xfa, 0x5e, 0x04, 0x86, - 0x6d, 0xd4, 0x71, 0x97, 0x01, 0xb1, 0x49, 0x56, 0xd8, 0x7d, 0x66, 0x75, 0x2d, 0x67, 0x43, 0x43, - 0xfa, 0xc9, 0x37, 0x8e, 0x8a, 0x54, 0x40, 0x62, 0x63, 0xa7, 0xfd, 0x53, 0xff, 0x61, 0xe1, 0x75, - 0x59, 0x8e, 0x7f, 0x2b, 0xfc, 0x0b, 0xbc, 0x1e, 0x64, 0xab, 0x12, 0x5b, 0x60, 0xcb, 0x4a, 0x66, - 0xa5, 0xc9, 0xeb, 0x05, 0x99, 0xe2, 0x70, 0xa2, 0xc5, 0x7b, 0x94, 0x44, 0x45, 0x14, 0xc4, 0x3f, - 0x09, 0x0b, 0x71, 0x52, 0x49, 0xe4, 0x4f, 0x65, 0xbf, 0x85, 0x1f, 0xd7, 0x72, 0xa9, 0x3a, 0x11, - 0x42, 0x00, 0xfd, 0xad, 0xcd, 0x8d, 0xdd, 0x0d, 0x0b, 0xe7, 0xd4, 0xa0, 0x2b, 0x93, 0x78, 0xce, - 0xd8, 0xcb, 0xcd, 0xa7, 0xa7, 0x32, 0xd4, 0x5f, 0x38, 0x43, 0xd1, 0xdf, 0x82, 0xdf, 0x49, 0x14, - 0xf8, 0x85, 0x77, 0xfa, 0x2b, 0x51, 0xf2, 0x70, 0xab, 0x06, 0xf2, 0x8c, 0x1a, 0x44, 0xbe, 0x75, - 0x0d, 0x2d, 0xf5, 0x91, 0xab, 0xeb, 0xd4, 0x82, 0x45, 0x1f, 0xfb, 0x39, 0xaa, 0x47, 0x26, 0x85, - 0x02, 0x51, 0x9b, 0x94, 0x43, 0xd6, 0x9b, 0x04, 0x0a, 0x1f, 0x46, 0x6f, 0x98, 0xc6, 0x69, 0xd6, - 0x92, 0xca, 0x1f, 0xfe, 0x1b, 0x54, 0x2a, 0x54, 0x13, 0xa4, 0x2b, 0x5a, 0xc5, 0x6a, 0xa0, 0xf9, - 0x8a, 0xb6, 0x24, 0xe9, 0xe1, 0x59, 0x19, 0x59, 0x08, 0xc0, 0xb2, 0x35, 0xd7, 0x89, 0x89, 0x25, - 0x43, 0xd0, 0x6a, 0xc4, 0x18, 0xab, 0xb5, 0xd0, 0x65, 0xb9, 0x4e, 0xac, 0x8c, 0x4a, 0x00, 0xb4, - 0xbf, 0x52, 0xdc, 0xa8, 0x14, 0x53, 0xa5, 0x6b, 0x1e, 0xaf, 0xa2, 0x44, 0x55, 0x90, 0x33, 0x96, - 0x59, 0x7e, 0xa1, 0x12, 0xb0, 0x3d, 0x98, 0x58, 0x1e, 0x5a, 0xe4, 0x84, 0xc7, 0x3b, 0x8a, 0x40, - 0x2a, 0x01, 0x6a, 0x3a, 0x2a, 0xc6, 0xf5, 0x7a, 0xe3, 0x85, 0x91, 0x42, 0x78, 0xd8, 0xc8, 0xa0, - 0x3c, 0xac, 0x18, 0x87, 0x20, 0x41, 0xef, 0x98, 0x4b, 0xad, 0x68, 0x4d, 0xe2, 0x60, 0x9b, 0x7a, - 0xa8, 0x7e, 0x18, 0x43, 0x3a, 0x9b, 0xf5, 0xb5, 0x29, 0x0f, 0x54, 0xc7, 0x52, 0x51, 0x52, 0xb5, - 0x32, 0x21, 0xed, 0xb6, 0x03, 0xb7, 0xa2, 0x4d, 0x75, 0x20, 0x85, 0xc5, 0xd4, 0xd5, 0x87, 0xf4, - 0x47, 0x20, 0xd2, 0x24, 0x37, 0x7d, 0x04, 0x69, 0x71, 0x7a, 0xd9, 0x65, 0xe4, 0x07, 0xe4, 0xc4, - 0x84, 0x8c, 0xec, 0xd0, 0x95, 0x48, 0x71, 0xff, 0x67, 0xd2, 0xf6, 0x70, 0x8f, 0x3b, 0x1c, 0x82, - 0x3f, 0x3b, 0xb1, 0x7b, 0x9d, 0x08, 0xfe, 0x93, 0x4c, 0x95, 0x27, 0x48, 0xe7, 0x32, 0x4d, 0xaf, - 0x0e, 0xbd, 0x87, 0x3e, 0xff, 0xec, 0x12, 0x2e, 0xed, 0x28, 0x87, 0xc3, 0x92, 0xb1, 0x18, 0x0e, - 0x4b, 0x3a, 0xa6, 0x8d, 0xc7, 0x99, 0x3f, 0x4a, 0x45, 0xe0, 0x45, 0x64, 0x53, 0x96, 0xe2, 0x83, - 0x87, 0xcc, 0xfb, 0x9b, 0xdd, 0xbf, 0xb8, 0x38, 0x19, 0xa9, 0xea, 0x54, 0x47, 0x34, 0xe9, 0x32, - 0x64, 0x3b, 0x6c, 0xae, 0xca, 0x03, 0x9d, 0x31, 0x51, 0x19, 0x33, 0x95, 0xb1, 0xa1, 0x19, 0x82, - 0x4a, 0x3e, 0xa4, 0xdf, 0x82, 0x0a, 0xf6, 0xcd, 0x30, 0x3b, 0x45, 0x3d, 0x31, 0xc5, 0xb9, 0x48, - 0xd1, 0x14, 0x27, 0x22, 0xc5, 0xfd, 0x4a, 0x96, 0xc9, 0xa3, 0x41, 0x98, 0x6d, 0x25, 0xe6, 0x54, - 0x4e, 0xea, 0xf3, 0x4e, 0x89, 0x59, 0x43, 0x2c, 0xf8, 0x9c, 0x0e, 0x10, 0xc0, 0x5f, 0xe5, 0xc3, - 0xae, 0x97, 0x9e, 0xf2, 0x41, 0x7e, 0x1b, 0x91, 0x96, 0x84, 0xdf, 0x1c, 0xc2, 0x9e, 0x6f, 0x95, - 0x1e, 0xaa, 0xc9, 0xa8, 0xc7, 0x40, 0x64, 0x24, 0xc8, 0xb0, 0xa3, 0x4e, 0xe6, 0x9c, 0xa6, 0x6d, - 0x3b, 0x7a, 0x95, 0x0d, 0x2f, 0xbd, 0xae, 0x63, 0x56, 0x88, 0xa8, 0x42, 0xd6, 0x49, 0xa8, 0x42, - 0xdf, 0x2c, 0xc8, 0xa8, 0x20, 0x01, 0xbe, 0x51, 0x70, 0xae, 0x94, 0x33, 0x64, 0xd3, 0x65, 0xf7, - 0x24, 0xfe, 0xec, 0xec, 0x92, 0x44, 0xd4, 0xdf, 0x6c, 0x92, 0x99, 0x21, 0xb0, 0x80, 0xa7, 0x03, - 0x79, 0x25, 0x33, 0x72, 0x95, 0xb1, 0xa9, 0x16, 0xfe, 0xdb, 0x3c, 0xde, 0x8b, 0x16, 0xb9, 0xde, - 0x51, 0xb5, 0xde, 0x99, 0x6f, 0xf7, 0x31, 0x92, 0x93, 0x08, 0x68, 0xc9, 0x5e, 0xf9, 0xbd, 0x61, - 0xe6, 0xf5, 0x3b, 0x19, 0x30, 0xc2, 0x5f, 0xf5, 0x78, 0xe7, 0x0a, 0x53, 0x4e, 0x4e, 0xa2, 0x53, - 0x2d, 0xc0, 0x30, 0x18, 0xd0, 0x4e, 0x35, 0x8e, 0x52, 0x8f, 0x23, 0x46, 0xc6, 0x05, 0x64, 0x79, - 0x73, 0x18, 0xf1, 0xa1, 0xd5, 0xe9, 0x9f, 0xd0, 0x29, 0x02, 0x41, 0x7e, 0x27, 0x76, 0x82, 0x5e, - 0xbb, 0xdd, 0x61, 0xe2, 0xf5, 0xbb, 0x5d, 0xc2, 0x89, 0x1c, 0x55, 0xd2, 0x8e, 0xf4, 0x00, 0xfa, - 0x18, 0x80, 0x8d, 0x77, 0x67, 0xff, 0x20, 0x32, 0x13, 0x19, 0xa2, 0xde, 0x69, 0xdf, 0x1c, 0x87, - 0x64, 0xef, 0x03, 0xac, 0x20, 0x9d, 0x6c, 0xbf, 0xa0, 0x5e, 0xb5, 0x90, 0xce, 0x30, 0xf7, 0xcb, - 0xcb, 0xa1, 0x8d, 0x71, 0x0a, 0x0a, 0xea, 0xf4, 0x2e, 0x2e, 0xdc, 0xfe, 0xc5, 0xf9, 0xcb, 0x8b, - 0x8b, 0xcb, 0xfe, 0x8b, 0xee, 0x55, 0xef, 0xc5, 0x55, 0xc7, 0x3d, 0x3f, 0xbf, 0xb8, 0xba, 0xbc, - 0xba, 0xe8, 0x9e, 0xe3, 0xe7, 0xc5, 0x55, 0xef, 0xec, 0xec, 0x04, 0x5e, 0x25, 0xef, 0xf4, 0x9d, - 0x76, 0xaf, 0x7b, 0xee, 0x9e, 0x5f, 0xf5, 0x7b, 0x97, 0xbd, 0xab, 0xab, 0xb3, 0xab, 0xb3, 0x97, - 0x2f, 0x5f, 0x9e, 0xfc, 0x6e, 0x83, 0x4d, 0xf8, 0xab, 0x7e, 0x17, 0xb3, 0x71, 0x5f, 0xf6, 0x5f, - 0x9c, 0x77, 0xaf, 0x2e, 0xbb, 0x97, 0xe7, 0xdd, 0xee, 0x8b, 0xb3, 0xab, 0x8b, 0x13, 0x08, 0x0f, - 0xde, 0xe9, 0x75, 0x9d, 0x0e, 0xfa, 0x70, 0x5f, 0x5c, 0x5e, 0x9d, 0x5d, 0xf4, 0x5e, 0x9e, 0xf7, - 0xfa, 0xdd, 0xab, 0x6e, 0xbf, 0xdd, 0xeb, 0x5d, 0xb8, 0x97, 0x2f, 0xae, 0xae, 0xce, 0xcf, 0xbb, - 0xbd, 0xee, 0xe5, 0x65, 0xef, 0xfc, 0x05, 0x80, 0x41, 0xc2, 0x78, 0x18, 0x1d, 0xea, 0xb9, 0x57, - 0xa8, 0xdf, 0xbd, 0xb8, 0xbc, 0x7c, 0x89, 0x9f, 0xab, 0xb3, 0xb6, 0xdb, 0xeb, 0x9d, 0xf7, 0x01, - 0xf9, 0xe2, 0xec, 0x05, 0x40, 0x5c, 0x02, 0x76, 0x02, 0xd8, 0xe0, 0x97, 0xce, 0x79, 0x17, 0x53, - 0x38, 0xbb, 0xbc, 0x3c, 0xeb, 0x5e, 0x9d, 0x9d, 0xf5, 0x7b, 0x7d, 0x82, 0x43, 0x7a, 0xdc, 0x3f, - 0xeb, 0x5f, 0x60, 0x32, 0x57, 0xe8, 0xf0, 0xe2, 0x45, 0xaf, 0x77, 0xf5, 0xe2, 0xbc, 0xed, 0x76, - 0x5f, 0x5c, 0x9d, 0x9f, 0x9d, 0x5f, 0x5c, 0x52, 0xfd, 0xcb, 0xfe, 0xd9, 0x79, 0x5f, 0xce, 0xed, - 0x82, 0x86, 0xf8, 0xd2, 0xed, 0xbe, 0xbc, 0xe8, 0x5f, 0x5d, 0x9e, 0x5d, 0xa0, 0xd6, 0xc5, 0x0b, - 0x39, 0x35, 0xc1, 0xa2, 0x82, 0xa9, 0x85, 0xf0, 0x30, 0x98, 0xf8, 0x67, 0x2a, 0x36, 0x78, 0xf8, - 0x67, 0x0c, 0x7e, 0x87, 0x85, 0xff, 0x2e, 0x25, 0xf1, 0x5e, 0xaf, 0x4e, 0x50, 0x49, 0x26, 0xb9, - 0x17, 0x0b, 0xd5, 0xe7, 0x67, 0xa0, 0xcd, 0x73, 0x7e, 0x3e, 0x70, 0xcf, 0x5f, 0x95, 0x1d, 0x3e, - 0x90, 0xeb, 0x98, 0xfa, 0x8d, 0x75, 0xc6, 0xac, 0x5d, 0xcc, 0xbd, 0x6c, 0x93, 0x67, 0x94, 0x82, - 0xed, 0x53, 0x37, 0xfb, 0x2f, 0x3f, 0x3b, 0x8d, 0x86, 0x90, 0x6b, 0x1e, 0x14, 0x78, 0x15, 0x27, - 0xd9, 0xb0, 0x6d, 0x31, 0x0f, 0xcf, 0x07, 0x0e, 0x72, 0xad, 0xba, 0x85, 0xb5, 0x23, 0xf2, 0xc8, - 0xe8, 0xb1, 0x63, 0x36, 0x7a, 0xa0, 0x33, 0x83, 0xb0, 0x02, 0x57, 0x16, 0x83, 0x79, 0xee, 0x19, - 0xa2, 0x58, 0xea, 0x7d, 0x69, 0x05, 0x6c, 0x13, 0x2b, 0x68, 0x1d, 0x14, 0x0a, 0xb6, 0xc3, 0xbc, - 0x73, 0xb3, 0x59, 0xcd, 0x9c, 0xb2, 0x1d, 0x9d, 0x43, 0x92, 0xea, 0x25, 0x61, 0xdb, 0xa6, 0x87, - 0xb6, 0xb2, 0x00, 0x15, 0x4e, 0xda, 0x8a, 0x7e, 0x72, 0xfa, 0x09, 0xf0, 0xb3, 0xa9, 0xfc, 0xd9, - 0x4c, 0x86, 0xe7, 0xa2, 0x51, 0x36, 0xf6, 0xe9, 0x88, 0xc5, 0x11, 0xdc, 0xdd, 0x6c, 0x3c, 0x50, - 0xc6, 0x4e, 0xc1, 0xec, 0xc8, 0x5d, 0xac, 0xd7, 0x91, 0x9b, 0xd3, 0xcf, 0x8a, 0x7e, 0x28, 0x86, - 0xd8, 0xe8, 0x48, 0x3a, 0xb1, 0x91, 0x8a, 0x52, 0xeb, 0x96, 0x18, 0x7a, 0x35, 0xf9, 0x60, 0x67, - 0xf6, 0x0a, 0xa7, 0x0d, 0x4b, 0x68, 0x67, 0xaa, 0xb5, 0xe6, 0xae, 0x81, 0xc1, 0x62, 0x38, 0x00, - 0x4b, 0x82, 0x71, 0x17, 0x8f, 0xc0, 0x21, 0x04, 0x6f, 0x2a, 0x58, 0x79, 0x80, 0x76, 0x81, 0xf0, - 0x16, 0x1f, 0x07, 0x99, 0x3f, 0x06, 0x32, 0x37, 0x41, 0x4a, 0x93, 0xe6, 0x71, 0x68, 0xab, 0xc7, - 0xa0, 0xad, 0x4c, 0x68, 0x41, 0xbc, 0x5c, 0x04, 0x4f, 0x40, 0x0b, 0x1e, 0x81, 0x56, 0x63, 0x17, - 0x6f, 0xec, 0x21, 0x00, 0x6c, 0xa7, 0x02, 0xae, 0xac, 0x9c, 0x03, 0xd0, 0x1b, 0xdc, 0x66, 0x6b, - 0x3b, 0xeb, 0xd0, 0x1a, 0x91, 0x09, 0xd6, 0x64, 0xaa, 0xa2, 0xee, 0x28, 0xe3, 0xd3, 0x47, 0xe7, - 0x80, 0xc6, 0x6e, 0xf6, 0x08, 0xe0, 0x7a, 0x16, 0x78, 0x23, 0xc9, 0x61, 0xce, 0x62, 0x9e, 0x71, - 0x9e, 0x3c, 0x09, 0x7e, 0xfe, 0x7c, 0xf0, 0xf3, 0x06, 0xf8, 0xc9, 0x53, 0xcb, 0x49, 0xd0, 0x27, - 0xcf, 0x87, 0x3e, 0x69, 0x40, 0x27, 0xff, 0x72, 0xbf, 0x58, 0xa8, 0x2d, 0x32, 0x5b, 0x71, 0x07, - 0x13, 0x76, 0x8a, 0xb4, 0x51, 0xa4, 0x84, 0xab, 0xed, 0xa3, 0x6f, 0x48, 0x90, 0xce, 0xf1, 0x88, - 0x48, 0x70, 0x7e, 0x63, 0x53, 0x6c, 0xec, 0x09, 0xaa, 0xa8, 0x0d, 0x22, 0x72, 0x59, 0x40, 0x1a, - 0xd5, 0xd9, 0xeb, 0xc2, 0x0d, 0x86, 0x3d, 0xc8, 0x9e, 0xa0, 0x39, 0xd0, 0x67, 0xb0, 0xb0, 0x98, - 0x21, 0x88, 0x8c, 0xd2, 0x82, 0x74, 0x37, 0x8f, 0xd1, 0x8b, 0x29, 0x20, 0xe2, 0xc7, 0xd1, 0x00, - 0xfb, 0xa4, 0x81, 0x86, 0x85, 0x34, 0x07, 0x04, 0x1a, 0xe2, 0x5a, 0x76, 0x0a, 0x34, 0xe4, 0x12, - 0x0d, 0xf1, 0x73, 0xd1, 0xa0, 0x2d, 0x8f, 0xe7, 0xa0, 0x41, 0x38, 0xf3, 0x4f, 0xa2, 0x01, 0xb5, - 0x9e, 0x89, 0x06, 0xe1, 0x6f, 0x98, 0x48, 0x96, 0x5e, 0xd5, 0x63, 0xaa, 0x02, 0x95, 0xf4, 0x61, - 0x6a, 0x24, 0x29, 0x7e, 0xe1, 0x66, 0x6d, 0x8b, 0xb5, 0x28, 0x31, 0xd7, 0x89, 0x49, 0xdb, 0x72, - 0xac, 0x03, 0x9a, 0x43, 0xef, 0x14, 0x50, 0xd4, 0x73, 0x06, 0x13, 0xc8, 0xff, 0xcd, 0xe5, 0x77, - 0x3c, 0xa4, 0x18, 0xd1, 0x10, 0x9a, 0xfb, 0xef, 0x36, 0x1d, 0x57, 0x92, 0x3a, 0x38, 0x13, 0x6f, - 0x7d, 0xf5, 0xc6, 0xc5, 0xdb, 0x99, 0x7c, 0x13, 0x36, 0xc5, 0xb7, 0x55, 0x4b, 0x71, 0x14, 0xf0, - 0x99, 0x4d, 0xd1, 0x35, 0xbd, 0x9d, 0x8f, 0x59, 0xcf, 0x71, 0xd8, 0x51, 0x72, 0xd8, 0x4b, 0xc4, - 0x04, 0x5b, 0xca, 0xdd, 0x75, 0x06, 0x15, 0xdd, 0x80, 0xde, 0x23, 0x10, 0x7b, 0x06, 0x4a, 0xe7, - 0xd0, 0x65, 0xe5, 0xa6, 0x41, 0xa5, 0xcf, 0xc2, 0x60, 0x60, 0xa0, 0x30, 0x38, 0x8c, 0x43, 0x99, - 0x08, 0xf6, 0x23, 0x73, 0xdb, 0x59, 0xae, 0x89, 0x44, 0xbb, 0xd8, 0xcf, 0x5c, 0xc6, 0x4f, 0xac, - 0xf6, 0x3f, 0x60, 0x43, 0x64, 0x8e, 0x78, 0xcc, 0xe5, 0x63, 0x9f, 0xa4, 0x6d, 0x2e, 0x1f, 0x50, - 0xa9, 0x16, 0xf0, 0xcb, 0xc6, 0x02, 0xf6, 0x5e, 0x9c, 0xfc, 0xb7, 0x58, 0x08, 0x5a, 0x04, 0xf5, - 0xd2, 0x1f, 0xd3, 0x1a, 0xa8, 0x97, 0xb3, 0xb1, 0x5c, 0xbd, 0xaf, 0xff, 0x74, 0x33, 0x22, 0x1a, - 0xf9, 0x72, 0xae, 0x60, 0x7c, 0xd7, 0x80, 0x51, 0x03, 0xa8, 0x5b, 0x9b, 0x3d, 0x7e, 0xd1, 0xa4, - 0x97, 0x47, 0xaa, 0xa3, 0x27, 0xdd, 0xcd, 0xa3, 0x14, 0x02, 0x5c, 0x3f, 0x83, 0x42, 0xc8, 0x91, - 0xdb, 0x98, 0xeb, 0xf3, 0xf2, 0xcf, 0x51, 0xc9, 0x81, 0x15, 0xc2, 0xe3, 0x67, 0xe1, 0x67, 0x82, - 0x46, 0x9c, 0x83, 0x2c, 0x5e, 0x07, 0x5c, 0x4c, 0x31, 0xf2, 0xf4, 0x00, 0x50, 0x49, 0xf7, 0x8f, - 0xa4, 0x20, 0xd2, 0x85, 0x26, 0xc9, 0xbc, 0x6d, 0x7d, 0x26, 0x53, 0x31, 0x52, 0xcf, 0x67, 0xf5, - 0x1f, 0xf6, 0xb1, 0x3a, 0x7c, 0x45, 0x83, 0x5f, 0x85, 0x73, 0x54, 0xf1, 0x2b, 0xbd, 0x89, 0xa5, - 0xfb, 0x74, 0x2f, 0xab, 0x3f, 0xd5, 0xf4, 0xf9, 0xac, 0x8e, 0x29, 0x6e, 0x2d, 0x24, 0xc9, 0x46, - 0xc8, 0xf4, 0x08, 0x02, 0x1d, 0x7e, 0xff, 0x36, 0xab, 0x93, 0x24, 0x7e, 0x16, 0x0e, 0x03, 0x03, - 0x89, 0xc1, 0x63, 0x58, 0x7c, 0x9a, 0xd9, 0x8d, 0xa8, 0xd7, 0x66, 0x03, 0x1a, 0x8d, 0x37, 0xb6, - 0x53, 0xc7, 0x42, 0xff, 0xc7, 0x40, 0x3b, 0x94, 0xc7, 0x6d, 0x34, 0x2d, 0x16, 0x42, 0x41, 0xe5, - 0x98, 0x1f, 0xcf, 0xde, 0x47, 0x7f, 0x70, 0xf2, 0x1d, 0xdd, 0x49, 0x9a, 0xe1, 0xf5, 0x9f, 0xa2, - 0x98, 0x0e, 0xb6, 0xc2, 0x82, 0x9e, 0xc6, 0xfc, 0xc7, 0x60, 0x1a, 0x95, 0x39, 0x4b, 0xc5, 0x85, - 0xaf, 0xe9, 0x94, 0xf6, 0x17, 0xe2, 0xba, 0xed, 0x22, 0x80, 0x6b, 0x91, 0xfb, 0xd6, 0x22, 0xcd, - 0xa2, 0x3f, 0xd2, 0xa4, 0x08, 0x62, 0x4b, 0x68, 0xa8, 0x38, 0xb8, 0x4f, 0xcb, 0xe2, 0xcb, 0x28, - 0xe3, 0x62, 0x0c, 0xb5, 0x4f, 0xaa, 0x76, 0x25, 0x13, 0x3f, 0x73, 0xc8, 0x57, 0x3e, 0x49, 0xdb, - 0x7d, 0xf8, 0xdf, 0x56, 0x18, 0x65, 0xa1, 0x3c, 0x57, 0x1b, 0x0f, 0x1f, 0x64, 0xc7, 0x22, 0x04, - 0xea, 0x55, 0xbd, 0xb6, 0xb7, 0x06, 0xa4, 0x5f, 0x60, 0xe5, 0x7b, 0x51, 0x07, 0x80, 0x3a, 0x04, - 0x48, 0x4c, 0x0e, 0x4b, 0xb3, 0xe0, 0xd1, 0x7c, 0x51, 0x20, 0x11, 0xde, 0x79, 0x11, 0x1c, 0xe9, - 0xf0, 0x5e, 0x3c, 0x32, 0xd1, 0x96, 0x92, 0x1d, 0x7e, 0xda, 0xdf, 0x78, 0x8d, 0xae, 0x32, 0x54, - 0x68, 0x42, 0xcd, 0x74, 0x03, 0x2a, 0xba, 0xf3, 0xba, 0xec, 0x1e, 0xff, 0x64, 0x17, 0xf9, 0x30, - 0xab, 0xbb, 0xc9, 0x87, 0x91, 0x97, 0x19, 0x9b, 0x7e, 0xff, 0x32, 0x43, 0xc9, 0x84, 0x7e, 0xa0, - 0x3b, 0x52, 0x88, 0xa7, 0x4b, 0x19, 0xb2, 0x19, 0x90, 0x1c, 0xb9, 0x46, 0x87, 0xc0, 0xb1, 0x7e, - 0x17, 0x03, 0xa2, 0x9d, 0x87, 0x27, 0xf0, 0x0a, 0xd4, 0xc7, 0x43, 0x0c, 0xce, 0xe3, 0x34, 0x47, - 0x3f, 0x6d, 0xef, 0xdb, 0x8a, 0x4b, 0x44, 0xb8, 0x8e, 0x82, 0x11, 0x42, 0xb8, 0xab, 0xb8, 0x8f, - 0x5e, 0x42, 0x71, 0x10, 0x52, 0x84, 0x80, 0x84, 0x39, 0xec, 0xe9, 0x95, 0xa2, 0xc8, 0x93, 0x0b, - 0x49, 0x2e, 0x4a, 0xa4, 0x2d, 0x5b, 0x97, 0xcd, 0x8d, 0x32, 0x61, 0x88, 0xd6, 0x45, 0x13, 0xa3, - 0x48, 0x7a, 0x09, 0xba, 0x8c, 0xa2, 0x1c, 0xf0, 0xd1, 0x64, 0x91, 0xb2, 0xf1, 0x3d, 0x79, 0x9d, - 0xad, 0xa0, 0xa0, 0xd5, 0x07, 0x7e, 0xb3, 0xe4, 0x19, 0x79, 0x3e, 0x5c, 0xd0, 0xdf, 0x4d, 0x70, - 0x67, 0x64, 0x89, 0x38, 0x9e, 0x9d, 0x28, 0x53, 0xbe, 0xc3, 0x9d, 0xd3, 0xf2, 0xc4, 0x88, 0x76, - 0x54, 0xb1, 0xb0, 0x2e, 0xab, 0x82, 0x60, 0xa9, 0x94, 0x12, 0xb2, 0xc3, 0x85, 0x31, 0x4a, 0xa0, - 0xf9, 0xd4, 0x3f, 0x73, 0x2f, 0x65, 0x89, 0xe1, 0x6c, 0xd5, 0x15, 0x72, 0x59, 0x26, 0xbd, 0x26, - 0x4f, 0xdd, 0xf3, 0xab, 0x8b, 0xe1, 0xfe, 0x0a, 0x14, 0x8b, 0xd8, 0x7f, 0xa9, 0x07, 0x11, 0x43, - 0x04, 0x85, 0x7e, 0xa7, 0x77, 0x12, 0xb6, 0x4b, 0xd0, 0x75, 0x0a, 0xbb, 0xed, 0xce, 0x8b, 0x87, - 0xb9, 0x17, 0x82, 0x72, 0xe2, 0x61, 0xe8, 0xe5, 0x1b, 0x19, 0x54, 0x47, 0xd3, 0xc2, 0xef, 0x9f, - 0x88, 0x91, 0xfe, 0xf0, 0x86, 0x45, 0x85, 0xbf, 0xef, 0x4a, 0x94, 0x5d, 0x7c, 0x96, 0xb4, 0x13, - 0xe7, 0x33, 0xb8, 0xf7, 0xd9, 0xfe, 0x1a, 0x72, 0xda, 0xf9, 0xef, 0x59, 0x61, 0x17, 0x27, 0x45, - 0x3b, 0x39, 0x49, 0x9c, 0x4d, 0xcd, 0xf8, 0x22, 0xe8, 0x5f, 0xef, 0x31, 0x08, 0xfa, 0x03, 0xe5, - 0x57, 0x2c, 0xd5, 0x69, 0xb2, 0x54, 0xa7, 0x21, 0x02, 0x8c, 0x0b, 0x5d, 0x85, 0x19, 0x79, 0x53, - 0x50, 0xb4, 0x6d, 0x2b, 0xb9, 0xa1, 0x92, 0x2a, 0x92, 0x5d, 0x92, 0x26, 0x28, 0x62, 0xc2, 0x84, - 0x58, 0x30, 0x31, 0x78, 0x24, 0x2d, 0x1a, 0x11, 0x69, 0x82, 0xbc, 0xe0, 0x3c, 0xfe, 0x3c, 0x99, - 0xc7, 0x52, 0x1c, 0x89, 0xd7, 0x1d, 0x09, 0x42, 0xa7, 0xb6, 0xc3, 0x38, 0x0d, 0xaf, 0x6f, 0xa3, - 0x5c, 0xc8, 0x0b, 0x3e, 0x84, 0x2c, 0x69, 0x8b, 0xd3, 0xfc, 0x5b, 0xb9, 0xd0, 0x01, 0x1d, 0x2a, - 0xa1, 0x26, 0x41, 0x52, 0x44, 0x7b, 0x9a, 0xf5, 0x5e, 0x76, 0x3b, 0x68, 0xba, 0x5b, 0x4a, 0x87, - 0xa0, 0x7c, 0x8a, 0x6d, 0x62, 0x6d, 0xec, 0x44, 0xa8, 0x93, 0x7a, 0xe8, 0xf1, 0xd6, 0xd0, 0x05, - 0x82, 0x28, 0xf0, 0xe8, 0x86, 0x77, 0xa0, 0x5c, 0x3c, 0xee, 0x29, 0xf2, 0x2a, 0xb6, 0x89, 0x28, - 0x70, 0x45, 0x72, 0xb7, 0xec, 0x44, 0x62, 0xf3, 0x31, 0xf6, 0xc5, 0xc4, 0xc5, 0xba, 0x05, 0x45, - 0x90, 0xf4, 0xed, 0x4e, 0xc4, 0x28, 0x72, 0x69, 0xa3, 0x8f, 0xd3, 0x04, 0x6a, 0x0c, 0x3c, 0x5d, - 0x51, 0x70, 0x56, 0x88, 0x73, 0xd9, 0x2c, 0x35, 0x82, 0x86, 0xf5, 0xde, 0x97, 0x1d, 0x93, 0x53, - 0x61, 0xbc, 0x83, 0x18, 0x4f, 0xd3, 0x93, 0xdc, 0x3c, 0x7f, 0x90, 0xef, 0x2e, 0x9e, 0xd0, 0x02, - 0x93, 0xf4, 0xee, 0x5b, 0x21, 0x85, 0x9a, 0x0b, 0x99, 0x68, 0x91, 0xa6, 0x6e, 0x1e, 0x42, 0xb0, - 0x25, 0x7a, 0x55, 0x0f, 0x89, 0x62, 0xa3, 0xb7, 0x70, 0x0b, 0x33, 0x79, 0x85, 0x99, 0x5b, 0xa5, - 0x56, 0x32, 0x2d, 0xfc, 0x52, 0x24, 0x25, 0x60, 0x26, 0xa2, 0xc5, 0xa9, 0x73, 0x6a, 0x73, 0x92, - 0xe3, 0x0e, 0xb1, 0x35, 0x90, 0x60, 0x47, 0x22, 0xaf, 0xac, 0xf2, 0xf4, 0x48, 0xd5, 0x94, 0xb7, - 0x98, 0x3d, 0x96, 0xcc, 0xce, 0x56, 0x7b, 0x4b, 0x51, 0xd6, 0xc9, 0x65, 0x0d, 0x63, 0xb8, 0x41, - 0x51, 0xdf, 0xab, 0xad, 0x4e, 0x51, 0xf8, 0xdd, 0x01, 0xaf, 0x4f, 0xb0, 0x70, 0x7d, 0xd8, 0xa2, - 0x14, 0xe7, 0x24, 0xdc, 0x3b, 0xac, 0x66, 0x2a, 0x93, 0xf7, 0x1d, 0x71, 0xfb, 0xb3, 0x66, 0xc1, - 0xf2, 0xa4, 0x6c, 0xa7, 0x18, 0xec, 0xab, 0x26, 0x7e, 0xf4, 0x39, 0x41, 0x6e, 0x1e, 0xd3, 0x33, - 0xee, 0xcd, 0x18, 0x5c, 0xfa, 0x80, 0x65, 0x81, 0x3e, 0x06, 0x8e, 0xe1, 0xe0, 0x0b, 0x06, 0xea, - 0x20, 0xc7, 0x62, 0x32, 0xed, 0x35, 0xb8, 0x8a, 0xee, 0xc7, 0xb4, 0xf2, 0x94, 0x6c, 0x14, 0xe1, - 0x15, 0x88, 0x92, 0xd7, 0xb4, 0x7d, 0x65, 0xcc, 0x70, 0x51, 0x6c, 0x1f, 0xaa, 0x69, 0x5b, 0x9d, - 0x39, 0xe1, 0x9d, 0x4e, 0x11, 0x5a, 0xed, 0x44, 0x9a, 0x1c, 0x11, 0xf0, 0xb5, 0xb4, 0xf7, 0xc4, - 0xf2, 0x46, 0xdd, 0xfa, 0x1a, 0x38, 0xec, 0xaa, 0xb6, 0xd5, 0x12, 0x6d, 0x3e, 0xb3, 0x36, 0x8e, - 0xfb, 0x31, 0x05, 0x62, 0x2d, 0x66, 0x39, 0xc2, 0x32, 0xa9, 0x6f, 0x0e, 0x18, 0xf3, 0xd9, 0xdd, - 0x13, 0x1c, 0x42, 0xa5, 0x8b, 0x9b, 0x3d, 0x42, 0x10, 0x4e, 0x0b, 0x7f, 0x64, 0xdd, 0xa4, 0x65, - 0x2e, 0xae, 0x27, 0x00, 0x56, 0x91, 0x96, 0xe1, 0x42, 0xa5, 0x45, 0x7e, 0xb9, 0xd4, 0xb9, 0x3c, - 0x99, 0x5a, 0x63, 0x36, 0x37, 0x04, 0x61, 0x62, 0xec, 0x84, 0x8a, 0x4e, 0x13, 0x75, 0x4a, 0x91, - 0x82, 0x7e, 0xd5, 0x11, 0x8d, 0x68, 0xea, 0xcb, 0x35, 0xca, 0xb0, 0x26, 0xe9, 0x8d, 0x4d, 0xf7, - 0x87, 0xeb, 0xfd, 0xd6, 0xb3, 0x4b, 0x87, 0x8e, 0xd8, 0xcb, 0x71, 0xda, 0x17, 0xf5, 0xd1, 0x33, - 0x71, 0xb2, 0xed, 0xb7, 0xdf, 0x44, 0x00, 0xf5, 0xb7, 0xdf, 0x7c, 0x48, 0x02, 0xdb, 0x8c, 0xa7, - 0xea, 0xb3, 0x3c, 0xf2, 0x58, 0xa6, 0x2d, 0x2e, 0xc0, 0x57, 0x85, 0x8e, 0xd3, 0x38, 0xd5, 0x5f, - 0x38, 0xbb, 0xe7, 0x42, 0x0e, 0xc4, 0x4d, 0x25, 0xdd, 0x88, 0x7b, 0x30, 0xf2, 0xfc, 0x87, 0xd8, - 0x31, 0x03, 0xc7, 0x3e, 0xa4, 0xc9, 0x5b, 0xc2, 0xc7, 0x97, 0xe9, 0x6d, 0x02, 0x96, 0x84, 0x49, - 0x40, 0x38, 0xc9, 0x85, 0xe1, 0x42, 0xfa, 0xe1, 0x69, 0x53, 0x41, 0x1f, 0xff, 0x13, 0x9a, 0x35, - 0x9b, 0x47, 0xc9, 0x50, 0x9b, 0x00, 0x6f, 0xc5, 0xab, 0xa7, 0xf3, 0xc1, 0xa5, 0x0f, 0x58, 0x81, - 0x6c, 0x16, 0xa7, 0xb7, 0x9e, 0xb5, 0x8a, 0xf2, 0x68, 0x02, 0xd3, 0x8c, 0x4d, 0xa3, 0x7c, 0x09, - 0x98, 0x5e, 0x36, 0xb4, 0xa2, 0x24, 0x8e, 0x12, 0xde, 0x99, 0x90, 0xc8, 0xb4, 0x28, 0x14, 0x45, - 0xcf, 0xea, 0xf6, 0x78, 0x57, 0x6f, 0x9d, 0x8b, 0x13, 0xa7, 0xa8, 0x2e, 0xc1, 0x7e, 0xc7, 0x67, - 0x05, 0x2a, 0xcb, 0x97, 0x0f, 0xe9, 0xd2, 0x1a, 0xfb, 0xdc, 0x61, 0x0b, 0xfb, 0x9d, 0x3c, 0xee, - 0x56, 0x5f, 0x24, 0xb7, 0xf5, 0xba, 0x81, 0x31, 0x4b, 0xb9, 0x0b, 0x69, 0x1e, 0x66, 0xaa, 0x10, - 0x74, 0x00, 0x87, 0x4c, 0x1d, 0x3e, 0x92, 0x87, 0x2d, 0xd3, 0xe4, 0x4d, 0xb2, 0x2c, 0x0b, 0xb2, - 0x77, 0x29, 0x93, 0x8e, 0xae, 0xd1, 0x69, 0x94, 0x2f, 0x48, 0x5e, 0x62, 0xc5, 0x5f, 0xc7, 0xc4, - 0x08, 0x3f, 0x02, 0x45, 0xb0, 0x98, 0xa9, 0x1f, 0x71, 0xa5, 0xe5, 0x4b, 0xa9, 0xee, 0x91, 0xa5, - 0xcd, 0x13, 0x49, 0x81, 0xf9, 0x90, 0x46, 0x49, 0xb6, 0xda, 0xf4, 0x83, 0xcc, 0xa0, 0x6b, 0xba, - 0x64, 0xc8, 0x71, 0x37, 0x14, 0x90, 0xfe, 0xa7, 0x43, 0x92, 0x63, 0x46, 0xe2, 0x4d, 0x67, 0xfd, - 0x0b, 0x59, 0x45, 0xba, 0xac, 0xed, 0xae, 0xa2, 0xb6, 0xb8, 0x04, 0x89, 0x4f, 0xb1, 0xa4, 0x96, - 0x27, 0xde, 0xeb, 0x45, 0xb5, 0xbc, 0xa3, 0x1e, 0x9d, 0xc6, 0x15, 0xb7, 0xbd, 0xe8, 0xf2, 0xf6, - 0xb4, 0xa0, 0x53, 0x4a, 0x5f, 0x05, 0x00, 0x61, 0xce, 0xbb, 0x3a, 0x1f, 0xbc, 0x73, 0xe3, 0x8a, - 0xf8, 0xfe, 0x61, 0x49, 0x67, 0xcd, 0x56, 0x9c, 0xe2, 0xea, 0xce, 0xc6, 0xdc, 0xbd, 0x33, 0xb8, - 0xce, 0xe8, 0x5a, 0xbe, 0xcb, 0x4e, 0x7b, 0xbb, 0xd5, 0xc1, 0x8c, 0x46, 0x65, 0x62, 0x48, 0x55, - 0xb7, 0xef, 0xb0, 0xa7, 0xc6, 0xb7, 0xef, 0x86, 0xd7, 0x9e, 0x21, 0xd2, 0xf6, 0xf5, 0xc6, 0x7e, - 0x63, 0xb8, 0x2f, 0x93, 0x86, 0x06, 0x93, 0x71, 0xc6, 0x32, 0x8b, 0xc9, 0x9e, 0x25, 0x9a, 0xd6, - 0x54, 0xb7, 0xb0, 0xc5, 0x09, 0x72, 0xf6, 0x50, 0xdd, 0xe4, 0xf3, 0xac, 0x37, 0x59, 0xfa, 0xad, - 0xa0, 0x97, 0x56, 0x95, 0xea, 0x74, 0x48, 0x58, 0x0a, 0xf2, 0x14, 0xc2, 0x8c, 0x4e, 0x18, 0xe7, - 0x9f, 0xa3, 0xa7, 0x15, 0x1f, 0x5a, 0x46, 0x2d, 0x9d, 0x09, 0x8a, 0xb5, 0xa0, 0x65, 0xe9, 0x8e, - 0x9f, 0xf7, 0x60, 0x75, 0x6e, 0xf9, 0xe4, 0x3a, 0x2a, 0x3a, 0x45, 0xb0, 0xec, 0x2c, 0xa0, 0xc6, - 0x62, 0x52, 0x65, 0x1d, 0x71, 0x66, 0xc0, 0x92, 0x51, 0x1e, 0x28, 0x9d, 0x96, 0xfa, 0xdf, 0x19, - 0x58, 0xac, 0x80, 0xd0, 0xc9, 0xe9, 0x92, 0x9a, 0x67, 0x89, 0x64, 0x4c, 0xc2, 0xc2, 0x6a, 0x93, - 0x8c, 0x74, 0xef, 0x1c, 0x29, 0x7c, 0xc5, 0xcb, 0xbd, 0x90, 0xa2, 0x70, 0x2e, 0xe2, 0x58, 0x6e, - 0x5d, 0xa8, 0x06, 0xe2, 0x82, 0x1b, 0x03, 0xfd, 0x78, 0xa8, 0x46, 0xf6, 0x08, 0x51, 0x97, 0x4e, - 0x4b, 0x9d, 0x8d, 0x97, 0x3e, 0x0c, 0x3f, 0xad, 0xb9, 0xf5, 0xeb, 0x32, 0xcd, 0x23, 0x42, 0x20, - 0xcc, 0x9b, 0x09, 0xd4, 0x44, 0x59, 0x80, 0x87, 0x77, 0xd9, 0x1a, 0xf8, 0x86, 0x7d, 0x04, 0xe4, - 0x61, 0x79, 0x2d, 0xd6, 0x38, 0xa0, 0x68, 0x3f, 0x88, 0x1b, 0x66, 0xdf, 0xd2, 0x57, 0x25, 0x1a, - 0x2e, 0x27, 0x7c, 0xd8, 0x62, 0xbd, 0xae, 0x56, 0x16, 0xec, 0xa4, 0x8e, 0xa5, 0xe7, 0x5f, 0xdc, - 0x7f, 0x90, 0xf7, 0xf3, 0x6c, 0x8b, 0x38, 0xcd, 0x72, 0xd4, 0x1d, 0xd3, 0x5b, 0x20, 0x3c, 0xbd, - 0x75, 0x93, 0x60, 0x15, 0xcd, 0x03, 0x3a, 0x10, 0x86, 0xde, 0xb2, 0xcf, 0xe7, 0x74, 0xe3, 0x3e, - 0xf2, 0x4f, 0x7f, 0xb5, 0xed, 0xe1, 0x51, 0x08, 0x07, 0xfc, 0x86, 0xaf, 0x81, 0xfe, 0x2c, 0x8d, - 0xa6, 0x8e, 0xeb, 0x9c, 0xe4, 0xc1, 0x2c, 0xc8, 0xa2, 0xd3, 0x48, 0x5f, 0x09, 0xa5, 0x8f, 0x9f, - 0x44, 0x3f, 0x2c, 0xd2, 0x84, 0xaf, 0xa3, 0x1f, 0xd2, 0x29, 0x7e, 0x82, 0xa9, 0x51, 0xca, 0x75, - 0x2f, 0x74, 0xb8, 0xdf, 0x30, 0x19, 0xed, 0x68, 0xbd, 0xce, 0xc0, 0x40, 0x10, 0x4b, 0xfa, 0xde, - 0xee, 0x50, 0x9d, 0xb5, 0xc3, 0xc2, 0xb5, 0xad, 0xd3, 0x53, 0xab, 0x0d, 0xb9, 0x92, 0xe6, 0x05, - 0x1e, 0x4b, 0x28, 0x8a, 0x04, 0xe3, 0x6f, 0xd3, 0xf1, 0xc6, 0x20, 0x0b, 0x17, 0x6d, 0xe8, 0xab, - 0x8d, 0x1d, 0x69, 0x29, 0x44, 0x27, 0x0f, 0xd9, 0x91, 0xc4, 0x98, 0xf2, 0x59, 0x41, 0x71, 0x77, - 0x5e, 0x46, 0xe6, 0x2d, 0x67, 0x19, 0x44, 0xf3, 0x0c, 0x4b, 0xe8, 0x59, 0x09, 0x86, 0x69, 0x89, - 0x5b, 0xa1, 0xe9, 0x35, 0xef, 0x88, 0x85, 0xb2, 0xbc, 0x3e, 0x93, 0xef, 0x9e, 0xf5, 0x49, 0xb7, - 0xdb, 0x85, 0x0e, 0x7d, 0x1c, 0x54, 0xa7, 0x2f, 0x81, 0x81, 0xb3, 0xf0, 0x78, 0x04, 0xd8, 0x6c, - 0x36, 0x03, 0x30, 0xc3, 0x42, 0x5d, 0x16, 0x36, 0xd7, 0xf1, 0x06, 0xee, 0x06, 0x82, 0x92, 0xdf, - 0x10, 0xcd, 0x43, 0x54, 0x55, 0x67, 0xbb, 0xe9, 0x70, 0xd0, 0x2b, 0x48, 0x29, 0xa2, 0xde, 0xbc, - 0xc6, 0x8c, 0x7c, 0x1f, 0x15, 0x63, 0x4f, 0xa5, 0x59, 0x02, 0x1f, 0x96, 0xbe, 0x7d, 0x00, 0x07, - 0x52, 0x9a, 0x71, 0xf4, 0xc1, 0x05, 0x65, 0xc6, 0xd1, 0x57, 0x17, 0x94, 0x19, 0x97, 0xfb, 0xff, - 0xb2, 0xe1, 0xb9, 0xd1, 0x49, 0x8a, 0x83, 0x6e, 0xe8, 0x9f, 0xf3, 0x42, 0x47, 0xa3, 0x2e, 0x13, - 0xc1, 0x64, 0x3c, 0xda, 0x99, 0x88, 0x80, 0xd2, 0x53, 0x04, 0x91, 0xc7, 0x6c, 0x44, 0x76, 0xa2, - 0x28, 0xa6, 0x0d, 0xee, 0xdd, 0x0a, 0xe3, 0x3d, 0xbe, 0x6b, 0x05, 0x91, 0xaa, 0x51, 0x68, 0xb5, - 0xbb, 0x1f, 0xa2, 0x2e, 0xd6, 0x90, 0x1b, 0x10, 0x4d, 0x8f, 0x77, 0x07, 0xa0, 0x1e, 0x47, 0x77, - 0x3f, 0x40, 0x5d, 0x4c, 0xf1, 0xe6, 0x0a, 0x60, 0xc3, 0x4f, 0xd6, 0x10, 0x83, 0x9d, 0x36, 0x6a, - 0x20, 0x4f, 0x81, 0xde, 0x19, 0xaf, 0xf6, 0xb5, 0x6b, 0x13, 0x77, 0x34, 0x96, 0x1e, 0x76, 0xd3, - 0xe9, 0x4e, 0x77, 0x9c, 0x6e, 0x2c, 0x6f, 0xda, 0x29, 0xb1, 0xb2, 0x25, 0x1d, 0x1e, 0x19, 0xe4, - 0xaf, 0xd2, 0x41, 0xde, 0xf6, 0xe3, 0xd3, 0x97, 0x2c, 0x6c, 0xfb, 0x3d, 0x75, 0xa9, 0xd3, 0xff, - 0xa9, 0xb1, 0xbf, 0x06, 0x73, 0x65, 0xe6, 0x07, 0x2e, 0x5d, 0x40, 0x0c, 0xdc, 0x39, 0x5b, 0xe1, - 0x77, 0x32, 0xe0, 0xf2, 0xdc, 0xec, 0xa8, 0xd7, 0x77, 0x2f, 0x4e, 0x42, 0x3d, 0xee, 0x99, 0x18, - 0xed, 0x42, 0xfc, 0xae, 0xc4, 0x88, 0xeb, 0xb3, 0x9c, 0x3b, 0x5e, 0xbb, 0xc0, 0xcb, 0x27, 0x33, - 0xf0, 0x0d, 0x4d, 0xfe, 0xd2, 0xbd, 0xbc, 0xbc, 0xa4, 0xf7, 0x99, 0x78, 0x3f, 0x3b, 0x73, 0xcf, - 0xce, 0xce, 0xf0, 0xde, 0x95, 0xef, 0x17, 0x5d, 0x91, 0x9e, 0x51, 0xfa, 0x52, 0xd7, 0xed, 0x76, - 0xc5, 0xfb, 0x4b, 0x5d, 0x77, 0x26, 0xdf, 0x05, 0x22, 0x25, 0xe0, 0xf1, 0x6e, 0x44, 0x40, 0x98, - 0xa9, 0x98, 0x62, 0xb5, 0xdd, 0x43, 0xa1, 0x3f, 0xb1, 0x15, 0x4e, 0xe7, 0xec, 0x28, 0x12, 0xe0, - 0xb0, 0xf9, 0xde, 0x72, 0x82, 0xab, 0x6a, 0x0c, 0x8c, 0x29, 0xc8, 0x98, 0xe9, 0xd4, 0x95, 0xd3, - 0x9e, 0xca, 0x60, 0x1f, 0x25, 0x64, 0xc4, 0x54, 0x0f, 0x48, 0x56, 0x9b, 0xab, 0x6a, 0x73, 0x5d, - 0x6d, 0xae, 0xab, 0x8d, 0xf7, 0x06, 0x28, 0x68, 0xb4, 0x93, 0xbd, 0xa3, 0x89, 0xc4, 0xc6, 0x3d, - 0x40, 0x37, 0x47, 0x23, 0x04, 0x51, 0xb3, 0xcf, 0x89, 0xea, 0x73, 0xa2, 0xfb, 0x9c, 0x54, 0x7d, - 0x6e, 0x36, 0x82, 0xc3, 0x6b, 0x9d, 0x3b, 0x2f, 0xb6, 0x75, 0xc6, 0x86, 0x71, 0xf6, 0xa0, 0xac, - 0x2e, 0x6f, 0xef, 0xe1, 0xb3, 0xfd, 0x47, 0xd2, 0x20, 0xbf, 0x45, 0xa4, 0x8c, 0x6c, 0xa9, 0x66, - 0x50, 0x8c, 0x9b, 0x41, 0xb1, 0xc1, 0xd3, 0x96, 0xee, 0xb0, 0xd3, 0x3b, 0x89, 0xda, 0x70, 0xc5, - 0x20, 0x41, 0x53, 0x08, 0x9c, 0xca, 0x1f, 0xac, 0xdd, 0x6a, 0x92, 0x52, 0x5d, 0x47, 0x39, 0xe4, - 0x5b, 0x0e, 0x74, 0x79, 0x92, 0x39, 0x8f, 0x88, 0x27, 0x33, 0x70, 0x95, 0xef, 0xf0, 0x90, 0xc6, - 0x4c, 0xde, 0x8e, 0x45, 0x68, 0xc8, 0xde, 0x09, 0x63, 0xe5, 0xce, 0xbe, 0xd8, 0x98, 0xa8, 0xbd, - 0x1b, 0xa8, 0x3a, 0x73, 0x2f, 0x4f, 0xe2, 0x41, 0x2d, 0x16, 0x0d, 0xf1, 0xb3, 0x27, 0x2e, 0x47, - 0x81, 0x37, 0x54, 0xdf, 0x0a, 0x56, 0xc5, 0x62, 0xd1, 0x48, 0x10, 0x13, 0x17, 0x8a, 0x2f, 0x96, - 0xc0, 0xfe, 0xc1, 0xea, 0x48, 0x03, 0x87, 0x4e, 0xb0, 0x97, 0x23, 0x6e, 0x4c, 0x74, 0xec, 0x63, - 0x31, 0xb4, 0xe1, 0x4c, 0x9f, 0xbd, 0x71, 0xa1, 0x8f, 0x37, 0x1b, 0x67, 0xe7, 0x8c, 0x49, 0x6d, - 0x79, 0x4d, 0xa3, 0x95, 0xb5, 0x4b, 0x08, 0xc9, 0xb6, 0x31, 0xf6, 0x5e, 0xf4, 0x61, 0x29, 0x73, - 0x6a, 0xa7, 0xfe, 0x43, 0x6d, 0xb2, 0x64, 0x1c, 0x96, 0x12, 0x99, 0x5f, 0xb5, 0x8d, 0x93, 0x99, - 0x16, 0x4e, 0xea, 0x28, 0x9f, 0x58, 0xba, 0xd8, 0x94, 0x15, 0x23, 0x2b, 0x08, 0xaf, 0xe7, 0x62, - 0x25, 0x3d, 0x0b, 0x0e, 0x58, 0x14, 0xd6, 0xae, 0xee, 0x27, 0x61, 0x18, 0xb6, 0xfa, 0x17, 0x9f, - 0xb1, 0x16, 0x69, 0xcb, 0x56, 0xb7, 0x75, 0xd1, 0xa5, 0x34, 0xe5, 0x76, 0x5b, 0x2f, 0xea, 0x7c, - 0xd8, 0x60, 0x35, 0x14, 0x0a, 0x8d, 0x7b, 0xd6, 0x4b, 0xf8, 0xd9, 0x2f, 0xc9, 0x63, 0xa5, 0x83, - 0x24, 0xe4, 0xb1, 0xc8, 0xe9, 0xee, 0x9d, 0xdb, 0x37, 0xaa, 0xbf, 0xe7, 0xcc, 0xb1, 0x36, 0xcb, - 0xc8, 0xbc, 0xeb, 0x4a, 0xcb, 0x4e, 0xc7, 0x97, 0x2d, 0xd0, 0xc3, 0x67, 0x96, 0x9e, 0xb1, 0x7a, - 0x7b, 0x7c, 0xca, 0xf0, 0xf5, 0x2d, 0xf2, 0xcb, 0x02, 0x60, 0x78, 0x8b, 0x47, 0xf8, 0x0e, 0x8f, - 0xc0, 0x84, 0x6f, 0xa1, 0x5b, 0x58, 0xad, 0x48, 0x64, 0xd4, 0x89, 0xc5, 0x42, 0x58, 0x39, 0x33, - 0xb2, 0x1c, 0xe4, 0x34, 0x27, 0x05, 0x7b, 0xd0, 0x66, 0xb0, 0x07, 0x2a, 0x11, 0x46, 0xb3, 0xa7, - 0x6e, 0x10, 0xc2, 0x3e, 0xe1, 0xcd, 0x80, 0x3c, 0x6c, 0xf2, 0x2a, 0xeb, 0xfd, 0x6a, 0xae, 0x3e, - 0x4d, 0xa6, 0x73, 0xc4, 0xad, 0x68, 0x76, 0xe7, 0xe5, 0xee, 0x1d, 0xbb, 0xc7, 0xef, 0x3d, 0xd9, - 0x2b, 0x86, 0xc5, 0x72, 0x6f, 0x58, 0x2c, 0x79, 0x21, 0xcd, 0x8d, 0xa2, 0x8a, 0x1a, 0x15, 0x75, - 0xd4, 0xa8, 0xa8, 0xa3, 0x46, 0xda, 0x56, 0xa1, 0xc3, 0x8d, 0x8a, 0xb2, 0x61, 0xab, 0x34, 0xed, - 0x9d, 0xb0, 0xb6, 0x77, 0xc8, 0x47, 0x3f, 0x6c, 0xef, 0x24, 0xb5, 0xbd, 0x13, 0xec, 0x8d, 0xb5, - 0x8e, 0x94, 0x02, 0x9a, 0xcd, 0xb6, 0xe4, 0x25, 0x0c, 0x9b, 0x92, 0x43, 0x62, 0xd2, 0x1a, 0x31, - 0x90, 0x15, 0x09, 0x4a, 0x56, 0x6b, 0xf1, 0x2e, 0x13, 0xff, 0xd5, 0x92, 0x5d, 0x8a, 0x5c, 0x08, - 0x53, 0x14, 0xd1, 0x5d, 0x5e, 0x3f, 0xde, 0x89, 0xbe, 0x28, 0xce, 0xda, 0x67, 0x46, 0xc9, 0x90, - 0xda, 0xc1, 0xfd, 0x84, 0x4c, 0x6f, 0xd7, 0x48, 0x73, 0x2b, 0xf6, 0x49, 0x7b, 0x67, 0x62, 0x6f, - 0x24, 0xa4, 0x83, 0x7d, 0x55, 0xb0, 0x9a, 0x22, 0xd3, 0xed, 0x54, 0x1e, 0xa4, 0x3c, 0xc9, 0x29, - 0x3e, 0xdd, 0xb6, 0xc3, 0x4e, 0x2a, 0xcf, 0x53, 0x9e, 0x80, 0x14, 0x84, 0xd4, 0x70, 0x36, 0x7f, - 0x5d, 0xd8, 0x47, 0x33, 0x9b, 0x8e, 0x2b, 0x54, 0x62, 0x3f, 0x28, 0xa4, 0x1c, 0x62, 0x33, 0x7d, - 0x05, 0xcc, 0xcf, 0x86, 0xe2, 0x6c, 0xba, 0xa4, 0x31, 0x11, 0xbb, 0x02, 0x9b, 0x7b, 0x76, 0xbe, - 0x2d, 0xa0, 0x42, 0x71, 0x2e, 0x22, 0x54, 0x00, 0x9c, 0x5d, 0xf1, 0xa4, 0x4e, 0x78, 0x89, 0xcf, - 0x5d, 0x1c, 0x1f, 0x3f, 0x09, 0x80, 0x44, 0xe1, 0xbf, 0x43, 0xc0, 0x7d, 0x41, 0xc1, 0xba, 0x43, - 0x9c, 0xbf, 0x5f, 0x92, 0x95, 0xa6, 0xa7, 0x56, 0x89, 0xbd, 0xc7, 0x65, 0xcd, 0x33, 0xba, 0x79, - 0x96, 0xfc, 0x48, 0x35, 0xc3, 0xb3, 0x87, 0x43, 0x72, 0x04, 0xd2, 0x61, 0x92, 0x16, 0x45, 0x0a, - 0x27, 0x34, 0xa0, 0x3d, 0x71, 0x69, 0xb1, 0x6d, 0xd5, 0x50, 0xf2, 0x23, 0x18, 0x75, 0xc7, 0xc4, - 0xd4, 0x70, 0x52, 0xc9, 0x63, 0x29, 0xe8, 0x56, 0xfe, 0x2e, 0x51, 0x17, 0x58, 0xf7, 0x70, 0xe3, - 0x1c, 0xa2, 0xf9, 0x6d, 0xb9, 0xd3, 0x53, 0x72, 0x47, 0x39, 0xed, 0xda, 0x23, 0xaa, 0xb6, 0x3c, - 0xff, 0xaa, 0x20, 0x9a, 0x8d, 0x14, 0xc4, 0xb1, 0x90, 0x48, 0xc6, 0xeb, 0xfd, 0xe6, 0x31, 0xf9, - 0x17, 0x9a, 0xe3, 0x08, 0xb7, 0xc6, 0x21, 0x25, 0xcf, 0xb7, 0xc6, 0x68, 0xd6, 0xeb, 0xbf, 0x38, - 0xba, 0xb0, 0x39, 0xba, 0xd0, 0x18, 0x1d, 0xe1, 0x78, 0xd2, 0xfc, 0xf8, 0xa4, 0xff, 0x60, 0xba, - 0x9d, 0x7a, 0xab, 0x32, 0xf3, 0x5e, 0x8a, 0xfe, 0x44, 0x80, 0x4d, 0x76, 0xf4, 0xa0, 0xca, 0xe0, - 0xf7, 0x2f, 0xb7, 0x40, 0xec, 0x92, 0x92, 0xb1, 0xc9, 0xeb, 0xc1, 0xa1, 0x27, 0xcd, 0x5d, 0x59, - 0x09, 0xd5, 0x89, 0xc2, 0xa6, 0x01, 0xe4, 0xf5, 0xfb, 0x90, 0x71, 0x4d, 0x9b, 0xc7, 0xeb, 0xf5, - 0xf8, 0xd9, 0xc6, 0x08, 0xe9, 0xdc, 0x56, 0xc2, 0x5e, 0x6c, 0x9e, 0x70, 0xa7, 0x12, 0xf4, 0x95, - 0x48, 0x4f, 0x7d, 0x9b, 0x37, 0xf6, 0x90, 0xb4, 0x84, 0x77, 0x6a, 0xc1, 0x4f, 0xbb, 0x9f, 0x42, - 0xca, 0xd1, 0x77, 0xc8, 0xfe, 0x84, 0x08, 0xd5, 0x9e, 0xe8, 0x23, 0xfb, 0x36, 0xb4, 0x27, 0xd1, - 0x7b, 0xd9, 0x6d, 0x8b, 0xcd, 0x1a, 0x32, 0xa0, 0x8f, 0xba, 0x8e, 0x73, 0x62, 0x27, 0xc5, 0xa9, - 0x38, 0x59, 0x90, 0x43, 0xd2, 0x4a, 0xc9, 0x99, 0xa2, 0xf3, 0xe6, 0xd6, 0xd3, 0xf6, 0xce, 0x15, - 0xcc, 0x51, 0xaf, 0x57, 0x0b, 0x5d, 0xde, 0xce, 0xe5, 0xbe, 0x5f, 0x98, 0xe6, 0x50, 0xe0, 0x27, - 0xb4, 0x35, 0x58, 0xea, 0xbc, 0x9c, 0x36, 0x32, 0x90, 0x57, 0x09, 0x5f, 0xe8, 0xa2, 0xff, 0x3d, - 0x8b, 0xc1, 0xba, 0x90, 0x59, 0xfb, 0xb6, 0x18, 0x36, 0xff, 0x0b, 0x62, 0x1e, 0xa9, 0xa3, 0xfd, - 0x16, 0xff, 0x7e, 0x4c, 0x6f, 0x6f, 0x26, 0xb6, 0x32, 0xd0, 0x42, 0x27, 0x61, 0x65, 0x27, 0x72, - 0x5e, 0xa5, 0xda, 0x6a, 0x55, 0xdb, 0x27, 0x47, 0xbd, 0xc1, 0x96, 0x1a, 0x09, 0x0d, 0x35, 0x92, - 0xee, 0x53, 0x23, 0xe9, 0xb6, 0x16, 0x10, 0xd4, 0xe2, 0xc7, 0xcf, 0x56, 0x23, 0x4f, 0x01, 0xf8, - 0x77, 0xa9, 0x91, 0x7f, 0x12, 0x01, 0xfd, 0x59, 0x45, 0x92, 0xfd, 0x05, 0x45, 0x22, 0x3a, 0xfa, - 0x96, 0xb8, 0xf8, 0x40, 0x5f, 0x01, 0x7b, 0x30, 0x42, 0x98, 0x59, 0x4a, 0xb7, 0x37, 0x7f, 0x86, - 0xcd, 0x03, 0xe6, 0xac, 0xb7, 0x6b, 0xdb, 0x57, 0x5d, 0xe8, 0x85, 0x29, 0x9f, 0x37, 0x8c, 0xe7, - 0xed, 0x1d, 0xd9, 0x6d, 0xb6, 0xd8, 0xb6, 0xd0, 0xe1, 0xe0, 0xb0, 0xd6, 0x3d, 0x8f, 0xe3, 0xf4, - 0x96, 0xb5, 0xe2, 0xe8, 0x86, 0xb3, 0x56, 0xf0, 0x7b, 0x19, 0xb0, 0x16, 0xf9, 0x3b, 0xac, 0x75, - 0x13, 0x50, 0xb8, 0x10, 0xaf, 0xa8, 0xe7, 0x58, 0xde, 0xde, 0xd6, 0x55, 0x1d, 0xd9, 0x44, 0x36, - 0x97, 0xa0, 0x34, 0x60, 0xd1, 0x7a, 0xf3, 0x14, 0x4a, 0xde, 0x1b, 0xe7, 0xaf, 0x0f, 0x63, 0xc6, - 0x9c, 0x2b, 0x8d, 0x23, 0x88, 0xeb, 0xf1, 0xc8, 0x88, 0x5e, 0x0b, 0x28, 0xc8, 0x79, 0x5e, 0x74, - 0x72, 0x88, 0x4d, 0xe9, 0x62, 0xb0, 0x96, 0x40, 0xa8, 0x12, 0x66, 0x72, 0x28, 0x0a, 0x37, 0xdf, - 0xd1, 0x52, 0x26, 0x3c, 0xcf, 0x45, 0x4c, 0xf0, 0xe0, 0xe0, 0xaa, 0x6a, 0xcf, 0x1d, 0x9b, 0x30, - 0x38, 0x59, 0xba, 0xa4, 0x2f, 0x47, 0xdf, 0x7b, 0xbd, 0x4e, 0x2e, 0x8d, 0xbc, 0x27, 0xb1, 0xf0, - 0x85, 0x10, 0x0f, 0x8f, 0xf4, 0x52, 0x39, 0x0b, 0xe5, 0x13, 0xfa, 0x3e, 0xfe, 0xff, 0xaf, 0xef, - 0xc3, 0xa6, 0xbe, 0x0f, 0x9f, 0xab, 0xef, 0x63, 0x73, 0x1c, 0xf1, 0xbf, 0x4b, 0xdf, 0x87, 0xa3, - 0xb8, 0x39, 0xba, 0x78, 0x4b, 0xdf, 0x93, 0xec, 0xbb, 0x36, 0xb6, 0xbc, 0xa2, 0xed, 0xbd, 0xcf, - 0x7a, 0x03, 0x6c, 0x10, 0xed, 0xd9, 0x06, 0x95, 0x6a, 0x95, 0x02, 0x7f, 0xea, 0xda, 0x9e, 0x21, - 0xd7, 0x7a, 0x32, 0x4f, 0x6c, 0x7d, 0xe5, 0xbe, 0x3e, 0x2c, 0x2c, 0xe7, 0xf6, 0x55, 0x33, 0x13, - 0x06, 0x03, 0xcf, 0xc0, 0x43, 0x5b, 0xd9, 0xd1, 0x94, 0xbe, 0x7d, 0x3c, 0x65, 0x36, 0xed, 0xfd, - 0x35, 0x1d, 0x2c, 0xfd, 0xee, 0x8d, 0x54, 0x6a, 0xec, 0xec, 0xdd, 0x28, 0xaa, 0x3e, 0xf9, 0x11, - 0x4c, 0xa7, 0x52, 0x84, 0x0b, 0xfd, 0xa7, 0xaf, 0xaf, 0x9a, 0xb2, 0xbd, 0xeb, 0x18, 0x1f, 0x0d, - 0xd8, 0x35, 0x5b, 0xb0, 0x8c, 0xa2, 0x23, 0xaf, 0x9e, 0x38, 0x53, 0x63, 0x30, 0x50, 0xc1, 0xa4, - 0x47, 0xec, 0xe9, 0xf0, 0xd1, 0xa6, 0x0a, 0x3d, 0x46, 0x5b, 0x5b, 0xbf, 0xd1, 0xe3, 0x5b, 0xbf, - 0x91, 0xf8, 0x8c, 0xe8, 0x73, 0xb6, 0x7e, 0xf5, 0xcc, 0xb6, 0xc3, 0xe3, 0xd5, 0xb7, 0xc5, 0xc5, - 0xa9, 0x13, 0x63, 0x8c, 0xfa, 0x03, 0xe8, 0x03, 0x65, 0xb7, 0xf0, 0xdb, 0xd6, 0x4f, 0x76, 0x51, - 0xdd, 0xa5, 0xa1, 0x3a, 0x72, 0xb3, 0xc8, 0xd8, 0x2b, 0x56, 0x87, 0x14, 0x15, 0x80, 0x7c, 0x29, - 0xbe, 0xcc, 0x98, 0xc0, 0x03, 0x8d, 0x1a, 0x94, 0xb0, 0x67, 0x0d, 0x8c, 0x63, 0x45, 0x8a, 0x37, - 0xfc, 0x64, 0x63, 0xa2, 0xba, 0xbe, 0x4c, 0x2c, 0xef, 0xf8, 0x3f, 0xec, 0x62, 0x55, 0xd7, 0xaf, - 0xe8, 0xe4, 0x26, 0x82, 0xaf, 0x20, 0x97, 0x83, 0xae, 0x8a, 0x5a, 0x2c, 0xda, 0xda, 0xd0, 0x55, - 0x5f, 0x8d, 0xdf, 0xc2, 0x4b, 0x63, 0x53, 0xbc, 0x39, 0x97, 0x82, 0xf5, 0x1c, 0x3a, 0x96, 0x90, - 0xa8, 0x4b, 0xa4, 0xf6, 0xff, 0xa3, 0x79, 0xa9, 0x4f, 0x90, 0xfb, 0xbe, 0x31, 0x28, 0xbd, 0xcf, - 0xfd, 0x18, 0x95, 0x72, 0x03, 0x05, 0x99, 0x3a, 0xe7, 0x90, 0x6c, 0x21, 0xa1, 0xd9, 0x74, 0xf7, - 0x13, 0x14, 0xa2, 0xb5, 0x89, 0x0c, 0xba, 0xae, 0xfb, 0xd4, 0x04, 0x8c, 0xf1, 0x6f, 0xf6, 0x8c, - 0xa5, 0xea, 0xd3, 0x32, 0xf0, 0xb7, 0x3b, 0xae, 0xd7, 0x52, 0x70, 0x1c, 0xfa, 0xc6, 0xc7, 0x60, - 0x8b, 0x7a, 0xbb, 0x4f, 0xad, 0x86, 0xb1, 0x16, 0x7a, 0xfd, 0x36, 0xbb, 0x32, 0xea, 0xb1, 0x86, - 0xd1, 0x33, 0x44, 0x44, 0x72, 0x60, 0xc2, 0x71, 0x6c, 0xce, 0x36, 0xdf, 0x9a, 0x6e, 0x9a, 0x1c, - 0x9c, 0xa7, 0x3e, 0x40, 0x20, 0x85, 0xe4, 0x60, 0xe7, 0x0b, 0xc1, 0xc3, 0x02, 0x02, 0xee, 0x80, - 0x68, 0xb3, 0x33, 0x14, 0xad, 0xd7, 0xe2, 0x41, 0x5f, 0x62, 0x74, 0xaa, 0xaf, 0x91, 0x44, 0x5b, - 0x02, 0x15, 0x15, 0xc4, 0xa7, 0x99, 0x77, 0x72, 0xf7, 0xc2, 0x4d, 0xd4, 0x97, 0x5a, 0xe4, 0xf9, - 0x09, 0x67, 0xb3, 0x17, 0x1e, 0x75, 0xb8, 0xd9, 0x9e, 0xe7, 0x6c, 0x66, 0x4e, 0xb4, 0x3e, 0x83, - 0x47, 0x0b, 0xfa, 0xa7, 0xa6, 0x26, 0xb9, 0x34, 0x53, 0x68, 0x41, 0x35, 0xf9, 0xa7, 0x20, 0xb4, - 0xd8, 0xa9, 0x3e, 0xa1, 0x00, 0xe1, 0xd3, 0xdb, 0x19, 0x06, 0x2d, 0xce, 0xfe, 0xeb, 0x92, 0xfa, - 0x20, 0x87, 0xf8, 0x80, 0xfb, 0xf6, 0x07, 0x70, 0x3a, 0xbd, 0x41, 0xf7, 0x55, 0x46, 0x9f, 0x93, - 0x16, 0x57, 0x03, 0xab, 0xe2, 0x51, 0xd6, 0xee, 0x8d, 0xf5, 0x89, 0x8d, 0x6d, 0x0d, 0x36, 0x38, - 0x3a, 0xda, 0xfe, 0x12, 0x8e, 0xf8, 0x6c, 0x00, 0x97, 0x4b, 0x43, 0x0f, 0x32, 0xf0, 0x6d, 0x63, - 0x91, 0x45, 0xc9, 0xe8, 0x71, 0x75, 0x55, 0xe8, 0x25, 0x90, 0x66, 0xb6, 0x04, 0xd3, 0xdb, 0x9a, - 0xa7, 0x29, 0x0c, 0x0f, 0x5e, 0x0f, 0xfd, 0xbf, 0x9b, 0x6a, 0x73, 0xd9, 0x07, 0x4a, 0x8d, 0x38, - 0x02, 0xc5, 0xd5, 0x10, 0x89, 0x8e, 0xa0, 0x9c, 0x42, 0x78, 0x50, 0x91, 0x03, 0xa5, 0x66, 0xce, - 0xbd, 0x26, 0xcb, 0x68, 0x57, 0x06, 0xbc, 0x13, 0x5f, 0x1d, 0xcf, 0x77, 0xe5, 0x52, 0x25, 0x71, - 0x8a, 0x1d, 0xa9, 0x9e, 0x47, 0x7f, 0xf0, 0xbd, 0x0d, 0x14, 0x30, 0x5b, 0x1f, 0x1d, 0xdd, 0xec, - 0x36, 0xdd, 0xf3, 0xc5, 0x81, 0xe7, 0xc8, 0x13, 0xd1, 0xd2, 0x36, 0x45, 0xc2, 0x23, 0xf2, 0x7c, - 0x9b, 0xf3, 0xc5, 0x07, 0xc3, 0x76, 0x07, 0xcc, 0x63, 0xfd, 0xc7, 0x2b, 0x9a, 0x2a, 0x4d, 0x7c, - 0x1f, 0x4b, 0xca, 0x92, 0x1d, 0x50, 0x86, 0x62, 0xde, 0x92, 0x27, 0xcf, 0x14, 0xd3, 0x86, 0x75, - 0xa6, 0x3f, 0xf3, 0xb0, 0xd7, 0x60, 0x13, 0x23, 0x11, 0x25, 0x9e, 0x3c, 0x96, 0x64, 0x49, 0xb7, - 0x74, 0x57, 0xf6, 0x99, 0xc5, 0xbb, 0x4c, 0x28, 0x3c, 0xd8, 0xed, 0x33, 0x55, 0x34, 0x5e, 0x71, - 0xdd, 0x6c, 0xb8, 0xd3, 0x99, 0x3c, 0xa1, 0x64, 0x08, 0x52, 0xd4, 0xf5, 0x7a, 0xfb, 0xeb, 0x4a, - 0x85, 0xd7, 0xac, 0xda, 0xf7, 0xfd, 0xea, 0x83, 0x4d, 0x66, 0x5d, 0x3a, 0x51, 0xd4, 0xac, 0xba, - 0x4d, 0x1a, 0x5b, 0x67, 0xe7, 0xaa, 0xaf, 0xfe, 0x49, 0x81, 0x91, 0x54, 0x1b, 0x1d, 0x3a, 0xa2, - 0xd0, 0x94, 0x65, 0xf4, 0x65, 0x6f, 0xb0, 0xc6, 0xe8, 0xa1, 0xfa, 0x8a, 0x90, 0x77, 0x5b, 0x6c, - 0x98, 0xf1, 0xba, 0x2c, 0x36, 0x63, 0xb8, 0x63, 0xb5, 0x8b, 0x16, 0xde, 0x8b, 0x93, 0x7d, 0xc4, - 0x18, 0x8d, 0x6a, 0x4c, 0x7e, 0x89, 0x3f, 0xf7, 0x1e, 0xcc, 0x90, 0x98, 0xdc, 0xd4, 0xdb, 0x6c, - 0x9c, 0x6d, 0xc7, 0x4a, 0x38, 0x55, 0x82, 0x2e, 0x7e, 0x88, 0xc2, 0x6b, 0x72, 0xaa, 0xa2, 0xa9, - 0x47, 0x01, 0x03, 0x7d, 0xb4, 0x48, 0x9f, 0xae, 0x83, 0xb4, 0x90, 0xa9, 0xcd, 0x06, 0x16, 0x47, - 0xd3, 0x67, 0x32, 0x34, 0x52, 0xfd, 0x1d, 0x24, 0xb1, 0x4f, 0xa2, 0x06, 0x53, 0xc7, 0x70, 0xa2, - 0x7d, 0x21, 0x9c, 0x8c, 0x3d, 0xd0, 0x59, 0x1e, 0xf5, 0x57, 0x34, 0x74, 0x3c, 0xa7, 0xdc, 0x22, - 0x01, 0x69, 0x4b, 0x52, 0x58, 0x5a, 0xb8, 0xa8, 0x5e, 0xa9, 0x1c, 0xa1, 0x44, 0x38, 0x22, 0x8e, - 0x3e, 0x9f, 0x75, 0xfd, 0x64, 0xf4, 0x50, 0xf2, 0xf7, 0x59, 0xb7, 0xab, 0x83, 0x14, 0x94, 0x94, - 0xe4, 0x28, 0xb7, 0x51, 0xb4, 0x55, 0x0e, 0xd1, 0xa7, 0x4e, 0x16, 0x7b, 0x97, 0x6c, 0x6b, 0xa3, - 0xca, 0xb3, 0x56, 0x90, 0xd5, 0x11, 0x1c, 0x1a, 0x1d, 0xcc, 0x7a, 0x6d, 0x42, 0x30, 0x22, 0x84, - 0x5e, 0x97, 0x99, 0x8e, 0x97, 0xf7, 0x92, 0xed, 0x7a, 0x67, 0x32, 0x12, 0x5a, 0x39, 0x63, 0xe6, - 0xeb, 0x0f, 0xcd, 0xf0, 0x28, 0x6b, 0x7a, 0xe4, 0xe4, 0x0f, 0xd6, 0x01, 0x0f, 0x4f, 0xbd, 0x18, - 0xa3, 0x6c, 0x1e, 0x21, 0x67, 0xf5, 0xd5, 0x1a, 0xd9, 0x47, 0xe3, 0xa0, 0x65, 0xaf, 0xcf, 0xaa, - 0xe3, 0xd7, 0xf2, 0x4f, 0xcb, 0xb0, 0x87, 0x1a, 0x15, 0x9a, 0x12, 0xd4, 0xb1, 0x4a, 0x22, 0x14, - 0xf9, 0xd7, 0x30, 0xa4, 0xbf, 0x62, 0x29, 0xac, 0x5b, 0x4c, 0x9e, 0xa4, 0x94, 0x00, 0xa4, 0x8b, - 0x70, 0x53, 0xb0, 0xbb, 0x82, 0x7d, 0x2c, 0xd8, 0xdb, 0x82, 0xbd, 0x2b, 0x7c, 0xfb, 0x8d, 0xe9, - 0xb5, 0xd8, 0x37, 0x85, 0x7f, 0x6d, 0xfa, 0x23, 0x5b, 0x24, 0xf2, 0xa6, 0x60, 0x37, 0xf0, 0x16, - 0xd1, 0xe6, 0x8d, 0x0f, 0x40, 0x6f, 0x0a, 0x23, 0x60, 0xfb, 0x86, 0xce, 0xa1, 0x2b, 0x75, 0x1f, - 0x81, 0xe2, 0x0e, 0x7c, 0x95, 0x54, 0x50, 0xbc, 0xd1, 0x8c, 0x57, 0x97, 0x9e, 0x12, 0xf3, 0x43, - 0x3a, 0xaa, 0xfa, 0x30, 0xa9, 0xbf, 0x6e, 0xfa, 0x7b, 0xc9, 0xb3, 0xfb, 0xf7, 0x3c, 0xe6, 0xe2, - 0x43, 0x7f, 0xf4, 0x65, 0xef, 0xc6, 0xdf, 0xd2, 0x88, 0xc4, 0xc1, 0x4d, 0xf1, 0xd7, 0x29, 0xa4, - 0xa0, 0x36, 0xbe, 0xfa, 0x75, 0xe0, 0x34, 0x01, 0x2b, 0x07, 0x37, 0x6e, 0x44, 0xdf, 0x59, 0x8c, - 0xe4, 0xb7, 0x9e, 0xb8, 0x2f, 0xfe, 0x86, 0x8c, 0xef, 0xa7, 0xf2, 0xbb, 0xed, 0x9e, 0x70, 0xdc, - 0x92, 0xf5, 0x3a, 0x71, 0x31, 0x37, 0xbf, 0x3a, 0x88, 0x4a, 0xb6, 0x0e, 0x2b, 0x49, 0x1f, 0xd3, - 0x5f, 0x26, 0xa1, 0x8f, 0x78, 0x43, 0x99, 0x7a, 0x74, 0x8a, 0x2c, 0x71, 0x28, 0xc9, 0x38, 0xfd, - 0xa1, 0x92, 0x3b, 0x66, 0x7c, 0xac, 0x7c, 0xfb, 0xaf, 0xc8, 0xd0, 0x5f, 0x33, 0xc8, 0x86, 0xa3, - 0x68, 0xec, 0x71, 0xd9, 0x55, 0xe3, 0x23, 0xaa, 0x89, 0xf9, 0x11, 0x55, 0x56, 0x32, 0x0a, 0x79, - 0x88, 0xbf, 0x7d, 0x42, 0x7f, 0x65, 0xa6, 0x24, 0x43, 0xce, 0x5e, 0x60, 0xb1, 0x76, 0x39, 0xf8, - 0x61, 0xfb, 0x24, 0x9e, 0x36, 0x88, 0xc5, 0x0d, 0x3e, 0xba, 0x3a, 0x00, 0x10, 0x56, 0x9c, 0x06, - 0xc4, 0x4a, 0xf4, 0x05, 0x51, 0xe3, 0xf0, 0x65, 0x30, 0xbd, 0x17, 0x4a, 0x67, 0x88, 0x35, 0xf1, - 0x0e, 0x1f, 0x1a, 0xb5, 0xbe, 0x7c, 0xf7, 0x56, 0x7c, 0xc4, 0x18, 0x79, 0x80, 0x43, 0xf7, 0xe3, - 0x09, 0xed, 0x0a, 0xd7, 0xf6, 0xc7, 0xc2, 0xbf, 0xa3, 0xff, 0xd7, 0xeb, 0x87, 0x8d, 0xe3, 0x82, - 0x33, 0x73, 0x8c, 0xc4, 0xb7, 0xc4, 0x5f, 0x71, 0xb3, 0x40, 0x78, 0xae, 0xf4, 0x5f, 0x7e, 0xaa, - 0x92, 0x52, 0xda, 0xf9, 0xef, 0x0a, 0x66, 0xbf, 0x2d, 0x7c, 0xe4, 0x96, 0x98, 0xaa, 0x2d, 0x9e, - 0xe2, 0x0f, 0x00, 0xb8, 0x0b, 0x7f, 0x01, 0x6a, 0x75, 0xab, 0x2f, 0x5f, 0x7f, 0x41, 0xdf, 0x96, - 0x9c, 0x13, 0x05, 0xbb, 0x92, 0x71, 0xfd, 0x89, 0x78, 0x91, 0xdb, 0xeb, 0xfe, 0x52, 0xbc, 0x88, - 0xe8, 0x94, 0x7f, 0x2b, 0xd2, 0x5f, 0xa4, 0x77, 0xfe, 0x3d, 0xd1, 0x3d, 0x78, 0xe0, 0xff, 0x00, - 0x6f, 0x95, 0xe5, 0xa4, 0x5e, 0x6e, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/rangetouch.js, do not edit!! -const uint16_t rangetouchJs_length = 1833; -const uint8_t rangetouchJs[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xb5, 0x58, 0xdf, 0x8f, 0xdb, 0xb8, - 0x11, 0x7e, 0x3f, 0xe0, 0xfe, 0x07, 0x59, 0x6d, 0x7d, 0xe4, 0x2e, 0x57, 0xb6, 0x17, 0xc8, 0x8b, - 0x1c, 0xc6, 0x48, 0x73, 0x39, 0xa0, 0x68, 0xb6, 0x29, 0xb2, 0x39, 0xb4, 0x80, 0xcf, 0x0f, 0xb2, - 0x44, 0xdb, 0xbc, 0xc8, 0xa4, 0x8e, 0xa4, 0xbc, 0x31, 0x76, 0xf5, 0xbf, 0x77, 0x86, 0x94, 0x6c, - 0x39, 0x6b, 0x27, 0x79, 0xb8, 0x2e, 0x16, 0xb6, 0x44, 0x0d, 0x87, 0x33, 0xdf, 0x7c, 0xf3, 0x43, - 0x1e, 0x8d, 0x22, 0xfe, 0xa7, 0xfd, 0xfd, 0xf8, 0xc3, 0x68, 0x14, 0x99, 0x4c, 0xad, 0x85, 0xd3, - 0x75, 0xbe, 0x49, 0x7e, 0xb7, 0xd1, 0xee, 0x36, 0x19, 0x27, 0x13, 0xff, 0xe0, 0x2e, 0xfb, 0x24, - 0xd5, 0x3a, 0x7a, 0x29, 0x55, 0x55, 0xbb, 0xc8, 0xed, 0x2b, 0xc1, 0x63, 0x2f, 0x1c, 0xbf, 0x8a, - 0x1e, 0xb4, 0xf9, 0x14, 0x69, 0x15, 0xf9, 0x7d, 0x51, 0x21, 0x76, 0x32, 0x17, 0xd6, 0xef, 0xda, - 0x38, 0x57, 0xd9, 0x74, 0x34, 0x5a, 0x4b, 0xb7, 0xa9, 0x97, 0x49, 0xae, 0xb7, 0x23, 0x9b, 0x6d, - 0x2b, 0xed, 0x9c, 0x1d, 0x1d, 0x8f, 0xf2, 0xa2, 0xef, 0x60, 0x93, 0xb2, 0x22, 0x8d, 0x3e, 0x6e, - 0x44, 0x74, 0xf7, 0x8f, 0x8f, 0xdd, 0x42, 0x44, 0xe0, 0x86, 0x7a, 0x91, 0x3f, 0xd3, 0xd7, 0xc1, - 0xaa, 0x56, 0xb9, 0x93, 0x5a, 0x11, 0xc1, 0x1c, 0x7d, 0x8c, 0xf5, 0xf2, 0x77, 0x91, 0xbb, 0x98, - 0x73, 0x74, 0x4d, 0xaf, 0x22, 0xf1, 0xb9, 0xd2, 0xc6, 0xd9, 0xe1, 0x30, 0xae, 0x55, 0x21, 0x56, - 0x52, 0x89, 0x22, 0x1e, 0x74, 0x0f, 0xb7, 0xba, 0xa8, 0x4b, 0x31, 0x0b, 0x5f, 0x49, 0x2b, 0xca, - 0x1d, 0xa1, 0x69, 0xdc, 0xa9, 0x3d, 0x6a, 0x0a, 0xbb, 0x87, 0xc3, 0xf0, 0x9d, 0x64, 0xdb, 0x62, - 0x16, 0x2e, 0x49, 0xfc, 0x01, 0x21, 0xf8, 0x88, 0x10, 0xc4, 0x60, 0x44, 0x4a, 0x04, 0x17, 0x4f, - 0x4f, 0x56, 0x94, 0x2b, 0x9a, 0x1c, 0x1f, 0xa1, 0xde, 0x86, 0xb8, 0x8d, 0xb4, 0x8c, 0x1c, 0x8c, - 0x06, 0x8b, 0x6b, 0xc0, 0xc6, 0x3a, 0x23, 0xc1, 0xea, 0x69, 0xb7, 0x1e, 0x89, 0xe0, 0xce, 0x4a, - 0x1b, 0xb2, 0xcb, 0x4c, 0xa4, 0xf8, 0x78, 0xaa, 0x5e, 0xba, 0xa4, 0x14, 0x6a, 0xed, 0x36, 0x53, - 0x75, 0x7d, 0x4d, 0x1f, 0x71, 0xdd, 0x70, 0x37, 0x57, 0x8b, 0xa9, 0x49, 0x84, 0xaa, 0xb7, 0xc2, - 0x64, 0xcb, 0x52, 0xf0, 0xfe, 0xcd, 0xd3, 0xd3, 0x60, 0xc2, 0x0c, 0xc4, 0x4b, 0xad, 0xe4, 0xba, - 0x0e, 0xcf, 0x07, 0x63, 0x16, 0xef, 0xb2, 0xb2, 0x16, 0xb1, 0x54, 0x91, 0x19, 0x0e, 0x89, 0x49, - 0x1e, 0x8c, 0x74, 0xed, 0x33, 0xca, 0xde, 0x7b, 0x04, 0x93, 0xe0, 0xdb, 0xbf, 0x8d, 0xae, 0x84, - 0x71, 0x7b, 0x30, 0xc7, 0x24, 0x9f, 0xc4, 0x9e, 0x19, 0xda, 0x34, 0x07, 0x2b, 0x1d, 0x5a, 0xc9, - 0x14, 0x7d, 0x34, 0xc2, 0xd5, 0x06, 0xee, 0x23, 0x50, 0x29, 0x66, 0x97, 0x34, 0x38, 0xf6, 0xe8, - 0x0f, 0x4e, 0x15, 0x3b, 0x9a, 0x98, 0x82, 0x3d, 0x7d, 0xfb, 0xf0, 0xbe, 0xb3, 0x07, 0xae, 0x1b, - 0x9a, 0x8a, 0xb9, 0x5b, 0x70, 0xd8, 0x72, 0x3c, 0xb7, 0x0d, 0x76, 0x40, 0xa6, 0x3d, 0x0d, 0x8c, - 0xb3, 0x44, 0xd0, 0xa9, 0x5c, 0x91, 0x76, 0x05, 0x58, 0xf9, 0xfe, 0x41, 0x75, 0xe7, 0xdf, 0xef, - 0xb7, 0x4b, 0x5d, 0xda, 0x0e, 0xb7, 0xaf, 0xc9, 0xa0, 0x1a, 0x87, 0xc0, 0x00, 0x96, 0x2b, 0x59, - 0x3a, 0x61, 0xc8, 0x31, 0x62, 0xee, 0xe0, 0xed, 0x59, 0x15, 0x3f, 0x0b, 0x9b, 0x1b, 0x59, 0x39, - 0x08, 0x1c, 0xda, 0xd8, 0x8b, 0x45, 0x43, 0x29, 0x65, 0x2a, 0xa9, 0x6a, 0xbb, 0x49, 0xb2, 0xaa, - 0x2a, 0xf7, 0x44, 0x21, 0x9a, 0xad, 0x32, 0x75, 0xf4, 0x0e, 0x76, 0x1e, 0x23, 0x6f, 0xf8, 0x64, - 0x6a, 0x5e, 0x66, 0x66, 0x0d, 0x6a, 0x94, 0xb3, 0x1d, 0x03, 0x4c, 0xc7, 0x00, 0xc9, 0x55, 0x5d, - 0x96, 0x03, 0x7e, 0x90, 0x98, 0x9b, 0xc5, 0xac, 0x7f, 0x93, 0x3e, 0x36, 0x53, 0xf3, 0xb7, 0xdb, - 0x99, 0x6a, 0x61, 0x21, 0x92, 0x32, 0x08, 0x73, 0x02, 0x07, 0xbc, 0xcd, 0xf2, 0x4d, 0xcf, 0x33, - 0x88, 0x23, 0x06, 0x54, 0x31, 0x09, 0x9c, 0xa2, 0x60, 0x6e, 0xfa, 0x0d, 0x0f, 0xed, 0xd9, 0x48, - 0x4b, 0x01, 0x00, 0xb2, 0x6f, 0x6d, 0x05, 0x33, 0x68, 0xda, 0xb3, 0xe9, 0x9c, 0x41, 0x00, 0xf5, - 0x65, 0x2a, 0x7d, 0x0b, 0x7d, 0x09, 0xe8, 0xa3, 0x13, 0x1d, 0xc0, 0xa2, 0x09, 0x70, 0x3d, 0x66, - 0x45, 0xf1, 0xe6, 0xfe, 0x1e, 0x69, 0x06, 0xb5, 0x6c, 0xbb, 0xfc, 0x8f, 0x2c, 0xdc, 0x26, 0x9d, - 0xbc, 0x60, 0x0f, 0x99, 0xcb, 0x37, 0xc8, 0xb8, 0x63, 0x16, 0xd6, 0x81, 0x67, 0xad, 0x86, 0x5e, - 0xd2, 0xb6, 0x2b, 0xaf, 0x8d, 0xc9, 0xf6, 0xc9, 0xca, 0xe8, 0x2d, 0x29, 0x74, 0xee, 0x21, 0x4f, - 0xfe, 0xa8, 0x85, 0xd9, 0xdf, 0x8b, 0x12, 0x8c, 0xd3, 0xe6, 0x75, 0x59, 0x82, 0x17, 0x34, 0x91, - 0x2a, 0x2f, 0xeb, 0x02, 0x80, 0xc1, 0xf4, 0xa7, 0x4d, 0x92, 0x67, 0xf0, 0x00, 0x75, 0x7b, 0xa3, - 0x34, 0x3f, 0x16, 0xb1, 0x83, 0xee, 0x10, 0x56, 0x31, 0x13, 0x98, 0xbd, 0x50, 0x1f, 0x6a, 0xd4, - 0x97, 0xe2, 0x6a, 0xc3, 0x72, 0x7e, 0x5a, 0xf5, 0xc2, 0x96, 0xc1, 0x80, 0x40, 0x79, 0x02, 0xe2, - 0x0a, 0x48, 0x43, 0xeb, 0x32, 0x95, 0x63, 0xd9, 0x82, 0x33, 0x58, 0x79, 0xe9, 0x00, 0xce, 0x45, - 0xc3, 0xb2, 0x73, 0x4f, 0x35, 0x5c, 0x43, 0x81, 0x0d, 0x28, 0x37, 0xcc, 0x7e, 0x45, 0xe6, 0x1e, - 0x8a, 0x97, 0x5a, 0x37, 0x6c, 0x75, 0x4e, 0x26, 0x40, 0x24, 0xad, 0xff, 0x86, 0xf5, 0x86, 0x6d, - 0xce, 0x89, 0xe5, 0xe0, 0xc8, 0xbf, 0x74, 0x21, 0xde, 0x49, 0x8b, 0x06, 0x17, 0xdc, 0xb2, 0x3d, - 0x5f, 0xb1, 0x25, 0xdf, 0xb0, 0xed, 0x25, 0xf9, 0xb7, 0xa5, 0x40, 0xc4, 0x41, 0x7c, 0x7d, 0x51, - 0x64, 0x17, 0x04, 0xaa, 0x73, 0x02, 0x10, 0x01, 0xfa, 0xf4, 0x44, 0xac, 0xff, 0x5a, 0xf9, 0xcf, - 0x0d, 0x7c, 0xd2, 0xe1, 0x70, 0x20, 0xda, 0x3c, 0x7b, 0x7a, 0xca, 0x60, 0x05, 0x16, 0x4e, 0x8b, - 0x4c, 0xfb, 0xb4, 0xc7, 0x94, 0x5d, 0x08, 0x04, 0x14, 0x9f, 0xc9, 0xab, 0x43, 0x65, 0xea, 0x9f, - 0x89, 0x2b, 0x8e, 0xc7, 0x31, 0x46, 0x33, 0xcf, 0x1c, 0x2a, 0xd9, 0x22, 0xe1, 0xc8, 0x88, 0xcc, - 0xd2, 0xdf, 0x12, 0xf2, 0x5b, 0x71, 0x4d, 0xe9, 0x0c, 0xae, 0xe7, 0xe2, 0xed, 0x82, 0xcc, 0xaf, - 0x6f, 0x16, 0xb3, 0xb0, 0xf4, 0xd7, 0x11, 0x9d, 0x76, 0xe5, 0x75, 0x76, 0x97, 0xb9, 0x0d, 0xec, - 0xfb, 0x4c, 0xc6, 0x8c, 0xb8, 0xf9, 0x64, 0x31, 0xc3, 0x8f, 0xd6, 0x9a, 0x74, 0x4c, 0x6f, 0x60, - 0xf1, 0x76, 0x31, 0xbb, 0xc6, 0x4f, 0xb8, 0xa5, 0xe9, 0x18, 0x1a, 0xce, 0x61, 0x7b, 0x95, 0x19, - 0x2b, 0x7e, 0x29, 0x35, 0x9e, 0x9e, 0x38, 0xfd, 0x8b, 0xfc, 0x2c, 0x0a, 0x48, 0xfa, 0x43, 0x86, - 0x78, 0xe5, 0x46, 0x43, 0x9f, 0x24, 0x62, 0xe4, 0xe8, 0x95, 0x6b, 0x9e, 0x13, 0xff, 0xa4, 0xf4, - 0x43, 0xc1, 0x20, 0xa7, 0x44, 0x04, 0xff, 0x81, 0x84, 0xa7, 0xf4, 0xa3, 0x6e, 0x63, 0xf4, 0x43, - 0xa4, 0xc4, 0x43, 0xf4, 0x11, 0x3a, 0xe9, 0x5b, 0x63, 0x20, 0x3b, 0xe3, 0x37, 0x99, 0x52, 0xda, - 0x45, 0x98, 0x08, 0x51, 0x16, 0xe5, 0x65, 0x66, 0x6d, 0x94, 0xc1, 0xff, 0xe1, 0xb0, 0x18, 0x92, - 0x37, 0x74, 0x4b, 0x47, 0xd9, 0x16, 0xf0, 0x9a, 0xe1, 0x4d, 0x22, 0x42, 0xd0, 0xb9, 0x48, 0x0b, - 0x1f, 0x19, 0x72, 0xb2, 0x7a, 0x3e, 0x0b, 0x31, 0xa8, 0xa0, 0xa2, 0x2f, 0x09, 0x3b, 0xab, 0x93, - 0x85, 0xc4, 0x1c, 0x1a, 0xf5, 0x41, 0x6b, 0x68, 0x4b, 0xdc, 0x90, 0xc7, 0x86, 0x49, 0x06, 0x1f, - 0x8a, 0x32, 0xff, 0x40, 0x2a, 0x09, 0xcd, 0xfc, 0x58, 0xbb, 0xb9, 0x83, 0x94, 0x9c, 0x3f, 0x02, - 0x3b, 0xd2, 0xd8, 0xc2, 0x5a, 0x15, 0xb3, 0xd0, 0xe8, 0xbe, 0x64, 0x80, 0xe2, 0x93, 0x67, 0xb5, - 0x7c, 0x38, 0xdc, 0x69, 0x59, 0x44, 0xe3, 0x01, 0xef, 0x15, 0xf1, 0x49, 0xbf, 0x88, 0x4f, 0xb0, - 0x88, 0x33, 0xed, 0x2b, 0x3d, 0xf6, 0xb7, 0xca, 0x73, 0x15, 0xfd, 0x9f, 0x69, 0xfe, 0x5d, 0x35, - 0xc8, 0xcb, 0x8a, 0xf4, 0x27, 0x3f, 0xf5, 0xcd, 0xfb, 0x53, 0xdf, 0xe2, 0x27, 0xa0, 0xc9, 0x36, - 0xa8, 0x9a, 0x8b, 0x45, 0xba, 0x7c, 0xa6, 0x55, 0xd0, 0x74, 0x1f, 0xa0, 0xd6, 0x5c, 0x74, 0xfd, - 0x70, 0x0b, 0x88, 0x56, 0x44, 0x53, 0xda, 0x2b, 0x26, 0x53, 0xf4, 0x30, 0x3f, 0x81, 0x0b, 0xad, - 0x0d, 0x71, 0xca, 0x13, 0x5f, 0x5f, 0x03, 0x0c, 0x25, 0x47, 0x36, 0xdc, 0xd5, 0x2e, 0x43, 0x70, - 0xde, 0x2f, 0xad, 0x30, 0xbb, 0x93, 0x26, 0x0b, 0xcc, 0xea, 0x59, 0xa0, 0x2e, 0x74, 0xab, 0xbe, - 0x48, 0x02, 0x65, 0x5d, 0x14, 0x58, 0x42, 0xec, 0x05, 0x69, 0xd4, 0x33, 0x1c, 0xd6, 0xd0, 0x75, - 0xd1, 0x1e, 0x34, 0xc0, 0xc1, 0x75, 0xee, 0x7b, 0x84, 0xff, 0x9f, 0x96, 0x89, 0x0e, 0xa6, 0x1c, - 0x91, 0x5c, 0xea, 0x62, 0xcf, 0x1e, 0xf3, 0x8d, 0x2c, 0x0b, 0x2c, 0x4d, 0xd8, 0x35, 0x6c, 0xbd, - 0x74, 0x46, 0x84, 0xd9, 0xa4, 0x63, 0x80, 0x86, 0xa4, 0xac, 0x7a, 0xc7, 0xf5, 0xaa, 0xac, 0x3f, - 0x07, 0x73, 0x05, 0x0f, 0x69, 0x58, 0x20, 0x89, 0x50, 0x38, 0x11, 0x14, 0x31, 0x83, 0xf6, 0x95, - 0x3e, 0xeb, 0x2b, 0xb1, 0x56, 0x7e, 0x9e, 0x86, 0x24, 0x32, 0x0e, 0xa7, 0xb4, 0x83, 0x39, 0xdd, - 0x45, 0x5b, 0xfa, 0x9a, 0x66, 0xc1, 0x20, 0x2a, 0x2d, 0xf3, 0x90, 0x95, 0xcf, 0x88, 0x07, 0x3d, - 0x3d, 0x69, 0x4f, 0x3b, 0xa5, 0x75, 0x12, 0xfa, 0xe0, 0x17, 0x19, 0x94, 0x58, 0xb7, 0x87, 0x51, - 0x18, 0x66, 0x52, 0x13, 0xf8, 0xc3, 0x63, 0xa5, 0x95, 0x88, 0xd9, 0x19, 0xa1, 0x07, 0xb1, 0xfc, - 0xa7, 0x74, 0xbf, 0x7e, 0x8f, 0xa8, 0x77, 0xe7, 0xb5, 0xb7, 0x88, 0xc7, 0xdb, 0x4c, 0xc9, 0xaa, - 0x2e, 0xb3, 0x90, 0xe5, 0x41, 0xbc, 0x04, 0x70, 0x85, 0x12, 0x30, 0x17, 0xe0, 0x08, 0x7a, 0x21, - 0x31, 0x79, 0xe8, 0x9e, 0x1d, 0x88, 0x10, 0x6a, 0x67, 0xf4, 0xfe, 0xff, 0xe0, 0xf2, 0x77, 0xba, - 0xfb, 0x6d, 0x57, 0xcf, 0xb8, 0x37, 0xb9, 0xec, 0x1e, 0x26, 0xd1, 0xd1, 0xbd, 0xc3, 0x9e, 0x4b, - 0xc5, 0xc4, 0x79, 0x3c, 0x98, 0x82, 0x21, 0x21, 0x06, 0xcf, 0x7c, 0xaf, 0x7b, 0xd7, 0x6e, 0x8a, - 0xd3, 0xd8, 0x88, 0xad, 0xde, 0x89, 0xd3, 0xd5, 0xe9, 0x3c, 0xee, 0x31, 0x8b, 0x85, 0x1b, 0x14, - 0xeb, 0xae, 0x85, 0x2a, 0xe2, 0xc5, 0x99, 0xfc, 0x11, 0x1e, 0xd4, 0x60, 0x32, 0x4c, 0x87, 0x40, - 0xe8, 0x73, 0x64, 0x07, 0x0c, 0x04, 0xb6, 0xb6, 0x06, 0x46, 0xcc, 0xc9, 0x09, 0xe1, 0x81, 0xe7, - 0xe7, 0xdc, 0xc0, 0x7e, 0x71, 0x08, 0x16, 0xbc, 0xac, 0xac, 0xb1, 0x54, 0x7f, 0x59, 0x52, 0x60, - 0x4c, 0x86, 0xc2, 0x03, 0x16, 0x83, 0x12, 0x26, 0xe1, 0x32, 0xdf, 0x20, 0x66, 0x85, 0x07, 0x4d, - 0xd8, 0xf9, 0x78, 0xc1, 0x6a, 0xde, 0x6b, 0x6e, 0x06, 0x87, 0xc2, 0xd7, 0x0e, 0xa6, 0x92, 0x65, - 0xed, 0xe0, 0xed, 0x6c, 0x2b, 0x81, 0x66, 0x50, 0x30, 0xc7, 0x50, 0x42, 0xbf, 0x26, 0x96, 0x7d, - 0xf6, 0x62, 0x93, 0x31, 0xbc, 0x90, 0x7c, 0x4d, 0x10, 0xb0, 0xac, 0x82, 0x24, 0x0c, 0x56, 0xfe, - 0xe1, 0xdf, 0xb1, 0x69, 0xc2, 0x0c, 0xf4, 0xa6, 0x94, 0x80, 0xcf, 0x07, 0x9c, 0x68, 0x29, 0x8c, - 0x55, 0xa0, 0x69, 0x54, 0x26, 0x0f, 0x38, 0x60, 0x5e, 0x9d, 0xf0, 0xf0, 0x38, 0x78, 0x8e, 0x6e, - 0xe9, 0x08, 0xc4, 0xba, 0x16, 0x3d, 0x7e, 0x45, 0xd4, 0xe9, 0x36, 0x99, 0xe4, 0x5e, 0xe9, 0x7f, - 0x6f, 0x4a, 0xe8, 0x17, 0x2b, 0x68, 0xa7, 0x33, 0x78, 0x19, 0x4c, 0x41, 0xe6, 0xa5, 0x02, 0x22, - 0x7b, 0x69, 0xca, 0x5e, 0x8c, 0x5f, 0xa9, 0x99, 0xba, 0xe1, 0x04, 0xee, 0x6e, 0x6e, 0xaf, 0x14, - 0xbd, 0xca, 0xd2, 0x17, 0xad, 0xc4, 0x35, 0xbf, 0xbd, 0x22, 0xea, 0xe6, 0xc5, 0x18, 0x16, 0x29, - 0xab, 0xaf, 0x77, 0x44, 0xe1, 0x91, 0x57, 0x44, 0xdf, 0xd4, 0x14, 0xeb, 0x5f, 0x17, 0x23, 0x7b, - 0x3e, 0x46, 0xbd, 0x64, 0x5a, 0x87, 0x61, 0xa8, 0x0b, 0x46, 0x52, 0x48, 0xdb, 0xa5, 0x99, 0x48, - 0x2a, 0x23, 0x90, 0x6b, 0x3f, 0x8b, 0x55, 0x56, 0x97, 0x08, 0xc0, 0x41, 0xcc, 0xeb, 0xf4, 0x64, - 0x45, 0xb0, 0x40, 0x07, 0x7b, 0x36, 0x35, 0xe0, 0xe0, 0xda, 0xb5, 0x48, 0x2c, 0x99, 0x9e, 0xb6, - 0x04, 0x5e, 0x18, 0x97, 0xf5, 0x12, 0x4e, 0xb0, 0xbe, 0xda, 0x4e, 0x05, 0x9e, 0x58, 0x61, 0x1f, - 0x09, 0xcf, 0xa1, 0xa8, 0x36, 0xe4, 0x40, 0x8d, 0x23, 0x83, 0x61, 0x28, 0x85, 0x55, 0xe8, 0x72, - 0xb3, 0x38, 0x70, 0x25, 0xc6, 0xea, 0x08, 0xad, 0x2f, 0x46, 0x4a, 0x2e, 0xc0, 0x07, 0x01, 0x1d, - 0xa3, 0x32, 0xda, 0x69, 0x94, 0x62, 0x1a, 0x70, 0xf0, 0x6b, 0x00, 0x07, 0x73, 0x2d, 0xe9, 0x34, - 0xcb, 0x1b, 0xe2, 0xfb, 0x02, 0xfe, 0x68, 0xf1, 0x97, 0xc8, 0xea, 0xda, 0xe4, 0xe2, 0x0e, 0x5e, - 0xdd, 0x20, 0xd2, 0xbf, 0x7e, 0x78, 0xc7, 0x4f, 0x7e, 0x63, 0xc1, 0x06, 0xf0, 0xe3, 0x0f, 0xff, - 0x03, 0x24, 0x8e, 0x90, 0x87, 0xc9, 0x11, 0x00, 0x00 -}; - diff --git a/wled00/html_pixart.h b/wled00/html_pixart.h deleted file mode 100644 index 790d8ea40..000000000 --- a/wled00/html_pixart.h +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Binary array for the Web UI. - * gzip is used for smaller size and improved speeds. - * - * Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui - * to find out how to easily modify the web UI source! - */ - -// Autogenerated from wled00/data/pixart/pixart.htm, do not edit!! -const uint16_t PAGE_pixart_L = 8364; -const uint8_t PAGE_pixart[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xd5, 0x3c, 0x6b, 0x7b, 0xda, 0x38, - 0xb3, 0xdf, 0xf3, 0x2b, 0x54, 0x77, 0xb7, 0xc5, 0x8b, 0x31, 0xb6, 0xb9, 0x06, 0xe2, 0xf4, 0x21, - 0xe4, 0x42, 0xb6, 0xb9, 0x93, 0xa4, 0x4d, 0xf3, 0xe6, 0xe9, 0x1a, 0x2c, 0xb0, 0x13, 0x63, 0x53, - 0xdb, 0x40, 0x08, 0xe5, 0xbf, 0x9f, 0x19, 0xc9, 0x06, 0x73, 0x49, 0x93, 0xf6, 0x74, 0xdf, 0xf3, - 0x9c, 0xed, 0x06, 0xdb, 0xd2, 0x48, 0x1a, 0xcd, 0x8c, 0xe6, 0x26, 0xd9, 0x5b, 0x6f, 0x76, 0x4f, - 0xeb, 0x97, 0x37, 0x67, 0x7b, 0xc4, 0x0a, 0x7b, 0xce, 0x36, 0xd9, 0x8a, 0x2f, 0xd4, 0x30, 0xe1, - 0xd2, 0xa3, 0xa1, 0x01, 0x35, 0x61, 0x3f, 0x43, 0xbf, 0x0d, 0xec, 0xa1, 0x2e, 0xd4, 0x8d, 0xb6, - 0x45, 0x33, 0x75, 0xcf, 0x0d, 0x7d, 0xcf, 0x11, 0xc8, 0x46, 0x1b, 0xee, 0xa8, 0x1b, 0xea, 0x82, - 0xeb, 0x65, 0xda, 0x58, 0x27, 0x11, 0xb8, 0x0b, 0x42, 0xcf, 0x87, 0xbb, 0xde, 0x20, 0x08, 0x33, - 0x3e, 0x1d, 0x1a, 0x8e, 0x6d, 0x1a, 0x21, 0x15, 0xd6, 0x75, 0x78, 0xe6, 0x1b, 0xdd, 0x9e, 0xb1, - 0xae, 0xa7, 0xb5, 0xe0, 0x7b, 0x8f, 0x7d, 0xdb, 0xa7, 0x81, 0x40, 0x66, 0xe0, 0x0a, 0xc2, 0x85, - 0x76, 0xe8, 0xd0, 0xed, 0x8d, 0x4f, 0x47, 0x7b, 0xbb, 0xe4, 0xcc, 0x7e, 0xa4, 0x0e, 0xa9, 0xf9, - 0x21, 0x01, 0x34, 0x87, 0xd4, 0x0f, 0xa9, 0xbf, 0x95, 0xe5, 0x00, 0x64, 0x2b, 0x08, 0xc7, 0x08, - 0x28, 0xb7, 0xbc, 0xc7, 0x49, 0xcb, 0xf3, 0x4d, 0xea, 0x57, 0xb4, 0xfe, 0x23, 0x09, 0x3c, 0x40, - 0x91, 0xbc, 0xed, 0x74, 0x3a, 0xd3, 0x96, 0x67, 0x8e, 0x27, 0x1d, 0xe8, 0x3d, 0xd3, 0x31, 0x7a, - 0xb6, 0x33, 0xae, 0xd4, 0x7c, 0xdb, 0x70, 0xa4, 0xc0, 0x70, 0x83, 0x4c, 0x40, 0x7d, 0xbb, 0x53, - 0x6d, 0x19, 0xed, 0x87, 0xae, 0xef, 0x0d, 0x5c, 0x33, 0xd3, 0xf6, 0x1c, 0xcf, 0xaf, 0xbc, 0x55, - 0x55, 0x75, 0x2a, 0x87, 0x5e, 0x3f, 0xd3, 0x37, 0xfc, 0x70, 0x32, 0xb2, 0xcd, 0xd0, 0xaa, 0x14, - 0x15, 0xa5, 0xff, 0x58, 0xed, 0x19, 0x7e, 0xd7, 0x76, 0x2b, 0x0a, 0x31, 0x06, 0xa1, 0x37, 0x95, - 0x11, 0x6b, 0xc3, 0x76, 0xa9, 0x3f, 0xe9, 0x19, 0x8f, 0x19, 0x0e, 0xa8, 0x2a, 0xca, 0x9f, 0x24, - 0x93, 0x47, 0x68, 0x8e, 0x51, 0xc6, 0x37, 0x4c, 0x7b, 0x10, 0x54, 0x94, 0x6a, 0xdf, 0x30, 0x4d, - 0xdb, 0xed, 0x56, 0x34, 0xac, 0x0c, 0xe9, 0x63, 0x98, 0x01, 0x52, 0x76, 0xdd, 0x4a, 0x1b, 0x66, - 0x4e, 0xfd, 0xa9, 0xa5, 0x72, 0x44, 0x03, 0xfb, 0x89, 0x56, 0x34, 0x39, 0x47, 0x7b, 0xd5, 0x08, - 0x21, 0xd3, 0x34, 0xe3, 0xa1, 0x55, 0x98, 0x9e, 0x52, 0xfd, 0xe1, 0x84, 0x1c, 0xc0, 0x28, 0x63, - 0x51, 0xbb, 0x6b, 0x85, 0x15, 0xb9, 0x30, 0xb5, 0xb4, 0x44, 0xb7, 0xaa, 0xac, 0xce, 0xba, 0xf5, - 0xbb, 0x2d, 0x23, 0xa5, 0x69, 0xaa, 0x14, 0xff, 0xc9, 0x45, 0x55, 0xfc, 0xe5, 0x71, 0xd6, 0x4d, - 0x28, 0x97, 0x18, 0x59, 0x2e, 0xfd, 0x2b, 0x03, 0xab, 0x72, 0x7e, 0x75, 0xe4, 0x2a, 0x7b, 0xc8, - 0xd8, 0x21, 0xed, 0x05, 0x71, 0xd1, 0x3d, 0x48, 0xaf, 0xdd, 0x19, 0x67, 0x22, 0x49, 0x8b, 0x8b, - 0x4d, 0x3b, 0xe8, 0x3b, 0xc6, 0xb8, 0xd2, 0x71, 0xe8, 0xe3, 0xb4, 0x9f, 0xa4, 0xd4, 0x9c, 0xfc, - 0xa5, 0x52, 0x69, 0x69, 0xcc, 0xc2, 0x0f, 0x11, 0x9c, 0xbe, 0xed, 0xd8, 0xd4, 0x31, 0x2f, 0x8d, - 0x96, 0x43, 0x93, 0x3d, 0x92, 0x1f, 0x74, 0xf9, 0x42, 0x87, 0x41, 0xdb, 0x70, 0xe8, 0xef, 0xec, - 0xd0, 0xf4, 0x41, 0xbe, 0x9f, 0x3c, 0x97, 0x4e, 0x62, 0x0a, 0xb4, 0x1c, 0xaf, 0xfd, 0x50, 0x9d, - 0x0b, 0x71, 0x52, 0x86, 0x2b, 0x39, 0xe0, 0x8a, 0x69, 0x04, 0x16, 0x85, 0x65, 0x85, 0xd2, 0xb8, - 0x2c, 0xda, 0xab, 0x2c, 0x58, 0x10, 0xf6, 0x78, 0xdd, 0x54, 0xdb, 0x03, 0x3f, 0x00, 0x74, 0xfb, - 0x9e, 0xcd, 0x80, 0x7e, 0xc8, 0xe6, 0xc4, 0x44, 0x0b, 0xd0, 0xc7, 0x7c, 0xa2, 0x48, 0x5f, 0x87, - 0x66, 0xfa, 0x76, 0xfb, 0x01, 0x96, 0x5e, 0x8c, 0xbf, 0x0b, 0x93, 0x99, 0xca, 0x86, 0x69, 0xf4, - 0x43, 0x7b, 0x48, 0x2f, 0x77, 0x27, 0x49, 0xd6, 0x56, 0xf1, 0x27, 0x63, 0x82, 0xb2, 0x69, 0x87, - 0xb6, 0xe7, 0x56, 0x7c, 0x6f, 0xc4, 0x8b, 0x46, 0xbe, 0xd1, 0x87, 0xa6, 0x78, 0x59, 0x23, 0x35, - 0x53, 0xb9, 0x07, 0xeb, 0xbb, 0x49, 0x1d, 0x68, 0xe6, 0xf9, 0x93, 0x55, 0x55, 0xa1, 0x69, 0x5a, - 0x72, 0x91, 0x46, 0xd4, 0x52, 0xe7, 0x3a, 0x28, 0x97, 0xcb, 0x45, 0xb3, 0xcf, 0x80, 0x46, 0xa9, - 0xe4, 0x67, 0xc4, 0xc8, 0xb4, 0xbc, 0x30, 0xf4, 0x7a, 0xac, 0x24, 0xa6, 0x95, 0x42, 0xca, 0xf0, - 0x14, 0x71, 0x50, 0xc3, 0xfb, 0x25, 0x1a, 0x2c, 0x92, 0xbd, 0xd4, 0x8f, 0xe6, 0x05, 0x38, 0x8d, - 0x80, 0xe3, 0x0b, 0x13, 0x7e, 0xf5, 0x12, 0x98, 0xd3, 0xec, 0xff, 0xdb, 0x3c, 0x39, 0xc7, 0x03, - 0xda, 0xed, 0xc1, 0x44, 0x82, 0x5d, 0x7b, 0x18, 0xe9, 0xea, 0x5c, 0x71, 0x3e, 0x56, 0xc6, 0xa1, - 0x9d, 0xb0, 0x02, 0x7d, 0x4e, 0xff, 0x22, 0xb6, 0xdb, 0x1f, 0x84, 0xb7, 0xe1, 0xb8, 0x4f, 0x75, - 0xdf, 0x70, 0xbb, 0xf4, 0x6e, 0x62, 0xf4, 0xfb, 0xd4, 0x80, 0xfb, 0x36, 0x65, 0x9d, 0x55, 0x33, - 0x3d, 0xef, 0x29, 0xb3, 0x52, 0x38, 0xa2, 0xad, 0x07, 0x3b, 0x5c, 0x29, 0x4f, 0xa2, 0x34, 0x9b, - 0x59, 0x2c, 0xea, 0x30, 0x5d, 0x9c, 0x24, 0xc9, 0x33, 0x75, 0xb6, 0x42, 0xd0, 0x10, 0xfa, 0x09, - 0xc0, 0xbc, 0x00, 0xe2, 0xcb, 0x6b, 0x62, 0x0e, 0x5b, 0xc1, 0x05, 0x6d, 0xf8, 0x30, 0x06, 0xd0, - 0x01, 0x20, 0x53, 0xa1, 0x47, 0x7c, 0xa4, 0x99, 0xf4, 0xb6, 0xd5, 0x6a, 0x91, 0x82, 0xf2, 0xa7, - 0x84, 0x74, 0xc7, 0x1b, 0x71, 0x95, 0x64, 0xd3, 0x95, 0xe9, 0x56, 0x3a, 0x5e, 0x7b, 0x10, 0x4c, - 0xbc, 0x41, 0x88, 0x1d, 0x57, 0x94, 0x35, 0x10, 0x95, 0x78, 0xb2, 0x01, 0x70, 0x15, 0xbb, 0x1b, - 0xb8, 0x2e, 0x6a, 0x9d, 0x0c, 0x20, 0xdc, 0x7e, 0x98, 0x24, 0x59, 0xf6, 0x3c, 0xda, 0x0a, 0xce, - 0xf8, 0x15, 0xe8, 0x2c, 0x0f, 0x16, 0x5a, 0x83, 0x5e, 0x2b, 0x1e, 0x43, 0x45, 0x26, 0x46, 0xda, - 0xa8, 0xb8, 0x22, 0x12, 0x30, 0xe5, 0xe4, 0x88, 0x68, 0xea, 0x97, 0x11, 0x7a, 0x8e, 0x6d, 0x4b, - 0x52, 0xfa, 0x3a, 0x44, 0x51, 0x2e, 0xd8, 0xc3, 0x1a, 0x42, 0xac, 0x30, 0x97, 0xd9, 0x37, 0x45, - 0x62, 0xff, 0xc4, 0x9f, 0x1f, 0x80, 0x51, 0x21, 0x5a, 0x61, 0x4a, 0xb4, 0xbe, 0x92, 0xf2, 0xf2, - 0x2a, 0x02, 0x95, 0x16, 0x10, 0x63, 0x04, 0x9a, 0xca, 0x6c, 0x80, 0x13, 0xe8, 0x1e, 0xd4, 0x26, - 0x6f, 0xc9, 0xb4, 0x33, 0x7a, 0x55, 0x36, 0x18, 0x98, 0x48, 0x81, 0xf7, 0x6c, 0xd3, 0x74, 0x60, - 0x61, 0x75, 0x06, 0x8e, 0x73, 0x09, 0x7a, 0x7d, 0x1f, 0x8d, 0x19, 0x47, 0x17, 0xd5, 0xfc, 0xdd, - 0x33, 0xea, 0x61, 0xbd, 0x4e, 0x88, 0x97, 0xa1, 0xed, 0x32, 0xeb, 0x14, 0x84, 0xe0, 0x52, 0xe1, - 0x72, 0x7c, 0x59, 0x59, 0xc4, 0x24, 0xce, 0xaf, 0xf1, 0xa4, 0x7e, 0xc1, 0x6e, 0xac, 0x5a, 0xad, - 0xdf, 0xa5, 0x3e, 0x3b, 0xce, 0xe3, 0xe5, 0xbe, 0x63, 0xfe, 0x1e, 0xb2, 0xfc, 0x7f, 0x99, 0xf5, - 0x82, 0x36, 0x0d, 0x06, 0xad, 0x9e, 0xfd, 0x6b, 0x82, 0x01, 0x9e, 0x23, 0x38, 0x31, 0x73, 0xaf, - 0x63, 0x09, 0x5b, 0x46, 0x87, 0xd7, 0xce, 0x7b, 0xc9, 0x65, 0x06, 0x1c, 0x5b, 0x03, 0x10, 0x27, - 0xf7, 0x7f, 0xc1, 0x19, 0xc6, 0x93, 0xdf, 0x83, 0xdd, 0xa2, 0x3b, 0xff, 0x6b, 0x64, 0x5f, 0xd2, - 0x71, 0x91, 0x5f, 0x88, 0x96, 0xef, 0xa5, 0xfe, 0xd6, 0xaf, 0x71, 0x5c, 0xcf, 0xa0, 0x54, 0x8c, - 0x49, 0xd7, 0xb7, 0xcd, 0x0c, 0x13, 0x88, 0xac, 0x96, 0x9c, 0x6f, 0x2c, 0x8e, 0x2c, 0xfa, 0xf9, - 0x19, 0x32, 0x26, 0xd8, 0x20, 0x5b, 0xa0, 0xdd, 0x97, 0xdc, 0xb4, 0x60, 0x08, 0x14, 0x86, 0xb9, - 0x4d, 0xd6, 0xe3, 0xf5, 0xd6, 0xee, 0x19, 0xa0, 0x0a, 0xe7, 0xf1, 0x55, 0xdc, 0x1a, 0xf1, 0xac, - 0x32, 0x64, 0x61, 0x72, 0x50, 0x12, 0x52, 0xc4, 0x3a, 0xa8, 0xa8, 0x1d, 0x9f, 0xc0, 0xdf, 0xf4, - 0x2d, 0xe7, 0xf8, 0x9a, 0x96, 0x8c, 0x30, 0x31, 0x73, 0x23, 0x35, 0xa3, 0x2a, 0x09, 0x47, 0x01, - 0x35, 0x11, 0x16, 0x4c, 0x65, 0xde, 0x47, 0xdb, 0x31, 0x82, 0x60, 0x82, 0xcd, 0xe6, 0xf6, 0x9d, - 0x01, 0x15, 0xfa, 0x2b, 0x1d, 0xa1, 0x7f, 0x21, 0x77, 0x8d, 0xfe, 0x24, 0x26, 0x1d, 0x3c, 0xbf, - 0xe5, 0xab, 0x22, 0x8a, 0x5a, 0x2b, 0x95, 0x16, 0xed, 0x40, 0x18, 0x3d, 0x89, 0x19, 0x2a, 0x08, - 0x33, 0x19, 0x88, 0x94, 0x00, 0x77, 0xc0, 0x13, 0x44, 0x66, 0x44, 0xa8, 0x0c, 0x7c, 0x27, 0xf5, - 0x1e, 0x02, 0x6e, 0xa3, 0xc2, 0x9e, 0xb3, 0x40, 0xba, 0xf4, 0x63, 0xcf, 0xa9, 0x0e, 0xc2, 0x4e, - 0x59, 0x82, 0x10, 0x78, 0xd8, 0x25, 0x2c, 0x0c, 0xd6, 0x85, 0x48, 0xa5, 0x2f, 0x29, 0x4f, 0x81, - 0x0c, 0x6d, 0x3a, 0xda, 0xf1, 0x1e, 0x21, 0xb8, 0x26, 0x0a, 0xd1, 0xf2, 0xf0, 0xbf, 0x40, 0xb6, - 0xfa, 0x46, 0x68, 0x11, 0xf0, 0xa3, 0x1d, 0x5d, 0x00, 0xa1, 0x42, 0xc3, 0x52, 0x47, 0x96, 0x09, - 0xc4, 0xd4, 0x85, 0x63, 0x55, 0x93, 0x8a, 0xd7, 0x9b, 0x47, 0x6a, 0x51, 0x2a, 0x1c, 0xc1, 0xbd, - 0x7a, 0x9d, 0xaf, 0x95, 0xa5, 0x32, 0xb4, 0x06, 0x8b, 0x46, 0xf2, 0x92, 0xaa, 0xd5, 0xe1, 0x27, - 0x27, 0x17, 0x4a, 0x24, 0x2f, 0xe7, 0x8b, 0x92, 0x5a, 0x90, 0x15, 0x70, 0x43, 0x64, 0x0d, 0x4a, - 0x8b, 0xb2, 0x56, 0x3c, 0x2a, 0xca, 0x25, 0x49, 0xcd, 0xcb, 0xe5, 0x3a, 0x3c, 0x15, 0x10, 0x72, - 0xb3, 0x44, 0x00, 0x2c, 0x87, 0x3f, 0x5a, 0xad, 0x28, 0x15, 0x59, 0x57, 0x2a, 0xc1, 0x71, 0x8e, - 0xd5, 0xb2, 0x5c, 0x2a, 0x4a, 0x25, 0xb9, 0x94, 0x3f, 0x52, 0x4b, 0x72, 0x4e, 0xda, 0x94, 0xb5, - 0xba, 0x8a, 0x8f, 0x92, 0xaa, 0xc8, 0x4a, 0x9e, 0xa8, 0x65, 0x49, 0x55, 0xd9, 0xef, 0x52, 0x53, - 0xb5, 0x7c, 0xad, 0x16, 0x8e, 0xa0, 0x7c, 0x13, 0x91, 0xd4, 0x72, 0xd7, 0x9a, 0x92, 0x40, 0x53, - 0x53, 0x10, 0x4f, 0xfc, 0x55, 0xe4, 0x7c, 0x8e, 0xa8, 0x9b, 0x72, 0x21, 0x2f, 0x95, 0x11, 0x93, - 0xf9, 0x80, 0x5f, 0x04, 0x92, 0xdd, 0xde, 0x42, 0x92, 0x6e, 0xbf, 0x17, 0xab, 0x09, 0xef, 0x31, - 0xa2, 0x1f, 0xde, 0x03, 0x23, 0x61, 0xfd, 0xc2, 0x1a, 0x23, 0x7f, 0x4d, 0xd6, 0x71, 0x0c, 0x84, - 0x19, 0xea, 0x0f, 0x51, 0x1b, 0x32, 0x4b, 0x19, 0x44, 0x42, 0x50, 0xf8, 0xd9, 0x25, 0xf3, 0x1a, - 0x53, 0x99, 0xf9, 0xb1, 0x8d, 0x28, 0xfd, 0x84, 0x3e, 0x5a, 0xb4, 0x12, 0x53, 0x03, 0xbd, 0xcd, - 0x87, 0xc9, 0x8f, 0x22, 0xf4, 0x1f, 0x7a, 0xb1, 0x2c, 0x02, 0x34, 0x69, 0xdb, 0xf3, 0x0d, 0x16, - 0x61, 0xb1, 0x75, 0x6e, 0x54, 0x86, 0x76, 0x00, 0x7a, 0xc8, 0xfc, 0xed, 0xfd, 0x5a, 0x1e, 0xac, - 0xaa, 0x49, 0xd2, 0xca, 0xfd, 0x42, 0x27, 0x46, 0x1b, 0xc3, 0x9e, 0xdf, 0x8c, 0xdb, 0x06, 0xc8, - 0x13, 0x4b, 0x4b, 0x91, 0x2d, 0xa4, 0x28, 0xf1, 0x29, 0x2c, 0xb1, 0xc0, 0xf2, 0xfc, 0xb0, 0x3d, - 0x08, 0x09, 0x2a, 0x3d, 0x81, 0x6c, 0x58, 0x3e, 0xed, 0xe8, 0x42, 0x62, 0x55, 0xf7, 0xdd, 0x2e, - 0x8c, 0x15, 0xd0, 0x62, 0x5e, 0xb2, 0xaf, 0x77, 0x4e, 0x2f, 0x46, 0xca, 0xc7, 0x83, 0xae, 0x57, - 0x83, 0xff, 0x4e, 0x9a, 0x57, 0xd6, 0xde, 0x55, 0x17, 0xee, 0x76, 0xf0, 0xb1, 0x76, 0x5e, 0xaf, - 0xdd, 0xe0, 0xb5, 0x53, 0xce, 0x6e, 0x5a, 0xac, 0xe4, 0xf3, 0x49, 0xf3, 0x42, 0x39, 0xac, 0xf9, - 0x41, 0xbe, 0x5d, 0x3c, 0x87, 0xe7, 0x87, 0x93, 0xbf, 0x2f, 0xf6, 0xf6, 0xaf, 0x4e, 0xf7, 0xd2, - 0xce, 0x55, 0x10, 0x9e, 0x6a, 0x6a, 0xed, 0xca, 0x6d, 0x9c, 0x04, 0xfb, 0xca, 0x75, 0x5a, 0xd9, - 0xfb, 0x7c, 0x6d, 0x0f, 0x6b, 0x9f, 0x3b, 0x35, 0x5a, 0xfa, 0xe6, 0x1c, 0x95, 0xf6, 0xbe, 0xec, - 0xb5, 0xcf, 0x0b, 0xed, 0xf3, 0xb2, 0x5b, 0x3f, 0xac, 0xb7, 0x76, 0xff, 0xde, 0x2f, 0x5d, 0xfa, - 0x43, 0xcb, 0x08, 0x8a, 0x37, 0xad, 0xf1, 0xae, 0xb9, 0x33, 0xd0, 0xac, 0xe6, 0x43, 0xe9, 0xc1, - 0xb6, 0x82, 0xf6, 0x47, 0xb5, 0x73, 0xb5, 0xa9, 0x36, 0x2e, 0x3e, 0x7e, 0x34, 0xf6, 0x3b, 0xea, - 0xa3, 0xe5, 0x9f, 0x95, 0xe9, 0xfd, 0xb1, 0x5b, 0x6f, 0x94, 0x0b, 0xca, 0x59, 0x36, 0x3d, 0xcc, - 0xb6, 0xeb, 0xda, 0xb7, 0xf6, 0xb7, 0x51, 0xbe, 0x1b, 0x1c, 0xec, 0xe6, 0x1a, 0x0f, 0xd9, 0x03, - 0x2d, 0x97, 0x6e, 0x0d, 0x9b, 0xe6, 0xa8, 0xe4, 0x3e, 0xa8, 0x1f, 0xcb, 0xe5, 0xd2, 0x0e, 0xad, - 0x9f, 0xe7, 0x6b, 0x07, 0xc7, 0x35, 0x7b, 0xef, 0xbe, 0x7d, 0x60, 0xec, 0x94, 0xba, 0xae, 0xb9, - 0xd7, 0xb1, 0x2e, 0xbe, 0x99, 0x17, 0xe7, 0xcd, 0xfa, 0xa6, 0xdb, 0x3e, 0xb7, 0x1f, 0x6a, 0xd7, - 0x76, 0x50, 0xfb, 0x74, 0xb0, 0xb3, 0xdf, 0xed, 0x5e, 0x14, 0xce, 0x87, 0xe7, 0xa5, 0xab, 0xf6, - 0xe5, 0x89, 0xb9, 0xd9, 0x3b, 0x1a, 0xee, 0x9a, 0x75, 0xad, 0xaf, 0xf9, 0xd6, 0xe1, 0x89, 0x76, - 0x90, 0xbf, 0xca, 0x0e, 0x2f, 0x5a, 0x2e, 0x1d, 0x8f, 0xdd, 0x27, 0xab, 0x1f, 0x94, 0x14, 0xaf, - 0x76, 0xe6, 0x58, 0x27, 0x67, 0x47, 0xf7, 0x5f, 0x5c, 0x43, 0x1d, 0xe6, 0xb3, 0x8f, 0xd7, 0xbd, - 0xf0, 0xbc, 0x71, 0x55, 0x0e, 0x9f, 0xce, 0x3f, 0x9f, 0xe6, 0xea, 0xf5, 0x87, 0xbc, 0xeb, 0x9f, - 0xed, 0x96, 0x8f, 0x8f, 0x4e, 0xd2, 0xc5, 0x6f, 0x66, 0x99, 0x76, 0xca, 0xd4, 0x1f, 0xed, 0x7c, - 0x1c, 0x36, 0x4a, 0x05, 0xe5, 0xf3, 0x47, 0xf5, 0xf3, 0x38, 0xef, 0xd8, 0x9b, 0xd9, 0xce, 0xf9, - 0xbe, 0x3f, 0xda, 0x3c, 0xab, 0x1d, 0x34, 0x77, 0xbb, 0x65, 0xe3, 0x69, 0x30, 0xfa, 0x7b, 0xf7, - 0xa4, 0x78, 0xdf, 0x1a, 0xd0, 0x7e, 0xc9, 0x48, 0x1f, 0xec, 0xef, 0xe7, 0xe8, 0xd3, 0x89, 0x42, - 0xdd, 0x42, 0x67, 0xf7, 0x5b, 0xf9, 0xbc, 0xe3, 0xa6, 0xaf, 0xbe, 0x5d, 0x77, 0xef, 0xad, 0x4f, - 0x85, 0x16, 0x3d, 0xeb, 0x8f, 0xea, 0x1f, 0x47, 0x57, 0x8d, 0xfb, 0xa2, 0xa1, 0xd5, 0xea, 0x37, - 0xa5, 0x27, 0xbf, 0x6e, 0xd6, 0xeb, 0xb9, 0xfc, 0xd5, 0xbd, 0xff, 0x34, 0x08, 0xef, 0x8f, 0xbe, - 0xd8, 0xe7, 0xf5, 0xec, 0x83, 0xa5, 0x34, 0x9c, 0xf1, 0xd9, 0x78, 0xb0, 0x19, 0x7e, 0x7c, 0x3a, - 0xce, 0xdb, 0x07, 0x67, 0x9d, 0xd2, 0xe0, 0xa0, 0x10, 0xec, 0xee, 0x8d, 0x3e, 0xf5, 0x6f, 0x3e, - 0x0d, 0x7d, 0xab, 0x5c, 0xb8, 0xf8, 0x72, 0x03, 0xdc, 0x3d, 0xec, 0x97, 0xd2, 0x9f, 0x8d, 0xf1, - 0x49, 0xf8, 0x6d, 0x1c, 0x7e, 0xa6, 0x47, 0xdf, 0x3e, 0xb5, 0xee, 0xaf, 0xae, 0x4e, 0xda, 0x47, - 0xf5, 0x74, 0x67, 0x70, 0xa0, 0xf5, 0xfa, 0x47, 0x83, 0x52, 0x78, 0xe6, 0x14, 0x82, 0x2f, 0xbb, - 0x35, 0xb7, 0x7f, 0xf4, 0xa0, 0xf4, 0x9e, 0xf6, 0x77, 0x6d, 0x3f, 0xbd, 0xb3, 0xff, 0xb7, 0xf3, - 0x50, 0xdf, 0xab, 0x1b, 0x1f, 0xf7, 0x07, 0xcd, 0x9d, 0x9b, 0xa6, 0x53, 0xcb, 0xf7, 0x8f, 0x3e, - 0x85, 0xf6, 0xc5, 0xfd, 0xde, 0xb8, 0x7b, 0x38, 0xde, 0xf3, 0xf7, 0x9f, 0xc6, 0x87, 0x1f, 0xef, - 0x7d, 0x7a, 0x73, 0xe9, 0xb4, 0xbe, 0x7c, 0xec, 0x1a, 0x0d, 0xff, 0xc2, 0x79, 0xf2, 0x1a, 0x5e, - 0x38, 0xa2, 0x9f, 0x69, 0xcd, 0xda, 0xb3, 0x0e, 0x1f, 0xcf, 0x76, 0x2e, 0x77, 0x77, 0xac, 0xf3, - 0x9b, 0xee, 0xde, 0x8d, 0x75, 0xd2, 0x1a, 0xb7, 0x0e, 0x4f, 0xac, 0xc7, 0x1b, 0x35, 0x68, 0x35, - 0x47, 0xa3, 0x87, 0x56, 0xe3, 0xf4, 0x8b, 0xff, 0x14, 0xe4, 0xae, 0x2f, 0x7a, 0xf7, 0x3d, 0xf7, - 0xf4, 0xa1, 0xd8, 0x3a, 0x7d, 0xf0, 0xbf, 0x3d, 0x1e, 0x37, 0x2e, 0x37, 0xc7, 0xf5, 0x6f, 0xe3, - 0xc7, 0x93, 0x71, 0xab, 0xb6, 0x7f, 0xdc, 0x55, 0x7b, 0x9f, 0x2e, 0x76, 0x0e, 0x6e, 0x9c, 0xae, - 0x46, 0x5b, 0xde, 0x69, 0x73, 0xff, 0xc0, 0xbc, 0x4c, 0x1f, 0x8e, 0x8e, 0x73, 0x7b, 0xb6, 0x53, - 0x7c, 0xda, 0x19, 0x7d, 0xfe, 0xb2, 0xaf, 0x3e, 0x3e, 0x34, 0x3f, 0x3d, 0x9c, 0x1a, 0xc5, 0x6f, - 0x61, 0xc3, 0xa1, 0x6d, 0x3a, 0x38, 0x1f, 0xd6, 0xd3, 0xdd, 0x7c, 0xff, 0xcb, 0x67, 0xdb, 0x38, - 0x0d, 0x37, 0xef, 0xc7, 0xbb, 0x2d, 0x2d, 0x7f, 0xae, 0x7d, 0xfb, 0x58, 0x2f, 0x7c, 0xbe, 0x6c, - 0x0e, 0x7d, 0xe7, 0x63, 0xee, 0x4b, 0xe3, 0xf8, 0x93, 0x92, 0x77, 0x8f, 0xcc, 0xe3, 0xb3, 0x8f, - 0xe1, 0xf9, 0xe9, 0xf1, 0x93, 0x77, 0x70, 0xf9, 0x74, 0xf6, 0x54, 0xdc, 0xbc, 0x39, 0x39, 0xd3, - 0x86, 0x76, 0x69, 0x57, 0x55, 0x3b, 0xe1, 0xf0, 0xfc, 0xd3, 0x4d, 0xfd, 0x69, 0x1c, 0x96, 0xee, - 0x3b, 0xa3, 0x53, 0x55, 0xb9, 0x3c, 0xef, 0x1e, 0x15, 0xac, 0x4b, 0xb6, 0x26, 0x6a, 0x3b, 0x7f, - 0x5f, 0x5c, 0x15, 0xf6, 0xfc, 0x87, 0xbf, 0xbb, 0xdd, 0xae, 0xae, 0x0b, 0xdb, 0x1b, 0x60, 0x3a, - 0xdb, 0xbe, 0xdd, 0x0f, 0x09, 0x73, 0x61, 0x05, 0x5c, 0xcb, 0xd9, 0x7b, 0x63, 0x68, 0xf0, 0x52, - 0x00, 0xe8, 0x0c, 0x5c, 0x96, 0x2c, 0x22, 0xdd, 0x43, 0x33, 0x45, 0xc5, 0x89, 0x4f, 0xc3, 0x81, - 0xef, 0x12, 0x53, 0xee, 0xd2, 0x70, 0xcf, 0xa1, 0x98, 0x74, 0xd8, 0x19, 0xb3, 0xaa, 0xe9, 0x0c, - 0xb4, 0xbd, 0xb7, 0x00, 0xd9, 0x06, 0xdf, 0x2a, 0xa4, 0x11, 0x30, 0x02, 0x0e, 0x0d, 0x1f, 0x0c, - 0xac, 0x09, 0x71, 0x38, 0x96, 0xa0, 0xaa, 0x60, 0xa3, 0x81, 0xae, 0xc8, 0x46, 0x39, 0x7a, 0x4c, - 0x58, 0xcf, 0x2f, 0x26, 0x98, 0x1d, 0xe6, 0x88, 0x00, 0x82, 0x51, 0x42, 0x5a, 0x88, 0x8a, 0x37, - 0x22, 0xab, 0xbf, 0xe0, 0xe0, 0xac, 0x77, 0x1b, 0xb1, 0x89, 0xa5, 0xae, 0x6f, 0xb1, 0xea, 0x2b, - 0x22, 0x34, 0x7a, 0x15, 0x1b, 0x0b, 0x6e, 0xc5, 0xb2, 0x59, 0x8c, 0xad, 0x12, 0x4b, 0x48, 0x54, - 0x8a, 0x2b, 0x7e, 0x46, 0x4e, 0x83, 0xff, 0x85, 0x6d, 0xee, 0x67, 0x6c, 0x70, 0x47, 0xe3, 0xad, - 0xa2, 0xe4, 0x20, 0x10, 0xe5, 0x3e, 0x46, 0x91, 0x68, 0x9a, 0x55, 0x1e, 0xe6, 0x1b, 0xc5, 0xa7, - 0x63, 0x15, 0xac, 0x7c, 0xde, 0xca, 0x0f, 0xcb, 0x56, 0x26, 0x0f, 0x4f, 0x65, 0xa2, 0x2a, 0xb3, - 0x27, 0x4d, 0x23, 0x45, 0x84, 0xb3, 0x32, 0xe5, 0x27, 0x21, 0xb6, 0xd6, 0x1b, 0xe4, 0xb9, 0xcd, - 0x01, 0xa4, 0xa4, 0x8a, 0xf4, 0x04, 0x1a, 0xe1, 0xb4, 0xb5, 0xed, 0x8d, 0xa8, 0x8e, 0x30, 0x4d, - 0x4b, 0x42, 0x8f, 0xb7, 0xfd, 0xbb, 0x79, 0x7a, 0x42, 0x52, 0x7d, 0xd6, 0x03, 0x90, 0x95, 0x00, - 0xf7, 0x58, 0x79, 0xcf, 0x08, 0x7d, 0xfb, 0x51, 0x84, 0x6e, 0x34, 0x68, 0xdf, 0xc7, 0xed, 0x08, - 0xcc, 0x80, 0x90, 0x0d, 0x1b, 0xb0, 0x9e, 0x27, 0x76, 0x85, 0x45, 0xaf, 0x8b, 0x79, 0xcb, 0x0c, - 0x30, 0x03, 0xa4, 0xf5, 0x06, 0x61, 0xa5, 0x03, 0x3d, 0x9b, 0x11, 0x79, 0x57, 0xd9, 0x11, 0xfa, - 0x28, 0x81, 0xa1, 0x19, 0xf7, 0xb2, 0xd6, 0x0f, 0x46, 0x40, 0xc7, 0x68, 0x01, 0x82, 0xe0, 0x3a, - 0xea, 0x82, 0x43, 0xcd, 0x26, 0x48, 0x56, 0x3f, 0xce, 0xd3, 0x09, 0xdb, 0x47, 0x14, 0x3a, 0xc0, - 0xa2, 0x0a, 0x88, 0x12, 0x83, 0xc4, 0x99, 0x87, 0x28, 0x47, 0xd0, 0x75, 0x24, 0x38, 0xf3, 0x94, - 0x28, 0xe3, 0x2c, 0x6b, 0x4c, 0x70, 0x32, 0x2b, 0xfd, 0x91, 0x8d, 0xa8, 0x49, 0x32, 0xeb, 0x89, - 0x8d, 0xbc, 0x3e, 0x93, 0xee, 0xa1, 0xe1, 0x0c, 0x28, 0xd6, 0x22, 0x85, 0x80, 0x00, 0x0c, 0x82, - 0x42, 0x4f, 0xf1, 0x9d, 0xb0, 0xad, 0xed, 0x92, 0x63, 0x56, 0x0d, 0x08, 0xf1, 0x56, 0x2b, 0xcd, - 0x7d, 0xcd, 0x11, 0xb6, 0x9b, 0xd4, 0xef, 0x03, 0x31, 0xc0, 0xd1, 0x91, 0xc0, 0x0b, 0xf5, 0x83, - 0x90, 0x80, 0x1f, 0xcf, 0xb3, 0x5b, 0xc8, 0x21, 0xcc, 0xda, 0x91, 0x77, 0x4e, 0x58, 0xcd, 0xcc, - 0xba, 0xd9, 0x58, 0xee, 0xc7, 0xd1, 0xfc, 0xe7, 0xfa, 0x61, 0xcd, 0xe3, 0x6c, 0x19, 0xc9, 0xbc, - 0xeb, 0x86, 0xd5, 0x39, 0x3a, 0xb8, 0xea, 0x18, 0xbe, 0x33, 0x5a, 0x65, 0x81, 0x1b, 0x8c, 0x25, - 0x3f, 0xc1, 0x91, 0x0d, 0xc6, 0x12, 0xf8, 0x01, 0x6a, 0xcc, 0x49, 0x75, 0x3a, 0x08, 0xc1, 0x0f, - 0x24, 0xbc, 0xb8, 0xf2, 0x4a, 0x9e, 0x6c, 0x24, 0x99, 0xb2, 0xd4, 0x23, 0x79, 0x15, 0x47, 0x46, - 0xc0, 0x4a, 0xe0, 0xde, 0x3a, 0x86, 0xcc, 0x64, 0xfd, 0x59, 0x7e, 0x80, 0xfb, 0x0f, 0x0c, 0xa9, - 0x5f, 0x5d, 0x1c, 0x25, 0x69, 0xb4, 0x08, 0x63, 0x19, 0xc2, 0x76, 0xc3, 0xeb, 0x51, 0x52, 0x0b, - 0x02, 0x1b, 0x3c, 0x53, 0x37, 0x24, 0x37, 0xb5, 0xe3, 0x44, 0x83, 0x17, 0x68, 0xba, 0xf1, 0x13, - 0x62, 0xce, 0xfc, 0xac, 0xfd, 0x25, 0xc2, 0x6e, 0xb0, 0xe8, 0x84, 0xb4, 0x3d, 0x93, 0xfe, 0x24, - 0x75, 0x63, 0xe2, 0xb2, 0xf5, 0xbb, 0xae, 0xef, 0xd7, 0x91, 0xd8, 0xa2, 0x8f, 0xcf, 0x50, 0xb8, - 0xb1, 0xf7, 0x99, 0xa4, 0xde, 0x7d, 0x1b, 0x78, 0x61, 0xb5, 0x93, 0xc7, 0x7f, 0xfc, 0x5e, 0x7c, - 0x96, 0xe0, 0xe0, 0x31, 0xc2, 0x84, 0x76, 0xf7, 0xea, 0x24, 0xa5, 0xe5, 0xf3, 0x52, 0xf4, 0x27, - 0xfe, 0x2b, 0xc4, 0x84, 0x98, 0xc2, 0xa7, 0xc0, 0x33, 0xb7, 0x3b, 0x9f, 0x5a, 0x6d, 0x56, 0xf6, - 0x4b, 0x6a, 0x63, 0x4d, 0x97, 0xaf, 0x54, 0x1c, 0xd6, 0xb8, 0x05, 0xa1, 0xfb, 0x7a, 0xc5, 0xb1, - 0xd1, 0x60, 0x95, 0x33, 0x4a, 0x2a, 0xf8, 0x8f, 0xdf, 0x43, 0x04, 0x27, 0x11, 0xb5, 0x24, 0x91, - 0x57, 0x11, 0x79, 0x23, 0x56, 0x33, 0x98, 0xec, 0x14, 0xb6, 0x2f, 0xf0, 0x42, 0x52, 0xbf, 0xd4, - 0x05, 0xce, 0x11, 0x29, 0xda, 0x64, 0xd7, 0x97, 0x98, 0xfc, 0x3c, 0xd3, 0x36, 0x7e, 0x52, 0xd1, - 0xb7, 0x98, 0xde, 0x72, 0x81, 0xc8, 0x3c, 0x59, 0x2b, 0x6c, 0xef, 0xcc, 0x4a, 0xd6, 0xb2, 0xec, - 0x87, 0x12, 0x51, 0x7d, 0x85, 0xbd, 0x67, 0xc9, 0x3c, 0xb2, 0xc1, 0x5d, 0x21, 0x4e, 0x39, 0xc6, - 0xeb, 0x15, 0x4c, 0x48, 0xcf, 0x76, 0x75, 0x41, 0x85, 0xab, 0x01, 0x86, 0x5e, 0x2b, 0x14, 0x84, - 0x98, 0xb9, 0xaa, 0x56, 0x66, 0x82, 0xd2, 0x37, 0x5c, 0xbe, 0xd6, 0xe6, 0x6d, 0xaf, 0x11, 0x42, - 0xd8, 0x06, 0x08, 0x20, 0x12, 0xd4, 0xff, 0x2e, 0x25, 0x71, 0x64, 0xf7, 0xec, 0x30, 0x26, 0xd1, - 0xc6, 0xb1, 0xf1, 0x48, 0x5c, 0x8f, 0x78, 0x1d, 0xc2, 0x2a, 0x83, 0x2c, 0x6a, 0xbd, 0xca, 0x7f, - 0x93, 0x5a, 0x2b, 0x48, 0x2d, 0x52, 0xab, 0xa0, 0x6a, 0x33, 0x6a, 0x69, 0x85, 0xe2, 0x22, 0xb5, - 0xe6, 0x6d, 0x23, 0x6a, 0x01, 0xc4, 0x33, 0xd4, 0x8a, 0x57, 0xa8, 0x65, 0x64, 0x30, 0xb5, 0x26, - 0xfc, 0x3c, 0xf5, 0x2c, 0xe3, 0x10, 0x56, 0x75, 0xa3, 0x46, 0x76, 0xe9, 0xd0, 0x6e, 0x53, 0x72, - 0xb8, 0xbb, 0x86, 0x4e, 0x1b, 0xeb, 0x35, 0x01, 0x9f, 0x7c, 0x54, 0xb5, 0xb0, 0x47, 0x20, 0x24, - 0x5c, 0x69, 0x4e, 0x10, 0x36, 0xce, 0x6c, 0x39, 0x31, 0x5f, 0xeb, 0x2b, 0xf8, 0x5a, 0x5f, 0xdb, - 0xfc, 0xc4, 0x89, 0x43, 0xfd, 0xaf, 0x8a, 0xa2, 0x0a, 0xff, 0xca, 0x0c, 0xaf, 0x16, 0xa7, 0x78, - 0xe5, 0xda, 0xdf, 0x06, 0x8b, 0x33, 0xdd, 0x78, 0x41, 0xe7, 0xbd, 0x76, 0xa6, 0x1b, 0x7c, 0xaa, - 0x38, 0x20, 0x79, 0x61, 0xaa, 0xc6, 0x6b, 0xe6, 0xfa, 0xb3, 0xea, 0xc2, 0x32, 0x4e, 0x8c, 0x1e, - 0x4d, 0x4e, 0x16, 0x9f, 0xff, 0xb5, 0x79, 0xb2, 0xc1, 0xe2, 0x89, 0xce, 0x3d, 0xf0, 0x8f, 0x76, - 0xd8, 0xb6, 0xa8, 0x2b, 0xfc, 0x8e, 0xc5, 0x0d, 0x1e, 0xc9, 0x15, 0x3a, 0x25, 0xb1, 0x78, 0x9e, - 0x65, 0x2d, 0x0f, 0x5c, 0x3b, 0x37, 0x39, 0xad, 0x0d, 0xf2, 0x3b, 0xa7, 0x15, 0x0f, 0xc9, 0xe7, - 0xf5, 0x1b, 0x3c, 0xc3, 0x10, 0xc2, 0x23, 0x0a, 0x4e, 0x06, 0xdb, 0x9c, 0x16, 0xb6, 0x2f, 0xd9, - 0x23, 0x89, 0x36, 0xab, 0x61, 0x71, 0xbc, 0xde, 0x39, 0x5c, 0x9c, 0x07, 0xdf, 0x6c, 0x8a, 0x67, - 0xe0, 0x46, 0x7a, 0xc6, 0x66, 0xb6, 0xb4, 0x9b, 0x90, 0x40, 0x25, 0x52, 0x3e, 0x4a, 0xa4, 0x7c, - 0x8a, 0xb9, 0x65, 0x4f, 0x73, 0x11, 0xc3, 0xe5, 0xc1, 0x93, 0x56, 0x7c, 0x6e, 0xd9, 0x58, 0xe0, - 0x89, 0x8d, 0xe7, 0x2d, 0x71, 0xe3, 0x7d, 0xd6, 0x3a, 0xb1, 0x19, 0x0f, 0xb1, 0x5f, 0x14, 0x83, - 0x25, 0x49, 0x99, 0x65, 0x31, 0xd2, 0x3c, 0xa8, 0x8a, 0xdb, 0xcd, 0xce, 0xb7, 0xd4, 0xb1, 0x20, - 0x9a, 0xd0, 0xac, 0x50, 0x58, 0x0a, 0x46, 0x7f, 0x21, 0xda, 0x7a, 0x9d, 0x10, 0xe2, 0xfc, 0x66, - 0x43, 0xb3, 0x49, 0xbc, 0x26, 0x16, 0x5e, 0x9f, 0x62, 0xc7, 0x2d, 0x04, 0xbb, 0xfd, 0x00, 0x9d, - 0x8d, 0x70, 0x69, 0x34, 0xb1, 0xcb, 0x94, 0x88, 0xbe, 0x12, 0xdb, 0xc4, 0x01, 0x25, 0xc1, 0x77, - 0x71, 0xe2, 0x20, 0x79, 0x5d, 0x32, 0x7e, 0x83, 0x65, 0xe3, 0x4b, 0xa4, 0xd4, 0x28, 0x19, 0x05, - 0x52, 0xc0, 0xd4, 0x36, 0x51, 0x32, 0x78, 0x37, 0x7b, 0xc2, 0x3b, 0x4b, 0x55, 0x8c, 0x44, 0x41, - 0x26, 0x51, 0x9d, 0x81, 0xa7, 0xe3, 0x12, 0x51, 0x0b, 0x46, 0x8e, 0xe4, 0x58, 0x91, 0x9a, 0xc9, - 0x65, 0xf0, 0x3e, 0x7a, 0x22, 0x4b, 0x4f, 0x24, 0xf1, 0x84, 0x35, 0x18, 0x74, 0x6f, 0xf0, 0xa8, - 0x9b, 0xbc, 0x73, 0x5b, 0x41, 0xbf, 0xca, 0x66, 0x12, 0x45, 0xd3, 0x8b, 0x3c, 0x7e, 0xc5, 0x1a, - 0x99, 0x49, 0x50, 0x94, 0x55, 0x9f, 0xc5, 0xd1, 0xc9, 0x0d, 0xa2, 0x25, 0x7d, 0x80, 0xa0, 0x9f, - 0x21, 0x94, 0x21, 0x15, 0x32, 0x5b, 0x35, 0x1c, 0x95, 0xd8, 0x14, 0xc7, 0x62, 0xb4, 0x98, 0x89, - 0x5f, 0xbb, 0x4a, 0x58, 0x5f, 0x33, 0xc3, 0x1c, 0x3b, 0x2f, 0x45, 0xcc, 0x08, 0xf1, 0x3e, 0x93, - 0xbf, 0x2b, 0x68, 0xdc, 0x80, 0x9a, 0xfd, 0x5d, 0x68, 0xdc, 0xac, 0x45, 0x23, 0x26, 0xe9, 0xc6, - 0xfa, 0x75, 0x93, 0xed, 0x47, 0x59, 0x89, 0x04, 0x62, 0x89, 0xe3, 0x50, 0x49, 0x21, 0x9e, 0x9d, - 0xf1, 0xc2, 0xb9, 0xed, 0xc2, 0x43, 0xc4, 0x33, 0x8b, 0xfa, 0xc0, 0xb8, 0x96, 0xbf, 0x0d, 0x01, - 0x15, 0x5e, 0x48, 0x1d, 0xe5, 0x14, 0xe3, 0xe5, 0x48, 0x3b, 0x18, 0x28, 0x8b, 0x09, 0xde, 0xce, - 0x14, 0x55, 0x34, 0x76, 0xac, 0x93, 0xf8, 0xb4, 0x10, 0x96, 0x4f, 0x2a, 0x89, 0xc7, 0x73, 0x6c, - 0x85, 0x3e, 0x16, 0xd2, 0x57, 0xc9, 0x05, 0xbd, 0x7c, 0x88, 0x8c, 0x69, 0xf1, 0x5e, 0x97, 0xf5, - 0xdd, 0xf7, 0x29, 0x2e, 0x32, 0x61, 0x25, 0x8b, 0x95, 0x38, 0xd4, 0x11, 0x1d, 0xcc, 0x84, 0xb1, - 0xfd, 0x76, 0x94, 0x5d, 0x67, 0x69, 0x3d, 0x3c, 0x05, 0x1b, 0x67, 0xd7, 0xe7, 0x04, 0x9e, 0x8b, - 0xa2, 0x6f, 0x8c, 0x32, 0x4b, 0x3b, 0x8e, 0xcf, 0xe2, 0x1f, 0xe3, 0xc3, 0xe0, 0x11, 0x9b, 0x1f, - 0x0c, 0x45, 0x0c, 0x27, 0xd4, 0x85, 0x0b, 0x63, 0x74, 0xc8, 0xe8, 0xce, 0x9b, 0xcc, 0xc7, 0x07, - 0x4a, 0x30, 0x8a, 0xce, 0xf0, 0x78, 0x2d, 0x0e, 0x31, 0x83, 0x39, 0xbc, 0xed, 0x76, 0xbc, 0xf5, - 0x64, 0x99, 0xab, 0xe0, 0x78, 0xa3, 0x97, 0x35, 0x43, 0xbf, 0x98, 0x25, 0x0c, 0xa0, 0xc0, 0xf4, - 0x5c, 0x67, 0x0c, 0x14, 0x88, 0xee, 0x04, 0x5c, 0xea, 0x31, 0xf0, 0x22, 0xa5, 0x98, 0x4b, 0xbf, - 0xb4, 0xbb, 0xfa, 0x2c, 0x86, 0x1c, 0x30, 0xf6, 0x6c, 0xfb, 0xe3, 0x68, 0x48, 0x5e, 0x3c, 0xb3, - 0x16, 0x89, 0x8d, 0x56, 0x44, 0x95, 0x3f, 0x26, 0x86, 0xeb, 0x1a, 0x7d, 0x75, 0x06, 0x0c, 0x0f, - 0x0c, 0x3b, 0x8e, 0x51, 0x34, 0x00, 0xb7, 0x7b, 0xae, 0xf9, 0x73, 0xfd, 0xcf, 0x67, 0x85, 0x5e, - 0x84, 0x95, 0xdb, 0x9e, 0x8d, 0x08, 0x6a, 0x2b, 0x80, 0x68, 0x4e, 0xd8, 0xbe, 0xe6, 0x37, 0x44, - 0x95, 0x15, 0xb9, 0xcc, 0x1b, 0xf0, 0xa5, 0x9e, 0x89, 0x15, 0x83, 0x11, 0xef, 0xe2, 0xe0, 0x81, - 0xe6, 0xa0, 0x92, 0xcd, 0x76, 0xed, 0xd0, 0x1a, 0xb4, 0xe4, 0xb6, 0xd7, 0xcb, 0x8e, 0xa8, 0xff, - 0x10, 0x80, 0xdb, 0xd7, 0xcb, 0x62, 0xfa, 0x25, 0xc3, 0x9c, 0x24, 0xf0, 0x91, 0x66, 0x49, 0xca, - 0x6c, 0xcb, 0xf1, 0x5a, 0x59, 0x0c, 0x96, 0xb3, 0x17, 0x7b, 0xb5, 0xdd, 0xe3, 0x3d, 0xb9, 0x87, - 0xf9, 0x1b, 0x6e, 0x91, 0x75, 0xe1, 0x6b, 0xcb, 0x31, 0xdc, 0x07, 0xd0, 0x34, 0xd4, 0xe9, 0x67, - 0x6b, 0x2d, 0xb0, 0x6f, 0x5b, 0x59, 0x03, 0x26, 0x00, 0x98, 0xce, 0x17, 0xe5, 0x12, 0x67, 0xd8, - 0x46, 0x34, 0x4f, 0x10, 0xaf, 0x97, 0x85, 0x19, 0x51, 0x12, 0x90, 0x33, 0xf9, 0x68, 0x1b, 0xee, - 0xd0, 0x08, 0xf8, 0x42, 0x43, 0x64, 0xeb, 0xec, 0x99, 0xd1, 0x9b, 0x57, 0x6d, 0xbf, 0x9c, 0x2e, - 0xf7, 0xfc, 0x14, 0xa6, 0xb7, 0xbb, 0xe0, 0x49, 0xe9, 0x98, 0x32, 0x9f, 0xf9, 0x54, 0xa2, 0x14, - 0x3c, 0x7d, 0xe6, 0x45, 0x5c, 0xfb, 0x62, 0xc1, 0xcd, 0xbc, 0xe0, 0x86, 0x15, 0x80, 0x2d, 0x98, - 0x17, 0xa1, 0x61, 0x10, 0xa5, 0xbe, 0x3f, 0xe2, 0x45, 0xf1, 0xe2, 0x07, 0xb8, 0xc3, 0xdd, 0x08, - 0x8a, 0x79, 0x3b, 0xa2, 0xf4, 0xf7, 0x51, 0x54, 0x10, 0x4b, 0xb5, 0x28, 0x85, 0xcd, 0x2e, 0x2f, - 0x5a, 0xf4, 0x70, 0x44, 0xa9, 0xe5, 0x77, 0x2d, 0x5e, 0xb3, 0x12, 0xd7, 0x42, 0xcf, 0x74, 0x86, - 0xc1, 0x92, 0x73, 0x23, 0x4a, 0xed, 0xfb, 0x56, 0x34, 0xa5, 0x15, 0x59, 0x16, 0xa5, 0x8e, 0xdf, - 0xe3, 0x95, 0x4b, 0xa9, 0x3b, 0x68, 0x76, 0x74, 0x12, 0x37, 0x5b, 0x0a, 0x0c, 0x45, 0x09, 0x43, - 0x23, 0xca, 0x6b, 0x59, 0x94, 0x84, 0x25, 0x57, 0xb3, 0x82, 0xab, 0xa8, 0xe4, 0x64, 0x56, 0xc2, - 0xbc, 0x6e, 0x51, 0x32, 0x9a, 0xbc, 0x60, 0x4d, 0x12, 0x06, 0xc6, 0xdb, 0x6f, 0x26, 0xc6, 0xdb, - 0x5f, 0x46, 0xc7, 0x69, 0x46, 0xd5, 0x2b, 0x89, 0x5f, 0x51, 0xb2, 0xd1, 0x12, 0xb1, 0xca, 0x84, - 0x52, 0xc1, 0xe2, 0xf6, 0x42, 0xf1, 0x7c, 0xe5, 0x03, 0x35, 0xe3, 0xaa, 0x15, 0xad, 0x80, 0xed, - 0x12, 0xad, 0x90, 0xb8, 0xed, 0x39, 0x7b, 0x63, 0xd7, 0x4a, 0x94, 0x46, 0xfa, 0xc8, 0x76, 0x4d, - 0x6f, 0x24, 0x71, 0x19, 0x8b, 0x78, 0x9d, 0x90, 0x3f, 0xc6, 0xb2, 0xeb, 0x65, 0x96, 0xf1, 0x00, - 0x19, 0xc9, 0x7b, 0xbd, 0x4c, 0xde, 0xb8, 0x0a, 0xd7, 0x64, 0xcd, 0xf7, 0x8d, 0xb1, 0x7e, 0x7b, - 0x27, 0xa1, 0x59, 0x42, 0xa6, 0xe9, 0x82, 0x20, 0x61, 0x88, 0x85, 0x96, 0xf4, 0xc2, 0x1b, 0x05, - 0xba, 0x29, 0x43, 0x48, 0xe8, 0x8f, 0x63, 0x32, 0xd4, 0x1c, 0x27, 0x25, 0xc8, 0x71, 0x1c, 0x06, - 0x93, 0xd0, 0x95, 0xaa, 0xbd, 0x95, 0x6c, 0x21, 0x3b, 0xd4, 0xed, 0x86, 0x56, 0xd5, 0x4e, 0xa7, - 0xc5, 0x64, 0xf9, 0xad, 0x7d, 0x27, 0xb3, 0xe5, 0x75, 0x64, 0x07, 0xa1, 0x0c, 0xbc, 0x01, 0x8e, - 0xb1, 0x3e, 0xaa, 0xb8, 0x22, 0x8c, 0x76, 0x3b, 0xf6, 0xe8, 0x74, 0xe1, 0x2d, 0xa5, 0x54, 0x90, - 0x78, 0x11, 0x06, 0x24, 0x71, 0x71, 0xa9, 0x54, 0x12, 0x40, 0xe0, 0x03, 0x78, 0x86, 0xa7, 0x76, - 0xbb, 0x2d, 0x48, 0x5d, 0x9f, 0x52, 0x37, 0xae, 0x57, 0x0a, 0xc5, 0x96, 0x62, 0x08, 0x92, 0x4f, - 0xcd, 0xb8, 0x08, 0x0a, 0x0a, 0x0a, 0xc0, 0x71, 0x3f, 0xd9, 0xeb, 0x76, 0x1d, 0x7a, 0xda, 0xe9, - 0x70, 0x8f, 0x51, 0x02, 0x8f, 0xb1, 0x56, 0x90, 0x0a, 0xf1, 0x61, 0x08, 0x3c, 0x3c, 0x31, 0x7f, - 0x2c, 0x49, 0x6a, 0xa9, 0xa1, 0x2e, 0x00, 0x2c, 0x41, 0x60, 0x0f, 0xc7, 0x00, 0x56, 0xa8, 0xe5, - 0xa4, 0x5c, 0x74, 0xe4, 0x02, 0x0f, 0x7e, 0x24, 0x1e, 0x4b, 0xd2, 0x66, 0xe2, 0x49, 0x55, 0x96, - 0x6b, 0xd5, 0xc2, 0x97, 0x45, 0xdc, 0xdc, 0xdf, 0x88, 0x9a, 0xba, 0x84, 0x9b, 0xba, 0x84, 0x9c, - 0xba, 0x88, 0x9d, 0xa6, 0xac, 0x54, 0x73, 0xf4, 0x62, 0x55, 0x91, 0x58, 0xf2, 0xcd, 0xeb, 0x03, - 0xf4, 0xc7, 0x05, 0x31, 0xb9, 0x3d, 0xf7, 0xea, 0xbd, 0x42, 0x1a, 0x32, 0x6d, 0x7f, 0x71, 0xb0, - 0xc3, 0x64, 0x31, 0xc0, 0xfd, 0xc0, 0xf5, 0xd2, 0xf8, 0xcf, 0x44, 0x00, 0xfd, 0x51, 0x09, 0xfd, - 0x01, 0x95, 0x50, 0xba, 0x85, 0xca, 0x1f, 0x13, 0xd4, 0x50, 0x32, 0x73, 0x06, 0xa7, 0x12, 0xaa, - 0x38, 0xa1, 0x32, 0x11, 0x6c, 0x13, 0x6b, 0x40, 0xa9, 0xcd, 0x2a, 0x00, 0xf4, 0xf6, 0x9f, 0xaa, - 0x03, 0xf1, 0x64, 0x08, 0x22, 0x1a, 0x62, 0x54, 0x48, 0x1f, 0x05, 0x5d, 0x47, 0x18, 0xa6, 0xfa, - 0xe5, 0x48, 0xf3, 0x7f, 0x98, 0xb5, 0xaa, 0x80, 0xe2, 0xe4, 0x77, 0x55, 0x58, 0xa7, 0x10, 0x4b, - 0x3b, 0x3a, 0x58, 0x80, 0x00, 0xdc, 0xd4, 0x30, 0x05, 0x6a, 0x8a, 0x57, 0x89, 0xac, 0x4f, 0x57, - 0x7f, 0xa3, 0x4a, 0x86, 0x9e, 0x51, 0xab, 0x86, 0x0e, 0xba, 0x4d, 0x8e, 0x73, 0xb4, 0x87, 0xae, - 0x49, 0x1f, 0xa3, 0xd6, 0x36, 0xab, 0xe1, 0xa9, 0xcf, 0xe0, 0xd6, 0xb8, 0x8b, 0xba, 0x36, 0x74, - 0xd0, 0x31, 0x6b, 0x1b, 0x78, 0xac, 0x66, 0x4d, 0x03, 0xd0, 0x59, 0x4b, 0x0d, 0x10, 0x87, 0x40, - 0x7f, 0xa3, 0x54, 0x59, 0xa2, 0x5c, 0x67, 0x10, 0xcb, 0x0d, 0xdf, 0xbd, 0x4b, 0x01, 0x88, 0x0a, - 0xfa, 0x50, 0x37, 0xd6, 0xb5, 0xf7, 0x59, 0xfb, 0x28, 0x7f, 0xab, 0x23, 0xcc, 0x72, 0x0f, 0x1f, - 0x00, 0x44, 0xad, 0xc4, 0x29, 0xe9, 0xb5, 0x20, 0x30, 0x08, 0xd0, 0x42, 0xe1, 0x54, 0x19, 0xa0, - 0xf6, 0x30, 0xf1, 0xa7, 0xad, 0xbf, 0x17, 0xde, 0x4b, 0x16, 0xfe, 0x56, 0x83, 0xef, 0xdf, 0x53, - 0xe0, 0xff, 0xdd, 0x82, 0x62, 0xd1, 0x85, 0x3b, 0x81, 0x83, 0xf6, 0x91, 0x80, 0xe0, 0x18, 0x08, - 0x6c, 0xf5, 0x77, 0xf5, 0xf6, 0x1e, 0xa8, 0xa8, 0x58, 0xa1, 0x81, 0x62, 0xc4, 0x0d, 0x64, 0x7c, - 0xe7, 0x0a, 0xa4, 0x28, 0x25, 0x68, 0xa6, 0x20, 0x4d, 0x46, 0x10, 0xfa, 0x5d, 0x80, 0x0b, 0xb6, - 0xef, 0x53, 0xd0, 0x48, 0x6e, 0xe8, 0x8c, 0x2b, 0x6f, 0x94, 0xa9, 0x28, 0x0d, 0x75, 0x97, 0x8e, - 0x08, 0xf3, 0x1e, 0xab, 0x43, 0x19, 0x5d, 0x4d, 0x2a, 0x0d, 0x65, 0x70, 0xd4, 0x3c, 0xc3, 0xd4, - 0x63, 0x99, 0x4b, 0x89, 0x13, 0x1c, 0x95, 0xea, 0x4c, 0xc9, 0xca, 0x6d, 0xcb, 0x76, 0xc0, 0x36, - 0xb8, 0xb7, 0xca, 0xdd, 0xc2, 0x3d, 0x0c, 0x5a, 0x0b, 0x43, 0xdf, 0x06, 0x6d, 0x4d, 0x53, 0xe8, - 0xaa, 0xa3, 0x61, 0x36, 0x74, 0x30, 0xcd, 0x7c, 0xb6, 0xd2, 0x18, 0xee, 0x6f, 0x22, 0xbe, 0xa4, - 0xe8, 0x1b, 0x3d, 0xa1, 0xb6, 0xbe, 0x7f, 0x37, 0xb6, 0xd4, 0xef, 0xdf, 0xc7, 0x5b, 0xaa, 0x08, - 0x44, 0x31, 0xf4, 0xa1, 0xcc, 0xdc, 0x76, 0x68, 0x32, 0x94, 0x79, 0x1c, 0x2c, 0xa5, 0xa2, 0xb2, - 0xed, 0x82, 0xaa, 0x7d, 0xff, 0x1e, 0x17, 0xe3, 0x13, 0x6f, 0xa2, 0x16, 0x01, 0x5a, 0x2d, 0x8a, - 0xa2, 0xd4, 0xe5, 0x80, 0xba, 0x01, 0x77, 0x1c, 0x4a, 0x1f, 0x23, 0xb9, 0xc0, 0x1f, 0xfe, 0xc4, - 0x82, 0x01, 0x22, 0xa4, 0x8d, 0xb4, 0x20, 0x91, 0x06, 0x8f, 0xb0, 0xe1, 0x71, 0x9c, 0x16, 0x48, - 0xaa, 0x67, 0x3c, 0x50, 0x12, 0x0c, 0x20, 0x76, 0x09, 0x2d, 0x3b, 0xc0, 0x7d, 0xda, 0xb6, 0x45, - 0x03, 0x02, 0xe1, 0xbf, 0x4f, 0xc0, 0xa2, 0x45, 0x1b, 0xb7, 0x7c, 0x3f, 0x54, 0x44, 0xcf, 0x5a, - 0x90, 0x7a, 0xb2, 0xe9, 0x47, 0xde, 0x77, 0x6a, 0xc8, 0x0e, 0x64, 0x1b, 0xd2, 0x98, 0x2b, 0xe5, - 0xa6, 0xde, 0x43, 0x92, 0xb0, 0xba, 0x5d, 0x70, 0xdf, 0x53, 0x71, 0xad, 0x8c, 0xce, 0xbc, 0x74, - 0x08, 0x4b, 0x95, 0x31, 0xf3, 0x0f, 0x5d, 0xad, 0xb2, 0xad, 0x46, 0x5d, 0xf7, 0x60, 0x22, 0x7f, - 0xe8, 0x20, 0x0f, 0xb1, 0xab, 0x33, 0x82, 0xd5, 0x37, 0xda, 0x6a, 0xc6, 0x56, 0x61, 0x94, 0xd6, - 0xf3, 0xe2, 0x04, 0x2b, 0x5a, 0x7a, 0xf3, 0x76, 0x74, 0x27, 0x3d, 0xe2, 0x25, 0xad, 0xde, 0x49, - 0x27, 0xec, 0x46, 0xbb, 0x93, 0x2e, 0xd9, 0x4d, 0x8e, 0x77, 0x4d, 0xf5, 0x51, 0x36, 0x2f, 0x85, - 0xfa, 0x31, 0x68, 0x1b, 0xb9, 0xe3, 0x78, 0xd0, 0x2b, 0xcd, 0x1a, 0x60, 0xa7, 0x75, 0x5a, 0xb5, - 0x3b, 0xa9, 0x78, 0x9f, 0x15, 0x06, 0x16, 0xab, 0xd4, 0x09, 0x20, 0x80, 0xe8, 0xa4, 0x52, 0x61, - 0xfa, 0x0f, 0xf1, 0x4f, 0x4d, 0x47, 0x34, 0xb0, 0x6c, 0xe2, 0xe8, 0xe1, 0x5f, 0x46, 0x3a, 0x65, - 0x64, 0xd4, 0x4c, 0xca, 0xc9, 0xc0, 0xbd, 0x28, 0x4e, 0x0f, 0xe5, 0xfe, 0x20, 0xb0, 0x52, 0xb7, - 0x2d, 0xe9, 0x51, 0x3a, 0x91, 0x2e, 0x25, 0x47, 0xa2, 0x52, 0x78, 0x87, 0xe5, 0x81, 0xe7, 0x87, - 0xa9, 0x14, 0x3c, 0x89, 0xfa, 0x36, 0xbd, 0x2d, 0xdc, 0x65, 0x42, 0xf8, 0xe1, 0x52, 0x7b, 0xaa, - 0xdf, 0xca, 0xb2, 0x7c, 0x78, 0x57, 0x3d, 0x5d, 0x82, 0xca, 0x23, 0x54, 0x3e, 0x82, 0xaa, 0xe1, - 0x0a, 0xd8, 0x05, 0xe5, 0x20, 0x5d, 0xe8, 0xa7, 0xd1, 0xc4, 0xa5, 0x7b, 0x5d, 0x91, 0xea, 0x48, - 0x30, 0x24, 0x0c, 0x9f, 0x99, 0x52, 0xa5, 0x5b, 0x17, 0x55, 0x0a, 0x76, 0x72, 0xc2, 0xf5, 0xd4, - 0xe9, 0x2d, 0xbd, 0x03, 0x71, 0x0b, 0x41, 0x14, 0xc1, 0xb0, 0x86, 0xb7, 0x40, 0x15, 0x0f, 0x2e, - 0x40, 0x93, 0x01, 0x5c, 0x72, 0x77, 0x7c, 0x6d, 0x75, 0x50, 0xed, 0xc0, 0x34, 0x7d, 0x11, 0x7e, - 0x76, 0xb7, 0x14, 0xa0, 0xf8, 0xae, 0x4e, 0x45, 0x09, 0x3a, 0xcb, 0xa8, 0x89, 0xae, 0x80, 0xa8, - 0x55, 0xec, 0x0a, 0xd6, 0xed, 0xbb, 0x77, 0xd8, 0x99, 0xae, 0xdb, 0x78, 0xa3, 0xc1, 0x8d, 0x07, - 0x6b, 0xb2, 0xa3, 0x03, 0x08, 0x74, 0xb9, 0xab, 0xeb, 0xb0, 0x8c, 0xdd, 0x0f, 0x02, 0x50, 0xb1, - 0xf6, 0x81, 0x82, 0x54, 0x09, 0x15, 0x41, 0xa8, 0xec, 0xe2, 0x4d, 0xba, 0x83, 0xbf, 0xe2, 0x94, - 0x91, 0x76, 0xd6, 0x20, 0xad, 0xea, 0x7a, 0xe7, 0xc7, 0x4d, 0x18, 0xe1, 0x59, 0x35, 0xa0, 0x57, - 0x43, 0xf4, 0x00, 0x47, 0x40, 0x9d, 0x71, 0x6d, 0xb0, 0xa5, 0x15, 0x0a, 0x50, 0xde, 0x47, 0xcd, - 0x21, 0x75, 0xb6, 0xe7, 0x68, 0x1b, 0xac, 0x07, 0x9b, 0xfd, 0x7a, 0x08, 0x1a, 0x88, 0x13, 0xa6, - 0x1c, 0x6f, 0x29, 0x70, 0xc8, 0xbd, 0xd3, 0x6f, 0x0d, 0xc9, 0x96, 0xbc, 0x3b, 0x54, 0xe8, 0x42, - 0x3a, 0x2a, 0x94, 0x7b, 0x46, 0x3f, 0x45, 0x81, 0x0d, 0x72, 0xe8, 0x35, 0x41, 0x1c, 0xdc, 0x6e, - 0x0a, 0x16, 0x91, 0xdc, 0x37, 0xcc, 0x26, 0x9e, 0x0f, 0x4c, 0x69, 0x92, 0xa0, 0x08, 0xa2, 0x28, - 0xdf, 0x7b, 0xb6, 0x9b, 0x12, 0x60, 0x36, 0xb5, 0xb4, 0x6e, 0xa6, 0xdb, 0xe9, 0x30, 0x6d, 0xcd, - 0x2d, 0x4d, 0x2d, 0x1d, 0x17, 0xdd, 0xa7, 0x75, 0x55, 0xba, 0xff, 0xd3, 0x01, 0xf9, 0xf9, 0xfe, - 0x9d, 0xea, 0x3a, 0x50, 0xf5, 0x43, 0xaa, 0xce, 0xc5, 0xa5, 0x26, 0x4a, 0xc8, 0x5d, 0xb1, 0x02, - 0x5d, 0x00, 0x8e, 0x8c, 0xcb, 0xd3, 0x29, 0x16, 0x2d, 0xf1, 0xb5, 0x1e, 0x0b, 0xfc, 0x8c, 0xbd, - 0xce, 0xcf, 0x1a, 0xb3, 0xc8, 0x88, 0xfd, 0x31, 0xa9, 0x83, 0x58, 0x4c, 0xef, 0xa6, 0xd3, 0x7f, - 0xaa, 0x33, 0x23, 0xc9, 0xb1, 0x71, 0x62, 0x63, 0xf4, 0x0f, 0x86, 0x11, 0x24, 0xf3, 0x99, 0x9c, - 0x9d, 0x36, 0x2f, 0x09, 0x8b, 0xb6, 0x20, 0xd8, 0xfa, 0x63, 0x82, 0x71, 0x46, 0xd4, 0x7b, 0xf6, - 0x3e, 0xf0, 0xdc, 0x6c, 0x10, 0xe2, 0x5b, 0xa9, 0x24, 0x63, 0x92, 0xf7, 0x7f, 0x4c, 0x9c, 0xe9, - 0x7b, 0x92, 0x69, 0x10, 0xa1, 0xce, 0x73, 0x81, 0x99, 0x4b, 0x30, 0xdc, 0x15, 0x62, 0xf4, 0xfb, - 0x8e, 0xdd, 0x66, 0x87, 0xf5, 0x58, 0x1b, 0xe1, 0x9f, 0x2a, 0xdd, 0x46, 0x21, 0xc3, 0x29, 0xff, - 0xc7, 0xdd, 0x3a, 0xd9, 0xfb, 0x7c, 0x49, 0xea, 0xa7, 0xc7, 0xc7, 0xb5, 0x93, 0x5d, 0x50, 0x38, - 0x03, 0x27, 0xb4, 0xfb, 0x0e, 0x25, 0x10, 0xd2, 0xf5, 0x0c, 0xd7, 0x0c, 0x88, 0xeb, 0x81, 0x69, - 0x1a, 0xf4, 0xfb, 0xb0, 0x3e, 0x40, 0xe1, 0xd8, 0x2e, 0xa9, 0x9d, 0x1d, 0x66, 0x21, 0x38, 0x09, - 0x58, 0x6a, 0x17, 0xf5, 0xce, 0xf6, 0x7f, 0x5c, 0x41, 0x1a, 0x40, 0x6f, 0xe4, 0xdd, 0x3b, 0x02, - 0x0a, 0x16, 0x3a, 0x76, 0xf0, 0xd9, 0x9d, 0x9a, 0xfa, 0x3f, 0x6f, 0xaf, 0x5c, 0xec, 0x8a, 0x25, - 0x80, 0x3b, 0xa8, 0xb8, 0x08, 0x04, 0xdd, 0xef, 0x43, 0x62, 0x38, 0x0e, 0x06, 0xe0, 0x63, 0x62, - 0x19, 0x43, 0xd4, 0x6e, 0xd0, 0x1f, 0x31, 0x69, 0x07, 0x7c, 0x69, 0x36, 0x08, 0xd3, 0x70, 0x3c, - 0x89, 0x08, 0xa3, 0x70, 0x3f, 0xc3, 0xeb, 0xf0, 0x62, 0x10, 0xa0, 0x8e, 0x0d, 0xa4, 0x60, 0x73, - 0x92, 0xc7, 0x46, 0xcf, 0xf9, 0x8f, 0xfb, 0x36, 0x43, 0xf0, 0x68, 0x34, 0x86, 0x23, 0x95, 0x18, - 0xf7, 0xaf, 0x78, 0xa6, 0xf4, 0x3f, 0x2e, 0x21, 0x6f, 0x79, 0x47, 0x34, 0xa8, 0xe0, 0x13, 0x21, - 0x7f, 0x4c, 0x58, 0x24, 0x12, 0x51, 0x92, 0x97, 0x11, 0xd2, 0xf1, 0x6d, 0x88, 0xaa, 0x9d, 0xf1, - 0x57, 0x96, 0x72, 0x67, 0x40, 0x27, 0xcb, 0x30, 0x03, 0xb6, 0xa3, 0xf2, 0xd5, 0x36, 0x79, 0xfd, - 0xd5, 0x72, 0x7d, 0x3c, 0xb2, 0xe7, 0x56, 0xc8, 0x76, 0x5c, 0x88, 0x03, 0x0e, 0x56, 0x41, 0x3a, - 0x9d, 0x05, 0x98, 0x5f, 0x60, 0x39, 0x97, 0xbf, 0x8e, 0x01, 0x4b, 0xf3, 0x95, 0xac, 0xc7, 0xd0, - 0x51, 0x4e, 0x1e, 0xa0, 0x00, 0x1d, 0xf2, 0xa1, 0x56, 0xe1, 0xe7, 0x21, 0xf0, 0x7e, 0x50, 0xc1, - 0x73, 0x0f, 0x78, 0x67, 0x56, 0x84, 0xbd, 0x8b, 0x8b, 0xd3, 0x8b, 0x37, 0x59, 0x97, 0xad, 0x60, - 0x02, 0xf6, 0xc7, 0x70, 0x81, 0x02, 0x0f, 0xae, 0x37, 0x72, 0xa3, 0x03, 0x09, 0xb2, 0x30, 0x5b, - 0x71, 0xc0, 0x7f, 0x90, 0x69, 0x81, 0x49, 0xf0, 0x57, 0x1d, 0x63, 0x2b, 0xa9, 0xc1, 0x2e, 0xd5, - 0x3e, 0x08, 0x5b, 0x27, 0xcd, 0x8c, 0xdd, 0x56, 0x6b, 0xfb, 0x53, 0xed, 0xe2, 0xe4, 0xf0, 0xe4, - 0xe0, 0xcd, 0x56, 0xb6, 0xb5, 0x4d, 0x2e, 0x67, 0x27, 0x4b, 0xdb, 0x63, 0x82, 0xf1, 0x17, 0xc8, - 0x40, 0xc8, 0xfc, 0x1a, 0x14, 0x02, 0x16, 0x49, 0xc9, 0x8b, 0x40, 0x29, 0xc3, 0xe9, 0x5b, 0x86, - 0x08, 0x62, 0x13, 0x90, 0x16, 0xc4, 0x0a, 0xc4, 0xee, 0xba, 0x1e, 0x04, 0x08, 0x00, 0xe6, 0x11, - 0xea, 0x32, 0x5b, 0x89, 0x52, 0x86, 0x3b, 0x0f, 0x20, 0x55, 0x04, 0x04, 0x15, 0x44, 0x9a, 0x0b, - 0x1e, 0x0d, 0x6c, 0x7c, 0xa9, 0x7b, 0x00, 0xa2, 0x86, 0x89, 0x9f, 0xe8, 0x20, 0x32, 0xdf, 0x39, - 0x9d, 0x09, 0x1d, 0x1f, 0x94, 0xd9, 0x52, 0x51, 0xfa, 0x2a, 0xdb, 0x2e, 0x44, 0x77, 0x8d, 0xcb, - 0xe3, 0x23, 0xbd, 0x23, 0x35, 0x16, 0x3d, 0x4d, 0x5d, 0x60, 0x87, 0xa1, 0xc1, 0x45, 0x02, 0x83, - 0xbb, 0xe3, 0x3d, 0x82, 0xe3, 0x7b, 0xc8, 0xcc, 0xe9, 0x74, 0xfa, 0x2b, 0x6e, 0xf4, 0xbc, 0x97, - 0x10, 0x6c, 0x97, 0xc1, 0xad, 0xaa, 0x1d, 0x87, 0x8b, 0xae, 0xce, 0xdd, 0xa9, 0x57, 0x3b, 0x52, - 0x55, 0x3b, 0xc2, 0x9d, 0x79, 0x14, 0x5b, 0xd1, 0x13, 0xf3, 0x36, 0x3e, 0x44, 0x5d, 0x71, 0x9f, - 0x24, 0x61, 0x8a, 0xe5, 0xcd, 0xf2, 0x5f, 0x0b, 0xcd, 0xc4, 0xca, 0x2b, 0x40, 0x59, 0x9f, 0x5c, - 0x75, 0x39, 0x49, 0x90, 0x64, 0xd3, 0x2c, 0x58, 0x0c, 0x4b, 0x4f, 0x25, 0x5b, 0x64, 0xe8, 0x5f, - 0x8e, 0x98, 0xd5, 0xaa, 0x11, 0x58, 0xe4, 0x16, 0x39, 0x60, 0xd9, 0x55, 0x65, 0xa6, 0x7d, 0x79, - 0x3c, 0x6a, 0xb0, 0xe8, 0x33, 0x2e, 0x33, 0xa0, 0xcc, 0xd8, 0x02, 0x47, 0x3a, 0x56, 0xc5, 0x16, - 0x58, 0x53, 0xfb, 0x2f, 0x9a, 0x36, 0xee, 0x24, 0x88, 0x11, 0xfd, 0x6e, 0x2b, 0x25, 0xa4, 0x2d, - 0xb0, 0x94, 0xe8, 0x50, 0xe1, 0x9d, 0x3a, 0xbb, 0xd3, 0xe0, 0x4e, 0x64, 0x3e, 0x2d, 0x42, 0xa9, - 0x1a, 0x1e, 0xb0, 0x67, 0x7f, 0xa2, 0x50, 0x75, 0x65, 0x74, 0x10, 0x9b, 0x2c, 0x8d, 0xe4, 0x4b, - 0xfc, 0xe9, 0x02, 0x64, 0x31, 0x65, 0xfc, 0xe5, 0x48, 0x36, 0xfc, 0xc1, 0x3f, 0x11, 0xca, 0x31, - 0xc9, 0xf5, 0x40, 0x39, 0x9c, 0xf0, 0xb6, 0xcc, 0xfe, 0x13, 0xa0, 0x1c, 0xb5, 0x0d, 0x9b, 0x18, - 0x98, 0x9b, 0x18, 0x6a, 0x5d, 0x7b, 0x3c, 0x8f, 0xae, 0x0b, 0xf8, 0xbe, 0x04, 0x61, 0x67, 0xd5, - 0x05, 0x29, 0x39, 0xb2, 0x09, 0x4f, 0xc8, 0xdc, 0x1a, 0xe6, 0x84, 0x75, 0x21, 0x4a, 0x0a, 0x47, - 0x85, 0x3b, 0x06, 0xb8, 0xfd, 0x30, 0x8c, 0x2e, 0x44, 0x9b, 0x0b, 0x51, 0x53, 0x0c, 0xaa, 0x53, - 0x16, 0x38, 0x2c, 0x60, 0xcf, 0x61, 0xb4, 0xb4, 0x93, 0xd5, 0x70, 0x44, 0xbc, 0xf2, 0xf3, 0x97, - 0xbe, 0xee, 0xae, 0x7a, 0x7e, 0x49, 0xfe, 0x48, 0x0b, 0x5c, 0x10, 0x81, 0x18, 0x6d, 0x87, 0x1a, - 0x3e, 0xc3, 0xff, 0x05, 0xd8, 0x85, 0x3a, 0x3d, 0xc9, 0x61, 0xc0, 0xae, 0x3f, 0x48, 0x0c, 0xea, - 0x4b, 0x96, 0xa4, 0x88, 0x3f, 0xb3, 0x38, 0x90, 0xbb, 0x26, 0x1d, 0x1e, 0x7b, 0x26, 0x85, 0x00, - 0xa3, 0x3a, 0x57, 0x86, 0x3a, 0xac, 0x3c, 0xae, 0xff, 0x71, 0x97, 0x34, 0x0a, 0xb8, 0xa0, 0xf6, - 0xcc, 0xf0, 0x8d, 0x5e, 0xc0, 0x42, 0x88, 0xab, 0x8b, 0xa3, 0x26, 0x4c, 0xa1, 0x6d, 0xf1, 0xb2, - 0x14, 0x5f, 0x48, 0xf2, 0xac, 0x61, 0xc0, 0x2a, 0xc1, 0xb3, 0x9d, 0xc7, 0xb1, 0x18, 0x57, 0xa0, - 0xc3, 0x39, 0x0b, 0x10, 0xd0, 0x50, 0xce, 0x22, 0x84, 0x6d, 0xf0, 0x1f, 0x04, 0x96, 0x57, 0xd4, - 0x75, 0x96, 0xbb, 0x5b, 0x54, 0x07, 0xe0, 0xf3, 0xcf, 0xf1, 0x8b, 0xdc, 0x05, 0x6c, 0xcf, 0x9b, - 0xbc, 0xd1, 0xfb, 0xfe, 0x68, 0xa9, 0x41, 0x14, 0xc3, 0xb0, 0x0a, 0xbf, 0x8d, 0xee, 0x91, 0x8d, - 0x89, 0x1e, 0xdb, 0xdc, 0x61, 0xc9, 0xf4, 0x03, 0x28, 0xa0, 0xa2, 0x68, 0xf7, 0xa2, 0x28, 0x68, - 0x5d, 0x9c, 0xcd, 0xb2, 0x55, 0xcf, 0xa8, 0xa5, 0xd6, 0x6a, 0x8d, 0x10, 0x39, 0xd0, 0xcc, 0x39, - 0x5b, 0xa7, 0x90, 0xf7, 0x71, 0x13, 0xc4, 0xf4, 0x28, 0xb7, 0xfb, 0xfc, 0x3d, 0x52, 0xdc, 0x25, - 0x69, 0x51, 0x62, 0x10, 0xf6, 0x19, 0x0c, 0xae, 0x20, 0x99, 0x7e, 0xac, 0xa2, 0x7a, 0x4f, 0x68, - 0xc8, 0x90, 0xa5, 0xd4, 0x9e, 0xc1, 0x66, 0x1d, 0xa2, 0x8c, 0x32, 0x49, 0x9b, 0x04, 0x4b, 0x93, - 0x73, 0xfb, 0xdd, 0x3b, 0x64, 0xa9, 0x07, 0xc0, 0x8e, 0xd7, 0x4d, 0x09, 0x97, 0xa0, 0xc9, 0x03, - 0xe6, 0x0a, 0x92, 0xf7, 0x42, 0x1a, 0x1c, 0xd4, 0xf7, 0x68, 0x8e, 0x18, 0x8a, 0x11, 0x56, 0x7c, - 0xff, 0x21, 0xd2, 0xde, 0xe0, 0x13, 0x4e, 0x81, 0x78, 0x6b, 0xd8, 0x21, 0xf2, 0x7c, 0x5c, 0xb3, - 0x2b, 0x88, 0x20, 0x00, 0x2b, 0xd1, 0xa1, 0x94, 0x08, 0x00, 0xa3, 0x60, 0xe3, 0x55, 0x0d, 0x66, - 0x59, 0x2d, 0x31, 0x8a, 0x72, 0xc2, 0x66, 0xb7, 0x4a, 0xd7, 0x4f, 0x97, 0x26, 0x28, 0x06, 0x13, - 0xc6, 0x24, 0xc5, 0x12, 0x1c, 0x4b, 0x6d, 0x4c, 0xa7, 0x46, 0x30, 0x76, 0xdb, 0x64, 0x26, 0x9e, - 0x7d, 0x10, 0x74, 0xc6, 0xff, 0x60, 0x16, 0xfd, 0x46, 0x59, 0x61, 0xd7, 0x6c, 0x0e, 0xbb, 0x67, - 0x10, 0x89, 0xd3, 0xb5, 0x28, 0xf2, 0x0c, 0x9b, 0x18, 0x25, 0x4f, 0xde, 0xa8, 0x73, 0xd7, 0x16, - 0x5d, 0xaa, 0x99, 0x0f, 0x2a, 0x86, 0xfe, 0x78, 0xb2, 0x96, 0xfc, 0x20, 0x66, 0xeb, 0xcb, 0x23, - 0xb2, 0x8a, 0xd1, 0xfa, 0x03, 0x7f, 0x7f, 0x64, 0xd8, 0x21, 0xe9, 0x50, 0xf0, 0xb6, 0x52, 0xb1, - 0x0f, 0x23, 0xa4, 0x17, 0x33, 0xe3, 0x9c, 0x23, 0x69, 0x21, 0xe9, 0xce, 0x48, 0x93, 0x1e, 0x0d, - 0x2d, 0x0f, 0x7c, 0x0e, 0x74, 0x7f, 0x04, 0x09, 0x0f, 0x86, 0x53, 0x3f, 0x00, 0xe7, 0x39, 0xe9, - 0xd1, 0x40, 0x50, 0xb2, 0xe2, 0xd2, 0x4c, 0x25, 0x3c, 0x36, 0x5e, 0xa1, 0x53, 0x50, 0xad, 0xd1, - 0xf0, 0xa1, 0x8c, 0x35, 0x29, 0xb1, 0xba, 0x16, 0x69, 0x57, 0x9c, 0xb6, 0x31, 0x8c, 0xc6, 0x24, - 0x55, 0x5c, 0x4e, 0x7d, 0x1f, 0x03, 0x51, 0x11, 0x02, 0x53, 0x30, 0x9d, 0xe1, 0x87, 0xd4, 0x7a, - 0x42, 0xc6, 0x79, 0x48, 0x4c, 0x9c, 0x87, 0x97, 0x76, 0x8f, 0x7a, 0x03, 0x88, 0x19, 0x13, 0x39, - 0x09, 0xfa, 0x2a, 0x11, 0x01, 0x54, 0x55, 0x9a, 0x13, 0xc5, 0xca, 0x33, 0xc3, 0xcc, 0x73, 0xa0, - 0xbf, 0x34, 0xd0, 0xe2, 0x20, 0xd3, 0x95, 0x45, 0xb0, 0xa5, 0x82, 0x3f, 0x96, 0xd0, 0xa4, 0xc2, - 0xb1, 0xcd, 0x92, 0xea, 0x5f, 0x1b, 0x20, 0x60, 0x3c, 0xf1, 0x8f, 0xe9, 0xdc, 0xbd, 0x21, 0xf4, - 0x85, 0xb9, 0x5d, 0x0a, 0xc2, 0x0a, 0xec, 0xc3, 0xfd, 0x52, 0x18, 0x02, 0x65, 0x32, 0x05, 0x31, - 0x72, 0x24, 0x81, 0xb0, 0x76, 0x99, 0xd4, 0x61, 0x32, 0x0a, 0x28, 0x8e, 0x22, 0xc4, 0x99, 0xe0, - 0x1a, 0x43, 0xbb, 0x6b, 0x84, 0x9e, 0x0f, 0x86, 0xc4, 0xee, 0xb7, 0x3c, 0xc3, 0x37, 0xe5, 0x91, - 0x6f, 0x87, 0x94, 0xd9, 0xaa, 0xc8, 0x6f, 0x4e, 0xb0, 0x62, 0xde, 0xd2, 0x94, 0xe9, 0x23, 0x6d, - 0xd7, 0xb9, 0x9b, 0xcc, 0xb7, 0x1f, 0x84, 0x67, 0x79, 0x26, 0xec, 0x1b, 0x36, 0x26, 0x42, 0x40, - 0x45, 0x21, 0x20, 0x41, 0x13, 0x52, 0x21, 0xb0, 0xc8, 0x40, 0x03, 0x4c, 0x59, 0xfa, 0x7f, 0xdd, - 0x5c, 0x2c, 0x76, 0x7e, 0x0d, 0x14, 0xaa, 0xcb, 0xb6, 0x65, 0x5e, 0x06, 0xf9, 0xfc, 0x12, 0x08, - 0x26, 0xec, 0x5e, 0x00, 0x31, 0x5e, 0x84, 0x60, 0xc1, 0xe3, 0x4b, 0x03, 0x1d, 0x9d, 0xbc, 0x04, - 0xc2, 0x83, 0x9b, 0x17, 0x81, 0xae, 0x5e, 0x01, 0x73, 0xf2, 0x22, 0x0c, 0x13, 0xa4, 0x97, 0xe8, - 0x07, 0x2a, 0xee, 0x05, 0x10, 0xb4, 0x81, 0xab, 0x20, 0x98, 0xf3, 0x8b, 0x00, 0x30, 0xab, 0xfb, - 0x7c, 0x1f, 0x4c, 0x22, 0x03, 0xaf, 0xcf, 0xd2, 0xc1, 0x71, 0x4e, 0x93, 0xa5, 0x86, 0x93, 0x69, - 0xd2, 0x3b, 0x69, 0x66, 0xd8, 0x75, 0x00, 0x66, 0x59, 0x2f, 0x58, 0x47, 0xf2, 0xa3, 0x34, 0xb3, - 0xf1, 0x0b, 0xe5, 0x63, 0x89, 0xb9, 0x04, 0x20, 0x47, 0x33, 0x45, 0xbb, 0xb4, 0x11, 0xf6, 0x9a, - 0x85, 0x12, 0x6d, 0x96, 0x82, 0xd3, 0xa0, 0x2f, 0xbb, 0x20, 0x7d, 0xdf, 0x0b, 0x3d, 0x88, 0x3f, - 0x3e, 0x18, 0x0e, 0xf5, 0xc1, 0x9f, 0xff, 0x04, 0xcb, 0x98, 0x87, 0x26, 0x68, 0x6f, 0x87, 0x20, - 0xda, 0xec, 0xc4, 0xd0, 0xc8, 0x82, 0x38, 0x27, 0xa0, 0xfe, 0x10, 0x04, 0x1d, 0xdf, 0x01, 0x64, - 0x3a, 0x9b, 0xa4, 0x3c, 0x9f, 0xbf, 0xbd, 0x01, 0x96, 0xd0, 0x1f, 0xb8, 0xf3, 0x9a, 0x40, 0x14, - 0xc4, 0x4a, 0xd2, 0x5a, 0x4c, 0x23, 0xd1, 0xf2, 0x5c, 0x76, 0x86, 0x41, 0x67, 0x68, 0xe1, 0x2e, - 0x13, 0x73, 0x2a, 0x23, 0x0d, 0xab, 0xcf, 0x53, 0x17, 0x91, 0x0d, 0x53, 0x15, 0xe5, 0xaf, 0x59, - 0xc2, 0x7c, 0x5e, 0x0b, 0x3e, 0x7b, 0xa1, 0xc0, 0xf2, 0x89, 0xa1, 0xfe, 0xcf, 0xf2, 0xe7, 0x3a, - 0x36, 0x15, 0x93, 0x76, 0x25, 0xc2, 0x3e, 0xd6, 0xf1, 0xc7, 0x84, 0x4e, 0xff, 0x94, 0xd8, 0x8b, - 0x9e, 0xfc, 0x5e, 0xfc, 0xa7, 0xca, 0xba, 0xe1, 0xe6, 0x6e, 0xfe, 0x9a, 0x21, 0xf3, 0x10, 0xf5, - 0x70, 0xca, 0x84, 0x7b, 0x01, 0x49, 0x8e, 0x08, 0x14, 0x57, 0xdb, 0x47, 0x8b, 0xd8, 0xd2, 0x04, - 0xaa, 0xe1, 0x22, 0xaa, 0xb1, 0x72, 0xc9, 0x16, 0x54, 0x8d, 0xe1, 0xe9, 0xbe, 0x84, 0x67, 0x98, - 0xc0, 0x33, 0x64, 0x78, 0xd2, 0x67, 0x90, 0x74, 0xa7, 0xb8, 0xf7, 0xf9, 0x92, 0x24, 0xc6, 0xc9, - 0x52, 0x9e, 0x3b, 0x5a, 0xb7, 0x9b, 0x46, 0x97, 0x77, 0xd3, 0x68, 0x72, 0x37, 0x2d, 0x64, 0x9b, - 0x47, 0xd1, 0x86, 0x9a, 0x84, 0x11, 0xf9, 0x1b, 0x9d, 0xed, 0x3e, 0xf0, 0x89, 0xc5, 0x62, 0x19, - 0x99, 0x5d, 0x3c, 0xf3, 0xf2, 0x05, 0x5c, 0x0b, 0xee, 0x0e, 0xcc, 0x4f, 0xc0, 0x88, 0x2c, 0x36, - 0x3f, 0x63, 0x67, 0x53, 0xa2, 0xdd, 0xda, 0xc4, 0x61, 0x15, 0x5c, 0x73, 0x6c, 0x87, 0x19, 0xfd, - 0xcf, 0xb9, 0x13, 0x8c, 0x2d, 0xd9, 0xd9, 0x18, 0xca, 0x5e, 0x00, 0xa3, 0x32, 0x42, 0xc1, 0x4c, - 0x77, 0x69, 0xc7, 0x80, 0x40, 0x3a, 0x95, 0xec, 0x54, 0x66, 0xb2, 0x9e, 0x4a, 0xbc, 0x0b, 0x06, - 0x31, 0x6c, 0x77, 0x0f, 0x23, 0x96, 0x67, 0xda, 0x62, 0x16, 0x7b, 0x79, 0xd7, 0x10, 0xdb, 0x64, - 0x50, 0x78, 0x85, 0xa5, 0x8e, 0x4e, 0x87, 0xcf, 0xf5, 0x93, 0x84, 0xf3, 0xc0, 0x47, 0x35, 0x5f, - 0x37, 0x9c, 0x4f, 0x7b, 0x30, 0xce, 0xc2, 0x88, 0xd5, 0x41, 0x1f, 0x3f, 0xec, 0x76, 0xc6, 0x49, - 0x01, 0xa2, 0x83, 0x6b, 0x9f, 0x25, 0x1c, 0x3a, 0x30, 0x3f, 0x9c, 0x6a, 0x00, 0x81, 0x64, 0x62, - 0xc0, 0xd9, 0xec, 0xd9, 0x98, 0xcb, 0xad, 0xf9, 0xee, 0xfb, 0xba, 0x76, 0x4b, 0x90, 0x51, 0x1a, - 0x14, 0x44, 0x17, 0x43, 0x15, 0xf4, 0xba, 0x2f, 0x98, 0xcb, 0x53, 0x0d, 0xe3, 0xad, 0x0e, 0x26, - 0x48, 0x11, 0x8b, 0x58, 0x00, 0x80, 0xf8, 0x63, 0x2e, 0x43, 0x5a, 0x09, 0x24, 0xc0, 0x8d, 0x9c, - 0x4a, 0x58, 0x6d, 0x98, 0xb5, 0x00, 0x23, 0x2d, 0x08, 0x7d, 0x16, 0x5e, 0xd1, 0x5b, 0x13, 0x56, - 0x44, 0x2f, 0xec, 0x81, 0xbb, 0x13, 0x8b, 0xcf, 0x1a, 0xa1, 0x46, 0x42, 0x45, 0x01, 0xe8, 0x8c, - 0xb3, 0xe0, 0x0b, 0xfe, 0xb8, 0x01, 0x23, 0xac, 0x14, 0x33, 0xf0, 0x05, 0x70, 0xaf, 0x2f, 0x48, - 0x11, 0x0f, 0x7f, 0x08, 0x19, 0x69, 0xd5, 0x84, 0x74, 0x2e, 0x08, 0xe2, 0xf3, 0xeb, 0x71, 0xce, - 0xaf, 0xf9, 0x1e, 0xc6, 0x7f, 0x7b, 0x43, 0x7c, 0xc6, 0x87, 0x85, 0x53, 0x91, 0xaf, 0xd9, 0xc1, - 0x92, 0x50, 0xd1, 0xad, 0xdd, 0xc5, 0x72, 0x31, 0x98, 0x0b, 0xc1, 0xa6, 0x24, 0x9c, 0xbe, 0x0f, - 0xa9, 0x50, 0x5f, 0x72, 0x36, 0x01, 0x6e, 0x69, 0xab, 0x5c, 0x5a, 0x13, 0xba, 0x46, 0xa1, 0x09, - 0x78, 0xa4, 0x61, 0xb2, 0xbf, 0xa5, 0xc6, 0xee, 0x33, 0x6d, 0x01, 0x9b, 0xf5, 0xfe, 0x68, 0xb8, - 0x5a, 0x01, 0xe6, 0xdc, 0x8d, 0xf5, 0x57, 0x32, 0xf0, 0xa6, 0x3e, 0xac, 0x8e, 0x68, 0x37, 0xfa, - 0x94, 0xdb, 0x6f, 0xe6, 0x15, 0x82, 0x09, 0x4f, 0x46, 0x4b, 0x33, 0x16, 0xb2, 0x4d, 0xe0, 0xad, - 0xd8, 0xa5, 0xad, 0x86, 0x98, 0x0a, 0xe2, 0xaa, 0x1e, 0x77, 0x1e, 0xb9, 0x07, 0x20, 0x60, 0x1a, - 0x83, 0x5b, 0x75, 0x7a, 0x1b, 0x46, 0x1b, 0x9c, 0x51, 0x26, 0x85, 0x97, 0xe0, 0x1d, 0x14, 0xcc, - 0xfc, 0x00, 0x5e, 0xfa, 0x98, 0x28, 0x1a, 0xf3, 0xa2, 0x31, 0xf7, 0x3f, 0x40, 0x4c, 0x5d, 0xb3, - 0x8e, 0xec, 0x81, 0x30, 0x42, 0x52, 0x80, 0xfa, 0x21, 0x6e, 0x98, 0xce, 0xbc, 0x0c, 0x88, 0x1e, - 0x12, 0x2e, 0x86, 0xbb, 0xd6, 0xc1, 0x48, 0xf4, 0x2d, 0xae, 0xc4, 0x78, 0x89, 0x2d, 0x79, 0x9e, - 0x8a, 0x68, 0x0f, 0xf5, 0xb9, 0xab, 0x2e, 0xb5, 0x87, 0xf3, 0x40, 0x16, 0x1d, 0x66, 0x6e, 0x63, - 0x6e, 0xef, 0x22, 0x43, 0xe0, 0x3e, 0x13, 0x7f, 0xb5, 0x87, 0x8b, 0xd1, 0x56, 0x9c, 0xab, 0x4b, - 0x45, 0xae, 0x7a, 0x14, 0x2f, 0x61, 0x80, 0xdb, 0x8d, 0x37, 0x5f, 0x52, 0x13, 0xdb, 0xac, 0x40, - 0xa8, 0x6a, 0x4a, 0x2e, 0x5c, 0x5c, 0xe9, 0x31, 0xa8, 0xa0, 0x4d, 0x34, 0xfc, 0x50, 0x7a, 0xa4, - 0xec, 0xd6, 0xeb, 0x4b, 0xe3, 0x59, 0xe1, 0x8d, 0x34, 0x8e, 0x4b, 0x6f, 0xa6, 0xa2, 0xb8, 0xc4, - 0x27, 0x27, 0xc9, 0x27, 0xca, 0x37, 0x3b, 0x26, 0x7c, 0x8f, 0xde, 0x41, 0xf2, 0xc2, 0x28, 0xcc, - 0x71, 0x67, 0x0f, 0x2e, 0x6e, 0x7c, 0xda, 0xe8, 0xaf, 0xe1, 0x36, 0x68, 0x54, 0xcf, 0xd2, 0x76, - 0x8f, 0x1c, 0xe0, 0x91, 0x66, 0xf8, 0x35, 0x90, 0xc6, 0xbc, 0x64, 0x1c, 0x95, 0x8c, 0x03, 0x30, - 0x8a, 0xcf, 0x4a, 0x93, 0xb4, 0x72, 0x56, 0x20, 0x0a, 0xb5, 0xd7, 0xc5, 0xe0, 0x3c, 0x56, 0x7f, - 0x21, 0xf8, 0x7f, 0x45, 0xa4, 0xf6, 0x13, 0xf9, 0x86, 0x28, 0x64, 0xfb, 0x41, 0x78, 0xfa, 0x42, - 0x67, 0x2f, 0xc6, 0xa7, 0x3f, 0x8f, 0xcc, 0x3a, 0x9a, 0x71, 0xd2, 0x3c, 0x9b, 0xb7, 0x60, 0x7b, - 0x8b, 0xff, 0x15, 0x4c, 0x57, 0x42, 0xea, 0x5f, 0xc0, 0xf6, 0x39, 0x25, 0xc4, 0x52, 0x22, 0xc8, - 0x84, 0xb9, 0x24, 0xdf, 0xde, 0x81, 0x42, 0x54, 0xaa, 0xee, 0x16, 0xad, 0xba, 0x20, 0xc7, 0xe1, - 0x82, 0x1c, 0xbb, 0x5c, 0x82, 0x85, 0x66, 0xfc, 0xb6, 0x03, 0x0a, 0x30, 0xc8, 0xaf, 0x0b, 0x12, - 0x19, 0xbd, 0x1b, 0x1f, 0x4e, 0xff, 0xef, 0x5d, 0xc7, 0x29, 0x3f, 0x09, 0x10, 0xbd, 0xb3, 0x80, - 0xbe, 0x82, 0xbe, 0x76, 0xe2, 0xaa, 0xf2, 0xec, 0x42, 0x4a, 0xb4, 0x8d, 0x4e, 0x10, 0x26, 0x54, - 0xf4, 0x7b, 0xf6, 0xea, 0x80, 0x6d, 0xea, 0x8b, 0x87, 0x8b, 0xc8, 0x8f, 0xdf, 0xab, 0x5f, 0xfc, - 0xc4, 0xd3, 0x0b, 0xaf, 0x16, 0x2c, 0xe8, 0xc8, 0xf8, 0x45, 0x02, 0x18, 0x11, 0xa4, 0xe5, 0xd9, - 0x8f, 0xfb, 0x14, 0xe5, 0x02, 0xd1, 0x94, 0xf3, 0xbc, 0xac, 0x69, 0x70, 0x25, 0x9a, 0x5c, 0xc4, - 0xaf, 0xeb, 0xb0, 0x6f, 0xe4, 0x10, 0xb5, 0x28, 0x97, 0x0b, 0x78, 0xcd, 0xcb, 0x85, 0x32, 0x5e, - 0xa1, 0x36, 0x07, 0x20, 0x6a, 0x89, 0xa8, 0xaa, 0xac, 0x92, 0x9c, 0x9c, 0x2b, 0x90, 0x4d, 0xfc, - 0xf0, 0x4f, 0x41, 0xd6, 0xf0, 0x4e, 0x2d, 0xc0, 0x5d, 0xb1, 0x4c, 0x4a, 0x58, 0x01, 0x3f, 0x65, - 0x78, 0x2c, 0xe5, 0xa0, 0x42, 0xc1, 0x6f, 0x03, 0x41, 0x07, 0x6a, 0x74, 0x91, 0xcb, 0x39, 0x7e, - 0xa7, 0xc9, 0x79, 0x2c, 0x2b, 0x6e, 0x12, 0x95, 0x7d, 0x33, 0xa8, 0x8c, 0xd7, 0xa2, 0xac, 0x5e, - 0x43, 0x8d, 0x5a, 0x38, 0x82, 0x91, 0x8b, 0x44, 0x55, 0xe4, 0xe2, 0x91, 0x0a, 0x57, 0xed, 0x48, - 0xd5, 0x00, 0xa9, 0xa3, 0x32, 0xde, 0x6e, 0xca, 0xf9, 0xa8, 0x86, 0x75, 0xa3, 0x16, 0xae, 0xa1, - 0xd9, 0x39, 0xe0, 0x00, 0xcd, 0xf3, 0x05, 0x52, 0x96, 0x15, 0x44, 0x61, 0x33, 0x4f, 0x4a, 0x30, - 0x3e, 0x4c, 0x07, 0x71, 0x6e, 0xc0, 0x6c, 0xcf, 0x0b, 0x58, 0xc3, 0x30, 0x51, 0x72, 0xd8, 0x52, - 0xc1, 0x17, 0x1c, 0xd4, 0x1c, 0x96, 0xe6, 0xd8, 0x54, 0xf1, 0x52, 0x90, 0x37, 0x0b, 0x11, 0x04, - 0xce, 0x0e, 0x5b, 0x94, 0x09, 0xd2, 0x4a, 0x2d, 0x37, 0x80, 0x3c, 0x85, 0x73, 0xfc, 0x82, 0x10, - 0x2b, 0xd4, 0x14, 0x59, 0x83, 0xbe, 0x4b, 0xf8, 0xab, 0x31, 0x9a, 0x41, 0x39, 0xde, 0x14, 0x64, - 0x7e, 0xcd, 0x23, 0x3a, 0x11, 0x54, 0x0e, 0xc9, 0x11, 0x35, 0xcd, 0x21, 0x9d, 0xf1, 0xda, 0x50, - 0x4b, 0xd7, 0xaa, 0x7a, 0xae, 0x22, 0xa2, 0x65, 0xec, 0x80, 0xa1, 0x5f, 0x2a, 0x32, 0x2c, 0x60, - 0x0e, 0xd8, 0x04, 0xe6, 0x72, 0x0d, 0xb4, 0x28, 0x9f, 0x73, 0x9e, 0x14, 0x58, 0x0f, 0x30, 0x3d, - 0x98, 0x97, 0xac, 0x01, 0xe4, 0x26, 0xd9, 0xc4, 0x1f, 0x15, 0x0f, 0xb7, 0xb1, 0x06, 0xaa, 0x0c, - 0xfc, 0x04, 0x3a, 0x23, 0xd9, 0x10, 0x11, 0x36, 0xc5, 0x52, 0x99, 0xdd, 0x14, 0xa2, 0x02, 0xc6, - 0x21, 0x00, 0x42, 0xea, 0x97, 0xf1, 0x17, 0xda, 0x62, 0x89, 0xc2, 0x31, 0xd3, 0x94, 0x63, 0xa4, - 0xb7, 0x0a, 0xb3, 0x4f, 0x7e, 0x1a, 0x89, 0xa5, 0xc1, 0x96, 0xe5, 0x3a, 0x7e, 0xd7, 0x21, 0xfa, - 0x92, 0x97, 0x40, 0x7e, 0xfe, 0x15, 0x99, 0xed, 0x97, 0x3e, 0x43, 0xb5, 0x29, 0x69, 0x6a, 0xa3, - 0x7c, 0x5d, 0x6a, 0xa8, 0x9b, 0xf8, 0x50, 0x68, 0x94, 0x6b, 0x9a, 0xa4, 0x45, 0xe7, 0x00, 0x8b, - 0x52, 0xe9, 0x5a, 0x53, 0x13, 0x05, 0x65, 0x49, 0x03, 0xca, 0x6e, 0x26, 0x4a, 0xf0, 0x4b, 0x3e, - 0xea, 0x75, 0x29, 0x51, 0x82, 0xbd, 0x1c, 0xab, 0x45, 0x49, 0x6d, 0xe4, 0x93, 0x70, 0x52, 0xee, - 0x5a, 0x2d, 0x35, 0xf2, 0xd7, 0xd0, 0xbe, 0x78, 0xad, 0xb2, 0xb9, 0x13, 0x3e, 0xf9, 0xe8, 0xb8, - 0x77, 0x9d, 0x25, 0xd4, 0x3c, 0x32, 0x4b, 0xe0, 0xbd, 0x7f, 0x3e, 0x0f, 0xf2, 0x2f, 0x52, 0x0a, - 0x97, 0x76, 0x94, 0xe2, 0xfe, 0x2f, 0xae, 0xef, 0x32, 0x2e, 0x84, 0x32, 0x2e, 0xae, 0x12, 0x3e, - 0xe6, 0x71, 0x7d, 0x43, 0x33, 0x58, 0x8d, 0x1a, 0xfe, 0xe4, 0x51, 0x28, 0xf3, 0xd8, 0xf7, 0x66, - 0x11, 0x00, 0xf1, 0x93, 0x5d, 0x9b, 0xb8, 0x1a, 0x4b, 0xff, 0x82, 0x7c, 0x36, 0xd4, 0xdc, 0x39, - 0xae, 0x7d, 0x5e, 0xa6, 0xca, 0x05, 0x5c, 0x04, 0xa8, 0x51, 0xd8, 0x27, 0xc2, 0x50, 0xc9, 0xb0, - 0x1b, 0x54, 0x26, 0xe5, 0x02, 0xd7, 0x18, 0xb0, 0x1a, 0x51, 0x7f, 0xe4, 0x50, 0x95, 0x6c, 0x32, - 0xad, 0x92, 0x8b, 0xb4, 0x0c, 0xd6, 0xa8, 0x4c, 0x23, 0x94, 0x0b, 0xd7, 0xff, 0xea, 0x32, 0x2f, - 0x23, 0x89, 0xb0, 0x21, 0x28, 0x27, 0x39, 0xcf, 0x86, 0x56, 0x80, 0xa8, 0x48, 0xc0, 0x22, 0x10, - 0x13, 0x2a, 0x8b, 0x00, 0x03, 0x15, 0xac, 0x36, 0x82, 0xff, 0x7d, 0xfa, 0x6b, 0xf3, 0x3a, 0x5a, - 0xd9, 0xb9, 0x35, 0xa2, 0xdd, 0x04, 0x81, 0x42, 0xd1, 0x36, 0xd9, 0xcb, 0x96, 0xef, 0xa5, 0xb5, - 0x1b, 0x77, 0x3f, 0xe1, 0x2d, 0x2d, 0x7c, 0xd5, 0x26, 0xfa, 0x8e, 0x0d, 0xbf, 0x6e, 0xb1, 0xd7, - 0x63, 0xb6, 0xff, 0x07, 0xa0, 0xe7, 0x12, 0xe4, 0xa6, 0x5e, 0x00, 0x00 -}; diff --git a/wled00/html_pxmagic.h b/wled00/html_pxmagic.h deleted file mode 100644 index 6f6ba41c0..000000000 --- a/wled00/html_pxmagic.h +++ /dev/null @@ -1,549 +0,0 @@ -/* - * Binary array for the Web UI. - * gzip is used for smaller size and improved speeds. - * - * Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui - * to find out how to easily modify the web UI source! - */ - -// Autogenerated from wled00/data/pxmagic/pxmagic.htm, do not edit!! -const uint16_t PAGE_pxmagic_L = 8581; -const uint8_t PAGE_pxmagic[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xbd, 0x7d, 0xdb, 0x76, 0xdb, 0x46, - 0xb2, 0xe8, 0x3b, 0xbf, 0x02, 0x86, 0x3d, 0x0e, 0x61, 0x81, 0x20, 0xa9, 0x5b, 0x14, 0x50, 0x90, - 0x26, 0xb1, 0x9d, 0x89, 0xf7, 0xf2, 0x24, 0x39, 0xb1, 0x66, 0xf6, 0x64, 0x69, 0x6b, 0xc5, 0x4d, - 0xa2, 0x49, 0x22, 0x06, 0xd1, 0x1c, 0x00, 0xd4, 0x25, 0x14, 0x3e, 0xe8, 0x3c, 0x9f, 0x4f, 0xd8, - 0x3f, 0x76, 0xaa, 0xaa, 0xbb, 0x81, 0xc6, 0x85, 0xb2, 0x14, 0xef, 0xb5, 0x3d, 0x33, 0x02, 0xd0, - 0xe8, 0x4b, 0x75, 0xdd, 0xab, 0xba, 0xc0, 0x39, 0x7d, 0xf6, 0xe6, 0xa7, 0xd7, 0x17, 0xbf, 0xfe, - 0xfc, 0xd6, 0x5a, 0xe6, 0xab, 0xf8, 0xcc, 0x3a, 0xc5, 0x8b, 0x15, 0xb3, 0x64, 0x11, 0xd8, 0x3c, - 0xb1, 0xb1, 0x81, 0xb3, 0x10, 0x2e, 0x2b, 0x9e, 0x33, 0x6b, 0xb6, 0x64, 0x69, 0xc6, 0xf3, 0xc0, - 0xfe, 0xc7, 0xc5, 0xf7, 0x83, 0x13, 0x5b, 0x37, 0xf7, 0x12, 0xb6, 0xe2, 0x81, 0x7d, 0x1d, 0xf1, - 0x9b, 0xb5, 0x48, 0x73, 0xdb, 0x9a, 0x89, 0x24, 0xe7, 0x09, 0xf4, 0xbb, 0x89, 0xc2, 0x7c, 0x19, - 0x84, 0xfc, 0x3a, 0x9a, 0xf1, 0x01, 0x3d, 0xb8, 0x51, 0x12, 0xe5, 0x11, 0x8b, 0x07, 0xd9, 0x8c, - 0xc5, 0x3c, 0x18, 0x37, 0x27, 0x61, 0x9b, 0x7c, 0x29, 0x52, 0x63, 0x8a, 0xbf, 0xb2, 0xdf, 0x45, - 0xce, 0x92, 0x19, 0x76, 0xcc, 0xa3, 0x3c, 0xe6, 0x67, 0x3f, 0x47, 0xb7, 0x3c, 0xb6, 0xfe, 0xce, - 0x16, 0xd1, 0xcc, 0xba, 0x10, 0x22, 0x3e, 0x1d, 0xca, 0x76, 0xeb, 0x34, 0xcb, 0xef, 0xe0, 0xda, - 0xf3, 0x53, 0x21, 0xf2, 0xed, 0x60, 0x20, 0xae, 0x79, 0x1a, 0xb3, 0x3b, 0x3f, 0x5d, 0x4c, 0x59, - 0x7f, 0xe4, 0x5a, 0xea, 0xbf, 0xde, 0x91, 0x33, 0x19, 0x0c, 0xa6, 0x6c, 0xf6, 0x69, 0x91, 0x8a, - 0x4d, 0x12, 0xfa, 0xcf, 0xc7, 0xe3, 0x31, 0xb4, 0xe4, 0xfc, 0x36, 0xf7, 0x9f, 0x4f, 0xa7, 0x53, - 0xb8, 0x5f, 0xa4, 0xec, 0x6e, 0x10, 0xb2, 0xf4, 0x93, 0xff, 0x7c, 0x7f, 0x7f, 0x5f, 0x37, 0xac, - 0x78, 0x18, 0x6d, 0x56, 0xfe, 0xf3, 0x83, 0x83, 0x03, 0xdd, 0x14, 0x47, 0x8b, 0x25, 0x8c, 0xe2, - 0xf4, 0x0f, 0xa7, 0x8d, 0x37, 0x5c, 0x0f, 0x3c, 0x39, 0x3c, 0x38, 0xda, 0xd7, 0x6d, 0xe5, 0xd8, - 0xe9, 0xd7, 0xa3, 0x93, 0xa9, 0x6e, 0x55, 0xc3, 0x0f, 0x4f, 0x18, 0xb4, 0x64, 0x9b, 0xd9, 0x8c, - 0x67, 0x99, 0x1a, 0x3e, 0x3a, 0x38, 0x3c, 0x1c, 0xcd, 0x8c, 0x66, 0x3d, 0xc3, 0xd1, 0xe1, 0xc9, - 0x6c, 0x7f, 0x6e, 0xbc, 0x50, 0x93, 0x9c, 0xb0, 0xd9, 0x37, 0xfb, 0xc7, 0xd0, 0xce, 0xd3, 0x54, - 0xa4, 0x6a, 0x16, 0x76, 0x32, 0x62, 0x23, 0x56, 0x36, 0xea, 0x39, 0xb0, 0xe7, 0xfe, 0xb4, 0x6c, - 0x56, 0x33, 0xcc, 0xe7, 0x47, 0xdf, 0x1c, 0xe1, 0x2e, 0x6e, 0x58, 0x9a, 0x44, 0xc9, 0x42, 0xcd, - 0x11, 0xc2, 0x72, 0xa3, 0x7d, 0xa3, 0x59, 0xcf, 0xc2, 0x4f, 0x8e, 0xc2, 0xd1, 0xa1, 0xf1, 0x42, - 0xcf, 0x03, 0x10, 0x8e, 0x8e, 0x0b, 0xdf, 0xcf, 0x78, 0xcc, 0x67, 0x79, 0x24, 0x92, 0xad, 0x81, - 0xee, 0x6b, 0x96, 0xf6, 0xcd, 0xed, 0x3b, 0xc5, 0xab, 0xed, 0x1c, 0xc8, 0x3d, 0x98, 0xb3, 0x55, - 0x14, 0xdf, 0xf9, 0x3f, 0xf0, 0xf8, 0x9a, 0xe7, 0xd1, 0x8c, 0xb9, 0xff, 0xe4, 0x69, 0xc8, 0x12, - 0xe6, 0x66, 0x2c, 0xc9, 0x06, 0x19, 0x4f, 0xa3, 0xf9, 0x64, 0x2a, 0x6e, 0x07, 0x59, 0xf4, 0x07, - 0x2c, 0xe6, 0x4f, 0x45, 0x1a, 0xf2, 0x74, 0x00, 0x2d, 0x93, 0x15, 0x4b, 0x17, 0x51, 0xe2, 0x8f, - 0x26, 0x6b, 0x16, 0x86, 0xf8, 0x6e, 0x54, 0x4c, 0x45, 0x78, 0xb7, 0x0d, 0xa3, 0x6c, 0x8d, 0x1c, - 0x30, 0x8f, 0xf9, 0xed, 0xe4, 0xf7, 0x4d, 0x96, 0x47, 0xf3, 0xbb, 0x81, 0x62, 0x2d, 0x7f, 0x06, - 0x7f, 0x78, 0x3a, 0x61, 0x00, 0x44, 0x32, 0x88, 0x72, 0xbe, 0xca, 0x74, 0xd3, 0x2a, 0x4a, 0x06, - 0x4b, 0x4e, 0x7b, 0x19, 0x8f, 0x46, 0xd7, 0xcb, 0x49, 0x1b, 0xfa, 0xb2, 0xc1, 0x29, 0x66, 0x2c, - 0xb9, 0x66, 0xd9, 0x96, 0xd8, 0x1b, 0xfb, 0xff, 0xa5, 0x98, 0x8b, 0x74, 0xb5, 0x95, 0x30, 0x01, - 0x78, 0x79, 0x2e, 0x56, 0xfe, 0xfe, 0x68, 0x7d, 0x5b, 0x64, 0x2b, 0x16, 0xc7, 0x25, 0x50, 0xd3, - 0x58, 0xcc, 0x3e, 0x4d, 0x68, 0xe7, 0x37, 0x72, 0xb1, 0xc3, 0xd1, 0x48, 0x6f, 0x65, 0x7f, 0x7d, - 0x6b, 0x8d, 0xac, 0xa3, 0xf5, 0xed, 0x64, 0x26, 0x62, 0x91, 0xaa, 0x65, 0x91, 0x45, 0x1d, 0x39, - 0x04, 0x90, 0xc0, 0xfd, 0x31, 0x74, 0x83, 0xd5, 0x04, 0x00, 0x6d, 0xac, 0x5f, 0xa2, 0xc3, 0x02, - 0x69, 0x12, 0x16, 0x2e, 0x3d, 0xa9, 0x2f, 0x8a, 0xf3, 0x0c, 0x68, 0xe3, 0x6a, 0xcb, 0x05, 0xdb, - 0x52, 0x5b, 0xc8, 0x67, 0x22, 0x65, 0x48, 0x31, 0x3f, 0x11, 0x09, 0xaf, 0x2d, 0x6e, 0x50, 0xac, - 0x01, 0x42, 0x6d, 0x13, 0xc7, 0xa3, 0x51, 0xe1, 0x47, 0x59, 0x9f, 0xf9, 0x4b, 0x14, 0x40, 0x97, - 0xf9, 0x73, 0x31, 0xdb, 0x64, 0x70, 0x65, 0xc0, 0x0a, 0xd7, 0xdc, 0xd9, 0xb6, 0x26, 0x95, 0xfc, - 0xe4, 0x14, 0xde, 0x6a, 0xf0, 0x07, 0x4f, 0xc5, 0x56, 0xc3, 0xff, 0x2c, 0x5a, 0xa1, 0x42, 0x61, - 0x49, 0x8e, 0xaf, 0x24, 0x26, 0x1b, 0x78, 0x1d, 0xc3, 0xe6, 0xea, 0xdd, 0x72, 0xb1, 0xd6, 0x7d, - 0xe0, 0xb6, 0xd5, 0x01, 0xa9, 0xcf, 0xa2, 0xa4, 0x8e, 0xb0, 0x1a, 0x9f, 0x74, 0x30, 0xc4, 0x0e, - 0xd6, 0xc1, 0xee, 0x83, 0x30, 0x4a, 0x25, 0x8f, 0xfb, 0xb0, 0xaf, 0xcd, 0x2a, 0x91, 0x4b, 0x40, - 0x07, 0xb5, 0x00, 0xe8, 0xb9, 0x59, 0x1f, 0x57, 0xb1, 0x06, 0xd6, 0x21, 0x00, 0xe3, 0x00, 0x79, - 0x6e, 0xa5, 0x32, 0xf4, 0xbf, 0x3e, 0x3e, 0x59, 0x97, 0xdc, 0x4b, 0x2c, 0xe2, 0xa5, 0xe2, 0xa6, - 0xce, 0xb6, 0xb4, 0xc8, 0x4d, 0xca, 0xd6, 0x40, 0x11, 0xbc, 0xb4, 0x80, 0xc9, 0xd6, 0x0c, 0xb4, - 0xeb, 0x94, 0xe7, 0x37, 0x9c, 0x27, 0xe6, 0x64, 0xc0, 0x40, 0x23, 0x84, 0x06, 0xa1, 0xda, 0xd2, - 0x34, 0x53, 0x96, 0x45, 0x99, 0x84, 0xe8, 0x88, 0x00, 0x1a, 0x13, 0x40, 0x6b, 0x91, 0x45, 0xb4, - 0x83, 0x94, 0xc7, 0x0c, 0x69, 0x54, 0xc9, 0x11, 0xb2, 0xa0, 0x9e, 0x63, 0x30, 0xdf, 0x00, 0xfb, - 0x1a, 0x13, 0x11, 0xee, 0x3e, 0x37, 0x38, 0x66, 0x53, 0xde, 0x64, 0xfa, 0x3a, 0x0d, 0x8f, 0x1a, - 0x1c, 0xf4, 0x35, 0x88, 0x41, 0x8b, 0xeb, 0x8b, 0x28, 0x59, 0x6f, 0xf2, 0xcb, 0xfc, 0x6e, 0xcd, - 0x83, 0x64, 0xb3, 0x9a, 0xf2, 0xf4, 0xca, 0x35, 0x9a, 0xb0, 0xcf, 0x95, 0x2b, 0xf5, 0x8d, 0x8b, - 0x0f, 0x2c, 0xe5, 0xcc, 0x24, 0xb1, 0x06, 0x0a, 0x77, 0x3c, 0x51, 0xaa, 0x23, 0x65, 0xc0, 0x77, - 0x99, 0x7f, 0x44, 0x4d, 0xa5, 0x44, 0x0f, 0xcc, 0xb5, 0x0d, 0xbd, 0xef, 0xa8, 0x61, 0xfe, 0x18, - 0x50, 0x9b, 0x89, 0x38, 0x0a, 0xad, 0x8e, 0x3e, 0x62, 0x93, 0xc7, 0xc0, 0x5e, 0x7e, 0x7d, 0x0b, - 0x95, 0xad, 0xa8, 0xc9, 0xce, 0x21, 0xe0, 0xc7, 0xd8, 0x04, 0x8d, 0xb8, 0x52, 0x50, 0x1f, 0xa0, - 0x60, 0x29, 0x2d, 0x44, 0xf7, 0xb3, 0x4d, 0x9a, 0xc1, 0x84, 0x6b, 0x11, 0x11, 0xf3, 0x55, 0x58, - 0x06, 0x78, 0xaa, 0x65, 0x0b, 0x8f, 0x26, 0x1c, 0xe0, 0x5e, 0xd6, 0x7f, 0x52, 0x01, 0xd6, 0xe6, - 0xb0, 0xe8, 0x1e, 0x98, 0x2f, 0xef, 0x4b, 0x28, 0x53, 0xf0, 0x0e, 0xf8, 0x95, 0xb3, 0xad, 0x23, - 0xf1, 0x44, 0xf2, 0x9b, 0x75, 0x82, 0xfc, 0x62, 0x0e, 0x57, 0x0f, 0x21, 0xcf, 0x66, 0x69, 0xb4, - 0x26, 0x63, 0xa0, 0x36, 0x78, 0x62, 0x6c, 0x10, 0xef, 0x4d, 0x12, 0x59, 0x1d, 0xf8, 0x43, 0x6b, - 0xe4, 0xb4, 0x75, 0xb1, 0x89, 0xdb, 0x3a, 0x4c, 0xc4, 0x80, 0xf4, 0xbf, 0xd1, 0x83, 0xb4, 0xab, - 0x0f, 0x8e, 0xf9, 0x3c, 0x07, 0xf2, 0xb5, 0x74, 0x64, 0x83, 0x70, 0x13, 0xc4, 0x77, 0x69, 0x26, - 0x8e, 0x3b, 0xb4, 0x60, 0x1d, 0x0d, 0xd9, 0xbf, 0x37, 0xc0, 0x93, 0x6d, 0xac, 0x55, 0xca, 0x49, - 0x8b, 0x05, 0x01, 0x80, 0x48, 0x28, 0x4a, 0x46, 0x4e, 0x39, 0xad, 0x0b, 0xfa, 0x14, 0x0d, 0x63, - 0x6c, 0x5a, 0xa8, 0xfd, 0x51, 0x9b, 0xa3, 0x89, 0x08, 0xa0, 0x74, 0x41, 0xba, 0x06, 0x52, 0x26, - 0xb6, 0x2d, 0x31, 0x6d, 0x74, 0xb0, 0x54, 0x3f, 0xb6, 0x5e, 0x73, 0x06, 0x24, 0x9e, 0x71, 0x69, - 0x01, 0x60, 0x43, 0xd3, 0x4f, 0x11, 0x60, 0xa2, 0xd9, 0xbe, 0x12, 0x7f, 0xb4, 0x1a, 0x0d, 0x21, - 0x8a, 0x56, 0x6c, 0xa1, 0x5a, 0x15, 0x5d, 0x07, 0xa9, 0x82, 0xb7, 0xc5, 0xcb, 0x4d, 0x50, 0x48, - 0x65, 0xf8, 0x3e, 0x9b, 0xa3, 0x5d, 0xd3, 0xdc, 0x6a, 0xdb, 0x95, 0xaa, 0x61, 0x53, 0xa0, 0xe1, - 0x26, 0xe7, 0x13, 0xd4, 0xf0, 0xa5, 0x3a, 0xdb, 0xb3, 0x8e, 0x51, 0x9b, 0xa5, 0x15, 0x45, 0x72, - 0x80, 0x2d, 0x43, 0x6b, 0x0c, 0x2e, 0x61, 0xce, 0x72, 0xde, 0x1f, 0x1f, 0x1c, 0x85, 0x7c, 0xe1, - 0x4c, 0x24, 0x07, 0x1e, 0x57, 0x0c, 0x78, 0x5c, 0xe1, 0x10, 0xe7, 0xdc, 0xff, 0x3c, 0x9b, 0xa8, - 0xdd, 0x3c, 0xd0, 0x51, 0xed, 0x6e, 0xc0, 0xaf, 0x01, 0xfe, 0x8c, 0x70, 0x51, 0x78, 0x61, 0x2a, - 0xd6, 0x7f, 0xc0, 0x9d, 0xa9, 0x9b, 0x0c, 0xde, 0x0c, 0x59, 0xb6, 0xe4, 0x9d, 0xab, 0x3e, 0xa0, - 0x9f, 0xa4, 0x60, 0xec, 0xd2, 0x37, 0x6d, 0x46, 0xd6, 0x82, 0x86, 0xe6, 0xc8, 0x1a, 0x77, 0xb2, - 0x4f, 0xd3, 0x8e, 0x48, 0x54, 0x2a, 0xec, 0xc7, 0xb1, 0xe5, 0x1d, 0x65, 0x16, 0x67, 0x19, 0x1f, - 0x00, 0x23, 0x82, 0xee, 0xa9, 0xf6, 0x25, 0xad, 0xfe, 0xb6, 0xa1, 0xac, 0x3e, 0x2b, 0xcb, 0x83, - 0x5d, 0xd0, 0x2b, 0xc8, 0xba, 0x27, 0xa8, 0x96, 0x85, 0x1b, 0xb6, 0xa0, 0x95, 0x1f, 0xa1, 0xc8, - 0xc1, 0xca, 0xa2, 0x0e, 0x1b, 0x64, 0x40, 0x37, 0x18, 0xf1, 0x00, 0x17, 0xef, 0x82, 0x4a, 0x71, - 0x0d, 0x22, 0xaa, 0x45, 0x47, 0x8d, 0x45, 0x42, 0x6c, 0x65, 0x0e, 0x14, 0x42, 0x91, 0x2f, 0xd1, - 0x2c, 0x9b, 0x10, 0xf8, 0xbe, 0x96, 0x32, 0xf9, 0x3c, 0xc8, 0x97, 0x60, 0xe1, 0x5a, 0x70, 0x99, - 0xba, 0x46, 0xad, 0x7a, 0xfc, 0x19, 0xcb, 0xa5, 0xd0, 0xdc, 0x30, 0x77, 0x7f, 0x69, 0xda, 0x12, - 0xc5, 0x80, 0x00, 0x56, 0x76, 0x13, 0xe5, 0xb3, 0x65, 0x5b, 0x5b, 0x94, 0x2e, 0x52, 0x94, 0x90, - 0xde, 0x93, 0x76, 0xbc, 0xad, 0xc8, 0xa5, 0x13, 0x23, 0x67, 0x91, 0x96, 0x63, 0x5b, 0xa1, 0x40, - 0xcf, 0x21, 0x25, 0x41, 0x76, 0xd2, 0x44, 0x68, 0xcb, 0x76, 0x03, 0x46, 0x14, 0xcb, 0xd1, 0x44, - 0x29, 0x67, 0x29, 0x7c, 0xa8, 0xd5, 0xc9, 0x83, 0x18, 0x3d, 0xc1, 0x7c, 0x6b, 0x34, 0x1c, 0x1c, - 0x6a, 0x05, 0x21, 0xd7, 0xf5, 0x0e, 0xb3, 0x06, 0x4c, 0xfe, 0x94, 0x83, 0xee, 0xe0, 0x5d, 0xa0, - 0x55, 0x3a, 0x49, 0x13, 0xe5, 0xb0, 0x22, 0x0a, 0x19, 0x07, 0x84, 0xf3, 0x80, 0x24, 0x8b, 0x20, - 0x3c, 0xe8, 0x22, 0x14, 0x04, 0x5c, 0xf3, 0x0e, 0xe2, 0x34, 0x80, 0x92, 0xf6, 0x77, 0xb6, 0xe4, - 0xb3, 0x4f, 0x3c, 0xdc, 0x6b, 0xa0, 0x6d, 0xc7, 0xbe, 0xcd, 0xe8, 0x4a, 0x8e, 0x27, 0x27, 0xbc, - 0x35, 0x1a, 0xa3, 0xa9, 0x25, 0x0b, 0xc5, 0x8d, 0x8f, 0xb6, 0x1b, 0x15, 0xd0, 0xae, 0xf1, 0xdd, - 0xeb, 0x6b, 0x14, 0x55, 0x8a, 0x96, 0xee, 0x80, 0x67, 0xf8, 0xbf, 0xfa, 0x63, 0xe0, 0x0b, 0xa7, - 0x78, 0x9e, 0x0b, 0x96, 0xe5, 0x83, 0xca, 0xef, 0x2e, 0xd1, 0x39, 0x87, 0x40, 0x3e, 0x9c, 0x18, - 0x01, 0xd2, 0xc4, 0xb0, 0x10, 0x7f, 0x80, 0x66, 0x09, 0xf9, 0xad, 0xff, 0x0d, 0xfc, 0x2b, 0x3c, - 0x9a, 0x63, 0xfb, 0x39, 0x37, 0x5d, 0xe2, 0x1f, 0x83, 0x9e, 0x52, 0xc5, 0xa1, 0xb4, 0x51, 0x88, - 0xa2, 0xc5, 0x4f, 0xeb, 0xb3, 0xb6, 0xc6, 0xeb, 0xd8, 0xc3, 0xaf, 0xfd, 0x03, 0x72, 0x90, 0x05, - 0xb8, 0xd8, 0x51, 0x7e, 0x07, 0x7c, 0x76, 0x1d, 0x65, 0xd1, 0x34, 0x8a, 0xf1, 0x61, 0x19, 0x85, - 0x21, 0x4f, 0x14, 0x6c, 0x96, 0xbc, 0x0c, 0x28, 0xec, 0xd4, 0x8b, 0x93, 0x4f, 0xd4, 0x74, 0x0b, - 0x3a, 0x02, 0xba, 0x98, 0xe7, 0x68, 0x27, 0xd0, 0x91, 0xc7, 0x61, 0x1e, 0xf9, 0xdc, 0x34, 0x9f, - 0xa7, 0x62, 0xfc, 0x5d, 0x74, 0xae, 0xe7, 0x06, 0x1c, 0x3d, 0x8a, 0xa2, 0xfa, 0x5d, 0x63, 0x8c, - 0x90, 0xbf, 0x1c, 0xa0, 0x02, 0xf8, 0x5d, 0x43, 0x6a, 0xf1, 0xbd, 0x1e, 0x34, 0x58, 0xa7, 0x62, - 0x91, 0x22, 0x70, 0x6d, 0x01, 0x21, 0xf6, 0x3f, 0xac, 0xd8, 0xbf, 0x92, 0x0e, 0x33, 0x1c, 0x42, - 0xfe, 0x28, 0x3d, 0xc0, 0x1a, 0x05, 0x28, 0x3b, 0xf4, 0xaf, 0xfe, 0xc8, 0xa9, 0xda, 0x06, 0x02, - 0xb8, 0x03, 0x28, 0x88, 0x53, 0x37, 0xa8, 0x17, 0x25, 0x4b, 0x9e, 0x46, 0x79, 0x03, 0x67, 0x56, - 0x13, 0x4c, 0xc3, 0x73, 0x44, 0x85, 0xc4, 0x52, 0x54, 0x0f, 0x61, 0x04, 0xbc, 0xd3, 0x87, 0x30, - 0x99, 0x78, 0xcf, 0xad, 0xa3, 0x55, 0xee, 0xd7, 0xed, 0xc4, 0x75, 0x1d, 0xd9, 0x5f, 0xb0, 0x98, - 0x49, 0x8f, 0x5a, 0x53, 0x73, 0x21, 0x45, 0x85, 0x2f, 0x58, 0xaa, 0x4e, 0xc7, 0x46, 0x63, 0xb5, - 0x1c, 0xe6, 0xfc, 0x40, 0x50, 0xdb, 0x61, 0x68, 0x33, 0xd6, 0xed, 0x12, 0xc2, 0x2a, 0x2e, 0x19, - 0x59, 0xd2, 0x1a, 0xc8, 0xe9, 0x2c, 0x6f, 0x0a, 0xa4, 0x0c, 0xeb, 0x79, 0x0a, 0x1d, 0x08, 0x4b, - 0x27, 0xb6, 0xca, 0xb9, 0xfc, 0xa5, 0x91, 0xb0, 0xa8, 0x6c, 0x48, 0x65, 0xaa, 0x66, 0x0c, 0xf6, - 0x9c, 0x19, 0xb1, 0x25, 0xc1, 0x69, 0xce, 0x61, 0x2c, 0xd5, 0x72, 0x38, 0xd5, 0x60, 0x2b, 0x5a, - 0x2d, 0x1a, 0xc1, 0xa9, 0x31, 0xca, 0x9c, 0x4c, 0x39, 0xe7, 0x86, 0x8a, 0x6a, 0x83, 0x82, 0xb3, - 0xf9, 0x31, 0xa9, 0xbb, 0x65, 0x14, 0x87, 0xdb, 0xda, 0x18, 0xe8, 0x37, 0xdd, 0x80, 0x34, 0x24, - 0x1d, 0xae, 0xdf, 0xa8, 0x1e, 0xfc, 0xa0, 0xe6, 0xec, 0x0a, 0x52, 0xdb, 0xaa, 0xa3, 0x61, 0x24, - 0xcb, 0xcc, 0xcf, 0x48, 0xf9, 0x75, 0x9d, 0xc1, 0xd2, 0x63, 0xe2, 0x59, 0xe9, 0x39, 0x3c, 0xec, - 0xf5, 0x35, 0x23, 0xa2, 0x56, 0x00, 0x24, 0xf7, 0xab, 0x5c, 0xc2, 0x6e, 0x58, 0x4c, 0x0f, 0xe5, - 0xc1, 0xc8, 0xba, 0x9c, 0xad, 0x8d, 0x5f, 0xed, 0x05, 0xe8, 0x2e, 0xd9, 0x63, 0x58, 0xd7, 0xc8, - 0xd7, 0x3d, 0x57, 0x99, 0xe2, 0xa6, 0x69, 0xaa, 0xb9, 0x1c, 0x3b, 0xd8, 0x62, 0x87, 0xc6, 0x54, - 0x33, 0x3a, 0x75, 0x9f, 0x47, 0x2f, 0xe4, 0xc5, 0x82, 0x11, 0xb5, 0xdb, 0x31, 0x4e, 0x9d, 0x17, - 0x3f, 0x13, 0xf1, 0x0c, 0xac, 0xf1, 0x37, 0xa8, 0x43, 0x09, 0xc4, 0x56, 0xab, 0x12, 0x2d, 0x23, - 0xca, 0xd9, 0xaf, 0xc2, 0x1c, 0xb2, 0x8c, 0x9f, 0x09, 0x71, 0x60, 0xad, 0xc7, 0xbb, 0x94, 0x2c, - 0x81, 0x90, 0x8f, 0x60, 0xcd, 0xd6, 0x51, 0x62, 0x8d, 0x33, 0x4b, 0x2a, 0x23, 0xf0, 0x02, 0xe7, - 0x98, 0xf4, 0x87, 0xdd, 0x03, 0x05, 0x20, 0x98, 0xcd, 0x79, 0xf8, 0x0e, 0x83, 0xc3, 0x6d, 0x2d, - 0xc4, 0xc0, 0x68, 0xf9, 0x1a, 0xd4, 0x49, 0xb8, 0xdd, 0xc1, 0x0b, 0x55, 0x56, 0xdb, 0x31, 0xf3, - 0x79, 0x5a, 0x55, 0x66, 0x19, 0x4e, 0x59, 0xc7, 0x5e, 0xdb, 0xea, 0x49, 0xe0, 0xcb, 0xf8, 0xa7, - 0xd3, 0x3e, 0x37, 0xd2, 0xab, 0x7f, 0x45, 0xfe, 0x63, 0x56, 0xdf, 0xcc, 0xda, 0x7d, 0x0d, 0xe8, - 0xdd, 0x6a, 0x35, 0xa9, 0xc3, 0xdb, 0x8a, 0x0b, 0x31, 0x87, 0x57, 0xa5, 0xed, 0x28, 0x69, 0xd7, - 0xcd, 0x83, 0x5a, 0x5c, 0x75, 0x86, 0xcd, 0x7d, 0x30, 0xd3, 0xd6, 0x0c, 0xc9, 0xaa, 0x64, 0x77, - 0xf1, 0xd7, 0x4f, 0xfc, 0x6e, 0x9e, 0x32, 0x40, 0x83, 0x85, 0xd8, 0xdf, 0xe6, 0x62, 0xdb, 0x8a, - 0x7d, 0x0f, 0x8e, 0x47, 0x18, 0xfb, 0xd6, 0x3a, 0x97, 0x36, 0xa4, 0x36, 0x40, 0x59, 0xdf, 0x71, - 0xbd, 0xef, 0x1c, 0x76, 0xfb, 0x2e, 0xd9, 0x1e, 0xfd, 0x65, 0xab, 0xdd, 0xa1, 0xb1, 0xe9, 0x0e, - 0xd1, 0x6d, 0xcc, 0xbb, 0xdd, 0xa8, 0x91, 0x53, 0x7c, 0x53, 0x1b, 0xb8, 0xab, 0x57, 0xd1, 0x3b, - 0x1d, 0xca, 0x63, 0x1c, 0xeb, 0x74, 0xa8, 0xce, 0x9e, 0xd0, 0xa7, 0x82, 0x4b, 0x18, 0x5d, 0x5b, - 0x33, 0x10, 0xfe, 0x2c, 0xb0, 0x4b, 0x67, 0xd2, 0x6e, 0xb7, 0x83, 0x1c, 0x61, 0x2b, 0xce, 0x6d, - 0xf5, 0xa2, 0x30, 0xb0, 0xf1, 0xee, 0x6f, 0x1c, 0x3a, 0xc3, 0x1a, 0xb6, 0x95, 0x08, 0xe2, 0x32, - 0xb8, 0xaf, 0x0f, 0x95, 0xc4, 0xc4, 0x91, 0xd9, 0xf5, 0x42, 0x37, 0x92, 0xc5, 0xb2, 0xad, 0xde, - 0xed, 0x2a, 0x4e, 0xb0, 0x4f, 0x9e, 0xaf, 0xfd, 0xe1, 0xf0, 0xe6, 0xe6, 0xc6, 0xbb, 0x39, 0xf0, - 0x44, 0xba, 0x18, 0x82, 0xdd, 0x1a, 0x0d, 0x61, 0x80, 0x6d, 0xc9, 0xa3, 0x2e, 0x1b, 0x1a, 0x6c, - 0x4b, 0x4a, 0x5b, 0x60, 0x8f, 0x0f, 0xe0, 0xa1, 0x87, 0xe7, 0x62, 0xdf, 0x89, 0xdb, 0xc0, 0x96, - 0x16, 0x11, 0x34, 0x33, 0x34, 0x9f, 0x9d, 0x52, 0x82, 0x64, 0xe7, 0xb0, 0xe1, 0xd9, 0x29, 0xce, - 0x8b, 0x58, 0x00, 0x20, 0x15, 0xa8, 0x3d, 0x05, 0x16, 0xf0, 0x57, 0x6b, 0xe3, 0xc8, 0x36, 0xb6, - 0x65, 0xec, 0x8d, 0x92, 0x28, 0x16, 0x6c, 0x1e, 0xe0, 0x16, 0x59, 0x8e, 0xc7, 0x6b, 0xf6, 0xd9, - 0x0f, 0xea, 0x0e, 0xb0, 0x4c, 0xef, 0xa1, 0x1f, 0xb9, 0xf7, 0x16, 0x65, 0xf6, 0x6c, 0xb4, 0x29, - 0x80, 0x22, 0x3a, 0x89, 0x2b, 0x07, 0x59, 0x88, 0xc4, 0xea, 0x29, 0xe5, 0xff, 0xde, 0x00, 0x1f, - 0x87, 0xdd, 0xa0, 0x3d, 0x0c, 0x88, 0x04, 0xe2, 0x67, 0xe0, 0x38, 0x9e, 0x5b, 0x3f, 0xc2, 0x43, - 0x13, 0x8c, 0x5e, 0x1b, 0x8e, 0x0a, 0x06, 0x79, 0x07, 0x33, 0x6f, 0xa0, 0xf9, 0x47, 0x7e, 0x63, - 0xc9, 0x89, 0xba, 0x40, 0x92, 0x97, 0x9e, 0x89, 0xa2, 0x47, 0x21, 0xcd, 0x7c, 0x6b, 0xa6, 0xa4, - 0x6c, 0x9c, 0xcc, 0xd8, 0xc8, 0x9a, 0xa1, 0xc7, 0x9e, 0xc0, 0x5e, 0xe4, 0x4d, 0xb5, 0x0f, 0x95, - 0xc2, 0x92, 0xb0, 0xeb, 0x6e, 0x04, 0x7e, 0xf9, 0xd0, 0x33, 0xe0, 0x15, 0x94, 0x11, 0x95, 0x9b, - 0x3a, 0xfb, 0x20, 0xc7, 0xe2, 0x41, 0xab, 0x88, 0x66, 0x80, 0x1c, 0xf9, 0xb6, 0xd1, 0x0d, 0x18, - 0x04, 0xe6, 0xa0, 0x33, 0xcf, 0xc0, 0xbe, 0xfc, 0x6a, 0x4e, 0xff, 0xbe, 0xba, 0xb2, 0x55, 0x06, - 0x8f, 0xc3, 0x52, 0xfa, 0x0e, 0xc0, 0x7e, 0x97, 0xc0, 0x9e, 0xa2, 0x70, 0xc3, 0x62, 0x6b, 0xe7, - 0x7c, 0xfb, 0xc6, 0x7c, 0x23, 0xd7, 0xaa, 0xa6, 0x3c, 0x7b, 0x87, 0x31, 0xd8, 0xce, 0x71, 0x07, - 0xb6, 0x65, 0x0c, 0x3b, 0xaa, 0x8d, 0xec, 0xfd, 0x82, 0x09, 0x0e, 0x63, 0xe8, 0x50, 0x02, 0xd5, - 0xa4, 0xd1, 0x23, 0x08, 0xd2, 0xdb, 0x41, 0x11, 0x93, 0x20, 0xe0, 0x8d, 0x00, 0xff, 0xd8, 0x67, - 0x3f, 0xd1, 0x75, 0x07, 0x39, 0x54, 0x27, 0xa9, 0x16, 0xf4, 0xc3, 0x9f, 0x26, 0x46, 0x4f, 0x61, - 0xe1, 0xf7, 0x4c, 0x24, 0xdd, 0xc8, 0xff, 0xcf, 0xf7, 0x6f, 0xdf, 0x58, 0xff, 0xf1, 0xe1, 0xa7, - 0x1f, 0x77, 0x62, 0x70, 0xc9, 0x00, 0x53, 0x3f, 0x88, 0x15, 0xb7, 0xbe, 0xcd, 0x40, 0xcf, 0xa3, - 0x49, 0xdb, 0xd9, 0x17, 0x5c, 0xbd, 0xd8, 0x3e, 0x7b, 0xfd, 0x8f, 0x5f, 0xde, 0x3f, 0x80, 0xd5, - 0xde, 0x6e, 0xec, 0x82, 0x00, 0x58, 0x7a, 0xd3, 0xa4, 0x62, 0x03, 0xdb, 0x74, 0x4e, 0x76, 0x08, - 0x47, 0xaf, 0x5b, 0x92, 0xe5, 0x99, 0xbe, 0x7d, 0xf6, 0x86, 0xae, 0x9f, 0xd7, 0x26, 0xaa, 0xbf, - 0x44, 0xbd, 0x7e, 0xe8, 0x56, 0x25, 0x9f, 0xd3, 0x24, 0x3d, 0x02, 0x60, 0x93, 0x44, 0xff, 0xde, - 0xf0, 0x77, 0x80, 0xe5, 0x7f, 0xd0, 0x9d, 0xf5, 0x2e, 0xfc, 0x3c, 0x14, 0xe5, 0x20, 0x09, 0x47, - 0xf5, 0xf8, 0x25, 0x90, 0xcc, 0x53, 0x08, 0xb5, 0xc2, 0xf8, 0xee, 0x47, 0x52, 0x6e, 0xdf, 0xab, - 0xa7, 0x4e, 0xf5, 0xd6, 0x86, 0xa8, 0x36, 0x58, 0xd9, 0xab, 0x5a, 0xd3, 0x2e, 0xdd, 0xf6, 0x38, - 0xd5, 0xd6, 0x7b, 0x9c, 0x6e, 0x33, 0x29, 0x9b, 0xf1, 0xc5, 0x0a, 0xf3, 0xd5, 0x36, 0x48, 0x00, - 0xdd, 0x99, 0x98, 0xed, 0xd5, 0x05, 0xaa, 0xec, 0x4b, 0x0a, 0xae, 0x1a, 0xd9, 0x64, 0x5d, 0x30, - 0x6e, 0x00, 0x04, 0x1b, 0x28, 0x6b, 0x37, 0x3e, 0x06, 0xc8, 0xa8, 0xa1, 0x34, 0x79, 0xc7, 0x30, - 0x48, 0xaf, 0x37, 0xb2, 0x1e, 0xa9, 0x36, 0x1e, 0x67, 0x74, 0xa6, 0x14, 0x7e, 0x25, 0xe0, 0xe5, - 0xd8, 0x67, 0xdf, 0x95, 0xf7, 0x15, 0x69, 0xcc, 0x99, 0x8c, 0x13, 0x1b, 0xbb, 0x41, 0x35, 0x4a, - 0xd8, 0x6a, 0xb2, 0x19, 0x73, 0xd2, 0xd6, 0xcd, 0xe7, 0xde, 0x2a, 0x4a, 0x68, 0xcb, 0xe0, 0x31, - 0x82, 0x6e, 0x3d, 0x3a, 0x2a, 0x6d, 0xd6, 0x78, 0xff, 0xc4, 0x2e, 0x69, 0x66, 0xe4, 0x7f, 0xed, - 0x4e, 0x06, 0xe9, 0xd5, 0x27, 0xfe, 0x27, 0xce, 0x51, 0x0e, 0x6f, 0x1d, 0xaa, 0x59, 0xf2, 0x7c, - 0xa9, 0xb6, 0x56, 0x03, 0x69, 0xbd, 0xa7, 0xf1, 0x4e, 0x37, 0x36, 0x4b, 0x37, 0x1f, 0x14, 0xd7, - 0xb7, 0xfa, 0xbe, 0x42, 0xa6, 0xec, 0xa9, 0x66, 0x92, 0xa9, 0xc2, 0xe6, 0xee, 0x28, 0x93, 0x38, - 0x15, 0xb7, 0x76, 0x59, 0xf3, 0x53, 0x4e, 0x49, 0xb8, 0x34, 0x56, 0x00, 0xfd, 0xbd, 0x66, 0x49, - 0x7d, 0xba, 0x12, 0x67, 0xc0, 0x1a, 0xf0, 0x12, 0x37, 0x57, 0x32, 0xe7, 0x13, 0x64, 0x97, 0x36, - 0x43, 0xbe, 0xe7, 0x1a, 0xd0, 0x96, 0xe4, 0x14, 0x92, 0xc0, 0x9e, 0x2e, 0xaa, 0x26, 0x8b, 0xda, - 0xbe, 0x6c, 0x6f, 0xad, 0x15, 0x68, 0x8b, 0xed, 0x75, 0x1f, 0xdc, 0x69, 0xaf, 0xb5, 0xd5, 0x27, - 0xef, 0x54, 0x1e, 0x20, 0xea, 0x4d, 0xfe, 0x42, 0x4f, 0xff, 0x13, 0xfb, 0x33, 0xe7, 0xa5, 0xad, - 0xd5, 0x16, 0x7a, 0x14, 0xfd, 0x7a, 0xad, 0x5d, 0x75, 0xdb, 0xae, 0xda, 0x52, 0x0f, 0x18, 0xb0, - 0xc7, 0x69, 0x05, 0x52, 0x45, 0x60, 0xa2, 0xf1, 0xd2, 0xad, 0xa6, 0x65, 0x95, 0x41, 0xb9, 0x53, - 0x39, 0x80, 0xf6, 0xa8, 0x6e, 0xb5, 0xa4, 0x1d, 0xdb, 0x7f, 0xc6, 0x6c, 0x48, 0xd5, 0x07, 0x2e, - 0x39, 0x5d, 0x1f, 0x06, 0x41, 0x79, 0xe4, 0x72, 0x84, 0xf4, 0xc7, 0xd5, 0x7d, 0xaf, 0x0b, 0x88, - 0x6e, 0xfc, 0x19, 0x62, 0xf6, 0xc5, 0xd8, 0x93, 0x21, 0x21, 0x5a, 0x3b, 0xbc, 0xee, 0xf0, 0xe2, - 0xeb, 0xd0, 0xab, 0x21, 0x96, 0x34, 0x71, 0xf2, 0x5e, 0x01, 0x7f, 0xf8, 0x30, 0x02, 0x77, 0xb9, - 0x20, 0x9b, 0x54, 0xa9, 0x89, 0x37, 0xea, 0xae, 0xae, 0xd3, 0x3b, 0x55, 0x7a, 0xef, 0x01, 0xfc, - 0x96, 0x13, 0x12, 0x8c, 0xd5, 0x93, 0x36, 0x62, 0xde, 0x91, 0xe1, 0xbb, 0x23, 0xa7, 0xcb, 0x3b, - 0x50, 0xf4, 0x4a, 0xe1, 0x67, 0x39, 0x5f, 0x63, 0x3f, 0xf0, 0xcf, 0x69, 0x95, 0x95, 0x08, 0xe5, - 0x22, 0x3c, 0x8d, 0x66, 0x76, 0xa7, 0xa9, 0x31, 0x34, 0xb8, 0x7d, 0x96, 0xf1, 0x59, 0x83, 0x84, - 0x8f, 0xe1, 0xaa, 0x5e, 0x4b, 0xa3, 0x45, 0x72, 0xba, 0x8b, 0xf2, 0xfe, 0x11, 0x88, 0x79, 0x88, - 0x74, 0xc6, 0xa4, 0x95, 0xfa, 0x8a, 0x1a, 0xc8, 0xd9, 0xaf, 0x7c, 0x15, 0x13, 0x37, 0xbd, 0x27, - 0x21, 0xe7, 0x11, 0xb8, 0xe9, 0x59, 0x9f, 0xc5, 0x11, 0x72, 0x7b, 0x5b, 0xf1, 0x76, 0x33, 0x7d, - 0xaf, 0x8d, 0x5c, 0xca, 0xbe, 0xec, 0xe2, 0x7c, 0xca, 0x29, 0x81, 0x1b, 0xbe, 0x14, 0x22, 0xe3, - 0x18, 0x1d, 0xe0, 0xb3, 0xe9, 0x1f, 0x61, 0x8d, 0xdf, 0x99, 0xf5, 0x1a, 0x9b, 0xad, 0x7c, 0xc9, - 0x72, 0x08, 0xf1, 0xe3, 0x18, 0x50, 0x03, 0x8b, 0xce, 0x38, 0xb4, 0x70, 0xac, 0x53, 0x4d, 0x45, - 0xb2, 0x38, 0x33, 0x40, 0xb4, 0xd6, 0x58, 0xd4, 0x9a, 0x61, 0xee, 0x83, 0x5e, 0xf5, 0x00, 0x47, - 0xd4, 0x57, 0x66, 0x09, 0xa0, 0x5d, 0x4e, 0x5b, 0x57, 0xc6, 0x04, 0x8a, 0xa2, 0x91, 0x7a, 0x40, - 0xf2, 0xa8, 0x5b, 0xad, 0x1a, 0x54, 0x71, 0xaa, 0xfd, 0x67, 0x3c, 0x48, 0x85, 0x8a, 0x3f, 0xe1, - 0x46, 0x12, 0xe0, 0xa0, 0x21, 0x08, 0xf9, 0x59, 0x33, 0x20, 0xeb, 0x29, 0xa8, 0x55, 0x2f, 0x02, - 0x5b, 0xdf, 0x3f, 0x39, 0x20, 0xeb, 0x35, 0xbc, 0xcd, 0xcd, 0x1a, 0xd3, 0xab, 0x10, 0x18, 0xd0, - 0xf5, 0x21, 0x5f, 0x52, 0x62, 0xb5, 0x27, 0x0d, 0x61, 0x66, 0xc9, 0x81, 0x3c, 0xb4, 0x72, 0x61, - 0x9d, 0x32, 0xa9, 0xea, 0x63, 0x1e, 0xbe, 0x0d, 0x23, 0xd0, 0xb4, 0xcb, 0x94, 0xcf, 0xcb, 0x14, - 0xd0, 0x25, 0xb6, 0x0f, 0xa2, 0xf5, 0xd5, 0x90, 0xd3, 0xcb, 0x5e, 0xce, 0xd2, 0x05, 0x56, 0x46, - 0xff, 0x36, 0x8d, 0x59, 0xf2, 0x89, 0x2c, 0x9f, 0xa4, 0x24, 0xc6, 0x80, 0x25, 0x59, 0x61, 0x61, - 0x76, 0x66, 0x01, 0x63, 0xc8, 0x95, 0x5a, 0xd4, 0x6d, 0xc4, 0x70, 0x88, 0x6a, 0x52, 0x45, 0xaa, - 0xc8, 0xa1, 0xf4, 0xfe, 0xaa, 0x06, 0x4d, 0x98, 0x5d, 0x2a, 0x7d, 0xad, 0x22, 0x2e, 0x35, 0xe0, - 0x3d, 0x52, 0x01, 0xda, 0xdf, 0xa4, 0x6c, 0x01, 0x06, 0x21, 0xb4, 0xf0, 0x05, 0xa0, 0x74, 0x1e, - 0xc5, 0xdc, 0x5a, 0xf2, 0x94, 0x23, 0x70, 0xb3, 0x38, 0x9a, 0x7d, 0x42, 0x1c, 0x64, 0x1a, 0xe3, - 0xf4, 0xfa, 0x74, 0xb8, 0x6e, 0xea, 0x4f, 0x6c, 0xd7, 0x0c, 0x98, 0x89, 0x4d, 0x3a, 0x53, 0x4e, - 0x80, 0xbe, 0xef, 0xb1, 0xd9, 0x8c, 0xaf, 0x73, 0x45, 0xdb, 0xe1, 0xef, 0xeb, 0x85, 0xab, 0xef, - 0xb8, 0xbe, 0x5d, 0x27, 0xfa, 0x6e, 0x11, 0xcd, 0x77, 0x9a, 0xa6, 0x27, 0x24, 0x74, 0x24, 0xcf, - 0x62, 0xde, 0x90, 0x0e, 0x03, 0x14, 0xa8, 0xf2, 0xc1, 0x2e, 0xd5, 0xaf, 0x7e, 0x26, 0x27, 0x3b, - 0x4f, 0xca, 0x04, 0xe1, 0x99, 0xa5, 0x6f, 0x61, 0x51, 0xd9, 0xa9, 0x25, 0x38, 0x43, 0x4c, 0x29, - 0x6a, 0x75, 0x4e, 0xa9, 0x9d, 0x94, 0x63, 0x96, 0xef, 0x41, 0xc3, 0x2a, 0x9d, 0x23, 0x33, 0x01, - 0x8e, 0x2e, 0x90, 0x9c, 0x50, 0xd7, 0x79, 0x19, 0x5e, 0xd5, 0x5a, 0x24, 0x59, 0xe5, 0x52, 0xa9, - 0x27, 0xe8, 0x12, 0x8a, 0x24, 0xbe, 0xc3, 0x36, 0x79, 0x87, 0x1a, 0xcc, 0x2a, 0xff, 0x9d, 0x0e, - 0xf5, 0x4c, 0x75, 0xc4, 0xa8, 0x63, 0x11, 0x7b, 0xa7, 0xd0, 0x37, 0xac, 0xfe, 0x2e, 0xe4, 0x75, - 0xe3, 0xee, 0xb5, 0x58, 0xdf, 0x5d, 0x88, 0xd7, 0x71, 0xb4, 0x9e, 0x0a, 0x96, 0x82, 0xe0, 0xf5, - 0x2c, 0x6c, 0x42, 0x0e, 0x2a, 0x1b, 0x3b, 0x90, 0xd9, 0x36, 0x6a, 0x4f, 0xa4, 0xd9, 0x07, 0x76, - 0x0d, 0x38, 0xc4, 0xbf, 0x4f, 0x9b, 0xbc, 0xf7, 0x98, 0x4d, 0xbd, 0x11, 0x37, 0x09, 0xca, 0xa8, - 0xca, 0x31, 0x82, 0xc8, 0xa8, 0x86, 0xf6, 0x4e, 0x7a, 0x3b, 0x14, 0xaa, 0x14, 0x85, 0x68, 0xb5, - 0x89, 0x29, 0xf3, 0xfc, 0x68, 0xa7, 0xeb, 0x61, 0x06, 0x6e, 0x80, 0xdb, 0xd3, 0xc8, 0x50, 0xeb, - 0x94, 0xf0, 0xea, 0x86, 0x07, 0xd8, 0xb8, 0xe3, 0xd2, 0x3b, 0x95, 0xe5, 0xe4, 0x67, 0xa8, 0x00, - 0x2b, 0x95, 0x97, 0x81, 0xce, 0x5b, 0x44, 0xf9, 0x72, 0x33, 0xf5, 0x66, 0x62, 0x35, 0x54, 0xdf, - 0x64, 0x0c, 0xe9, 0x53, 0x0c, 0xfa, 0x12, 0x03, 0x3f, 0xc4, 0xb0, 0xad, 0xa6, 0x16, 0xec, 0x59, - 0x7f, 0xa3, 0x41, 0xd6, 0xcb, 0x19, 0x30, 0xc4, 0xc4, 0x6a, 0x7e, 0xba, 0x21, 0xf5, 0x21, 0xca, - 0x93, 0x5a, 0xb3, 0xa1, 0xf8, 0x1a, 0xa5, 0x23, 0x14, 0x09, 0xd5, 0x7b, 0xa8, 0x03, 0xb5, 0x4a, - 0x94, 0x86, 0xea, 0xb4, 0x40, 0xba, 0x0e, 0x67, 0x3d, 0x18, 0x9c, 0xe5, 0x56, 0x18, 0x84, 0x62, - 0xb6, 0xc1, 0xec, 0x82, 0x0b, 0x06, 0x97, 0xad, 0xb2, 0x20, 0xe1, 0x37, 0xd6, 0x3f, 0x7e, 0x79, - 0xff, 0x81, 0xb3, 0x74, 0xb6, 0xfc, 0x99, 0xda, 0xfa, 0x37, 0x51, 0x12, 0x8a, 0x1b, 0x2f, 0x16, - 0x33, 0xf2, 0xfc, 0xbc, 0x8c, 0x5e, 0x3a, 0x2e, 0x26, 0xbf, 0x03, 0x39, 0xce, 0x83, 0xfd, 0xf5, - 0xed, 0x65, 0x62, 0x3b, 0xe7, 0xcd, 0x06, 0xbf, 0x39, 0x1c, 0x87, 0x9d, 0x77, 0x35, 0xfa, 0xe0, - 0x06, 0xd1, 0x7f, 0x6c, 0x77, 0x9d, 0x8a, 0x5c, 0x00, 0xd9, 0xa5, 0x2e, 0xf5, 0xed, 0x20, 0x08, - 0x9a, 0x23, 0x74, 0x97, 0x73, 0x69, 0x7c, 0x6c, 0x7f, 0x57, 0x07, 0xac, 0x23, 0xb1, 0xd0, 0xde, - 0xfc, 0x06, 0x1b, 0x0b, 0x3e, 0xbe, 0xd8, 0xea, 0x17, 0xc5, 0x70, 0xf8, 0x62, 0x8b, 0x0b, 0x17, - 0x1f, 0x27, 0x12, 0x1f, 0x3a, 0x9d, 0x1f, 0x80, 0x86, 0x47, 0xac, 0xf4, 0xab, 0x04, 0xbf, 0x33, - 0xd1, 0xb7, 0x9e, 0xb4, 0xa7, 0xf8, 0xe8, 0x96, 0x6d, 0x2c, 0x0c, 0xdf, 0x62, 0x3d, 0xe3, 0xfb, - 0x08, 0x1c, 0x3a, 0xa0, 0x49, 0x1f, 0x62, 0x42, 0xca, 0x8c, 0xb8, 0x2c, 0xbb, 0x4b, 0x66, 0x7d, - 0x27, 0x38, 0xdb, 0x3e, 0x08, 0x43, 0x35, 0x73, 0xf1, 0xd1, 0x65, 0x37, 0x2c, 0xc2, 0xd2, 0x53, - 0x99, 0x38, 0xea, 0x3b, 0xaa, 0x41, 0xba, 0x02, 0x7d, 0xa7, 0x5c, 0x96, 0xec, 0x56, 0xdf, 0x29, - 0xa8, 0x56, 0xc6, 0xc2, 0x8c, 0x2b, 0x8a, 0x3d, 0xae, 0x13, 0x5c, 0x5e, 0xb9, 0xf4, 0xcc, 0x93, - 0x90, 0x9e, 0xb7, 0xc5, 0x64, 0xbe, 0x49, 0xe8, 0x98, 0xcd, 0xd2, 0xbb, 0xe3, 0xce, 0x36, 0xe5, - 0xf9, 0x26, 0x4d, 0xac, 0x10, 0xe9, 0xf5, 0x56, 0x36, 0x7f, 0x77, 0xf7, 0x2e, 0x84, 0x57, 0x45, - 0xd9, 0xbd, 0xb1, 0xda, 0x56, 0xe2, 0xca, 0x40, 0x52, 0xe9, 0x0d, 0x38, 0x13, 0xee, 0x91, 0x74, - 0xc8, 0x8b, 0xa7, 0xdc, 0xbb, 0xbe, 0x5d, 0x3a, 0x06, 0xb6, 0x5b, 0xdf, 0xac, 0x53, 0x10, 0x7e, - 0xac, 0x72, 0x31, 0x54, 0x02, 0x31, 0x20, 0x51, 0xaf, 0xb3, 0xa5, 0x6e, 0x3e, 0x2f, 0xaa, 0xe5, - 0xca, 0x10, 0xc4, 0x71, 0xd5, 0xdb, 0xdc, 0x78, 0x6b, 0x78, 0xe1, 0xe5, 0xfb, 0xc4, 0x78, 0x2f, - 0xa9, 0xe9, 0xb2, 0x40, 0x93, 0x63, 0xcf, 0x1e, 0xae, 0x49, 0x3b, 0x64, 0x1e, 0xe5, 0xac, 0xdd, - 0xcc, 0x7c, 0x45, 0x4d, 0x93, 0x3c, 0xbd, 0x53, 0xdb, 0x16, 0x81, 0xa4, 0xc5, 0x9c, 0x43, 0xd0, - 0xde, 0x67, 0x8e, 0x1b, 0xab, 0x06, 0x41, 0xa3, 0x81, 0x38, 0x51, 0xf0, 0xd3, 0xf4, 0x77, 0x70, - 0x10, 0xbc, 0x4f, 0xfc, 0x2e, 0xeb, 0xc7, 0x8e, 0x9b, 0x06, 0x91, 0x07, 0x6c, 0x0c, 0xa2, 0xdc, - 0xe7, 0xc1, 0x99, 0x2d, 0xe8, 0x2d, 0xb0, 0x34, 0x2a, 0x30, 0x31, 0xb7, 0xe2, 0x4b, 0x7e, 0xf5, - 0xf2, 0xe5, 0x33, 0xbc, 0x78, 0x7a, 0xf7, 0x2f, 0x5f, 0xd2, 0x63, 0xa2, 0xaf, 0x5e, 0x06, 0x3a, - 0x24, 0xcf, 0xfe, 0x13, 0xd4, 0x46, 0x3f, 0x71, 0x1c, 0x77, 0x46, 0x53, 0x26, 0xe1, 0x03, 0x13, - 0x3e, 0x38, 0x1f, 0xc8, 0x53, 0xe2, 0xdc, 0xdf, 0xaf, 0xf1, 0xc3, 0xb5, 0x77, 0x80, 0x95, 0xc8, - 0x5b, 0x8b, 0x75, 0xdf, 0x71, 0xf6, 0xc6, 0x6e, 0x18, 0x6c, 0xd7, 0x19, 0x70, 0x91, 0x5f, 0xbe, - 0x9c, 0x39, 0x6e, 0xe2, 0x27, 0xae, 0x48, 0xfc, 0x67, 0x23, 0x57, 0xf8, 0xcf, 0xc6, 0xae, 0x9e, - 0xd6, 0x87, 0xae, 0x7e, 0xea, 0x02, 0x41, 0xfc, 0x6f, 0xd3, 0x94, 0xdd, 0x79, 0xf3, 0x54, 0xac, - 0xfa, 0xdb, 0x98, 0x27, 0x8b, 0x7c, 0xe9, 0xa7, 0x9e, 0xbc, 0x29, 0x5c, 0x64, 0xff, 0xf1, 0xe8, - 0x15, 0x77, 0x5c, 0xa3, 0x72, 0xe2, 0x31, 0x23, 0x72, 0xc0, 0x1e, 0x5f, 0x83, 0x6f, 0xe0, 0x8f, - 0x5c, 0xe0, 0x64, 0x3c, 0xd3, 0x75, 0x57, 0xc1, 0x76, 0xc5, 0xf3, 0xa5, 0x08, 0x7d, 0xfb, 0xe7, - 0x9f, 0x3e, 0x5c, 0xd8, 0x2e, 0xaa, 0x36, 0x1f, 0xcf, 0x13, 0x00, 0x4b, 0x69, 0x94, 0x80, 0xbf, - 0x74, 0xd7, 0x0f, 0x9d, 0xc2, 0x20, 0x1a, 0xaf, 0x11, 0x2d, 0x73, 0x57, 0xc0, 0x19, 0xaa, 0x6e, - 0x09, 0x79, 0x47, 0xbe, 0xe4, 0x8a, 0x80, 0x13, 0xc0, 0x16, 0x69, 0xd8, 0xfe, 0xc7, 0x9f, 0xd5, - 0x3e, 0x2d, 0xfb, 0xc5, 0x36, 0x29, 0xc0, 0x56, 0x01, 0x5e, 0x2c, 0x35, 0x10, 0xad, 0xd1, 0xdd, - 0x47, 0xfc, 0xce, 0x09, 0xe7, 0x04, 0x51, 0x92, 0x63, 0xec, 0xb7, 0x54, 0xf7, 0x04, 0x3d, 0xb1, - 0x26, 0x49, 0x32, 0x96, 0x6f, 0xd9, 0x7b, 0xdc, 0xb5, 0xe9, 0xac, 0xdd, 0x76, 0x8a, 0xe6, 0x10, - 0xf3, 0x55, 0x43, 0x1a, 0x22, 0xf0, 0x6f, 0x52, 0xec, 0x91, 0x07, 0x80, 0xf6, 0x24, 0x38, 0xe2, - 0x07, 0x5a, 0xfe, 0x9e, 0xc6, 0xc0, 0xa8, 0x1f, 0x44, 0x30, 0x9a, 0x64, 0x4b, 0x71, 0xd3, 0x77, - 0x94, 0xba, 0x8b, 0x41, 0x4e, 0x57, 0x6c, 0xdd, 0x97, 0x8b, 0x02, 0x2b, 0x25, 0x74, 0x7a, 0x28, - 0x56, 0x51, 0xc6, 0xfb, 0xfd, 0xdc, 0x8d, 0x51, 0x6b, 0xc1, 0xbc, 0x17, 0xd1, 0x8a, 0x8b, 0x4d, - 0xde, 0xaf, 0x54, 0x59, 0x85, 0xda, 0xa4, 0x29, 0x0f, 0x5a, 0x40, 0x12, 0x2d, 0x0f, 0x71, 0x4d, - 0x1e, 0x04, 0x0a, 0x48, 0x2c, 0x99, 0x37, 0xef, 0x60, 0x5e, 0x71, 0x99, 0xa3, 0x34, 0xe0, 0xc5, - 0xe0, 0x5e, 0x7a, 0x44, 0xae, 0xe5, 0x5e, 0x8d, 0x6f, 0xe3, 0x8a, 0x6f, 0x53, 0xbd, 0x0c, 0xf8, - 0x01, 0xd1, 0x22, 0x01, 0x9c, 0x35, 0xf9, 0x38, 0x02, 0x45, 0x09, 0x92, 0xf3, 0x08, 0xee, 0x49, - 0x6b, 0xdc, 0x93, 0x37, 0xb8, 0x67, 0x66, 0x70, 0x4f, 0xa2, 0xb9, 0x27, 0xd7, 0xdc, 0x93, 0x54, - 0xdc, 0x23, 0x0f, 0x74, 0x81, 0x77, 0x00, 0xea, 0xff, 0x0d, 0xee, 0x01, 0xa4, 0x42, 0xc0, 0x74, - 0xb7, 0x05, 0xe5, 0x09, 0x72, 0x92, 0xbc, 0x12, 0x7b, 0x7b, 0xb0, 0x65, 0x67, 0x22, 0x21, 0x54, - 0x84, 0xf5, 0xa0, 0x0b, 0x6a, 0xa5, 0xfc, 0xbc, 0x93, 0xb2, 0xb2, 0x6f, 0xa5, 0x85, 0x3d, 0x08, - 0xb7, 0x93, 0x3e, 0xbd, 0x5a, 0x46, 0x21, 0x47, 0x63, 0xe3, 0xa9, 0x75, 0xea, 0xad, 0xb0, 0xa0, - 0xe3, 0xab, 0x87, 0x26, 0x17, 0x2b, 0xbb, 0x55, 0x4a, 0xa3, 0xc1, 0x9e, 0x18, 0x28, 0x9e, 0xe3, - 0x52, 0xc1, 0xd0, 0x06, 0x2e, 0x2f, 0xd5, 0xb4, 0x0a, 0x7b, 0x1d, 0xcd, 0xb1, 0xbb, 0x38, 0x8e, - 0xa3, 0x2a, 0x6f, 0x70, 0x5c, 0x16, 0x5c, 0xda, 0x18, 0x4a, 0xd9, 0x2e, 0x5c, 0xf0, 0x2f, 0x04, - 0x53, 0xf0, 0x17, 0x03, 0xa9, 0x2b, 0xe4, 0x4f, 0x43, 0x1b, 0x2b, 0x23, 0x83, 0x46, 0x81, 0xac, - 0x88, 0x7b, 0x99, 0xb8, 0xec, 0x2a, 0xc8, 0x3d, 0xf0, 0x46, 0x23, 0x00, 0xc3, 0x03, 0x08, 0x94, - 0x8d, 0x04, 0x22, 0xa2, 0x6b, 0x90, 0x57, 0x56, 0x0d, 0x20, 0xb6, 0xc1, 0x94, 0x64, 0x5e, 0x94, - 0xcc, 0xe2, 0x4d, 0x08, 0x5b, 0x64, 0xc8, 0x62, 0x71, 0x70, 0x49, 0x9f, 0x0d, 0xfa, 0x76, 0x23, - 0x36, 0xb7, 0x5d, 0x69, 0x8e, 0x6c, 0xbb, 0x70, 0x55, 0x0f, 0x19, 0x8c, 0x97, 0x2f, 0x54, 0x8c, - 0x5e, 0x5c, 0x4d, 0xc4, 0xcb, 0x97, 0xc8, 0xdd, 0x9b, 0x6c, 0xd9, 0xf7, 0x3c, 0x4f, 0x90, 0x9c, - 0xf6, 0x25, 0x9c, 0xbc, 0x00, 0xbc, 0xf7, 0xe5, 0x04, 0x5c, 0x8d, 0x04, 0x97, 0x42, 0x23, 0xb5, - 0x00, 0x8f, 0x02, 0x9c, 0x08, 0x20, 0x3c, 0x10, 0x19, 0x40, 0x03, 0x6f, 0xe4, 0x87, 0x8b, 0xbf, - 0xbf, 0x0f, 0x6c, 0xdb, 0x05, 0xb9, 0x13, 0xe9, 0x5b, 0x06, 0x68, 0x6b, 0x0c, 0x4f, 0x70, 0xca, - 0x52, 0xb1, 0xa0, 0x1a, 0xf8, 0x89, 0xb2, 0x03, 0xc0, 0x5d, 0x09, 0xe0, 0xde, 0xc3, 0x9a, 0xfb, - 0x24, 0x7c, 0x8d, 0xd5, 0x65, 0xb4, 0x47, 0xe7, 0x11, 0x5c, 0xa8, 0x78, 0xa1, 0xc9, 0x0c, 0x95, - 0x57, 0xd3, 0x76, 0x24, 0xca, 0xa3, 0x32, 0xc7, 0x64, 0x05, 0x5d, 0x21, 0x00, 0x66, 0xc8, 0xf0, - 0x39, 0x28, 0xd9, 0x8c, 0xc4, 0xaf, 0x7c, 0x35, 0x99, 0xfc, 0xed, 0x60, 0x99, 0x96, 0x42, 0x1c, - 0x66, 0x58, 0xfb, 0x63, 0xbb, 0x75, 0x6b, 0x9e, 0xa1, 0x60, 0xf3, 0x85, 0x1f, 0x17, 0x6d, 0x9b, - 0x5e, 0x91, 0x54, 0x9e, 0xc6, 0xbd, 0xe1, 0x73, 0xb6, 0x89, 0x73, 0x4d, 0xb9, 0x91, 0xab, 0x3f, - 0x3d, 0x70, 0xcb, 0xef, 0x11, 0x80, 0x8a, 0x31, 0x50, 0x31, 0x22, 0x5e, 0x02, 0x7e, 0x19, 0xc1, - 0x3c, 0x25, 0x45, 0x63, 0x45, 0xd1, 0x28, 0x04, 0x22, 0x24, 0x7e, 0xee, 0x92, 0x85, 0x07, 0x33, - 0x9b, 0x61, 0x29, 0x1b, 0x93, 0x8f, 0xbf, 0xfa, 0x19, 0x3d, 0xff, 0xea, 0x0b, 0x83, 0xe6, 0xf9, - 0xfd, 0x7d, 0x09, 0x06, 0xaa, 0x06, 0xe5, 0x21, 0x29, 0x08, 0xd8, 0x20, 0xd1, 0x20, 0x88, 0x41, - 0x86, 0x5c, 0xe0, 0xb8, 0xbc, 0xce, 0x06, 0x51, 0x93, 0x0d, 0x32, 0x35, 0x87, 0x50, 0x73, 0xc4, - 0x7a, 0x86, 0xa8, 0x70, 0xd3, 0x8a, 0x33, 0x66, 0x26, 0x67, 0x64, 0xae, 0x00, 0x3b, 0xe2, 0xe1, - 0x79, 0x25, 0x28, 0x12, 0x4f, 0x9e, 0x61, 0xc6, 0x6e, 0xd5, 0xa2, 0x0e, 0x31, 0x23, 0x77, 0x04, - 0x7a, 0x3b, 0x05, 0x44, 0xcc, 0xbc, 0xb2, 0x1a, 0x00, 0x1c, 0x89, 0x44, 0xf9, 0xd1, 0xb1, 0xcb, - 0xd4, 0x5d, 0x04, 0xec, 0xaa, 0xda, 0x5e, 0x45, 0x67, 0x47, 0xe3, 0xfd, 0xf3, 0x03, 0x7f, 0x8c, - 0xc0, 0x83, 0x73, 0x0d, 0x4e, 0x48, 0xf1, 0x14, 0xa6, 0x7b, 0x56, 0xe7, 0x3a, 0x60, 0xb6, 0xa7, - 0xfa, 0xd4, 0xa5, 0x95, 0xd4, 0x49, 0x22, 0xc3, 0x01, 0xd5, 0x79, 0x26, 0x90, 0x7d, 0x4a, 0xe9, - 0x18, 0x1c, 0x2c, 0x53, 0x3c, 0x4e, 0xe5, 0x6c, 0xa3, 0x40, 0x53, 0x5e, 0xc3, 0x70, 0xb7, 0x1b, - 0x76, 0x36, 0x69, 0x0a, 0x1f, 0xf5, 0x9f, 0xb0, 0x8e, 0xa8, 0x42, 0x6a, 0x8b, 0xbe, 0xb1, 0xaf, - 0x5c, 0x0a, 0xa4, 0xdb, 0xd5, 0x5b, 0x62, 0xa7, 0xd6, 0x3d, 0xe9, 0xe3, 0x02, 0x64, 0x66, 0xb4, - 0xb5, 0x51, 0x55, 0x97, 0x12, 0x15, 0xb6, 0xa3, 0x66, 0xcb, 0xd2, 0x59, 0x00, 0x9a, 0xa6, 0x29, - 0xbe, 0x0b, 0x95, 0x06, 0xea, 0x14, 0x5f, 0xb5, 0x79, 0xd4, 0xaf, 0x3c, 0xbb, 0x1c, 0x5d, 0x75, - 0xf9, 0xe7, 0x5a, 0xb1, 0x77, 0xf9, 0xe6, 0xaa, 0x0e, 0xa3, 0x43, 0x82, 0x0d, 0x31, 0x2f, 0xf3, - 0x3e, 0xa8, 0xe8, 0x8d, 0xd6, 0x5a, 0x0e, 0x09, 0xfd, 0x10, 0xad, 0x4d, 0x81, 0xfd, 0xf2, 0x73, - 0x90, 0x7d, 0x4f, 0xf6, 0x90, 0x6e, 0x02, 0x3c, 0x03, 0x41, 0x40, 0xee, 0xb4, 0xff, 0x5e, 0xd1, - 0x09, 0x5c, 0x94, 0xad, 0xfc, 0x7a, 0xdd, 0x8f, 0xdc, 0x69, 0x1a, 0x81, 0x87, 0x0b, 0x52, 0x3a, - 0x73, 0x23, 0x3f, 0x2c, 0x02, 0xbd, 0x0e, 0x98, 0x50, 0x65, 0x57, 0x4d, 0x62, 0xa2, 0x45, 0xa9, - 0xbb, 0x21, 0x66, 0x10, 0xe6, 0x6e, 0xa5, 0x0f, 0x2d, 0xe7, 0x44, 0x4d, 0xb3, 0x2d, 0x27, 0x06, - 0xbb, 0x41, 0x66, 0x54, 0x31, 0xdd, 0x2a, 0xc0, 0x64, 0x1a, 0xcb, 0x65, 0xe1, 0x4e, 0x3f, 0x71, - 0x1b, 0x1e, 0x8a, 0x39, 0x2d, 0x5a, 0x78, 0x25, 0x38, 0x2b, 0x30, 0x46, 0xa6, 0xae, 0x8e, 0xbe, - 0x40, 0x51, 0x6b, 0x4a, 0x97, 0xc7, 0xd9, 0x8f, 0x23, 0x79, 0x87, 0x0d, 0x37, 0xf5, 0xb6, 0x41, - 0x3d, 0xc5, 0x00, 0xac, 0x1d, 0x9c, 0xa9, 0x37, 0x99, 0xf1, 0x46, 0x9d, 0x8d, 0x95, 0xef, 0x44, - 0x07, 0xdb, 0xe8, 0x77, 0xf1, 0x8e, 0x60, 0x91, 0x74, 0x5d, 0xa4, 0x74, 0x5d, 0x5a, 0xa0, 0x95, - 0x57, 0x0a, 0x49, 0xea, 0x34, 0x84, 0xbf, 0xcd, 0x7a, 0x39, 0x89, 0xe4, 0xf7, 0x40, 0x8e, 0x37, - 0xa0, 0xd9, 0x26, 0xd1, 0xbc, 0x6f, 0x30, 0x56, 0xea, 0x68, 0xe3, 0xa8, 0xb6, 0x6b, 0xbb, 0x1c, - 0xa2, 0xe0, 0x38, 0xe3, 0x9d, 0xa1, 0x47, 0x8a, 0xb8, 0xd0, 0xe1, 0xc6, 0x34, 0x16, 0x53, 0xd4, - 0x43, 0x72, 0x7e, 0xc0, 0x5f, 0xff, 0x32, 0xb9, 0x72, 0x23, 0x80, 0x13, 0x5c, 0x61, 0x3f, 0xf1, - 0xf0, 0x52, 0x54, 0xd6, 0xb7, 0x5c, 0x00, 0xe4, 0x5d, 0xeb, 0x63, 0x73, 0xee, 0x32, 0x23, 0x45, - 0x87, 0x26, 0x2b, 0xcc, 0x26, 0xe5, 0x42, 0xc4, 0xde, 0x35, 0x07, 0x0a, 0xc5, 0x38, 0xc9, 0x90, - 0xad, 0xa3, 0x21, 0x46, 0xe2, 0x43, 0x89, 0xcd, 0x73, 0xb6, 0x12, 0x1b, 0xfc, 0x35, 0x91, 0xbd, - 0xcc, 0xed, 0xf2, 0x8a, 0x73, 0x60, 0xca, 0xad, 0xaa, 0x21, 0xf6, 0x43, 0x57, 0x0e, 0xf2, 0x57, - 0xda, 0x3a, 0xce, 0xb4, 0xcb, 0x0b, 0x28, 0x79, 0x36, 0xf3, 0xc4, 0x27, 0x47, 0xa9, 0xb7, 0x6b, - 0x11, 0xe1, 0x61, 0x01, 0xb2, 0x5b, 0x58, 0xb2, 0xdb, 0xa4, 0x91, 0x9e, 0x50, 0x8c, 0xbe, 0xc1, - 0x4c, 0xc5, 0x1a, 0xff, 0x2c, 0x83, 0x31, 0x3f, 0x78, 0x15, 0xbb, 0x8b, 0x60, 0x55, 0x45, 0x25, - 0x18, 0xfa, 0x54, 0xda, 0x31, 0x69, 0xc9, 0x2a, 0xaf, 0x64, 0x35, 0x23, 0xb9, 0x12, 0x28, 0xab, - 0x31, 0x88, 0x54, 0x64, 0xc8, 0x6a, 0x82, 0x41, 0xb8, 0x21, 0x7c, 0xa2, 0x14, 0x3e, 0xd9, 0xb3, - 0x80, 0xb0, 0x00, 0x3c, 0x28, 0x56, 0x58, 0x2f, 0xb6, 0xf9, 0xde, 0xb8, 0xf8, 0x38, 0xd9, 0x48, - 0x43, 0x0d, 0x8d, 0xb3, 0xe2, 0xfe, 0xc5, 0xb6, 0x1d, 0x1f, 0x7c, 0x74, 0xdc, 0xb5, 0xec, 0x03, - 0x5e, 0x83, 0xb9, 0x35, 0xd9, 0x58, 0x57, 0x02, 0xa9, 0xbb, 0x4d, 0x40, 0xce, 0x21, 0x76, 0x1e, - 0xa1, 0xef, 0xd4, 0xe5, 0x91, 0x2f, 0xb4, 0xe4, 0xdf, 0x05, 0x1b, 0xda, 0x7e, 0xe9, 0x9c, 0x5e, - 0x82, 0x81, 0xb8, 0x82, 0xc0, 0x47, 0x79, 0xa4, 0xf7, 0xe4, 0xf4, 0xd4, 0xb4, 0x83, 0x40, 0x27, - 0x4d, 0xe2, 0x1e, 0x00, 0xbe, 0xc4, 0xf2, 0x39, 0x57, 0xd6, 0xc5, 0x5d, 0x55, 0xae, 0xa9, 0x70, - 0xce, 0xed, 0xe7, 0xb6, 0x6f, 0x0f, 0x87, 0x36, 0x6d, 0xb3, 0xf8, 0xaf, 0x04, 0x77, 0x0c, 0x7e, - 0xe2, 0x44, 0x9b, 0xe2, 0x3b, 0xef, 0x77, 0x11, 0x25, 0x7d, 0xfb, 0xbf, 0x50, 0x5a, 0x14, 0xfd, - 0x20, 0x62, 0x52, 0x5f, 0x71, 0xb4, 0x74, 0xac, 0xbb, 0x76, 0x97, 0x4f, 0xd1, 0x2f, 0xa5, 0x66, - 0x29, 0xe9, 0xc2, 0xeb, 0x49, 0x1e, 0xd3, 0x4c, 0x54, 0x4e, 0x5f, 0x87, 0x9d, 0x30, 0xfc, 0xc4, - 0x0e, 0x25, 0x62, 0x54, 0x1d, 0x75, 0xaa, 0x12, 0xed, 0x3a, 0x76, 0x68, 0x12, 0xed, 0x42, 0x02, - 0x53, 0xc9, 0x0f, 0xfb, 0x6a, 0xba, 0xc4, 0x2c, 0xb5, 0x40, 0x8e, 0x2a, 0x23, 0xcb, 0x0c, 0xe3, - 0xca, 0xf2, 0x09, 0xed, 0x87, 0xf4, 0xa3, 0x42, 0xed, 0x47, 0xad, 0x3a, 0x81, 0xef, 0x50, 0x3f, - 0xda, 0x7b, 0x72, 0x37, 0xd5, 0x7c, 0x40, 0x83, 0x75, 0xf5, 0xb4, 0x02, 0x57, 0x05, 0xc3, 0x60, - 0x06, 0xe4, 0x66, 0x31, 0x15, 0x6a, 0x80, 0xc8, 0x94, 0x0d, 0xb2, 0x6e, 0xc2, 0xbd, 0x0b, 0xe2, - 0xf3, 0xd4, 0x5f, 0xba, 0x73, 0xb8, 0xce, 0xfc, 0x85, 0x7b, 0x0d, 0xd7, 0x8d, 0x7f, 0xe7, 0xde, - 0xc0, 0x75, 0xed, 0xcf, 0xdd, 0xf7, 0xc1, 0xdf, 0x59, 0xbe, 0xf4, 0xe6, 0xb1, 0x00, 0x3f, 0xa0, - 0xbf, 0x19, 0xdc, 0x39, 0xc3, 0x7d, 0xc7, 0x7d, 0x5b, 0x6b, 0x5d, 0x0f, 0xe6, 0xd4, 0x3a, 0x0d, - 0x0e, 0x4f, 0x5e, 0x5d, 0xbb, 0xbf, 0xe3, 0xe5, 0xc6, 0xbd, 0x0d, 0xa6, 0xa7, 0xc1, 0xd7, 0xc7, - 0x27, 0xe7, 0xe3, 0x43, 0x7f, 0x7c, 0xe2, 0x7e, 0x40, 0xd1, 0xdd, 0xce, 0xf2, 0x5b, 0xff, 0xa2, - 0x08, 0x24, 0x59, 0x5f, 0x93, 0x3c, 0xf6, 0xef, 0xdc, 0xb9, 0x33, 0xb9, 0xc0, 0x2f, 0x90, 0x6f, - 0x94, 0xac, 0xba, 0x23, 0xf8, 0x0f, 0x35, 0x4b, 0x56, 0x7f, 0x13, 0x5c, 0x60, 0xde, 0x91, 0xde, - 0xa2, 0x6e, 0xed, 0xeb, 0xf7, 0x84, 0x85, 0x52, 0xb0, 0x5f, 0xb8, 0x38, 0xfd, 0xa7, 0xc6, 0xf4, - 0x53, 0xf7, 0x77, 0x67, 0xf2, 0x09, 0xed, 0x4e, 0xfc, 0x41, 0x1e, 0x21, 0x3c, 0x1f, 0xd1, 0x3f, - 0xdb, 0x95, 0xad, 0xbf, 0x00, 0x6a, 0x69, 0x46, 0xea, 0x09, 0x02, 0xd3, 0xc7, 0x24, 0x08, 0x0f, - 0x46, 0x13, 0x7e, 0x7a, 0x33, 0xe1, 0x10, 0x1b, 0xeb, 0xb6, 0x1c, 0xda, 0xf2, 0xd3, 0xeb, 0x49, - 0x0e, 0x6d, 0x5b, 0x6c, 0x00, 0x7b, 0xf5, 0xea, 0x7a, 0x0f, 0x34, 0x01, 0x48, 0x1a, 0x6c, 0x1a, - 0x9c, 0x73, 0xbc, 0x70, 0xf0, 0x29, 0xf2, 0xc1, 0x7b, 0x08, 0x06, 0xf8, 0xe0, 0x2d, 0x90, 0xdf, - 0x56, 0xeb, 0xa1, 0xfe, 0x03, 0x47, 0x5f, 0x9c, 0x05, 0x23, 0xf8, 0x7b, 0x7a, 0xf7, 0xf2, 0x65, - 0x44, 0xb7, 0xd1, 0xe9, 0xfc, 0xfe, 0xfe, 0x19, 0xbc, 0xc9, 0xb1, 0x8d, 0x9f, 0xce, 0xf5, 0xe4, - 0xf1, 0x79, 0xf4, 0xea, 0x6e, 0x4f, 0xf8, 0x1c, 0xfe, 0xe6, 0x13, 0xe0, 0x23, 0x54, 0xd8, 0x74, - 0x34, 0xde, 0x7f, 0x73, 0x79, 0xf8, 0x0a, 0x8c, 0x00, 0x5d, 0xf6, 0xc6, 0xfa, 0x66, 0x5f, 0xdf, - 0x1c, 0x5c, 0x51, 0xaa, 0x77, 0x9b, 0x82, 0x36, 0x59, 0x00, 0x7b, 0x4d, 0x91, 0xb3, 0x96, 0xfc, - 0xf6, 0x42, 0xfc, 0xb2, 0x98, 0x82, 0x5a, 0x9a, 0x7c, 0x90, 0xea, 0x07, 0xec, 0x8c, 0x89, 0x9a, - 0x8f, 0x29, 0xbc, 0x45, 0x55, 0xe6, 0x82, 0xe4, 0x87, 0xf4, 0x77, 0x55, 0x38, 0x1f, 0x4d, 0x44, - 0x41, 0xc4, 0xe1, 0x1e, 0x9e, 0xc0, 0x7f, 0x9d, 0x02, 0xad, 0x97, 0xa5, 0x26, 0xd2, 0x7b, 0x44, - 0x54, 0xe3, 0x87, 0x2b, 0xc4, 0x6f, 0xc1, 0x18, 0x46, 0xe2, 0xd9, 0xed, 0x27, 0xae, 0x51, 0x3f, - 0xa6, 0x7f, 0x76, 0xd9, 0xde, 0x98, 0x93, 0xf2, 0x4f, 0x60, 0xae, 0xf6, 0xf6, 0x0f, 0xdd, 0x30, - 0xc8, 0xe0, 0x82, 0xa4, 0x13, 0x60, 0x7b, 0x6e, 0xf7, 0xec, 0xf5, 0xad, 0xf5, 0x6d, 0x1a, 0xb1, - 0xd8, 0xae, 0xc1, 0xac, 0x57, 0x46, 0x23, 0x7b, 0x5e, 0x9e, 0xd6, 0xfb, 0xe6, 0x52, 0x68, 0xcf, - 0xbf, 0xc5, 0x4f, 0xed, 0x02, 0x5b, 0x7e, 0x65, 0xa7, 0x1b, 0xbf, 0x03, 0x11, 0x42, 0x68, 0x03, - 0x7b, 0x15, 0x85, 0x61, 0xcc, 0xf5, 0xcc, 0x17, 0xf0, 0x0e, 0x7c, 0xa9, 0x99, 0x1b, 0x3a, 0x85, - 0x2c, 0xbb, 0xea, 0xe7, 0xa0, 0x82, 0xa0, 0xb7, 0x3d, 0xb6, 0xfd, 0x28, 0xf8, 0x30, 0x99, 0x02, - 0x8b, 0x7d, 0x9a, 0x50, 0xcb, 0x3e, 0xb6, 0xd0, 0xd7, 0xb6, 0xfd, 0x0f, 0x8e, 0xf9, 0xe2, 0x00, - 0x5f, 0x50, 0xa1, 0x22, 0xbc, 0x28, 0xa4, 0xde, 0xad, 0x78, 0x15, 0xed, 0x4b, 0x29, 0xac, 0xcc, - 0x41, 0x73, 0x54, 0x3e, 0x82, 0x1d, 0x22, 0x73, 0x53, 0x69, 0x42, 0x9a, 0x85, 0x4b, 0xc6, 0x00, - 0x36, 0x04, 0xef, 0x60, 0x84, 0x21, 0x2d, 0x3a, 0x52, 0x19, 0x1a, 0x49, 0x5e, 0x85, 0x6a, 0xc0, - 0x7e, 0x68, 0x09, 0x81, 0xd9, 0xf8, 0xb3, 0x20, 0x60, 0xe0, 0xca, 0x07, 0x62, 0x32, 0x0e, 0x82, - 0x64, 0x90, 0x9f, 0x67, 0x92, 0x5a, 0xcc, 0xf1, 0xd5, 0x1d, 0xd8, 0x0c, 0xf0, 0x13, 0xc0, 0x19, - 0x13, 0x05, 0x43, 0x37, 0x5e, 0x27, 0x31, 0xc6, 0x94, 0x43, 0x93, 0x59, 0xd6, 0xee, 0x71, 0xfa, - 0x2d, 0x0e, 0xcf, 0x2a, 0x48, 0x0d, 0x1e, 0x05, 0x93, 0x4c, 0xb3, 0x2b, 0xdd, 0xad, 0x35, 0x65, - 0xd6, 0x4c, 0xc2, 0x9b, 0x65, 0x26, 0x9d, 0xda, 0x56, 0x56, 0x64, 0x94, 0xb0, 0x61, 0x9c, 0xc8, - 0xce, 0xb3, 0x73, 0x51, 0x65, 0x58, 0x9e, 0x53, 0x86, 0xc5, 0xcb, 0xc5, 0x7b, 0x71, 0xc3, 0xd3, - 0xd7, 0x80, 0xfd, 0xbe, 0x83, 0x3f, 0x5c, 0x76, 0x21, 0x7e, 0x00, 0xb2, 0xec, 0x1f, 0x1d, 0xb9, - 0xea, 0x7f, 0x46, 0x2b, 0x81, 0x67, 0x1e, 0x5f, 0x68, 0xf1, 0x00, 0x34, 0x1f, 0xc0, 0x12, 0x60, - 0x59, 0x79, 0x73, 0x05, 0x47, 0x6d, 0x1a, 0xa2, 0x54, 0xf3, 0xed, 0xb0, 0xef, 0x39, 0xc3, 0x85, - 0x6b, 0xbf, 0x18, 0xbf, 0x18, 0x43, 0xa7, 0x49, 0x69, 0x8f, 0x31, 0x47, 0x84, 0xb9, 0x53, 0xe4, - 0xa0, 0xa1, 0xb7, 0xdd, 0x2f, 0x86, 0x0b, 0x47, 0x5b, 0xed, 0x92, 0xda, 0xdc, 0x1d, 0x1f, 0x3b, - 0x7a, 0x77, 0x20, 0xb2, 0x39, 0x88, 0x6c, 0x02, 0x22, 0xcb, 0x4c, 0x06, 0xa8, 0x43, 0xad, 0x02, - 0xc4, 0x52, 0xec, 0xf6, 0xfa, 0xfc, 0xf4, 0x74, 0x7c, 0x7c, 0x9f, 0x9f, 0x9e, 0x9e, 0xdc, 0x27, - 0x88, 0x88, 0x0f, 0xe4, 0x84, 0xf4, 0x71, 0x66, 0x2f, 0xa3, 0xb4, 0xc2, 0xe0, 0xd8, 0xd8, 0xac, - 0xe4, 0x57, 0x6d, 0x57, 0x81, 0xa5, 0x80, 0x87, 0xca, 0xfc, 0x95, 0xc1, 0x4a, 0x14, 0x72, 0xe6, - 0x92, 0xe6, 0x09, 0xb8, 0xac, 0xe0, 0xe9, 0xe5, 0xd5, 0x2c, 0x35, 0x45, 0x8b, 0x1e, 0x58, 0xe9, - 0x7f, 0x85, 0x2a, 0x88, 0x7a, 0x5b, 0xd2, 0x90, 0x3a, 0xd9, 0xe8, 0x44, 0xc8, 0x14, 0x00, 0xcc, - 0xad, 0x43, 0xff, 0x7c, 0x52, 0x06, 0xb5, 0xa8, 0xe7, 0x5f, 0xe3, 0x67, 0x48, 0x20, 0x80, 0xf6, - 0x3e, 0x84, 0xb0, 0xdb, 0x1b, 0xd2, 0x3c, 0x2c, 0xfc, 0x1e, 0x0b, 0x5b, 0x60, 0xaa, 0xf8, 0x8e, - 0xbc, 0x23, 0x0d, 0x2d, 0xf3, 0xc8, 0xdb, 0xfd, 0xb0, 0x12, 0x22, 0x5f, 0xc2, 0x8e, 0xff, 0xcf, - 0x86, 0xe1, 0xf7, 0x54, 0x81, 0xbd, 0x84, 0xa9, 0xc1, 0x07, 0x6e, 0xbc, 0x7e, 0x9b, 0xb0, 0x69, - 0x8c, 0x89, 0x85, 0x71, 0x69, 0x36, 0x12, 0x32, 0x1b, 0x26, 0xb2, 0x6b, 0x4e, 0x13, 0x6d, 0x4b, - 0x2e, 0x86, 0x0e, 0x13, 0xca, 0xc5, 0xf9, 0x1d, 0x5b, 0xc5, 0xa0, 0x11, 0x7c, 0xe9, 0x3c, 0x51, - 0x13, 0xde, 0x61, 0x93, 0x81, 0x9d, 0x50, 0x1d, 0x79, 0x93, 0xcb, 0xae, 0xe8, 0x86, 0xf2, 0x0b, - 0xea, 0x6e, 0xa2, 0xb4, 0x4a, 0xa2, 0xb4, 0x0a, 0x25, 0xdf, 0x7d, 0x16, 0xd8, 0xe0, 0x7d, 0x03, - 0xb1, 0x28, 0x12, 0x19, 0xea, 0x24, 0xbd, 0x7c, 0x6b, 0x6a, 0x16, 0x80, 0xa3, 0xd9, 0xf9, 0x76, - 0x80, 0x40, 0x51, 0x77, 0xba, 0x31, 0xbb, 0x13, 0x94, 0x38, 0x00, 0xd1, 0x3a, 0x04, 0x96, 0x8d, - 0xe4, 0xbc, 0xf9, 0x6d, 0x6e, 0x17, 0xfa, 0xb8, 0x0a, 0x83, 0x8b, 0xef, 0x30, 0xd2, 0xb8, 0xe4, - 0x57, 0x2a, 0xb4, 0x60, 0x94, 0xa4, 0xec, 0x8a, 0x88, 0x29, 0x3b, 0xdf, 0xa2, 0x31, 0x03, 0xf2, - 0x46, 0xf2, 0x60, 0x0f, 0xfc, 0x65, 0x4f, 0xef, 0x1f, 0x5d, 0xe6, 0xbc, 0xf0, 0x5e, 0x6c, 0xb3, - 0xe2, 0x23, 0x34, 0x53, 0x7d, 0x0c, 0xc4, 0x33, 0x38, 0x6f, 0xca, 0xaf, 0xc1, 0x08, 0x54, 0xf3, - 0xc6, 0x06, 0x8b, 0x12, 0x92, 0x1f, 0xf0, 0xfc, 0xd4, 0x67, 0x10, 0x9d, 0x8e, 0x5f, 0xed, 0x23, - 0x80, 0x4e, 0xe7, 0xaf, 0xfc, 0x78, 0xa1, 0xd3, 0xf5, 0x33, 0x8e, 0x73, 0x41, 0x8f, 0x96, 0x0c, - 0x80, 0xbf, 0xab, 0x88, 0x3f, 0x22, 0x74, 0x21, 0x7e, 0x45, 0xe0, 0xb6, 0x92, 0x8a, 0x10, 0xeb, - 0x6c, 0x2f, 0xf3, 0x2b, 0x7f, 0xab, 0x57, 0xfd, 0x8d, 0xd2, 0xaf, 0x89, 0x2b, 0xd7, 0xf8, 0x0d, - 0x34, 0x3b, 0x73, 0x67, 0x62, 0xb5, 0x62, 0x49, 0xf8, 0x1b, 0x04, 0x17, 0x1f, 0x91, 0x1e, 0xd6, - 0xe0, 0x5f, 0x16, 0x86, 0x50, 0x96, 0xae, 0x89, 0x42, 0xf4, 0x98, 0x39, 0x47, 0x6b, 0x10, 0x5a, - 0x5f, 0x61, 0x86, 0xf6, 0x2b, 0x6b, 0xf0, 0x83, 0x65, 0xbf, 0x96, 0xdf, 0xe6, 0x0d, 0x2e, 0x90, - 0x30, 0x56, 0x8b, 0x4d, 0x3e, 0x56, 0x0b, 0xcc, 0xe7, 0x4f, 0x59, 0x61, 0x6b, 0x23, 0xe7, 0xcd, - 0x19, 0xd8, 0xf2, 0x47, 0xae, 0x54, 0x14, 0x85, 0xe9, 0xa4, 0x13, 0xe3, 0x3f, 0x40, 0x26, 0x03, - 0x95, 0x2a, 0xf4, 0xd8, 0x01, 0x5c, 0xfe, 0x25, 0xdb, 0x37, 0xe0, 0xa9, 0x91, 0x08, 0x00, 0x2b, - 0xdf, 0xa0, 0x2c, 0x83, 0xdd, 0xac, 0x0e, 0xc6, 0x6c, 0xcb, 0xb2, 0x3d, 0x79, 0x6e, 0xd8, 0x2f, - 0x23, 0x23, 0x4b, 0x85, 0x64, 0xb0, 0x1a, 0x90, 0x13, 0xd4, 0x9a, 0x54, 0xd8, 0x20, 0x16, 0x6e, - 0x76, 0xe5, 0x54, 0x27, 0x51, 0xcf, 0xf4, 0x49, 0x54, 0x76, 0x7f, 0x2f, 0x8f, 0x28, 0xa3, 0x8c, - 0xae, 0xe0, 0xe5, 0x9f, 0x53, 0x90, 0x88, 0xd0, 0xfb, 0xe0, 0x42, 0x95, 0x59, 0x35, 0x5e, 0x69, - 0xee, 0xd6, 0x2c, 0xbc, 0x39, 0x0b, 0x77, 0xce, 0x01, 0x91, 0x38, 0x66, 0x6f, 0xec, 0x14, 0xfd, - 0x0c, 0x6d, 0xd5, 0x47, 0xbf, 0x9a, 0x18, 0xc3, 0xb2, 0x1c, 0x9b, 0xf1, 0xf5, 0x47, 0xc7, 0x08, - 0xc9, 0x94, 0xab, 0x81, 0xfb, 0x35, 0xc4, 0x49, 0x87, 0x5d, 0x10, 0xc6, 0xab, 0xb3, 0x25, 0x1b, - 0xb0, 0xb1, 0xcf, 0x0f, 0xc0, 0x8f, 0x28, 0x2b, 0xb0, 0x9c, 0x32, 0x11, 0xae, 0xe9, 0x47, 0x27, - 0x75, 0x2d, 0x49, 0x0f, 0xa3, 0x6b, 0xa0, 0xa7, 0xf0, 0xa8, 0x28, 0xc7, 0x2b, 0x4b, 0xa3, 0x03, - 0x5b, 0x7e, 0xe5, 0x6a, 0xbb, 0xad, 0x57, 0xba, 0xc8, 0x38, 0x00, 0x78, 0x47, 0xa3, 0x3d, 0x7b, - 0x95, 0x75, 0x74, 0xba, 0x88, 0x56, 0xa0, 0xa3, 0xbf, 0x57, 0x20, 0x07, 0xb6, 0xfc, 0x04, 0x1a, - 0x3b, 0x52, 0xd9, 0x0e, 0x26, 0x2c, 0x29, 0xc9, 0x2b, 0x2b, 0x5b, 0x6c, 0x37, 0xaf, 0x4e, 0x28, - 0x5b, 0x20, 0x62, 0x75, 0x3c, 0xc0, 0x18, 0x77, 0x0e, 0xa5, 0x1f, 0x1a, 0x01, 0xd1, 0x8f, 0xc9, - 0x0d, 0x54, 0xcc, 0x05, 0x26, 0x49, 0xd4, 0xb2, 0x62, 0xb1, 0x9e, 0x3e, 0xda, 0x85, 0x81, 0xa8, - 0x7b, 0x76, 0xfd, 0x5d, 0xb0, 0x8d, 0x99, 0xfc, 0x16, 0x8e, 0xca, 0xb7, 0xed, 0x97, 0x5d, 0x58, - 0x6a, 0x77, 0xe2, 0x31, 0x03, 0x03, 0x37, 0x22, 0x0c, 0xd6, 0xb3, 0x78, 0x6e, 0xe5, 0x59, 0x35, - 0x6a, 0x7f, 0x9c, 0x5a, 0x4f, 0xd0, 0xdf, 0xc6, 0xa9, 0x1e, 0x9d, 0xcf, 0x69, 0x62, 0xa8, 0x8f, - 0x8c, 0xc1, 0xbf, 0x6c, 0xf7, 0x48, 0xf9, 0x4a, 0x5c, 0x63, 0x8c, 0xee, 0x02, 0x74, 0x74, 0x92, - 0xa7, 0xa3, 0x78, 0xcc, 0x9d, 0x82, 0x53, 0x94, 0xa9, 0x49, 0x54, 0x95, 0x56, 0x60, 0x53, 0x99, - 0x96, 0xc1, 0x85, 0x65, 0x92, 0x80, 0xec, 0x61, 0x70, 0x80, 0xe7, 0xd4, 0x64, 0x13, 0x83, 0xd1, - 0x44, 0xb3, 0xde, 0x0e, 0x5c, 0x67, 0x4d, 0x5c, 0xeb, 0xb9, 0x30, 0x09, 0x61, 0xfa, 0x2c, 0x94, - 0x08, 0xca, 0xd1, 0x49, 0xbc, 0xbf, 0xef, 0xf3, 0x6e, 0x88, 0x1a, 0xf9, 0x4f, 0x5e, 0x65, 0x54, - 0x45, 0x50, 0x95, 0xbd, 0x50, 0x38, 0x12, 0x57, 0x39, 0xfa, 0x08, 0x53, 0x9b, 0x31, 0xb0, 0xa4, - 0xc6, 0x4b, 0x8c, 0x06, 0xb2, 0x89, 0xa7, 0xfc, 0x92, 0x5d, 0x75, 0xae, 0xea, 0xb2, 0xbd, 0x3d, - 0x97, 0x9d, 0x05, 0x79, 0xe5, 0x45, 0xc2, 0xbe, 0x01, 0xfa, 0x8e, 0x01, 0xf4, 0x09, 0x3e, 0x10, - 0x1f, 0x0c, 0x25, 0xf9, 0xbb, 0x2f, 0x5f, 0x02, 0x6e, 0x67, 0xa9, 0x80, 0xe0, 0x44, 0x60, 0xb4, - 0x4a, 0xd8, 0x2f, 0x44, 0xfd, 0xc0, 0xa6, 0xce, 0x0e, 0x99, 0x43, 0xc3, 0xb3, 0x8e, 0x84, 0xff, - 0x0a, 0x11, 0x87, 0xc5, 0x5f, 0x36, 0x55, 0x50, 0x34, 0x37, 0x55, 0x3c, 0x34, 0x6a, 0x93, 0xab, - 0x41, 0x11, 0x1d, 0xe7, 0x56, 0x07, 0x76, 0x94, 0x10, 0x6d, 0xa7, 0x7e, 0x75, 0x8d, 0x19, 0x16, - 0xfd, 0x34, 0x28, 0xa8, 0x4e, 0x14, 0x6c, 0x3c, 0xbc, 0xe9, 0xde, 0xbf, 0x6e, 0x97, 0x3f, 0xd4, - 0x81, 0x78, 0xc4, 0x1f, 0x63, 0x8b, 0xc1, 0xcb, 0x07, 0xdf, 0x30, 0xf4, 0x50, 0x8c, 0x35, 0xdf, - 0xc2, 0x32, 0x73, 0x78, 0x81, 0x9e, 0x1f, 0xfe, 0xb2, 0x90, 0x6d, 0x78, 0xf6, 0x94, 0x58, 0x7a, - 0x2c, 0x64, 0x8a, 0xc9, 0x1f, 0x02, 0x4e, 0x52, 0xb3, 0x09, 0x5b, 0xa8, 0x8f, 0xfa, 0x76, 0xc0, - 0x85, 0xbf, 0xac, 0x64, 0x40, 0xa5, 0x6b, 0x8f, 0xd1, 0x46, 0x71, 0x0f, 0x35, 0x30, 0x00, 0xa5, - 0x8e, 0x0b, 0xcb, 0x43, 0x25, 0x23, 0x4b, 0x5e, 0xfb, 0x10, 0xdf, 0xf1, 0xc0, 0xb3, 0x48, 0xef, - 0xe4, 0xc1, 0xb1, 0x48, 0xbf, 0x8d, 0xe3, 0xbe, 0x2c, 0xfb, 0x77, 0x55, 0xd9, 0xb1, 0x6b, 0xe9, - 0x5a, 0x56, 0x5b, 0xb2, 0x71, 0x12, 0x3c, 0x1b, 0x95, 0x7e, 0xb6, 0xbd, 0x06, 0x15, 0x48, 0x52, - 0xdb, 0x4f, 0xd8, 0x75, 0xb4, 0x60, 0x30, 0x87, 0x87, 0xbf, 0x5b, 0xbd, 0x01, 0x67, 0xf9, 0xfe, - 0xbe, 0x6a, 0x03, 0x82, 0xa7, 0xef, 0x55, 0xbb, 0x73, 0x6e, 0xbf, 0x05, 0x56, 0x00, 0x19, 0x5e, - 0xad, 0x85, 0xf5, 0xdf, 0xff, 0xd7, 0x12, 0x98, 0x41, 0x63, 0xf9, 0x7f, 0xff, 0xbf, 0x34, 0x12, - 0x10, 0x71, 0x5f, 0x2c, 0xa3, 0xcc, 0x9a, 0x47, 0x3c, 0x0e, 0x2d, 0xb8, 0x29, 0xbf, 0x61, 0xd0, - 0x76, 0xb5, 0x92, 0xd1, 0x32, 0x65, 0x89, 0xdb, 0x03, 0xcc, 0x8b, 0x8c, 0x63, 0x4d, 0xc3, 0xa5, - 0xc6, 0xc8, 0x95, 0x74, 0xbb, 0x9e, 0xe5, 0x2a, 0x51, 0x4c, 0xf0, 0x67, 0x78, 0x18, 0x28, 0x82, - 0x9c, 0x32, 0x34, 0x13, 0x01, 0xa1, 0xad, 0x44, 0xf3, 0xa4, 0x22, 0xac, 0xaa, 0xec, 0xa3, 0x10, - 0x62, 0x05, 0xb8, 0xe0, 0x21, 0xa5, 0x08, 0x40, 0xdb, 0x51, 0x36, 0x9e, 0xa8, 0x46, 0x71, 0xad, - 0x22, 0xe4, 0xfd, 0xbd, 0xe6, 0x15, 0xb3, 0xd5, 0xd9, 0xc2, 0x52, 0x63, 0xe9, 0x3f, 0x17, 0x22, - 0x10, 0x9e, 0x8c, 0x4f, 0x7f, 0x14, 0x21, 0x2f, 0x60, 0x9a, 0x0c, 0xa4, 0xf6, 0x19, 0x40, 0x8d, - 0xd1, 0xec, 0x3f, 0x11, 0x60, 0x50, 0x96, 0x7d, 0x07, 0xa6, 0xa2, 0x6a, 0x6e, 0x9a, 0x08, 0x4d, - 0xfa, 0xcb, 0x97, 0x23, 0xba, 0xa7, 0xf3, 0x0e, 0x25, 0xef, 0x0e, 0x12, 0xba, 0x21, 0x02, 0xea, - 0x67, 0x3b, 0x6c, 0xa7, 0x54, 0x7f, 0xbc, 0x3c, 0x19, 0x25, 0xd5, 0xfa, 0x77, 0x99, 0x57, 0xbf, - 0xbf, 0xa7, 0x4a, 0x38, 0xc4, 0x0f, 0x30, 0x4f, 0xd9, 0xc8, 0x54, 0xc5, 0x4e, 0x5e, 0xe7, 0x87, - 0xbe, 0x5d, 0xff, 0x65, 0x0f, 0x34, 0xd6, 0xa0, 0x0c, 0x77, 0x59, 0xf2, 0xb6, 0x81, 0x6d, 0x8c, - 0x76, 0xf3, 0x86, 0xf9, 0xc0, 0x21, 0xa4, 0x7a, 0x30, 0x55, 0x12, 0x80, 0x17, 0x02, 0x28, 0xa3, - 0x84, 0xd0, 0xb6, 0x4b, 0x94, 0x9a, 0x9b, 0x4c, 0x1e, 0x01, 0x2f, 0xd6, 0xc7, 0xa8, 0x09, 0xe4, - 0xa2, 0xa0, 0xee, 0x40, 0x2f, 0x25, 0x45, 0xf9, 0x9b, 0x85, 0x6d, 0x05, 0xa5, 0x7f, 0xc5, 0x10, - 0x64, 0x13, 0x58, 0xac, 0x2d, 0x54, 0x30, 0xfe, 0xc1, 0xd1, 0x62, 0xbd, 0x6b, 0x64, 0x5b, 0x1c, - 0xeb, 0xdf, 0x04, 0x80, 0x79, 0xa2, 0x13, 0x2e, 0x49, 0x6f, 0x45, 0x43, 0xfa, 0x82, 0x68, 0xce, - 0x53, 0xd9, 0x38, 0x31, 0x4a, 0x48, 0x20, 0x56, 0x31, 0xfb, 0xe3, 0x79, 0x52, 0x5e, 0x73, 0x45, - 0x3e, 0x52, 0x3a, 0xc4, 0xc2, 0x72, 0xb2, 0xf2, 0xdb, 0xf8, 0x67, 0x1f, 0x5d, 0x43, 0x67, 0x3c, - 0xbc, 0x17, 0x0a, 0xb2, 0x94, 0x9e, 0x56, 0x2b, 0xa9, 0xb8, 0xab, 0xd0, 0x87, 0xd1, 0x0f, 0xd4, - 0xa2, 0xd6, 0x04, 0x74, 0xc7, 0x86, 0xcd, 0xb0, 0xcb, 0x93, 0x95, 0xcb, 0x28, 0x65, 0x89, 0xb3, - 0xad, 0xef, 0x53, 0xbf, 0x7c, 0xda, 0x4e, 0x65, 0x72, 0xb1, 0xde, 0xd3, 0xfe, 0x13, 0x9f, 0x5d, - 0xd8, 0x93, 0x3a, 0xca, 0xaa, 0xe4, 0x7f, 0xab, 0xe6, 0xdb, 0xd9, 0x8d, 0xc6, 0xaa, 0xec, 0xa9, - 0xa3, 0x32, 0xc9, 0xac, 0x13, 0xc9, 0x1f, 0x53, 0x35, 0x56, 0x3b, 0x93, 0x2d, 0x3e, 0x5b, 0xb8, - 0x04, 0xfe, 0x4c, 0x55, 0x47, 0xc6, 0x8a, 0x46, 0x11, 0xd3, 0x84, 0xe9, 0x3a, 0x32, 0xfb, 0x83, - 0x51, 0x32, 0x66, 0xe9, 0xc2, 0xf9, 0x50, 0x55, 0x87, 0xd9, 0x4f, 0x39, 0x81, 0x69, 0xe0, 0x09, - 0x3f, 0x14, 0x78, 0x3c, 0x76, 0xca, 0x44, 0x9f, 0x59, 0x8b, 0x5b, 0x7d, 0x3d, 0xd9, 0x59, 0x8c, - 0xab, 0x02, 0x44, 0x7e, 0xae, 0x8a, 0x2d, 0x64, 0x39, 0xa3, 0x79, 0x5c, 0xe6, 0x3e, 0x1b, 0x39, - 0x7e, 0xad, 0xc5, 0x28, 0x97, 0xf9, 0xdc, 0xb9, 0xda, 0xb6, 0x70, 0xeb, 0xe7, 0xeb, 0x58, 0x48, - 0x83, 0x15, 0xaa, 0x54, 0xc2, 0xb0, 0x6b, 0x49, 0xa7, 0xc9, 0x30, 0xcd, 0x2f, 0x35, 0x9e, 0xc4, - 0x31, 0x1d, 0x27, 0xdb, 0xe0, 0x76, 0x48, 0x66, 0x55, 0xe4, 0x57, 0x94, 0x2d, 0x8d, 0xef, 0x4c, - 0xaf, 0xe4, 0xdd, 0xa4, 0x51, 0xce, 0x29, 0x2b, 0xad, 0xeb, 0xa1, 0xd5, 0xb9, 0x9b, 0x8d, 0x8d, - 0x10, 0xf3, 0xae, 0x23, 0xf9, 0xdd, 0xd5, 0xac, 0x02, 0xce, 0xa0, 0x77, 0x39, 0x77, 0xe8, 0xf1, - 0x5b, 0x3e, 0x7b, 0x2d, 0x53, 0x05, 0x98, 0x58, 0x5d, 0xdf, 0xd9, 0x4f, 0x9b, 0xaa, 0x55, 0x89, - 0xda, 0xc0, 0x51, 0xe3, 0xc3, 0x0f, 0xe7, 0x33, 0xba, 0x69, 0x57, 0xed, 0x76, 0xfb, 0xf8, 0x3f, - 0xef, 0xaa, 0xff, 0x68, 0xa4, 0xd8, 0x6c, 0x12, 0x4b, 0x7b, 0x8f, 0x6a, 0x57, 0xde, 0x00, 0xf7, - 0x3b, 0xe8, 0x0c, 0xa0, 0x5f, 0x0b, 0x7e, 0x70, 0x5e, 0x23, 0xa7, 0x71, 0xba, 0xf6, 0x44, 0x3d, - 0xa8, 0x8f, 0x05, 0x93, 0xae, 0xe3, 0x40, 0x55, 0x5b, 0xa5, 0xcf, 0xf3, 0x32, 0x43, 0xff, 0xed, - 0x3e, 0xc4, 0x9b, 0xe8, 0x7a, 0x26, 0x56, 0x56, 0x3b, 0x65, 0x26, 0xac, 0x7a, 0xbb, 0x8f, 0x84, - 0xd4, 0x2c, 0xd2, 0xcf, 0xbe, 0xbb, 0x7b, 0x8d, 0xe6, 0x18, 0x13, 0x61, 0xed, 0x02, 0x88, 0xe4, - 0x41, 0xf0, 0x26, 0x46, 0xe5, 0x75, 0xee, 0x54, 0x11, 0x56, 0x95, 0xcf, 0x40, 0x7f, 0xa6, 0xe1, - 0x1a, 0xcb, 0x14, 0x69, 0x72, 0x6e, 0xe3, 0xcf, 0x6f, 0x81, 0x53, 0x48, 0x4e, 0x57, 0xd1, 0x10, - 0xa5, 0xc6, 0xaf, 0x32, 0x74, 0x6d, 0x8c, 0x9c, 0xd9, 0x1d, 0x14, 0xe8, 0x3a, 0xb8, 0x35, 0xcd, - 0x90, 0x0c, 0x28, 0x93, 0xd3, 0x60, 0xff, 0xe8, 0xe8, 0x3c, 0xf1, 0xe1, 0xaf, 0x81, 0xe1, 0x72, - 0xc3, 0xaa, 0xa1, 0x1b, 0xb0, 0x2f, 0x80, 0x49, 0xed, 0xa9, 0x0b, 0x30, 0xbd, 0x68, 0x62, 0x2e, - 0xaa, 0xab, 0x5f, 0xfe, 0xac, 0x3d, 0x7e, 0x34, 0x39, 0xeb, 0x15, 0x29, 0x49, 0x47, 0x40, 0xd4, - 0x34, 0xf1, 0x49, 0x47, 0xc1, 0x1a, 0xff, 0x72, 0x9b, 0x5c, 0x72, 0x39, 0x84, 0xac, 0x79, 0x77, - 0xe0, 0xa7, 0xed, 0x7f, 0x57, 0xe0, 0x65, 0x22, 0xaf, 0x7d, 0x80, 0xf4, 0xc5, 0x42, 0xd2, 0x75, - 0x26, 0xa5, 0x4d, 0x9a, 0x49, 0xcc, 0x3f, 0x21, 0x1d, 0x0f, 0x8b, 0x45, 0xad, 0x6c, 0xe0, 0x8b, - 0xb7, 0x51, 0x2f, 0x42, 0x48, 0x3a, 0x2b, 0x26, 0xf4, 0xb6, 0xd8, 0xd3, 0xb6, 0xc5, 0xce, 0xfb, - 0x9a, 0x82, 0x07, 0xed, 0xe0, 0x98, 0x76, 0x08, 0xb6, 0x5a, 0x77, 0x19, 0xef, 0x88, 0x9f, 0x9d, - 0xc6, 0xf6, 0x0d, 0x17, 0xe1, 0x8b, 0x37, 0x6f, 0xba, 0x1b, 0x9d, 0x5b, 0x67, 0x6d, 0xce, 0x76, - 0x6b, 0x27, 0x94, 0x4f, 0x40, 0x47, 0x76, 0xde, 0x97, 0x66, 0xf1, 0xab, 0x77, 0x73, 0xeb, 0x4e, - 0x6c, 0xac, 0x1b, 0x96, 0x00, 0xaf, 0xc7, 0xb1, 0xa5, 0x7e, 0xfa, 0xcf, 0xfc, 0x18, 0x1d, 0xe3, - 0x73, 0xf0, 0x36, 0x72, 0x94, 0x0a, 0x7b, 0x64, 0x7f, 0xe5, 0xda, 0xea, 0x07, 0x64, 0x6d, 0x17, - 0x3f, 0xda, 0xc0, 0x82, 0x4a, 0x9e, 0x7f, 0x9b, 0x83, 0xb3, 0x38, 0x85, 0x00, 0x16, 0x76, 0x42, - 0x9f, 0x00, 0xdb, 0xae, 0x5d, 0x7d, 0xe4, 0xeb, 0xec, 0xc0, 0x79, 0x29, 0x56, 0x07, 0x80, 0xfd, - 0xcf, 0xcc, 0xf3, 0x88, 0x6f, 0x89, 0x77, 0xe6, 0x3d, 0x4a, 0xc2, 0x36, 0x29, 0x68, 0x7e, 0x08, - 0xfc, 0x39, 0xdf, 0xc8, 0xe2, 0x2d, 0x7f, 0x31, 0xdf, 0xe1, 0x2f, 0x9a, 0x04, 0xd4, 0x79, 0x6a, - 0x97, 0x3d, 0x50, 0xd2, 0x69, 0x94, 0x7b, 0x96, 0xdf, 0x8f, 0x3a, 0x66, 0x20, 0x00, 0x21, 0xfc, - 0x0e, 0x4f, 0x32, 0xd9, 0x91, 0x87, 0x62, 0xf5, 0x44, 0x5b, 0x7e, 0xbe, 0x23, 0xd5, 0xa9, 0xbc, - 0xc9, 0x8e, 0x9a, 0x48, 0xa0, 0x49, 0xd6, 0x4d, 0xb6, 0xfa, 0x10, 0xe8, 0x09, 0x48, 0xc5, 0xdf, - 0xac, 0x91, 0x9f, 0x60, 0xe2, 0x0f, 0x39, 0xd2, 0xff, 0xb9, 0xd8, 0xff, 0x07, 0xff, 0x03, 0x8d, - 0x05, 0x6d, 0x6c, 0x00, 0x00 -}; diff --git a/wled00/html_settings.h b/wled00/html_settings.h deleted file mode 100644 index 8082d0b81..000000000 --- a/wled00/html_settings.h +++ /dev/null @@ -1,2235 +0,0 @@ -/* - * More web UI HTML source arrays. - * This file is auto generated, please don't make any changes manually. - * Instead, see https://kno.wled.ge/advanced/custom-features/#changing-web-ui - * to find out how to easily modify the web UI source! - */ - -// Autogenerated from wled00/data/style.css, do not edit!! -const uint16_t PAGE_settingsCss_length = 888; -const uint8_t PAGE_settingsCss[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x56, 0x51, 0x8b, 0xab, 0x38, - 0x14, 0xfe, 0x2b, 0x2e, 0x65, 0x60, 0x2e, 0x54, 0x51, 0xab, 0x9d, 0xde, 0xc8, 0xc2, 0xb2, 0xef, - 0xf7, 0x6d, 0x58, 0x16, 0x96, 0x79, 0x88, 0xe6, 0x58, 0x43, 0x63, 0x22, 0x49, 0xbc, 0xb5, 0x23, - 0xfe, 0xf7, 0x4d, 0xa2, 0x8e, 0xb6, 0x23, 0x73, 0x5f, 0x2e, 0xa5, 0x25, 0xe6, 0xc4, 0xe4, 0x3b, - 0xdf, 0xf9, 0xce, 0x97, 0x56, 0xba, 0x66, 0xbd, 0x16, 0x6d, 0x51, 0xf9, 0xb8, 0xd0, 0x54, 0x70, - 0x54, 0x63, 0x4e, 0x9b, 0x96, 0x61, 0xfb, 0x30, 0xe4, 0x82, 0xdc, 0xfa, 0x52, 0x70, 0xed, 0x97, - 0xb8, 0xa6, 0xec, 0x86, 0xfe, 0x01, 0x49, 0x30, 0xc7, 0x7b, 0x85, 0xb9, 0xf2, 0x15, 0x48, 0x5a, - 0x66, 0x2e, 0xac, 0xe8, 0x3b, 0xa0, 0x48, 0x42, 0x9d, 0x69, 0xe8, 0xb4, 0x8f, 0x19, 0x3d, 0x73, - 0x54, 0x00, 0xd7, 0x20, 0xb3, 0x1c, 0x17, 0x97, 0xb3, 0x14, 0x2d, 0x27, 0x68, 0x17, 0xc7, 0x71, - 0x56, 0x08, 0x26, 0x24, 0xda, 0x95, 0x65, 0x99, 0x31, 0xca, 0xc1, 0xaf, 0x80, 0x9e, 0x2b, 0x8d, - 0xe2, 0x30, 0x7c, 0xca, 0x6a, 0x2c, 0xcf, 0x94, 0xa3, 0x70, 0xa8, 0x64, 0x9f, 0x0b, 0x49, 0x40, - 0xfa, 0xd3, 0xf2, 0xe3, 0xf1, 0x68, 0x26, 0x03, 0x65, 0xf0, 0x5e, 0x29, 0xd1, 0x15, 0x8a, 0x8f, - 0x61, 0xd3, 0x0d, 0x78, 0x8f, 0x51, 0x25, 0x7e, 0x82, 0xec, 0xa7, 0x75, 0xf1, 0xa9, 0x1c, 0x31, - 0x10, 0x28, 0x84, 0x74, 0x69, 0x20, 0x2e, 0x38, 0x0c, 0x41, 0xae, 0xf9, 0x3e, 0x6f, 0xb5, 0x16, - 0xbc, 0x5f, 0x43, 0x3a, 0x1c, 0x0e, 0x6b, 0x48, 0xbf, 0xc8, 0x76, 0x04, 0x85, 0x82, 0x43, 0x51, - 0x79, 0x4a, 0x30, 0x4a, 0x3c, 0xb7, 0xc1, 0x84, 0x55, 0x62, 0x42, 0x5b, 0x85, 0xe2, 0xa4, 0xe9, - 0x32, 0x42, 0x55, 0xc3, 0xf0, 0x0d, 0x51, 0xee, 0xb2, 0xcc, 0x99, 0x28, 0x2e, 0x2b, 0xb2, 0x62, - 0x83, 0x7e, 0x4e, 0x37, 0x8a, 0x9b, 0xce, 0x3b, 0x8d, 0xdf, 0xac, 0xc1, 0x84, 0x50, 0x7e, 0x46, - 0xf6, 0xd9, 0x06, 0xb2, 0x9a, 0x72, 0x7f, 0x4c, 0x39, 0xb1, 0xf1, 0xa2, 0x95, 0xca, 0x80, 0x6d, - 0x04, 0x75, 0xec, 0x6e, 0xe6, 0x3a, 0xa6, 0xe9, 0xc8, 0x5a, 0x6d, 0xf7, 0x88, 0xd2, 0x22, 0x58, - 0x55, 0x2f, 0xbd, 0x3f, 0x6b, 0x85, 0x2f, 0xf4, 0xec, 0x27, 0xb2, 0x7c, 0xef, 0x54, 0x81, 0x79, - 0x3f, 0xce, 0xfb, 0x5a, 0x34, 0xc8, 0x77, 0xd3, 0x81, 0x19, 0x4a, 0x71, 0xed, 0xed, 0x4c, 0x98, - 0x35, 0x42, 0x51, 0x07, 0x46, 0x69, 0x5a, 0x5c, 0x6e, 0x2b, 0x05, 0xcc, 0xd5, 0xb4, 0x3a, 0x78, - 0xf7, 0x29, 0x27, 0xd0, 0xa1, 0x68, 0x08, 0x18, 0xbf, 0x4c, 0xe5, 0x36, 0xa5, 0x0f, 0x2a, 0x60, - 0xcd, 0xdf, 0xfd, 0x4a, 0x48, 0x0c, 0x4a, 0xbd, 0x6c, 0x8a, 0x73, 0x43, 0x7c, 0xab, 0x21, 0x1b, - 0x81, 0x3a, 0x19, 0x04, 0x15, 0x25, 0xd0, 0xcf, 0x94, 0x8f, 0xf5, 0x06, 0x39, 0x8b, 0x42, 0x02, - 0x19, 0x82, 0x2b, 0x96, 0x7c, 0x16, 0x49, 0x89, 0xc3, 0x81, 0xf2, 0xa6, 0xd5, 0xbf, 0x41, 0x09, - 0xe9, 0x9d, 0x12, 0xc6, 0x6d, 0x91, 0x41, 0x82, 0x73, 0x06, 0x64, 0x3e, 0xf0, 0x74, 0x3a, 0x8d, - 0x91, 0xff, 0xf4, 0xad, 0x81, 0x3f, 0x79, 0x5b, 0xe7, 0x20, 0xdf, 0xf6, 0xab, 0x29, 0x9b, 0xee, - 0xdb, 0x5e, 0x01, 0x83, 0x42, 0xf7, 0x4b, 0x55, 0x6a, 0x30, 0xb5, 0xaa, 0xe7, 0x42, 0x18, 0x39, - 0x6c, 0x6c, 0x33, 0x35, 0x44, 0x02, 0xf5, 0x46, 0x30, 0xe8, 0xba, 0xb9, 0x63, 0xa2, 0x30, 0xdc, - 0x7c, 0x3f, 0xf8, 0x58, 0x71, 0x4a, 0xb7, 0x17, 0xcc, 0xf1, 0x63, 0xb2, 0x1d, 0xaf, 0xa7, 0x78, - 0x7a, 0xdc, 0x8e, 0xab, 0x7e, 0x11, 0xf0, 0x26, 0x80, 0x8f, 0x05, 0x0f, 0x08, 0x8b, 0x0a, 0x8a, - 0x4b, 0x2e, 0xba, 0xb7, 0x5e, 0x4b, 0x43, 0x7d, 0x29, 0x64, 0x8d, 0x8c, 0x02, 0x19, 0x3c, 0x47, - 0x41, 0xfa, 0x6d, 0xa2, 0xc5, 0x97, 0xce, 0x40, 0x9c, 0x10, 0x35, 0xf1, 0x36, 0x5f, 0xbf, 0x5b, - 0x29, 0xc1, 0x18, 0x86, 0x5e, 0x9f, 0x53, 0x52, 0x06, 0x6f, 0x2b, 0xda, 0x23, 0x9b, 0xc8, 0x54, - 0x8c, 0x85, 0xfb, 0xec, 0xb7, 0xab, 0x65, 0x3c, 0x22, 0x68, 0xa8, 0xed, 0xa9, 0x6e, 0x6a, 0xbd, - 0xc8, 0x75, 0xa6, 0xd3, 0xbf, 0x75, 0xb6, 0x92, 0x89, 0x2b, 0x02, 0xc6, 0x68, 0xa3, 0xa8, 0x1a, - 0xb4, 0xec, 0xd7, 0xae, 0x69, 0x6a, 0xfa, 0x64, 0x92, 0xfe, 0x68, 0x73, 0xab, 0x90, 0x80, 0xa4, - 0x33, 0x9d, 0xc6, 0x91, 0xff, 0xa0, 0x75, 0x23, 0xa4, 0xc6, 0x5c, 0x0f, 0x81, 0x61, 0x6e, 0x9d, - 0x64, 0x90, 0x5a, 0xc7, 0xbe, 0x37, 0x94, 0x61, 0xf7, 0xfa, 0xe3, 0xd5, 0xd3, 0x56, 0xbd, 0x8b, - 0x6c, 0x9e, 0x86, 0x5d, 0xad, 0xce, 0xf7, 0xfd, 0xb5, 0xd3, 0x02, 0x2b, 0xdd, 0x8b, 0x06, 0x17, - 0x54, 0xdf, 0x4c, 0xd7, 0x7f, 0xee, 0xf2, 0x24, 0x49, 0x1e, 0x3c, 0x27, 0x75, 0x2e, 0x64, 0xcc, - 0xa9, 0x76, 0x5a, 0xfa, 0x44, 0xe0, 0x88, 0xeb, 0x65, 0x65, 0x83, 0xb6, 0x12, 0xd9, 0x84, 0xcd, - 0x37, 0x75, 0xe3, 0x5a, 0xb9, 0xf3, 0x17, 0x3f, 0x28, 0x69, 0x07, 0x64, 0xe3, 0xde, 0x99, 0xfd, - 0x25, 0xcd, 0x16, 0xed, 0xb8, 0x91, 0xb9, 0xdc, 0xe0, 0xdf, 0x67, 0x3f, 0x0d, 0x9f, 0xac, 0x82, - 0x66, 0xd6, 0xbf, 0x9b, 0xeb, 0xc7, 0x1a, 0x0d, 0x4a, 0x6d, 0xba, 0x2e, 0xb9, 0x40, 0x55, 0xc6, - 0xd3, 0xe6, 0x0c, 0xa3, 0x2d, 0x1f, 0x3b, 0x26, 0x99, 0xb9, 0x30, 0xeb, 0xd1, 0x7b, 0x4b, 0x4c, - 0x80, 0x72, 0x2f, 0x48, 0xd5, 0x7e, 0x19, 0x7a, 0xb1, 0xfd, 0x71, 0x92, 0x53, 0x33, 0x6b, 0xd6, - 0x9b, 0x84, 0xfc, 0x72, 0xe7, 0x3c, 0x8e, 0x36, 0x77, 0x1e, 0xfe, 0xb2, 0x96, 0x80, 0x3d, 0x55, - 0x48, 0x00, 0xee, 0x61, 0x4e, 0xbc, 0xe7, 0x25, 0x89, 0x97, 0xa3, 0xe1, 0xee, 0x5b, 0xbf, 0x52, - 0x36, 0xd4, 0x98, 0xb2, 0x3b, 0xa7, 0x71, 0x5a, 0xdf, 0x7f, 0xed, 0x46, 0x0d, 0x56, 0xea, 0x6a, - 0x2a, 0xf7, 0x60, 0x51, 0xec, 0xb3, 0x65, 0x3d, 0x36, 0xcd, 0xd7, 0xf8, 0x92, 0x53, 0xf8, 0x80, - 0xef, 0x93, 0x45, 0x84, 0xbf, 0xb0, 0x88, 0xc3, 0x83, 0x09, 0x8e, 0xad, 0x3b, 0xfd, 0x27, 0xb0, - 0x37, 0xef, 0xb0, 0x33, 0x37, 0xbd, 0xf2, 0xa6, 0xee, 0x9d, 0x34, 0x9c, 0xd8, 0xc0, 0xf0, 0x3f, - 0x39, 0x38, 0xc0, 0xa3, 0xef, 0x08, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings.htm, do not edit!! -const uint16_t PAGE_settings_length = 1115; -const uint8_t PAGE_settings[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xb5, 0x56, 0xdb, 0x52, 0xe3, 0x46, - 0x10, 0x7d, 0xf7, 0x57, 0x0c, 0xb3, 0x15, 0x56, 0x2a, 0x64, 0xf9, 0x42, 0x2a, 0x95, 0xc8, 0x96, - 0xa9, 0x2c, 0x97, 0x8d, 0x53, 0x50, 0x4b, 0x05, 0x58, 0x92, 0x4a, 0xf2, 0x30, 0xd6, 0xb4, 0xac, - 0x59, 0xa4, 0x19, 0xd5, 0x4c, 0xcb, 0xe0, 0xb0, 0xfc, 0x7b, 0x7a, 0x64, 0x63, 0x60, 0xe1, 0x21, - 0x9b, 0x90, 0x17, 0xcb, 0xd3, 0xea, 0x39, 0x7d, 0xfa, 0xf4, 0xc5, 0x1e, 0x6f, 0x1d, 0x7c, 0xd8, - 0x3f, 0xff, 0xed, 0xf4, 0x90, 0x15, 0x58, 0x95, 0x93, 0xb1, 0xff, 0x64, 0xa5, 0xd0, 0xf3, 0x94, - 0x83, 0xe6, 0x74, 0x06, 0x21, 0x27, 0xe3, 0x0a, 0x50, 0xb0, 0xac, 0x10, 0xd6, 0x01, 0xa6, 0xfc, - 0xe2, 0xfc, 0xa8, 0xfb, 0x3d, 0x5f, 0x5b, 0x3b, 0x99, 0xd1, 0x08, 0x9a, 0xcc, 0xd7, 0x4a, 0x62, - 0x91, 0x4a, 0x58, 0xa8, 0x0c, 0xba, 0xed, 0x21, 0x52, 0x5a, 0xa1, 0x12, 0x65, 0xd7, 0x65, 0xa2, - 0x84, 0x74, 0x10, 0x55, 0xe2, 0x46, 0x55, 0x4d, 0xb5, 0x39, 0x37, 0x0e, 0x6c, 0x7b, 0x10, 0x33, - 0x3a, 0x6b, 0xc3, 0x59, 0x47, 0x8b, 0x0a, 0x52, 0xbe, 0x50, 0x70, 0x5d, 0x1b, 0x8b, 0x14, 0x05, - 0x15, 0x96, 0x30, 0xb9, 0x3c, 0x3e, 0x3c, 0x60, 0x67, 0x80, 0xa8, 0xf4, 0xdc, 0x8d, 0x7b, 0x2b, - 0xe3, 0xd8, 0x65, 0x56, 0xd5, 0x38, 0xe9, 0x2c, 0x84, 0x65, 0xa5, 0xc9, 0x54, 0x1d, 0xc9, 0x54, - 0x9a, 0xac, 0xa9, 0x88, 0x50, 0x44, 0x86, 0x74, 0x6b, 0xe0, 0x1f, 0xb5, 0x35, 0x68, 0x52, 0x5e, - 0x20, 0xd6, 0x09, 0x1f, 0xe5, 0x8d, 0xce, 0x50, 0x19, 0xcd, 0xe6, 0x53, 0x19, 0x60, 0x78, 0x6b, - 0x01, 0x1b, 0xab, 0x99, 0x8c, 0xe7, 0x80, 0x87, 0x25, 0xf8, 0xbb, 0xef, 0x96, 0xed, 0xab, 0xbb, - 0x8d, 0x6b, 0x69, 0x84, 0xfc, 0xf9, 0x2c, 0xc0, 0xc8, 0xa4, 0x5b, 0xfd, 0xf0, 0xb6, 0x04, 0x64, - 0x90, 0xca, 0x38, 0xb3, 0x20, 0x10, 0xd6, 0x97, 0x02, 0xbe, 0xa2, 0xc3, 0xc3, 0x11, 0xc4, 0x24, - 0xd4, 0x8f, 0x88, 0x56, 0xcd, 0x1a, 0x04, 0x7a, 0x61, 0x33, 0x1e, 0x61, 0x18, 0x7d, 0x69, 0xc7, - 0x65, 0x0d, 0x3c, 0xe2, 0x08, 0x37, 0xd8, 0xfb, 0x24, 0x16, 0xe2, 0x1e, 0xe0, 0x99, 0xa3, 0x70, - 0x4b, 0x4d, 0x10, 0x26, 0x8c, 0x64, 0x3c, 0x33, 0x72, 0x19, 0x8b, 0xba, 0x06, 0x2d, 0xf7, 0x0b, - 0x55, 0xca, 0x00, 0xbc, 0xbf, 0x90, 0xf2, 0x70, 0x41, 0x2c, 0x8e, 0x95, 0xa3, 0x72, 0x80, 0x0d, - 0xb8, 0xe7, 0xcc, 0xa3, 0x20, 0x4c, 0x27, 0xb7, 0xef, 0x01, 0x3f, 0x06, 0xe1, 0xdd, 0xcb, 0x7e, - 0x60, 0xad, 0xb1, 0x44, 0x8f, 0xfc, 0xa8, 0x96, 0xce, 0x94, 0x10, 0x97, 0x66, 0x1e, 0xf0, 0x43, - 0x6f, 0x67, 0xeb, 0xe4, 0x49, 0x76, 0x96, 0xab, 0x12, 0xda, 0x34, 0xa8, 0x78, 0x96, 0xd2, 0x3d, - 0x5e, 0xdb, 0x4d, 0xce, 0xe8, 0x62, 0xae, 0xe6, 0x8d, 0x15, 0xad, 0x5a, 0xab, 0x34, 0x58, 0x2e, - 0xe8, 0x82, 0x8c, 0xff, 0xd0, 0x53, 0x9d, 0x99, 0xaa, 0x26, 0xd1, 0x80, 0xd5, 0x62, 0x0e, 0x4c, - 0x0a, 0x14, 0x5b, 0x9c, 0xf8, 0x3c, 0x08, 0x7c, 0x16, 0xac, 0x54, 0xc5, 0xf4, 0x5a, 0x69, 0x69, - 0xae, 0x89, 0x42, 0xd6, 0x82, 0x8d, 0x54, 0x1e, 0x70, 0x1f, 0x39, 0xe1, 0x69, 0x8a, 0x71, 0x5b, - 0xca, 0xcc, 0x94, 0x61, 0x5b, 0xdd, 0x7e, 0x14, 0xb4, 0x65, 0x4f, 0xbd, 0x77, 0x79, 0x86, 0xc6, - 0x12, 0xbc, 0xaf, 0xe3, 0x14, 0xa1, 0xf2, 0x0a, 0x64, 0xd3, 0x9a, 0x87, 0xe1, 0xe7, 0xcf, 0x6b, - 0x37, 0xba, 0x5d, 0xd5, 0xc4, 0xfc, 0x88, 0xf0, 0xd8, 0x89, 0x91, 0x10, 0xb3, 0xd3, 0x12, 0x84, - 0x03, 0x46, 0x8a, 0x80, 0x65, 0x6d, 0x97, 0x4d, 0x4f, 0x89, 0x5b, 0xf4, 0x04, 0xd1, 0x3d, 0x45, - 0x8c, 0x5a, 0xb4, 0x90, 0xea, 0x5c, 0x3a, 0x68, 0x69, 0x1b, 0x4f, 0x4d, 0x60, 0xe1, 0xbb, 0x37, - 0x82, 0xd4, 0xc4, 0xae, 0xa4, 0x29, 0x08, 0x06, 0x91, 0x89, 0xa9, 0x4c, 0xee, 0x52, 0x61, 0x11, - 0xf0, 0x1e, 0x0f, 0xf7, 0xba, 0x83, 0x64, 0x61, 0x94, 0x64, 0xfd, 0x30, 0x76, 0x75, 0xa9, 0xb0, - 0xb5, 0x52, 0xbf, 0x94, 0xa0, 0xe7, 0x58, 0x4c, 0x06, 0xdb, 0xdb, 0xc1, 0xa6, 0x61, 0x1f, 0xb2, - 0x8d, 0xd6, 0xd9, 0xae, 0xb2, 0xc0, 0xb8, 0x30, 0x0e, 0x7d, 0xa8, 0x9d, 0x80, 0x7c, 0x68, 0x4c, - 0xf6, 0x78, 0xc2, 0x77, 0x56, 0x5f, 0x13, 0xce, 0xc3, 0x1d, 0x02, 0xdd, 0x81, 0xdf, 0xfb, 0x7f, - 0x86, 0x77, 0xeb, 0xc6, 0x25, 0x49, 0x2e, 0x7e, 0x39, 0xa6, 0x60, 0x6e, 0x3d, 0x42, 0x3d, 0x17, - 0x7f, 0x72, 0x7b, 0x75, 0xda, 0xa7, 0x54, 0xb7, 0x06, 0x8f, 0x0a, 0xb1, 0xf6, 0xdc, 0xcc, 0x85, - 0xa7, 0xb3, 0x77, 0x4f, 0x89, 0x80, 0x09, 0xb9, 0x65, 0xd1, 0xc6, 0xc1, 0xbb, 0xce, 0xb8, 0xb7, - 0x1e, 0xc2, 0xb1, 0xc3, 0x25, 0xcd, 0x64, 0xc7, 0xb7, 0xe7, 0xad, 0xef, 0xe8, 0xae, 0x28, 0xd5, - 0x5c, 0x27, 0x59, 0x2b, 0xed, 0x68, 0x26, 0xb2, 0xab, 0xb9, 0x35, 0x8d, 0x96, 0xc9, 0x9b, 0xe1, - 0x70, 0x38, 0x2a, 0x40, 0xcd, 0x0b, 0x4c, 0x06, 0xfd, 0x7e, 0x7d, 0x33, 0xaa, 0x84, 0x9d, 0x2b, - 0x9d, 0xf4, 0xef, 0xfc, 0xfa, 0xb9, 0xed, 0x76, 0x8b, 0xe4, 0x87, 0x45, 0x71, 0x47, 0xad, 0x8f, - 0x46, 0xdf, 0x3e, 0xbe, 0xb9, 0xbb, 0xbb, 0x3b, 0x22, 0x3d, 0x8c, 0x4d, 0xde, 0xe4, 0x79, 0x3e, - 0xca, 0x69, 0xf7, 0x74, 0x73, 0x51, 0xa9, 0x72, 0x99, 0x7c, 0x04, 0x2b, 0x85, 0x16, 0xd1, 0x4f, - 0x50, 0x2e, 0x00, 0x55, 0x26, 0x22, 0x27, 0xb4, 0xeb, 0xd2, 0x86, 0x51, 0xf9, 0x48, 0x2a, 0x52, - 0x5b, 0x2c, 0x93, 0x19, 0x71, 0xbf, 0x1a, 0xcd, 0x8c, 0x95, 0x60, 0x93, 0x41, 0x7d, 0xc3, 0xa8, - 0xdd, 0xa9, 0x1a, 0x2d, 0xee, 0xca, 0xda, 0xb5, 0xd4, 0xd4, 0x8d, 0x4b, 0x68, 0xa5, 0x04, 0x44, - 0x24, 0x5c, 0xc5, 0x70, 0xea, 0x2f, 0x48, 0xbe, 0x5b, 0x54, 0x4a, 0xdf, 0x13, 0xdf, 0xbc, 0x6f, - 0x37, 0x5d, 0x42, 0xcd, 0x92, 0x05, 0x94, 0xcc, 0x37, 0xac, 0xcb, 0xbe, 0xa5, 0x94, 0xc2, 0xfb, - 0x9c, 0x86, 0x8b, 0x82, 0x89, 0x06, 0x0d, 0xeb, 0x8f, 0xb2, 0xc6, 0x3a, 0x62, 0x5e, 0x1b, 0xe5, - 0x15, 0x69, 0xa5, 0x6b, 0x25, 0x1b, 0xf7, 0x56, 0x5b, 0xd6, 0x2b, 0x47, 0xf3, 0xe6, 0x4b, 0x96, - 0x72, 0x1a, 0x08, 0x5a, 0x7e, 0x2b, 0x09, 0x98, 0xdf, 0x13, 0x29, 0x77, 0xcd, 0xac, 0x52, 0xc8, - 0x99, 0xa2, 0xd7, 0x33, 0x5a, 0x95, 0x46, 0x67, 0xd4, 0x65, 0x57, 0xe9, 0xdb, 0x2f, 0x46, 0x26, - 0xdd, 0x54, 0x9b, 0x87, 0x6f, 0x27, 0xef, 0x48, 0xbe, 0x71, 0x6f, 0x05, 0x34, 0x61, 0x2f, 0x23, - 0xfe, 0x03, 0xa8, 0x4d, 0xe3, 0x5c, 0xab, 0x5c, 0x79, 0xdc, 0x4b, 0x75, 0xa4, 0xfc, 0x46, 0x6e, - 0xea, 0xe7, 0xe8, 0x9d, 0xa7, 0xf0, 0x5f, 0x81, 0x4e, 0x0b, 0xc3, 0x79, 0x74, 0x3f, 0x88, 0xa7, - 0x16, 0x72, 0xb0, 0xa0, 0x33, 0x70, 0x9d, 0xe7, 0x31, 0xbc, 0x0a, 0x43, 0x39, 0x43, 0xcd, 0x59, - 0x2b, 0x63, 0xca, 0xef, 0x8b, 0xac, 0x8d, 0x06, 0xfe, 0x1f, 0x32, 0x1c, 0x1e, 0x78, 0x06, 0xc3, - 0x03, 0xb6, 0xff, 0x78, 0xab, 0x3d, 0x30, 0xe8, 0xbc, 0x2c, 0xe2, 0x57, 0x44, 0x68, 0x5a, 0x05, - 0x3b, 0x17, 0xd4, 0x9c, 0x6c, 0xea, 0x9b, 0x21, 0x17, 0x19, 0xbc, 0x9c, 0xa2, 0xac, 0x6e, 0xfe, - 0x8f, 0x1c, 0x09, 0xd6, 0x53, 0x38, 0x38, 0xf9, 0x95, 0x7d, 0x68, 0xb0, 0x6e, 0xf0, 0x35, 0x8b, - 0xd8, 0xfe, 0x58, 0x11, 0xfa, 0x19, 0x3d, 0x1f, 0xf2, 0x7b, 0xa9, 0x88, 0xff, 0x3e, 0x01, 0x54, - 0x15, 0xf8, 0x18, 0xe7, 0xf4, 0x64, 0xdb, 0xec, 0x44, 0x64, 0xd6, 0xb8, 0x57, 0xad, 0x51, 0xe5, - 0xe1, 0x7d, 0x89, 0x2a, 0x23, 0x5f, 0x97, 0xbb, 0x83, 0x95, 0x3c, 0x40, 0x1b, 0x41, 0xe1, 0x92, - 0xe8, 0x5f, 0xd4, 0xf4, 0x9b, 0x08, 0x0f, 0xfc, 0x7d, 0x38, 0xda, 0x06, 0x7e, 0x35, 0xf8, 0xbf, - 0x65, 0x7f, 0x03, 0x8f, 0x35, 0xff, 0x66, 0xa6, 0x09, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_wifi.htm, do not edit!! -const uint16_t PAGE_settings_wifi_length = 2387; -const uint8_t PAGE_settings_wifi[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xb5, 0x58, 0xff, 0x53, 0xdb, 0x3a, - 0x12, 0xff, 0x3d, 0x7f, 0x85, 0xd0, 0xdd, 0x30, 0xf6, 0xe0, 0x38, 0x09, 0x69, 0xfb, 0x7a, 0x21, - 0x4e, 0x0f, 0x42, 0x5e, 0xe1, 0x1e, 0x85, 0x5c, 0xc3, 0x95, 0xb9, 0xe1, 0x3a, 0xef, 0x19, 0x5b, - 0x49, 0x54, 0x1c, 0xc9, 0xcf, 0x92, 0x13, 0x18, 0xc8, 0xff, 0x7e, 0xbb, 0x92, 0x9d, 0xc4, 0x01, - 0xda, 0x9b, 0x0e, 0x37, 0x9d, 0x29, 0xb6, 0xb5, 0xda, 0xfd, 0xec, 0xb7, 0x8f, 0x56, 0xe9, 0xee, - 0x1c, 0x5f, 0xf4, 0x2f, 0xff, 0x3d, 0x1c, 0x90, 0xa9, 0x9e, 0x25, 0xbd, 0x2e, 0xfe, 0x4f, 0x92, - 0x50, 0x4c, 0x02, 0xca, 0x04, 0x85, 0x77, 0x16, 0xc6, 0xbd, 0xee, 0x8c, 0xe9, 0x90, 0x44, 0xd3, - 0x30, 0x53, 0x4c, 0x07, 0x34, 0xd7, 0xe3, 0xfa, 0x7b, 0x5a, 0x7c, 0xad, 0x89, 0x70, 0xc6, 0x02, - 0x3a, 0xe7, 0x6c, 0x91, 0xca, 0x4c, 0x53, 0x12, 0x49, 0xa1, 0x99, 0x00, 0xb1, 0x05, 0x8f, 0xf5, - 0x34, 0x78, 0xdb, 0x6c, 0xae, 0x44, 0xb7, 0x96, 0x62, 0x36, 0xe7, 0x11, 0xab, 0x9b, 0x17, 0x8f, - 0x0b, 0xae, 0x79, 0x98, 0xd4, 0x55, 0x14, 0x26, 0x2c, 0x68, 0x79, 0xb3, 0xf0, 0x8e, 0xcf, 0xf2, - 0xd9, 0xea, 0x3d, 0x57, 0x2c, 0x33, 0x2f, 0xe1, 0x0d, 0xbc, 0x0b, 0x49, 0x9f, 0x58, 0xee, 0x75, - 0x35, 0xd7, 0x09, 0xeb, 0x5d, 0xf1, 0x5f, 0x39, 0x19, 0x31, 0xad, 0xb9, 0x98, 0xa8, 0x6e, 0xc3, - 0x7e, 0xec, 0xaa, 0x28, 0xe3, 0xa9, 0xee, 0xd5, 0xe6, 0x61, 0x46, 0x12, 0x19, 0xf1, 0xd4, 0x8b, - 0x83, 0x58, 0x46, 0xf9, 0x0c, 0x00, 0x79, 0xf0, 0x21, 0xd8, 0x69, 0xe1, 0x9f, 0x34, 0x93, 0x5a, - 0x06, 0x74, 0xaa, 0x75, 0xda, 0xa1, 0x1e, 0xd8, 0x13, 0x67, 0x52, 0xa6, 0x2a, 0x68, 0x7a, 0x69, - 0xc6, 0x46, 0xf0, 0x3a, 0x1a, 0x9d, 0x1e, 0x07, 0x94, 0x1e, 0x8c, 0x73, 0x11, 0x69, 0x2e, 0x05, - 0x99, 0x9c, 0xc6, 0x8e, 0x76, 0x1f, 0x32, 0xa6, 0xf3, 0x4c, 0x90, 0xd8, 0x9f, 0x30, 0x3d, 0x48, - 0x18, 0xaa, 0x3d, 0xba, 0x37, 0x4b, 0xcb, 0x95, 0x68, 0x34, 0xa8, 0x48, 0x46, 0x19, 0x0b, 0x35, - 0x2b, 0x84, 0x2b, 0x82, 0x27, 0x8e, 0xfb, 0xb0, 0xe0, 0x22, 0x96, 0x0b, 0x5f, 0xa6, 0x4c, 0x38, - 0x06, 0x8f, 0xea, 0x34, 0x1a, 0xb7, 0x42, 0xfa, 0x8b, 0x84, 0xa1, 0x95, 0xc6, 0x18, 0x76, 0xe7, - 0x19, 0x53, 0x0d, 0x55, 0xf8, 0xda, 0xf8, 0xcb, 0x82, 0x8f, 0x79, 0xbd, 0x7c, 0xa5, 0x1b, 0x0a, - 0x8f, 0xb6, 0x14, 0x02, 0xc8, 0x7f, 0x7d, 0x3e, 0x73, 0x68, 0x63, 0x2d, 0xec, 0xd1, 0xdf, 0x15, - 0x4b, 0xc6, 0x9b, 0xbb, 0xce, 0x61, 0x17, 0xe4, 0x4c, 0x69, 0xa2, 0x03, 0x74, 0x93, 0x62, 0x3c, - 0xa8, 0x7b, 0xa0, 0xfd, 0x98, 0x2b, 0xcc, 0x43, 0x1c, 0xec, 0x34, 0x3d, 0xed, 0x6b, 0x76, 0xa7, - 0xfb, 0x65, 0x6e, 0x31, 0x48, 0x02, 0x54, 0xfa, 0xbe, 0x4f, 0xbd, 0x31, 0xd3, 0xd1, 0x74, 0x6d, - 0xed, 0x9b, 0x92, 0xa2, 0x21, 0x98, 0xa6, 0xae, 0xeb, 0xeb, 0x29, 0xe0, 0xd0, 0x41, 0x4f, 0xfb, - 0xf8, 0xd5, 0xd9, 0xf8, 0x72, 0x71, 0xf3, 0x8d, 0x45, 0xda, 0x0f, 0x95, 0xe2, 0x13, 0xe1, 0x3c, - 0x2c, 0xbd, 0x07, 0xd8, 0xb2, 0x90, 0xd9, 0xad, 0xea, 0x5c, 0x7f, 0x5d, 0x7a, 0xda, 0xf5, 0xcb, - 0x77, 0x5f, 0x41, 0xe2, 0x1d, 0x47, 0x7b, 0xcc, 0x0d, 0x7a, 0xcc, 0xcf, 0x60, 0x47, 0x5d, 0x9b, - 0x3f, 0xae, 0x9f, 0xb1, 0x38, 0x8f, 0x58, 0xb9, 0xe8, 0x68, 0x90, 0x9d, 0x31, 0x6b, 0x10, 0xd6, - 0xe3, 0x20, 0x08, 0x98, 0x79, 0x70, 0x1f, 0x1f, 0xb5, 0x9f, 0xe6, 0x6a, 0xea, 0x30, 0x17, 0x74, - 0x7b, 0xd7, 0x5f, 0x4b, 0x28, 0x2c, 0xe8, 0x3d, 0xf0, 0xb1, 0xd3, 0x34, 0xa2, 0x09, 0x13, 0x13, - 0x3d, 0xdd, 0xdd, 0x5d, 0x95, 0x44, 0xb7, 0xd5, 0x74, 0x8b, 0x54, 0xae, 0xbe, 0xed, 0xed, 0x79, - 0x73, 0xc9, 0x63, 0x02, 0x51, 0xbd, 0xe4, 0x33, 0x26, 0x73, 0xed, 0x9c, 0x7b, 0x2d, 0xd6, 0x76, - 0x0f, 0x36, 0x2a, 0xe9, 0x20, 0x61, 0x9a, 0x08, 0x1b, 0xd0, 0xfe, 0x08, 0xc2, 0x09, 0x36, 0x84, - 0xfb, 0x80, 0x5f, 0x75, 0x00, 0x25, 0x42, 0x21, 0x0d, 0xe0, 0xbf, 0x89, 0x33, 0x28, 0x3a, 0xd4, - 0x3a, 0xe3, 0x37, 0xb9, 0x66, 0x0e, 0xe5, 0x31, 0xf5, 0xcc, 0x16, 0x6f, 0x7b, 0x05, 0x5b, 0xe1, - 0xa5, 0x35, 0x29, 0xa0, 0x73, 0xc5, 0x04, 0xd7, 0x2f, 0x1d, 0x17, 0x04, 0x36, 0x2b, 0x59, 0xf8, - 0xf3, 0x30, 0xc9, 0xd9, 0xc1, 0x58, 0x66, 0x0e, 0x22, 0x60, 0x80, 0x8f, 0x75, 0xb5, 0x1f, 0x4d, - 0x79, 0x12, 0x67, 0x4c, 0x14, 0x7e, 0x1f, 0xb0, 0xbd, 0x3d, 0x17, 0x22, 0xcb, 0x66, 0x72, 0xce, - 0xfa, 0xb8, 0xe6, 0xac, 0x65, 0xae, 0xd9, 0x57, 0x77, 0xa5, 0x40, 0x82, 0x02, 0xd9, 0x2d, 0xe3, - 0x75, 0x20, 0x61, 0x5f, 0x51, 0x43, 0xdc, 0x38, 0x27, 0x53, 0x2c, 0x2d, 0xf4, 0x7a, 0x0b, 0xa6, - 0xc1, 0x41, 0x3d, 0x76, 0x2d, 0xbf, 0xda, 0xbc, 0x78, 0xbc, 0x52, 0x58, 0x7f, 0xfc, 0xf5, 0x61, - 0xb5, 0xb6, 0x24, 0x4e, 0xf1, 0x86, 0xb9, 0x5e, 0x92, 0xf8, 0x68, 0xe6, 0xfe, 0xb1, 0xde, 0x0a, - 0x09, 0x2b, 0xfc, 0xda, 0xdd, 0xdd, 0x36, 0x63, 0x83, 0xcb, 0x30, 0x92, 0xab, 0x47, 0x8c, 0x59, - 0x98, 0x42, 0x5f, 0xc4, 0xd6, 0x35, 0xee, 0x2e, 0x2d, 0x64, 0x59, 0x85, 0x2c, 0x9f, 0x87, 0x4c, - 0x77, 0xfa, 0xd8, 0x3f, 0xb2, 0xda, 0x07, 0x17, 0x50, 0x43, 0x19, 0x29, 0x2a, 0xd5, 0x34, 0x43, - 0xd5, 0x88, 0x74, 0x3d, 0x01, 0x01, 0x4d, 0x93, 0x30, 0x62, 0x57, 0x5c, 0x4f, 0x91, 0x00, 0x36, - 0x1b, 0xab, 0xf5, 0x5c, 0x63, 0xd1, 0xe5, 0x46, 0x7b, 0x42, 0x36, 0x8b, 0xaa, 0xa9, 0xd4, 0xd2, - 0x8e, 0x7e, 0x7c, 0x34, 0x90, 0x76, 0x02, 0x6d, 0xa3, 0x50, 0xd4, 0xe9, 0x81, 0x4d, 0x30, 0xba, - 0xc4, 0x45, 0x9a, 0x63, 0x85, 0x31, 0x5f, 0xdf, 0xa7, 0x40, 0xa2, 0x68, 0x08, 0x62, 0xef, 0x43, - 0xec, 0x50, 0x0f, 0x3c, 0x59, 0x72, 0xb5, 0xcf, 0x55, 0xaf, 0x81, 0x99, 0x6d, 0x72, 0xa9, 0xd7, - 0xde, 0x77, 0x61, 0xd9, 0xd8, 0x08, 0x36, 0xaa, 0xca, 0xd3, 0x15, 0xc7, 0xd8, 0x06, 0xe6, 0x44, - 0x86, 0xf1, 0x3f, 0x46, 0xd8, 0x94, 0x40, 0x1d, 0x16, 0xbe, 0xb0, 0x45, 0x6f, 0xf8, 0x19, 0x20, - 0x89, 0xed, 0x84, 0x65, 0x11, 0xc5, 0xbe, 0xdc, 0xfe, 0x8e, 0xc0, 0x21, 0xf6, 0x88, 0xbc, 0xf1, - 0x2d, 0x9c, 0x87, 0xa5, 0x82, 0x27, 0x82, 0xa1, 0xba, 0x17, 0xa0, 0x02, 0xba, 0x3b, 0xf6, 0x6f, - 0x64, 0x7c, 0x5f, 0xc9, 0x82, 0x40, 0xf9, 0x30, 0x8e, 0x07, 0x73, 0x88, 0xf1, 0x19, 0x57, 0x10, - 0x6a, 0x96, 0x39, 0x14, 0x61, 0x52, 0xcf, 0x01, 0xe2, 0x78, 0xf8, 0xc8, 0xf4, 0x17, 0xc7, 0x5d, - 0x3e, 0x2f, 0xc7, 0xb2, 0x4c, 0x66, 0x00, 0x0f, 0xe4, 0xb0, 0x62, 0x64, 0x02, 0x85, 0x2f, 0x27, - 0x0e, 0x1d, 0xe0, 0x77, 0x52, 0xf8, 0x0b, 0x64, 0x48, 0xc6, 0x3c, 0x61, 0xc6, 0x0d, 0x38, 0xcd, - 0x80, 0xb2, 0xe8, 0x59, 0xf1, 0x5d, 0x8e, 0xf1, 0xc0, 0x1c, 0xf3, 0x49, 0x9e, 0x85, 0x26, 0x40, - 0xd6, 0x0d, 0x32, 0x0e, 0x39, 0xd2, 0xfc, 0x7f, 0xc4, 0xa9, 0x88, 0xe4, 0x2c, 0x85, 0x38, 0x31, - 0x92, 0x86, 0x13, 0x46, 0xe2, 0x50, 0x87, 0x3b, 0x40, 0xd2, 0x1b, 0x31, 0x1d, 0xad, 0xea, 0xa0, - 0xa0, 0x78, 0x38, 0xc7, 0x8c, 0x32, 0xac, 0x06, 0x8a, 0x96, 0x3b, 0x34, 0x80, 0x5a, 0x30, 0x67, - 0x5b, 0x24, 0x13, 0xd7, 0x1c, 0x77, 0x4d, 0xcf, 0x31, 0xe7, 0x60, 0x80, 0xd2, 0xc9, 0x48, 0xcb, - 0x0c, 0xd4, 0xe3, 0xe9, 0x75, 0xaa, 0xd9, 0x0c, 0x23, 0x10, 0x9d, 0xa6, 0xc0, 0xd3, 0x8f, 0x8f, - 0x85, 0x18, 0xec, 0x9e, 0xa5, 0x80, 0xfc, 0x57, 0xd0, 0x47, 0x3e, 0xc9, 0x98, 0xf9, 0x64, 0x98, - 0xb0, 0x50, 0x31, 0x02, 0x11, 0x81, 0x4a, 0xbf, 0x3a, 0x1b, 0x1c, 0x93, 0xd3, 0x21, 0x60, 0xf3, - 0x2a, 0x1a, 0x55, 0x55, 0xa3, 0x67, 0xb4, 0xb9, 0x50, 0x7a, 0x89, 0x62, 0x0f, 0xb6, 0x22, 0x01, - 0x5a, 0xa8, 0xa7, 0x58, 0x71, 0x9e, 0x40, 0x56, 0x4e, 0x60, 0x2c, 0x70, 0x5a, 0x50, 0x59, 0x90, - 0x26, 0x65, 0x4a, 0x88, 0x36, 0xa8, 0xfb, 0xa1, 0xde, 0xea, 0x18, 0x76, 0x6d, 0xba, 0xbe, 0x4a, - 0x13, 0xae, 0xcd, 0xd7, 0x83, 0x92, 0xa2, 0x7a, 0xfb, 0xbb, 0xbb, 0xce, 0xea, 0x04, 0x5f, 0x7b, - 0xeb, 0x15, 0xde, 0x5a, 0x2f, 0xb4, 0x3f, 0x95, 0x4a, 0xa3, 0xa9, 0x3d, 0x60, 0x30, 0x9c, 0x1b, - 0x3e, 0xd0, 0x0e, 0xdd, 0xb3, 0x8f, 0x1d, 0x4a, 0xdd, 0x3d, 0x50, 0xba, 0x27, 0xae, 0x9b, 0x5f, - 0xdd, 0x65, 0x51, 0xab, 0x4f, 0xce, 0xca, 0x86, 0x82, 0x23, 0xeb, 0x43, 0x1a, 0xb4, 0xc0, 0xd5, - 0x9d, 0x96, 0x71, 0x17, 0x4c, 0xc7, 0xfe, 0x68, 0xec, 0x87, 0x26, 0x23, 0xc1, 0xd3, 0x2d, 0x78, - 0x32, 0x43, 0x34, 0xd7, 0x49, 0x2b, 0x44, 0x56, 0xf3, 0x00, 0x42, 0xff, 0x50, 0xc2, 0x07, 0x10, - 0x80, 0xc2, 0x20, 0x36, 0x98, 0xf4, 0xb2, 0xd6, 0x6d, 0x14, 0x13, 0x4c, 0x57, 0xe9, 0x7b, 0x18, - 0x68, 0xfe, 0xce, 0x67, 0x08, 0x99, 0xe4, 0x59, 0x02, 0x3d, 0x82, 0x9f, 0xfc, 0x48, 0x01, 0x0d, - 0x1d, 0x80, 0xa0, 0x11, 0xe8, 0x36, 0xec, 0xec, 0x86, 0x25, 0x0f, 0x95, 0x88, 0xce, 0x00, 0x87, - 0xc0, 0x01, 0xd0, 0xeb, 0x02, 0x57, 0xcf, 0x6a, 0x04, 0x7b, 0x1d, 0x9f, 0x7e, 0x57, 0x94, 0xd8, - 0x6e, 0x1f, 0x8d, 0x29, 0x81, 0x49, 0x6d, 0x2a, 0x61, 0x25, 0x85, 0x30, 0x81, 0x68, 0xcc, 0xe7, - 0x24, 0x4a, 0xe0, 0x28, 0x06, 0x8e, 0x90, 0x80, 0x6d, 0x51, 0xfd, 0x36, 0x65, 0x49, 0x7a, 0x44, - 0x7b, 0xb5, 0x2e, 0xb4, 0x9a, 0x06, 0xaf, 0x2c, 0x9b, 0xd8, 0x17, 0x0a, 0x56, 0x23, 0x48, 0xe5, - 0x6d, 0x40, 0x4f, 0xd0, 0xec, 0x87, 0x6e, 0xc3, 0x2e, 0x00, 0x34, 0x50, 0xd1, 0x7b, 0x7e, 0x4f, - 0x6d, 0xb5, 0xe9, 0x08, 0x37, 0x1d, 0x85, 0xd1, 0xed, 0x7a, 0x5f, 0x65, 0x87, 0xca, 0x6f, 0x66, - 0x1c, 0x30, 0x8e, 0xc2, 0x39, 0x23, 0xbb, 0x04, 0x78, 0x52, 0x00, 0x9d, 0xaf, 0x85, 0xa7, 0x19, - 0xe0, 0xb2, 0x96, 0xa6, 0xfb, 0x76, 0x2a, 0x84, 0x74, 0xe4, 0x29, 0x04, 0x66, 0x1f, 0x3e, 0xb5, - 0x7b, 0xc5, 0x0e, 0xa2, 0x25, 0x61, 0x77, 0xd0, 0xd2, 0xd8, 0x8f, 0x05, 0x5f, 0x83, 0x4c, 0x7b, - 0x65, 0xae, 0x56, 0x45, 0x88, 0x71, 0x33, 0x83, 0xd0, 0xda, 0xbf, 0x73, 0x84, 0x8a, 0xec, 0xb7, - 0x01, 0x15, 0xac, 0x9f, 0x5b, 0x65, 0x26, 0xba, 0xc4, 0x31, 0xcc, 0x48, 0x18, 0x34, 0xd1, 0x3d, - 0x9a, 0x14, 0x52, 0x63, 0xeb, 0x23, 0x02, 0xb7, 0x83, 0xe2, 0x5d, 0x43, 0xca, 0x64, 0x83, 0x90, - 0x49, 0x41, 0xc7, 0xe5, 0xa8, 0x8b, 0x8f, 0x2b, 0xf6, 0x0d, 0x68, 0x7b, 0x9f, 0x1a, 0x3b, 0xa5, - 0x99, 0x14, 0x52, 0x02, 0x0f, 0xf1, 0x53, 0x6d, 0xe5, 0xca, 0x5a, 0xd3, 0xb0, 0xa2, 0xe9, 0x5d, - 0xdb, 0x6a, 0x1a, 0x69, 0xe0, 0x8d, 0x08, 0xba, 0x98, 0xc0, 0x59, 0x8e, 0x61, 0x0d, 0x35, 0x69, - 0xfa, 0xe6, 0x1f, 0x81, 0x52, 0x21, 0xc7, 0x27, 0xfd, 0x61, 0x05, 0x6c, 0xa1, 0xee, 0xb4, 0x49, - 0x0b, 0x4b, 0x22, 0x9f, 0xdd, 0xb0, 0x8c, 0x96, 0xf5, 0x01, 0xa5, 0x35, 0xe3, 0x22, 0xa0, 0x4d, - 0x63, 0x2e, 0xa0, 0xfb, 0x6f, 0xdf, 0x52, 0x92, 0xb1, 0x3f, 0x73, 0x0e, 0xe3, 0x59, 0x8f, 0xf8, - 0x64, 0x4b, 0x4f, 0xeb, 0x95, 0xf4, 0xec, 0xbf, 0x92, 0x9e, 0xf6, 0x4f, 0xe9, 0xd9, 0x08, 0xe5, - 0x04, 0x26, 0xfc, 0x45, 0x78, 0xdf, 0xa9, 0x6d, 0x04, 0xcd, 0xea, 0xfe, 0xf8, 0xd3, 0x31, 0xab, - 0x55, 0xf5, 0xbc, 0x52, 0xcc, 0x3e, 0xbe, 0x52, 0xcc, 0x3e, 0xfe, 0x7c, 0xcc, 0x6a, 0x45, 0xd0, - 0xa0, 0xb3, 0xa1, 0x0f, 0x41, 0x4a, 0xdd, 0x76, 0x9e, 0xc4, 0x6d, 0xf4, 0x3f, 0xc4, 0xad, 0xf6, - 0x5d, 0xa0, 0x85, 0x9e, 0xd6, 0x2b, 0xe9, 0xd9, 0x7f, 0x25, 0x3d, 0xed, 0x9f, 0xd3, 0x83, 0x01, - 0x9a, 0x1d, 0x9f, 0x8f, 0x08, 0x4c, 0x27, 0x70, 0x1b, 0x54, 0x65, 0xeb, 0x5a, 0xa2, 0xc1, 0xae, - 0x15, 0x92, 0xa0, 0x80, 0x6d, 0x5c, 0x73, 0xb3, 0x6d, 0x34, 0x0a, 0xdb, 0xb5, 0x0a, 0xdd, 0x14, - 0xdc, 0xf0, 0xe9, 0x09, 0xcb, 0x10, 0x33, 0x52, 0x24, 0xb8, 0xbf, 0x9f, 0x70, 0x38, 0xef, 0x81, - 0x22, 0x3a, 0xa4, 0xab, 0xd2, 0x50, 0xac, 0x50, 0xf2, 0x14, 0xce, 0x81, 0xf3, 0x35, 0xa9, 0xb1, - 0x18, 0x4e, 0x22, 0x10, 0x30, 0x00, 0x0b, 0xba, 0x35, 0x73, 0x0e, 0x23, 0x87, 0x51, 0x84, 0x40, - 0x87, 0x92, 0x0b, 0x6d, 0x98, 0xb6, 0x76, 0x38, 0x24, 0x48, 0x8f, 0xcf, 0x62, 0x3f, 0x1c, 0xbe, - 0xc8, 0x8f, 0x16, 0xf0, 0xe1, 0x53, 0x5a, 0x34, 0xed, 0x76, 0xc2, 0x63, 0xb0, 0x35, 0x34, 0x52, - 0x1d, 0x52, 0xd9, 0x1e, 0x4d, 0x59, 0x74, 0x7b, 0x23, 0xef, 0x56, 0x2a, 0x4e, 0x2c, 0x01, 0x22, - 0x90, 0x92, 0x2c, 0x9f, 0x82, 0xc1, 0xab, 0xb3, 0xfb, 0x3d, 0x76, 0x2d, 0x94, 0x0d, 0x6d, 0xa6, - 0x36, 0xd8, 0x15, 0x94, 0x6a, 0x18, 0x92, 0x20, 0x8b, 0x8e, 0xff, 0xf0, 0xde, 0x7b, 0xd7, 0x5e, - 0xba, 0x8f, 0x70, 0x66, 0x10, 0xf3, 0xe3, 0x44, 0x40, 0x07, 0xc6, 0x04, 0x58, 0x80, 0x44, 0xfb, - 0xe4, 0xbd, 0xf9, 0xa9, 0x05, 0x46, 0x09, 0x96, 0xa9, 0x12, 0xd6, 0x46, 0xc4, 0x88, 0x39, 0xca, - 0xf0, 0x4e, 0x27, 0x58, 0xd2, 0xa9, 0x16, 0xd1, 0x61, 0xff, 0x85, 0x22, 0xba, 0x2b, 0xab, 0xa8, - 0x55, 0x56, 0x51, 0xab, 0xbd, 0x55, 0x44, 0xe0, 0x3a, 0x3a, 0xa8, 0x30, 0xb1, 0xe6, 0x66, 0x54, - 0xea, 0x84, 0x03, 0xbe, 0x6b, 0xef, 0x40, 0xc4, 0x8e, 0xfa, 0x50, 0x8a, 0x98, 0xea, 0x32, 0xd3, - 0xb8, 0x10, 0x8e, 0x71, 0x06, 0xbc, 0x91, 0x12, 0x12, 0x6a, 0x65, 0xb7, 0xf7, 0xb4, 0x68, 0xef, - 0x98, 0xab, 0x8d, 0xe2, 0xd8, 0x12, 0xab, 0x15, 0x72, 0x90, 0xbd, 0xc3, 0x04, 0x28, 0x53, 0xbd, - 0xa4, 0x08, 0xce, 0xaa, 0x73, 0x36, 0x07, 0x6b, 0x0e, 0x1e, 0xa1, 0x19, 0x83, 0xf9, 0x78, 0x06, - 0x83, 0x22, 0x8b, 0xdd, 0xd5, 0x0e, 0x9c, 0x96, 0x8c, 0x0b, 0xa5, 0x63, 0xcf, 0x97, 0x2b, 0x56, - 0x2b, 0x4e, 0x6c, 0x73, 0xb6, 0x55, 0xaa, 0x83, 0xbb, 0x94, 0x65, 0x1c, 0x7f, 0x96, 0x81, 0xa2, - 0x37, 0x05, 0x7a, 0x6c, 0xef, 0x65, 0x36, 0xf6, 0x2a, 0x61, 0x2c, 0xfd, 0x41, 0x45, 0x5d, 0x8d, - 0x6c, 0xea, 0xba, 0xbc, 0x57, 0xeb, 0x83, 0x5d, 0x9c, 0x94, 0xc8, 0x02, 0x66, 0xd9, 0x55, 0xd4, - 0xe6, 0x1c, 0x72, 0xce, 0x95, 0xca, 0x99, 0xf2, 0x4d, 0x92, 0x8f, 0xed, 0x50, 0xc0, 0x84, 0xb1, - 0xc4, 0xc7, 0xd6, 0x18, 0x57, 0x04, 0x4f, 0x77, 0x1c, 0x4e, 0x22, 0x99, 0x81, 0xbb, 0x3a, 0xb9, - 0xf7, 0x08, 0x17, 0xf8, 0xeb, 0x91, 0x62, 0x8a, 0xa4, 0x72, 0x01, 0xb1, 0xc0, 0xdb, 0x47, 0x3e, - 0x33, 0xde, 0xfb, 0xdd, 0x06, 0x37, 0x43, 0x9a, 0x1d, 0xf1, 0xe0, 0xce, 0x1e, 0x53, 0xe3, 0xd5, - 0x15, 0xa4, 0x3a, 0xc1, 0x32, 0xfa, 0x0c, 0xd7, 0x78, 0xcd, 0xec, 0x8c, 0xc3, 0x7b, 0xf6, 0x36, - 0x63, 0x0a, 0x9c, 0xe1, 0xed, 0x46, 0x11, 0x89, 0xd1, 0x1d, 0x8c, 0x86, 0xf5, 0xf3, 0x8b, 0x2b, - 0x83, 0xec, 0x37, 0xf0, 0x97, 0x94, 0x57, 0x53, 0x44, 0x86, 0x38, 0x73, 0x85, 0x98, 0x42, 0x92, - 0x19, 0x6d, 0x3f, 0x80, 0x84, 0x91, 0x00, 0x58, 0xb5, 0x81, 0x75, 0xce, 0x22, 0xf8, 0x41, 0x08, - 0x3f, 0x0f, 0x6c, 0x08, 0x4f, 0xc2, 0x2c, 0x5e, 0x84, 0xc0, 0x1b, 0x9f, 0x0e, 0xfb, 0xab, 0x2d, - 0xb5, 0xa7, 0x3c, 0xf0, 0x19, 0xd6, 0xed, 0x8e, 0xb3, 0x10, 0x2e, 0xef, 0x23, 0xc6, 0xc4, 0x56, - 0xd6, 0xb3, 0x84, 0xc7, 0x98, 0x76, 0x51, 0x49, 0xb8, 0x99, 0x11, 0x6b, 0x66, 0xac, 0xc5, 0x80, - 0xc1, 0x00, 0x5c, 0x04, 0x6c, 0x80, 0x57, 0x78, 0x3c, 0x89, 0x2e, 0xc1, 0x96, 0x0d, 0x57, 0xa5, - 0x33, 0x06, 0x97, 0x27, 0xcf, 0xb5, 0x06, 0xea, 0xaf, 0xbd, 0x54, 0xbd, 0x7f, 0x83, 0xf2, 0x3e, - 0xea, 0xef, 0xd8, 0xeb, 0xd2, 0x97, 0x37, 0x6d, 0x98, 0x5c, 0xf1, 0x82, 0x07, 0xe7, 0x1e, 0xc4, - 0xe5, 0xa5, 0x4d, 0xc8, 0x68, 0x90, 0x8f, 0xf6, 0x7e, 0x7d, 0x78, 0x31, 0x78, 0x49, 0xe8, 0x1d, - 0xed, 0x19, 0x99, 0x63, 0x96, 0xdf, 0xbd, 0x24, 0xf3, 0x0b, 0xed, 0xfd, 0x76, 0x7a, 0x59, 0xff, - 0x32, 0x78, 0x11, 0xdf, 0x7b, 0xda, 0xfb, 0x67, 0xce, 0x05, 0xa0, 0xab, 0x1f, 0xf3, 0x49, 0xfd, - 0x22, 0xd2, 0x21, 0x40, 0xbc, 0xac, 0x83, 0xaf, 0xcf, 0x1a, 0x2f, 0xdb, 0xf6, 0xcd, 0x7a, 0x9f, - 0x41, 0xf1, 0x22, 0x0d, 0x40, 0x80, 0x46, 0x2c, 0x9b, 0xfc, 0xf2, 0x06, 0x55, 0x3e, 0x23, 0x57, - 0x2a, 0x7c, 0x4b, 0x7b, 0x97, 0x0b, 0x9e, 0xf0, 0xc9, 0x54, 0x9f, 0x01, 0xb9, 0x7e, 0x5f, 0x2b, - 0x70, 0xc2, 0xd5, 0xf3, 0x02, 0xb5, 0x35, 0xfd, 0x5c, 0x5d, 0x42, 0x00, 0xc1, 0x68, 0xb3, 0xb5, - 0x96, 0xda, 0xe4, 0x89, 0x75, 0x31, 0xe0, 0xdd, 0xe1, 0xff, 0x7d, 0x3d, 0x69, 0xe0, 0xdd, 0x0b, - 0x99, 0x0a, 0x2f, 0x68, 0x78, 0x5b, 0xc3, 0xdf, 0xdf, 0xff, 0x0b, 0x68, 0xad, 0xac, 0xd2, 0x8f, - 0x17, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_leds.htm, do not edit!! -const uint16_t PAGE_settings_leds_length = 8389; -const uint8_t PAGE_settings_leds[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xdd, 0x7d, 0xeb, 0x76, 0xdb, 0x38, - 0xd2, 0xe0, 0x7f, 0x3d, 0x05, 0x8d, 0xee, 0x76, 0xc8, 0x16, 0x25, 0x91, 0xb2, 0x95, 0x76, 0x24, - 0x51, 0x5e, 0x5f, 0x92, 0xb4, 0xbf, 0xb1, 0x63, 0x1f, 0xdb, 0xe9, 0xcc, 0x77, 0xd2, 0xd9, 0x0e, - 0x44, 0x41, 0x12, 0x63, 0x8a, 0xd4, 0x90, 0x94, 0x2f, 0x6b, 0x7b, 0x9f, 0x69, 0x9f, 0x61, 0x9f, - 0x6c, 0xab, 0x70, 0xe1, 0x45, 0x24, 0x65, 0xf7, 0xce, 0xb7, 0x7f, 0x76, 0xce, 0xe9, 0x98, 0x22, - 0x0b, 0x85, 0x42, 0xa1, 0xae, 0x40, 0x01, 0x33, 0xdc, 0x3a, 0x3e, 0x3f, 0xba, 0xfe, 0xcf, 0x8b, - 0xf7, 0xda, 0x3c, 0x59, 0xf8, 0xa3, 0x21, 0xfe, 0xab, 0xf9, 0x34, 0x98, 0x39, 0x84, 0x05, 0x04, - 0x7e, 0x33, 0x3a, 0x19, 0x0d, 0x17, 0x2c, 0xa1, 0x9a, 0x3b, 0xa7, 0x51, 0xcc, 0x12, 0x87, 0xac, - 0x92, 0x69, 0x6b, 0x8f, 0xc8, 0xb7, 0x8d, 0x80, 0x2e, 0x98, 0x43, 0x6e, 0x3d, 0x76, 0xb7, 0x0c, - 0xa3, 0x84, 0x68, 0x6e, 0x18, 0x24, 0x2c, 0x00, 0xb0, 0x3b, 0x6f, 0x92, 0xcc, 0x9d, 0x9e, 0x65, - 0xa5, 0xa0, 0x6b, 0x9f, 0x26, 0xec, 0xd6, 0x73, 0x59, 0x8b, 0xff, 0x30, 0xbd, 0xc0, 0x4b, 0x3c, - 0xea, 0xb7, 0x62, 0x97, 0xfa, 0xcc, 0xb1, 0xcd, 0x05, 0xbd, 0xf7, 0x16, 0xab, 0x45, 0xfa, 0x7b, - 0x15, 0xb3, 0x88, 0xff, 0xa0, 0x63, 0xf8, 0x1d, 0x84, 0xa4, 0xd4, 0xf3, 0x68, 0x98, 0x78, 0x89, - 0xcf, 0x46, 0xa7, 0xef, 0x8f, 0xb5, 0x2b, 0x96, 0x24, 0x5e, 0x30, 0x8b, 0x87, 0x1d, 0xf1, 0x6e, - 0x18, 0xbb, 0x91, 0xb7, 0x4c, 0x46, 0x8d, 0x5b, 0x1a, 0x69, 0x13, 0x67, 0x12, 0xba, 0xab, 0x05, - 0x50, 0x62, 0xfa, 0x74, 0x19, 0xb1, 0x5b, 0xa7, 0xd7, 0xc3, 0xfe, 0x0e, 0x45, 0xb7, 0x7f, 0x38, - 0x16, 0xfe, 0x39, 0x73, 0x76, 0xd9, 0x0e, 0x3e, 0x5c, 0x1c, 0x3a, 0xbb, 0xd6, 0xbb, 0xb7, 0xf8, - 0x78, 0xea, 0xd8, 0x3b, 0x3b, 0xfc, 0xe5, 0xe9, 0xf8, 0x5f, 0xab, 0x30, 0x71, 0xac, 0xc1, 0xa4, - 0xbd, 0x5a, 0xfc, 0xb5, 0x74, 0xbe, 0x7e, 0x33, 0x27, 0xed, 0x28, 0xbe, 0x9d, 0xc8, 0xa7, 0xf0, - 0xaf, 0xd9, 0xd2, 0x0b, 0xc5, 0x0f, 0x00, 0x17, 0xbf, 0x7a, 0xd6, 0x00, 0xfb, 0xf7, 0x43, 0xd7, - 0x5b, 0x9a, 0x89, 0xb7, 0x60, 0xe1, 0x2a, 0x31, 0xdd, 0x55, 0x9c, 0x84, 0x8b, 0xab, 0x84, 0x46, - 0x49, 0xec, 0x6c, 0xd9, 0x66, 0xcc, 0x9f, 0x8e, 0xbd, 0x28, 0x79, 0xc0, 0xe6, 0xd0, 0xf8, 0xe8, - 0xfc, 0xfc, 0x96, 0x45, 0x91, 0x37, 0x61, 0xb1, 0xd3, 0x33, 0xa1, 0x35, 0x82, 0xc1, 0x9f, 0x65, - 0x14, 0x26, 0xa1, 0x43, 0xe6, 0x49, 0xb2, 0xec, 0x93, 0xc1, 0x74, 0x15, 0xb8, 0x89, 0x17, 0x06, - 0xda, 0xef, 0xba, 0xf1, 0x78, 0xe7, 0x05, 0x93, 0xf0, 0xae, 0x1d, 0x2e, 0x59, 0xa0, 0x73, 0x80, - 0xb8, 0xdf, 0xe9, 0xdc, 0x04, 0x61, 0xfb, 0xce, 0x67, 0x93, 0xf6, 0x8c, 0x75, 0xa6, 0x8c, 0x26, - 0xab, 0x88, 0xc5, 0x9d, 0x58, 0x72, 0xaa, 0xf3, 0x13, 0x7c, 0x69, 0xa9, 0x5f, 0xc4, 0x78, 0x4e, - 0xf1, 0x1d, 0xae, 0xe1, 0x9b, 0xb1, 0xe4, 0xf3, 0xe5, 0xa9, 0x4e, 0x3a, 0x19, 0xb0, 0x49, 0xfe, - 0x8a, 0x99, 0x3f, 0xcd, 0xb7, 0x9a, 0x9d, 0x4c, 0x74, 0x66, 0x3c, 0x46, 0x0c, 0xba, 0x09, 0x34, - 0xec, 0x33, 0x79, 0xef, 0x33, 0x64, 0xfa, 0xe1, 0x03, 0xff, 0x94, 0x81, 0x86, 0xd3, 0x29, 0x82, - 0xe6, 0x61, 0xe2, 0xc3, 0x87, 0x4f, 0x30, 0xbb, 0xf0, 0xfa, 0xab, 0xf5, 0xad, 0x7d, 0x4b, 0xfd, - 0x15, 0x73, 0x5a, 0x76, 0xd6, 0xc4, 0x0f, 0xe9, 0xe4, 0x3f, 0xae, 0x74, 0x66, 0x06, 0xce, 0x96, - 0x65, 0x3c, 0xfa, 0x2c, 0xd1, 0x12, 0x67, 0xd2, 0x76, 0x23, 0x18, 0x16, 0x93, 0x38, 0x74, 0x22, - 0x26, 0x9d, 0x18, 0x83, 0xa4, 0x0d, 0xb4, 0x1e, 0x24, 0x49, 0xe4, 0x8d, 0x57, 0x09, 0x83, 0x0f, - 0x91, 0x4b, 0x4c, 0x66, 0x98, 0xeb, 0xef, 0x93, 0x87, 0x25, 0x23, 0x26, 0x49, 0xd8, 0x7d, 0xd2, - 0xf9, 0x41, 0x6f, 0xa9, 0x42, 0x50, 0x02, 0xa4, 0xf1, 0x43, 0x00, 0x28, 0x02, 0x03, 0xa6, 0x77, - 0x1c, 0x4e, 0x1e, 0xda, 0x74, 0x09, 0xac, 0x99, 0x1c, 0xcd, 0x3d, 0x7f, 0xa2, 0x27, 0x08, 0x4f, - 0x27, 0x93, 0xf7, 0xb7, 0x40, 0xc5, 0xa9, 0x17, 0x83, 0xcc, 0xb3, 0x48, 0x27, 0x48, 0x33, 0x31, - 0x75, 0xc3, 0x19, 0x3d, 0x7e, 0x64, 0xc9, 0x1f, 0xba, 0x61, 0xba, 0x73, 0xe6, 0xde, 0x5c, 0x79, - 0xf0, 0x84, 0xd8, 0x0f, 0x4f, 0x75, 0x44, 0x77, 0x35, 0xad, 0x68, 0x1b, 0xaf, 0xc6, 0x0b, 0x2f, - 0x21, 0x66, 0x12, 0x3d, 0x5c, 0xf1, 0x47, 0xc3, 0x6c, 0xd9, 0x8e, 0x23, 0x84, 0x0f, 0x58, 0xb4, - 0xbd, 0x2d, 0x1e, 0xdb, 0xf1, 0xdc, 0x9b, 0x26, 0x80, 0x67, 0xe9, 0x05, 0xc7, 0x51, 0xb8, 0x84, - 0x49, 0x0b, 0x62, 0xdd, 0x78, 0xae, 0xa6, 0x08, 0x84, 0x2a, 0x8c, 0x80, 0x11, 0x40, 0x11, 0xa8, - 0x66, 0x1c, 0xfa, 0xac, 0xed, 0x87, 0x33, 0x9d, 0xbc, 0xc7, 0xf7, 0x9a, 0x64, 0x33, 0xcc, 0xb0, - 0x36, 0xf5, 0x7c, 0xc6, 0x19, 0x06, 0xba, 0x18, 0x01, 0x63, 0x4f, 0xe5, 0xfb, 0x70, 0x8a, 0xea, - 0x3e, 0xf5, 0x66, 0xab, 0x88, 0xf2, 0x79, 0x11, 0x0c, 0xd3, 0xa6, 0xd4, 0x43, 0x39, 0xfb, 0x33, - 0x38, 0x09, 0xdc, 0x70, 0xb1, 0x84, 0xe9, 0x61, 0xda, 0x92, 0xce, 0x98, 0x36, 0xa1, 0x09, 0xdd, - 0x02, 0x31, 0xc9, 0xcd, 0x7e, 0x3c, 0x0f, 0xef, 0xae, 0x43, 0x1a, 0x27, 0x62, 0x36, 0x6d, 0xe3, - 0x11, 0x75, 0x24, 0x71, 0x50, 0x80, 0x48, 0x82, 0x1f, 0xf8, 0x04, 0x7a, 0x01, 0x90, 0xfc, 0xfb, - 0xf5, 0xd9, 0xa9, 0xc3, 0x60, 0x2c, 0xae, 0x4f, 0xe3, 0x18, 0x25, 0xc4, 0x09, 0xf6, 0xe5, 0x30, - 0xfa, 0x04, 0x31, 0x11, 0xd3, 0xf5, 0x19, 0x8d, 0xae, 0x85, 0x72, 0xe9, 0x52, 0xc9, 0xf8, 0x04, - 0x26, 0x0f, 0x30, 0x3e, 0x1a, 0x78, 0x0b, 0x4e, 0xaa, 0x43, 0x82, 0x30, 0x80, 0x41, 0x49, 0x08, - 0x07, 0x66, 0x40, 0x35, 0xd2, 0x15, 0x6d, 0x20, 0xf8, 0xf9, 0xae, 0x72, 0xcf, 0xed, 0x88, 0x2d, - 0x7d, 0xea, 0xa2, 0x28, 0xf1, 0x4e, 0x09, 0x8e, 0xc9, 0xec, 0xbe, 0xb3, 0xac, 0xdc, 0xc8, 0xc6, - 0xa7, 0x1e, 0xcc, 0x54, 0x8c, 0xe3, 0x32, 0x13, 0x93, 0x9a, 0x9e, 0xf1, 0xc8, 0xad, 0x0c, 0x13, - 0x56, 0x26, 0x10, 0x56, 0x86, 0x4a, 0x1b, 0x93, 0x08, 0x03, 0xe3, 0x65, 0xed, 0x61, 0x0e, 0xe3, - 0xf3, 0x7f, 0xe8, 0x82, 0x21, 0xcc, 0xe1, 0xa2, 0xf1, 0xaf, 0x15, 0x03, 0x11, 0x60, 0x3e, 0x73, - 0x93, 0x30, 0x3a, 0xf0, 0x7d, 0x9d, 0xfc, 0xb4, 0x38, 0x3d, 0xd2, 0xbc, 0x60, 0xb9, 0x4a, 0xbe, - 0xa2, 0x41, 0xfc, 0xef, 0xce, 0xe9, 0x37, 0x60, 0xd8, 0x34, 0x8c, 0x74, 0x0f, 0xcc, 0x93, 0x37, - 0x84, 0x39, 0x65, 0xc1, 0x2c, 0x99, 0x0f, 0xbc, 0x66, 0x53, 0xa0, 0x0a, 0x1c, 0xf6, 0xd5, 0xfb, - 0xd6, 0x46, 0xe8, 0x36, 0x08, 0x56, 0x0c, 0x52, 0x1d, 0xcc, 0x74, 0xcb, 0xec, 0x1a, 0x03, 0x6f, - 0x0a, 0x93, 0x6b, 0x11, 0xc7, 0x09, 0x9e, 0x9e, 0xc8, 0xa9, 0xad, 0x1e, 0xba, 0xea, 0x61, 0x07, - 0x1f, 0xd4, 0x0c, 0x55, 0x61, 0x11, 0x38, 0x96, 0xe8, 0x29, 0x4e, 0x40, 0x05, 0xab, 0x74, 0x9a, - 0x9c, 0x5e, 0x93, 0x66, 0x92, 0x29, 0xb6, 0x69, 0x5b, 0xc6, 0xc8, 0xd9, 0xb3, 0x0c, 0x74, 0x0f, - 0x5e, 0xb0, 0x62, 0xcf, 0x80, 0xe1, 0x15, 0x64, 0xe0, 0xc3, 0x2e, 0xa7, 0x67, 0x7b, 0x9b, 0x90, - 0x2d, 0x41, 0x0e, 0xc7, 0x08, 0xbf, 0x5b, 0x76, 0xe1, 0x8d, 0x20, 0x99, 0x3a, 0xc2, 0x46, 0xb7, - 0xa1, 0x27, 0x97, 0x22, 0x75, 0xa8, 0x33, 0x9c, 0xe2, 0x1a, 0xe6, 0xc6, 0xfc, 0x47, 0x1b, 0x66, - 0x82, 0x18, 0x6d, 0xe0, 0xe9, 0x7b, 0xea, 0xce, 0x75, 0xd4, 0x17, 0x26, 0xf0, 0x8e, 0x5a, 0xf6, - 0xf6, 0x36, 0x6d, 0x2f, 0x57, 0xf1, 0x3c, 0x1b, 0xb4, 0xfc, 0x66, 0xa0, 0x48, 0xd0, 0x76, 0x1c, - 0xc2, 0x98, 0x03, 0x67, 0x14, 0x38, 0x4e, 0x06, 0x91, 0x11, 0x66, 0x18, 0xd2, 0x44, 0x0a, 0xd5, - 0xfa, 0x7e, 0x15, 0x46, 0xd1, 0x83, 0xc9, 0xe7, 0x5e, 0xfb, 0xf9, 0xf1, 0x3f, 0xae, 0xce, 0x3f, - 0xb5, 0x05, 0x6b, 0xbd, 0xe9, 0x83, 0x4e, 0x8d, 0x67, 0xcd, 0xa5, 0xc1, 0x9b, 0x44, 0x1b, 0x33, - 0x0d, 0x3c, 0xe2, 0xa4, 0xfd, 0xdd, 0x30, 0x33, 0x64, 0x0e, 0x21, 0xe2, 0xd7, 0x14, 0xfc, 0x1b, - 0xa8, 0xbd, 0xb9, 0x65, 0xe3, 0xd8, 0x3a, 0xbf, 0x6e, 0xe9, 0xc1, 0x42, 0x73, 0x1c, 0x8d, 0x9c, - 0x5c, 0x12, 0xed, 0xe9, 0x49, 0x0b, 0x16, 0x8e, 0x43, 0x0e, 0xaf, 0x89, 0xa1, 0x6d, 0x6f, 0xff, - 0xda, 0x49, 0xdd, 0xd5, 0x7f, 0x29, 0xad, 0x29, 0x56, 0xa0, 0x99, 0x46, 0x4c, 0x88, 0x28, 0x18, - 0x15, 0xff, 0xe1, 0x65, 0xa2, 0x51, 0x7a, 0x7f, 0x38, 0x5e, 0xd3, 0x1e, 0xfc, 0xc8, 0xe4, 0xf7, - 0x87, 0x92, 0x5f, 0x1f, 0x26, 0xf6, 0xc7, 0x0b, 0xf2, 0xeb, 0x2b, 0xc1, 0xf1, 0x95, 0xe0, 0xf8, - 0x4a, 0x70, 0x7c, 0x25, 0x38, 0xbe, 0xf1, 0xc8, 0xe1, 0xe1, 0xd1, 0xf1, 0x0b, 0x98, 0x6c, 0x43, - 0xf4, 0x14, 0x56, 0xf6, 0xf4, 0x5a, 0x19, 0x0f, 0x5f, 0x90, 0x71, 0x21, 0xb4, 0x3f, 0x52, 0xa1, - 0xcd, 0xf1, 0x24, 0xf7, 0x7e, 0x8d, 0xe7, 0x17, 0x5e, 0xc0, 0x6d, 0xae, 0xef, 0xb9, 0x28, 0x05, - 0xc9, 0x1d, 0x63, 0x01, 0x30, 0x3f, 0xd5, 0xc5, 0xe7, 0x0e, 0xfe, 0x90, 0x44, 0x3f, 0x6f, 0x71, - 0x56, 0xff, 0x28, 0xb0, 0xfa, 0x47, 0x9e, 0xd5, 0xcf, 0xf0, 0x3f, 0xd1, 0xc1, 0x96, 0x95, 0x59, - 0x9e, 0xd4, 0xcd, 0xa0, 0x5f, 0x56, 0xda, 0x81, 0xb6, 0x3b, 0x87, 0xa7, 0x8d, 0x91, 0x13, 0x0c, - 0xf9, 0x98, 0x4d, 0xe9, 0xca, 0x47, 0x9f, 0xb3, 0xa5, 0x0c, 0x96, 0x22, 0x19, 0x98, 0x96, 0x84, - 0xcb, 0x0b, 0xf0, 0x43, 0x74, 0x46, 0x85, 0x41, 0x95, 0x22, 0xc9, 0xa3, 0xa7, 0x91, 0x0d, 0xe6, - 0x52, 0x5a, 0x24, 0x72, 0x1d, 0x86, 0xda, 0x82, 0x06, 0x0f, 0x1a, 0x84, 0x6f, 0xb1, 0x06, 0x02, - 0xa0, 0x2d, 0x98, 0x96, 0x84, 0xda, 0x9c, 0x06, 0x13, 0x9f, 0x6d, 0x91, 0x01, 0x1a, 0xcb, 0xa1, - 0xcd, 0x76, 0xb7, 0xb7, 0xf5, 0xa0, 0xe9, 0x90, 0x3f, 0x83, 0x3f, 0xa3, 0x23, 0x70, 0x5a, 0x10, - 0x15, 0x45, 0xa0, 0x0a, 0xe8, 0x8d, 0x68, 0xa0, 0xbd, 0xbf, 0xba, 0xd8, 0xe9, 0xb6, 0x89, 0x72, - 0x54, 0x81, 0xf1, 0xcc, 0x49, 0xe7, 0x8e, 0xf6, 0x0f, 0xea, 0x7b, 0x13, 0x2f, 0x79, 0xd0, 0x0d, - 0xf4, 0x96, 0xf0, 0x56, 0x38, 0x55, 0x3d, 0x67, 0xb1, 0x59, 0xc0, 0xbd, 0xb0, 0x34, 0xb8, 0xdc, - 0x03, 0x61, 0xb8, 0x09, 0xba, 0xcf, 0x31, 0xb0, 0xc9, 0x80, 0x37, 0x3c, 0x3d, 0x90, 0x7c, 0x60, - 0xfb, 0x22, 0x80, 0xec, 0x5b, 0xa6, 0x02, 0x06, 0x58, 0xe1, 0x69, 0x26, 0x5e, 0x0c, 0x2e, 0xe2, - 0x01, 0x60, 0x88, 0x17, 0xf8, 0x1e, 0xf8, 0x9a, 0xbe, 0x74, 0x39, 0x1c, 0x74, 0x19, 0xaf, 0xba, - 0xaf, 0x80, 0x2d, 0xf4, 0x37, 0xb2, 0xb6, 0xb7, 0xd3, 0x48, 0xe1, 0xf3, 0x49, 0x91, 0xf2, 0xd3, - 0x83, 0xa2, 0xa7, 0x38, 0x3d, 0x00, 0xe3, 0x25, 0xda, 0xad, 0x53, 0x2d, 0x28, 0x38, 0x3d, 0x80, - 0x6e, 0x4b, 0x24, 0xf4, 0x2c, 0xa7, 0x82, 0x8c, 0x62, 0x67, 0x8a, 0x86, 0xc7, 0xf8, 0xce, 0x4b, - 0xc0, 0x20, 0x56, 0x30, 0x0a, 0xc2, 0x32, 0x73, 0x9d, 0x0c, 0xc0, 0x6d, 0xe6, 0xb4, 0x26, 0x47, - 0x12, 0xa8, 0x9b, 0x4b, 0x63, 0xa6, 0x59, 0xfd, 0x4a, 0x54, 0xb6, 0x29, 0x27, 0x66, 0x30, 0x86, - 0x00, 0xef, 0x66, 0xc0, 0x61, 0x77, 0xac, 0x7e, 0xa9, 0x83, 0x1d, 0xab, 0x00, 0xd1, 0xab, 0x80, - 0xe8, 0xe5, 0x21, 0x7a, 0x15, 0x10, 0xbd, 0x02, 0x44, 0xb7, 0x0a, 0xa4, 0x9b, 0xc2, 0x4c, 0x84, - 0xf0, 0xf7, 0x37, 0x30, 0x54, 0xb1, 0xf2, 0x99, 0xc3, 0x2c, 0x6c, 0x00, 0xc8, 0x62, 0x19, 0x14, - 0xea, 0x5c, 0xcc, 0xcc, 0x92, 0x33, 0xb6, 0xc0, 0x78, 0x41, 0x85, 0xb4, 0x2f, 0x18, 0x99, 0x23, - 0xd2, 0x0c, 0x32, 0x23, 0x03, 0x61, 0x52, 0xf3, 0x85, 0x16, 0x57, 0xa7, 0x6b, 0x2d, 0xb0, 0x1b, - 0x0a, 0x71, 0x42, 0x1a, 0xa7, 0xe3, 0x50, 0x8f, 0x15, 0xeb, 0x41, 0xd7, 0xa8, 0xb3, 0xf3, 0x2b, - 0xc4, 0x4f, 0x6c, 0xb8, 0xd3, 0xdd, 0xd7, 0xbb, 0x6f, 0xc1, 0x62, 0x6d, 0x6f, 0x77, 0xdf, 0xc1, - 0x9f, 0xa7, 0x27, 0x3d, 0xf9, 0xd5, 0xe9, 0x1a, 0x66, 0xa6, 0x98, 0x3b, 0x18, 0x91, 0x56, 0xd1, - 0x69, 0x15, 0x7a, 0xdd, 0x67, 0xa3, 0xee, 0xde, 0x7e, 0xd7, 0xfa, 0x35, 0x69, 0xd2, 0xbe, 0xdd, - 0xe3, 0x7f, 0x10, 0xc9, 0xc8, 0x01, 0x2c, 0xe2, 0xe3, 0x1e, 0x7f, 0xf9, 0x96, 0xff, 0xcb, 0x5f, - 0xec, 0xf2, 0xc7, 0x1d, 0xfc, 0xd7, 0x80, 0x37, 0x3b, 0xe0, 0x76, 0xd9, 0x70, 0x77, 0x6f, 0xbf, - 0x27, 0xde, 0x65, 0x3c, 0x04, 0x49, 0x65, 0x3c, 0x8a, 0xc4, 0x91, 0x61, 0x3c, 0x69, 0x26, 0xf8, - 0x0f, 0x8e, 0x51, 0xc8, 0xd6, 0x62, 0x79, 0x47, 0xa3, 0x00, 0xec, 0x45, 0x69, 0xa6, 0xf8, 0xe0, - 0xcf, 0x94, 0xae, 0xfd, 0xd6, 0xb5, 0xac, 0x92, 0x1e, 0xc0, 0xcc, 0x3b, 0x4e, 0x41, 0x74, 0xa5, - 0x05, 0x70, 0xec, 0x6e, 0xbf, 0xa4, 0xab, 0xba, 0xfc, 0x56, 0x94, 0x75, 0x73, 0x53, 0x20, 0x27, - 0x02, 0x0e, 0x15, 0xc9, 0x5d, 0x7f, 0xcb, 0x85, 0x1d, 0x1e, 0x84, 0x1d, 0xc2, 0xfd, 0x79, 0x65, - 0x8f, 0x64, 0x86, 0xd9, 0xcc, 0x7b, 0x6a, 0x72, 0xd1, 0x8d, 0x0a, 0x63, 0x63, 0x4d, 0x48, 0xd3, - 0xcf, 0x0b, 0x5e, 0x88, 0xde, 0x68, 0x7b, 0x3b, 0x1c, 0xbe, 0x7b, 0xbb, 0x4f, 0x4e, 0x2e, 0x34, - 0x48, 0x0e, 0x20, 0x1b, 0x8c, 0xfb, 0xa4, 0x1f, 0x8e, 0x76, 0xdf, 0xed, 0x93, 0x63, 0x30, 0xf6, - 0xda, 0xc7, 0x8b, 0x93, 0x73, 0xf1, 0xc6, 0xde, 0x27, 0xf8, 0x03, 0xbf, 0x13, 0xf1, 0x56, 0x5a, - 0x31, 0xbb, 0x8c, 0x78, 0xf7, 0x1d, 0xe2, 0x7d, 0xbb, 0xbb, 0x4f, 0x8e, 0xfc, 0x1b, 0x85, 0x03, - 0x3c, 0x06, 0x6d, 0x3a, 0x52, 0xc0, 0x43, 0xd3, 0x87, 0xe4, 0xc7, 0xb1, 0x07, 0xee, 0xb0, 0x37, - 0x70, 0x95, 0x5b, 0x8f, 0x6b, 0x84, 0x87, 0x34, 0x5d, 0xe8, 0x02, 0xa4, 0x67, 0x10, 0x03, 0x4b, - 0x73, 0x84, 0x6f, 0x6f, 0xbb, 0xc3, 0xdd, 0xa7, 0x27, 0xd1, 0x23, 0x64, 0x43, 0x2e, 0x7f, 0xb6, - 0xf1, 0x63, 0x0f, 0x40, 0xdc, 0xe6, 0xae, 0x35, 0x0c, 0xf7, 0xf5, 0xb8, 0x46, 0x21, 0xcd, 0x18, - 0xa2, 0xf8, 0x7f, 0xad, 0xbc, 0x88, 0x5b, 0x2b, 0xa3, 0x5f, 0x06, 0x14, 0x73, 0x9e, 0x07, 0x83, - 0xf4, 0x3c, 0x75, 0x81, 0x10, 0xdf, 0x81, 0x2e, 0x08, 0x06, 0x47, 0x53, 0xce, 0x06, 0x65, 0xb1, - 0x2a, 0xde, 0x3d, 0x3d, 0xed, 0x00, 0x89, 0xa1, 0x19, 0x72, 0xd9, 0x0d, 0x41, 0x76, 0xa1, 0x6d, - 0xad, 0x56, 0xfb, 0xb9, 0xbc, 0x17, 0x82, 0x11, 0x33, 0x8f, 0x10, 0x62, 0x57, 0x70, 0xfe, 0x37, - 0x0e, 0xc7, 0xb7, 0x8f, 0xf9, 0xe4, 0x96, 0xdd, 0xe7, 0x69, 0xe5, 0xb3, 0x99, 0x3c, 0x39, 0x01, - 0x4c, 0x81, 0xfd, 0x1b, 0x76, 0xd1, 0xed, 0x22, 0x43, 0xba, 0x7b, 0xf8, 0xbc, 0xc3, 0x9f, 0x77, - 0x39, 0xe7, 0x76, 0x81, 0x73, 0xbb, 0x3b, 0x5b, 0x4e, 0xf8, 0xf4, 0xb4, 0xb7, 0x87, 0x34, 0x71, - 0xec, 0x6e, 0xc8, 0xb1, 0x17, 0x59, 0x90, 0xe3, 0x36, 0xb6, 0x77, 0x24, 0x82, 0xbd, 0x7d, 0xc1, - 0x9b, 0x7e, 0xca, 0x4b, 0x8e, 0x62, 0xe2, 0xcd, 0x00, 0x47, 0x93, 0xdc, 0x91, 0x32, 0x1e, 0x45, - 0x46, 0x49, 0xa5, 0xf2, 0x14, 0x56, 0x33, 0xe4, 0xcb, 0x79, 0x91, 0x21, 0x96, 0x51, 0xec, 0xce, - 0xad, 0xe8, 0xee, 0x95, 0x94, 0x46, 0x64, 0xc3, 0x88, 0x37, 0x37, 0x8d, 0xc9, 0x7f, 0x0d, 0xb3, - 0xa6, 0x55, 0x78, 0xec, 0xb7, 0xd9, 0xa4, 0x39, 0x3d, 0x4b, 0x29, 0x54, 0x55, 0x20, 0xa1, 0xf0, - 0xd0, 0x12, 0x9e, 0x00, 0xa6, 0xd9, 0x82, 0x69, 0xde, 0xdc, 0xce, 0xaf, 0xe8, 0x7f, 0x77, 0x6f, - 0x53, 0x8f, 0x60, 0xd2, 0xca, 0xd6, 0x24, 0x1b, 0xec, 0x49, 0x70, 0x0b, 0xb1, 0x17, 0x9b, 0x68, - 0x90, 0x4b, 0x43, 0xc8, 0x0f, 0x6d, 0x2f, 0x21, 0x50, 0x04, 0xdb, 0x34, 0xd1, 0xf4, 0x28, 0x4c, - 0x28, 0x7e, 0xb2, 0xf7, 0xac, 0xff, 0xfd, 0xbf, 0x8c, 0x34, 0x14, 0x9a, 0x6c, 0xc6, 0x37, 0x61, - 0xf7, 0x68, 0x42, 0xf8, 0x1a, 0x59, 0x9f, 0x3c, 0xcb, 0xe9, 0xbf, 0x2b, 0xcf, 0x7b, 0x52, 0x22, - 0x38, 0xe1, 0x42, 0x05, 0xf6, 0xf6, 0xe0, 0x4b, 0x5b, 0xd8, 0x56, 0x36, 0xe1, 0x08, 0x1d, 0x19, - 0x9f, 0x1c, 0x5d, 0xe6, 0xe2, 0x0c, 0x43, 0xac, 0xcf, 0xfd, 0xad, 0x54, 0x1b, 0x2c, 0xaf, 0x65, - 0xc6, 0xf0, 0x5f, 0x04, 0x2e, 0x26, 0x4b, 0xbb, 0xfd, 0x52, 0xda, 0xbd, 0x74, 0xfc, 0x9a, 0xb4, - 0xdb, 0x5c, 0x55, 0x7e, 0x52, 0xf9, 0xcc, 0x11, 0xe4, 0x09, 0x4b, 0x99, 0xab, 0x60, 0x6e, 0xb3, - 0x54, 0xb9, 0xcd, 0xd2, 0xa8, 0x35, 0x20, 0x2b, 0xae, 0x2f, 0xe0, 0x55, 0x1d, 0xbe, 0xba, 0x30, - 0xa8, 0x68, 0xac, 0x12, 0xa3, 0xa5, 0x4a, 0x8c, 0x44, 0x1f, 0x2f, 0xe7, 0x35, 0xab, 0x5c, 0x00, - 0xc1, 0x93, 0x9a, 0x47, 0x4e, 0x3d, 0x76, 0x06, 0xfe, 0xd1, 0x14, 0x3f, 0xbc, 0x00, 0x58, 0xc2, - 0x1f, 0xc5, 0x14, 0xb9, 0xa1, 0x1f, 0x46, 0x0e, 0xf9, 0x69, 0x3a, 0x9d, 0x92, 0x41, 0x9a, 0x05, - 0xa5, 0x0d, 0xb3, 0x55, 0xd2, 0xac, 0x7d, 0xcb, 0xce, 0xad, 0x04, 0x6c, 0xa2, 0x5b, 0x25, 0x74, - 0x4b, 0xb9, 0x12, 0xe0, 0x97, 0x56, 0x02, 0xfc, 0xb5, 0x95, 0x00, 0xb7, 0x66, 0x25, 0x00, 0xe7, - 0xef, 0xdf, 0x59, 0x0a, 0x70, 0x37, 0x2c, 0x05, 0xfc, 0x00, 0xb9, 0xf8, 0x91, 0xc9, 0x05, 0xa6, - 0xb3, 0x30, 0x3c, 0x6f, 0xcb, 0xf9, 0x21, 0x68, 0xba, 0x05, 0x2a, 0x5f, 0x4a, 0x6b, 0x6f, 0x15, - 0x17, 0x6e, 0x15, 0x17, 0x6e, 0x15, 0x17, 0x6e, 0x15, 0x17, 0x6e, 0x73, 0x69, 0xed, 0x6d, 0x65, - 0x5a, 0xbb, 0xa8, 0xec, 0xe9, 0xb5, 0x69, 0xed, 0x62, 0x53, 0x5a, 0x2b, 0xd8, 0xff, 0xa3, 0xc4, - 0xfe, 0xec, 0xcd, 0x3a, 0x8b, 0xb2, 0x6f, 0x88, 0xcd, 0x78, 0x7e, 0x76, 0xc5, 0x32, 0x04, 0xb0, - 0x96, 0xe5, 0x96, 0x21, 0x72, 0x33, 0x68, 0xec, 0x97, 0xe5, 0x0a, 0xbc, 0x33, 0xe9, 0x97, 0x5e, - 0xaf, 0xad, 0x6c, 0x6c, 0x42, 0x49, 0xc2, 0x88, 0x06, 0x33, 0x34, 0x1c, 0x5c, 0x44, 0x9f, 0x9f, - 0x99, 0x1f, 0x33, 0xce, 0xad, 0x69, 0x55, 0x0b, 0xa4, 0x75, 0x90, 0x5f, 0xba, 0x87, 0xcc, 0x2c, - 0x5b, 0xb8, 0xff, 0xba, 0xfa, 0x06, 0x76, 0x87, 0x5b, 0x29, 0x3f, 0x46, 0x85, 0x91, 0x9e, 0x2b, - 0x94, 0xa6, 0x4b, 0xbe, 0x04, 0xb3, 0x85, 0xa9, 0x0e, 0x58, 0x9e, 0x3c, 0x26, 0x73, 0x0a, 0x91, - 0x81, 0xfe, 0x90, 0xf5, 0x5a, 0xc2, 0x63, 0x18, 0xcd, 0xe9, 0x28, 0xc4, 0x60, 0xc8, 0x79, 0x68, - 0x4e, 0x0d, 0x73, 0x3a, 0x8a, 0xe0, 0x47, 0xe4, 0xc0, 0xe3, 0xdf, 0xd3, 0xde, 0x21, 0xfa, 0x2b, - 0x3d, 0x6e, 0x42, 0x4b, 0x60, 0xbc, 0xe8, 0x07, 0xad, 0x2a, 0x2e, 0x80, 0x1f, 0xc9, 0xcd, 0x1a, - 0x19, 0x1e, 0x2c, 0x4b, 0xef, 0x1d, 0x27, 0xde, 0x27, 0xc0, 0x2f, 0x9d, 0x34, 0xe3, 0x26, 0xd1, - 0x96, 0xf3, 0x87, 0xd8, 0x73, 0xa9, 0xaf, 0xac, 0xfa, 0xc2, 0x2a, 0x64, 0x3a, 0xd4, 0x14, 0x3b, - 0x26, 0xb4, 0x83, 0xa1, 0xfe, 0xaf, 0x90, 0xfa, 0x4b, 0x37, 0x34, 0xa6, 0x99, 0x13, 0x1e, 0x53, - 0xf7, 0x66, 0x16, 0x85, 0xab, 0x60, 0xe2, 0x7c, 0x47, 0x33, 0x4e, 0xa3, 0xd6, 0x2c, 0xa2, 0x13, - 0x0f, 0x57, 0xf3, 0xdf, 0x59, 0x13, 0x36, 0x33, 0xb5, 0x9f, 0x1f, 0xc5, 0xda, 0xc1, 0x5b, 0x6b, - 0x5f, 0x3c, 0xbc, 0x83, 0x28, 0x9d, 0xcf, 0x7e, 0x6e, 0x06, 0x5d, 0xd7, 0x25, 0xcf, 0x9a, 0xa5, - 0x80, 0x9f, 0x7f, 0x31, 0xb5, 0x9f, 0x76, 0x77, 0x77, 0xb3, 0xdf, 0x1a, 0xf4, 0xff, 0x8b, 0xf1, - 0x5d, 0xce, 0x06, 0x9b, 0xd4, 0xa5, 0x04, 0xd1, 0xe8, 0x8c, 0x26, 0x73, 0xb4, 0x46, 0x3a, 0xb7, - 0xa3, 0xe6, 0x9e, 0x65, 0x19, 0x4f, 0x4f, 0xa2, 0xe7, 0x3d, 0xab, 0xda, 0x3f, 0x56, 0xe0, 0x13, - 0xe2, 0xa8, 0xb0, 0xd1, 0xfb, 0x0a, 0x6c, 0xb6, 0xb5, 0x3e, 0x10, 0xe9, 0xe6, 0x20, 0xd1, 0x8c, - 0xc3, 0xa0, 0xc0, 0xcc, 0xac, 0xff, 0x3d, 0xeb, 0x17, 0x5c, 0x85, 0x07, 0x74, 0x6d, 0x5c, 0x39, - 0xd1, 0x16, 0x6c, 0x11, 0x46, 0x0f, 0xa4, 0x99, 0xad, 0xb0, 0xec, 0x7f, 0xd7, 0xf4, 0xe1, 0x78, - 0xf4, 0xfe, 0xf2, 0xf2, 0xfc, 0xb2, 0xaf, 0x7d, 0xe6, 0x2b, 0x25, 0x21, 0xf8, 0x63, 0x60, 0x06, - 0xcf, 0x3e, 0x0f, 0xb7, 0x86, 0x9d, 0xf1, 0xc8, 0xf8, 0x0e, 0x21, 0xba, 0xd1, 0x07, 0x7c, 0x96, - 0x58, 0x81, 0x59, 0x02, 0x84, 0x74, 0xe0, 0xdc, 0x29, 0xce, 0x1c, 0x4e, 0xbb, 0xcb, 0x3c, 0x5f, - 0xd7, 0x01, 0x6d, 0x33, 0xfe, 0x55, 0x64, 0x37, 0x46, 0xa7, 0x07, 0xa3, 0xe8, 0x74, 0x07, 0x33, - 0x67, 0x36, 0xea, 0xed, 0x67, 0x50, 0x33, 0xa3, 0x3f, 0xe3, 0x4d, 0x1f, 0x70, 0xbd, 0xe8, 0x14, - 0x92, 0x73, 0xa7, 0xb4, 0x32, 0x61, 0x9e, 0x38, 0xf9, 0x94, 0x2a, 0x5b, 0xb1, 0x98, 0x0d, 0xed, - 0xb6, 0xd5, 0xdd, 0xde, 0xde, 0x3a, 0x85, 0xff, 0x4e, 0xf6, 0x01, 0xc5, 0xfb, 0xab, 0x0b, 0xad, - 0xf7, 0x07, 0x2e, 0x36, 0x6a, 0x77, 0x5e, 0x32, 0xd7, 0xec, 0x03, 0xed, 0xf3, 0xd5, 0xa1, 0x16, - 0xaf, 0x96, 0x4b, 0xff, 0x81, 0xf4, 0xf5, 0x87, 0xa6, 0x73, 0xba, 0x4f, 0xec, 0xee, 0x1f, 0x1a, - 0xe9, 0x9f, 0xec, 0x93, 0x2f, 0x57, 0xdd, 0x3d, 0xbb, 0xa7, 0x89, 0xdf, 0x04, 0x1a, 0x12, 0x13, - 0x20, 0x66, 0xf8, 0x0f, 0x39, 0x90, 0xad, 0x70, 0x21, 0x2d, 0xe0, 0x21, 0x01, 0xae, 0x34, 0xe1, - 0xb0, 0x89, 0x88, 0x00, 0xe6, 0xf5, 0x83, 0xb5, 0xc5, 0x68, 0xcd, 0xb1, 0x43, 0x74, 0xbe, 0x4a, - 0x15, 0xc6, 0x89, 0xc6, 0xa6, 0x53, 0x40, 0x13, 0x9b, 0xda, 0xff, 0x24, 0x83, 0x71, 0xd3, 0x99, - 0x3b, 0xf3, 0x02, 0x27, 0xe6, 0x46, 0x7f, 0x6e, 0x8e, 0x79, 0xc7, 0x5e, 0xac, 0xb1, 0x20, 0x5c, - 0xcd, 0xe6, 0xc6, 0x70, 0x1c, 0x8d, 0xb2, 0xb5, 0xa0, 0xc2, 0xf4, 0x3e, 0x14, 0x96, 0x88, 0xb2, - 0xf7, 0x27, 0xa8, 0x6f, 0x63, 0xf1, 0xf1, 0x87, 0x90, 0x89, 0xa2, 0xb8, 0xee, 0x49, 0x4e, 0x9e, - 0x5c, 0xcb, 0xe4, 0x94, 0x28, 0xc9, 0xcc, 0x6d, 0x9d, 0xd1, 0x38, 0x79, 0x1f, 0x4c, 0xe4, 0xca, - 0x1e, 0x1b, 0xda, 0x6a, 0xb5, 0xce, 0x1a, 0xdc, 0xbe, 0xb4, 0xde, 0x70, 0x05, 0x82, 0xc5, 0x5a, - 0xe0, 0x46, 0x32, 0x13, 0xd2, 0x7c, 0x79, 0x89, 0x62, 0xbd, 0xc9, 0x40, 0x2c, 0xf9, 0xbd, 0x6c, - 0xaa, 0x4a, 0x0d, 0x25, 0xa5, 0x01, 0xcf, 0xa1, 0x02, 0x91, 0x43, 0x41, 0xea, 0x6d, 0x98, 0x5e, - 0xfc, 0x89, 0x7e, 0xd2, 0x6f, 0x8d, 0x7d, 0xab, 0x7f, 0x9b, 0x0d, 0x15, 0x92, 0x5a, 0x9c, 0xd4, - 0x74, 0x9b, 0x50, 0x6c, 0x5b, 0xac, 0x75, 0x77, 0xa4, 0xf6, 0x74, 0x74, 0xe2, 0x5d, 0x5d, 0xe3, - 0xd2, 0xa1, 0x93, 0xa4, 0xb1, 0xdb, 0x54, 0xdf, 0xd2, 0x21, 0xcd, 0x02, 0xb7, 0x45, 0x47, 0x18, - 0x49, 0x1d, 0x36, 0x71, 0xeb, 0xe6, 0xe9, 0xa9, 0x25, 0x5e, 0x82, 0x44, 0x53, 0xe9, 0x53, 0x3d, - 0x91, 0xf4, 0x41, 0x84, 0x48, 0xb8, 0x1f, 0x45, 0x00, 0xb5, 0x5c, 0xfd, 0x7d, 0x38, 0xf1, 0x6e, - 0x35, 0xbe, 0x79, 0xe4, 0xf0, 0x4e, 0x46, 0x7f, 0x06, 0xc3, 0x79, 0xa4, 0xde, 0xc4, 0x0b, 0x1f, - 0xdf, 0xfc, 0xfc, 0x48, 0x9b, 0xf6, 0x73, 0x1f, 0x3e, 0x89, 0x50, 0x43, 0x13, 0xfb, 0xdb, 0xa7, - 0xd7, 0xf0, 0xe1, 0x99, 0x68, 0x10, 0xa8, 0xcc, 0xd1, 0x2c, 0x38, 0xe4, 0xf3, 0x89, 0x9e, 0x44, - 0xc0, 0x0e, 0x32, 0x82, 0x2f, 0x82, 0x2c, 0x9c, 0xe8, 0x37, 0xc3, 0x70, 0xc9, 0x87, 0x2d, 0x13, - 0xd4, 0x6e, 0x97, 0x68, 0x2a, 0xe4, 0x1d, 0x71, 0x75, 0xb8, 0x1f, 0x76, 0x04, 0xc8, 0x68, 0x0d, - 0x74, 0xc7, 0x22, 0xa3, 0xab, 0x7f, 0xbc, 0xdd, 0xb3, 0xbb, 0xda, 0xe5, 0xc7, 0xc3, 0x2f, 0xb5, - 0x60, 0x36, 0x19, 0x5d, 0x9f, 0xd9, 0x7b, 0xf6, 0x6e, 0x1d, 0x44, 0x77, 0x97, 0x40, 0x92, 0x69, - 0xdd, 0xfc, 0xfe, 0x3f, 0x6a, 0x21, 0x7a, 0x02, 0x47, 0xf7, 0x5d, 0x2d, 0xc4, 0x5b, 0x32, 0xfa, - 0x7c, 0x74, 0xb5, 0xf7, 0xce, 0xda, 0xa9, 0x05, 0x79, 0xa7, 0x40, 0x76, 0x37, 0x12, 0xdc, 0x83, - 0x71, 0xe1, 0xc8, 0x2d, 0xbb, 0x16, 0x02, 0x86, 0x74, 0x70, 0x71, 0x60, 0x5b, 0xdd, 0x5a, 0x88, - 0x2e, 0x19, 0x9d, 0x5e, 0x1c, 0xef, 0xed, 0x59, 0x6f, 0x6b, 0x41, 0x76, 0x39, 0xc8, 0xdb, 0xbd, - 0x7a, 0x8a, 0x7b, 0x3b, 0x64, 0x74, 0xf1, 0x6e, 0xcf, 0xae, 0x05, 0xb0, 0xdf, 0x09, 0x52, 0x6d, - 0x5b, 0xfb, 0x32, 0xf7, 0x12, 0x56, 0x07, 0xb7, 0x0b, 0x43, 0x3a, 0x0f, 0x3a, 0xe7, 0xd3, 0x69, - 0x2d, 0x04, 0x0c, 0xe9, 0xe2, 0xcb, 0xd9, 0x0b, 0x68, 0xba, 0x02, 0xe8, 0xe8, 0xe8, 0xba, 0x16, - 0x64, 0x47, 0x80, 0x00, 0x83, 0x6b, 0x41, 0x76, 0x53, 0x90, 0xda, 0x39, 0xd8, 0xed, 0xa5, 0x30, - 0xcd, 0x7c, 0x6f, 0x7f, 0xde, 0xef, 0xb8, 0x5b, 0xad, 0xd6, 0x1a, 0xf0, 0xdb, 0x0c, 0xf8, 0x38, - 0x07, 0xdd, 0x6a, 0x01, 0x38, 0x7b, 0xf3, 0x0c, 0xca, 0x51, 0x6c, 0xb0, 0x07, 0xec, 0x38, 0x3e, - 0xbe, 0xc0, 0x06, 0x9a, 0x1e, 0xb0, 0xe4, 0x2e, 0x8c, 0x6e, 0x8c, 0xac, 0x8f, 0xa0, 0xb2, 0x97, - 0x3d, 0xe0, 0xd0, 0x7b, 0xbb, 0xbd, 0x63, 0x57, 0x37, 0x13, 0x9d, 0x95, 0xbb, 0x02, 0x96, 0x1d, - 0x44, 0x49, 0xeb, 0x13, 0x4b, 0x6a, 0xbb, 0x5b, 0x6f, 0xb2, 0x97, 0x52, 0xf7, 0xa5, 0x1a, 0xbe, - 0x23, 0x34, 0x74, 0x84, 0xde, 0x00, 0x7e, 0xa2, 0x9d, 0xf0, 0x26, 0x0e, 0x71, 0x43, 0xa1, 0xf4, - 0xdc, 0xbc, 0x3b, 0x44, 0xda, 0xf7, 0xbe, 0x8c, 0x36, 0x46, 0x47, 0x18, 0x4e, 0x68, 0xe7, 0xd1, - 0x84, 0x45, 0x25, 0x7b, 0x71, 0x74, 0xce, 0x9b, 0x96, 0x89, 0x01, 0x4e, 0x7d, 0xbc, 0x3c, 0xac, - 0x27, 0x16, 0x98, 0x92, 0x9f, 0xea, 0xd2, 0x77, 0x18, 0xfe, 0xe1, 0xe5, 0xc7, 0xfa, 0xef, 0x20, - 0x2e, 0x97, 0x87, 0x1b, 0xbe, 0x83, 0xac, 0x1c, 0x7e, 0xbc, 0xac, 0xff, 0x0e, 0x72, 0xf2, 0xf1, - 0xf0, 0xb2, 0x92, 0x39, 0x1d, 0xe0, 0x4b, 0x9e, 0x3d, 0x13, 0x6f, 0x86, 0x83, 0xbc, 0x2b, 0x31, - 0x88, 0xfb, 0xba, 0xd1, 0xd5, 0x1d, 0x5d, 0xf6, 0xb5, 0x22, 0x5b, 0xbe, 0x48, 0xb6, 0x94, 0x99, - 0xf2, 0x09, 0xda, 0xd4, 0x6a, 0x25, 0x28, 0xa5, 0xb6, 0xad, 0xd5, 0x2a, 0x40, 0x57, 0x7c, 0xff, - 0x58, 0x6b, 0x31, 0xc5, 0xf7, 0x6c, 0x54, 0x2f, 0x8e, 0xc9, 0xaf, 0x19, 0xd3, 0x91, 0x1f, 0xba, - 0x37, 0xeb, 0x83, 0xba, 0xba, 0xa8, 0x1b, 0xd4, 0x95, 0x1f, 0xde, 0xb1, 0x38, 0xd9, 0x30, 0x2e, - 0x84, 0xd8, 0x30, 0xac, 0x4f, 0x61, 0xb4, 0xa0, 0xfe, 0x86, 0x71, 0x7d, 0xa0, 0xf5, 0xe8, 0x77, - 0xc5, 0xe7, 0x02, 0x01, 0x55, 0x03, 0xc7, 0x3f, 0xf1, 0x92, 0x06, 0x9c, 0x01, 0xcb, 0x78, 0x22, - 0x46, 0x23, 0xd6, 0x79, 0xa0, 0x01, 0x7c, 0x19, 0x69, 0x43, 0xb1, 0x71, 0x8c, 0xa5, 0x39, 0x0e, - 0x09, 0x56, 0x8b, 0x31, 0x8b, 0x88, 0x72, 0x8d, 0x57, 0x42, 0x4b, 0xb0, 0xb5, 0x1f, 0x8b, 0x67, - 0xe9, 0x53, 0x7d, 0x4d, 0xa4, 0x63, 0x44, 0xc3, 0x95, 0x04, 0xe0, 0x08, 0x86, 0xc8, 0xa8, 0xf9, - 0xef, 0x6c, 0xa2, 0xa8, 0xfc, 0xf9, 0x51, 0xc5, 0x42, 0xd4, 0xe0, 0x0e, 0x96, 0xf7, 0x04, 0xfe, - 0x38, 0x97, 0xc8, 0x21, 0xd2, 0x6f, 0x0e, 0xba, 0xdb, 0x01, 0xee, 0x81, 0x0d, 0x88, 0xa6, 0x16, - 0x83, 0xb5, 0xce, 0x68, 0x3b, 0x18, 0xc7, 0xcb, 0x41, 0x79, 0x0e, 0xdd, 0x5a, 0xc5, 0x3d, 0xe5, - 0x71, 0x45, 0x7f, 0xe3, 0xa0, 0x8e, 0x8a, 0x03, 0x91, 0x23, 0xb0, 0xe5, 0x08, 0x78, 0xd4, 0x7e, - 0x71, 0xf8, 0x4c, 0xb2, 0xa9, 0xcc, 0x48, 0x4a, 0x87, 0x80, 0xb4, 0x12, 0xa0, 0x50, 0x30, 0x5b, - 0x1a, 0x97, 0x4e, 0x89, 0xe3, 0x96, 0xe4, 0x38, 0x5f, 0xa4, 0x97, 0x0c, 0xdf, 0x44, 0x9a, 0x25, - 0x48, 0x4b, 0xfb, 0x53, 0x01, 0xcc, 0x5a, 0x74, 0x62, 0x0c, 0x20, 0x4a, 0xff, 0xbc, 0x9c, 0xe8, - 0xc9, 0xdc, 0x8b, 0x81, 0x67, 0x9d, 0x62, 0xaf, 0xb6, 0xec, 0xf5, 0x15, 0x1d, 0xda, 0x05, 0x5e, - 0xfc, 0xcd, 0x7e, 0xba, 0xaf, 0xef, 0xa7, 0xfb, 0xef, 0xf4, 0xb3, 0xf3, 0xfa, 0x7e, 0x76, 0xfe, - 0x9d, 0x7e, 0x76, 0x5f, 0xdf, 0xcf, 0xee, 0xdf, 0xef, 0x67, 0x4d, 0x86, 0xa3, 0x5a, 0x19, 0x46, - 0x69, 0xca, 0xa8, 0x82, 0xa4, 0x48, 0x50, 0xa5, 0x16, 0x79, 0x25, 0x75, 0x6b, 0x32, 0xce, 0xd7, - 0x58, 0xc7, 0xe1, 0xbd, 0xa2, 0xf0, 0xe8, 0x0f, 0x35, 0x96, 0x6a, 0x33, 0x18, 0x6f, 0xec, 0xfe, - 0xea, 0xc6, 0x5b, 0x6a, 0x53, 0x2f, 0x82, 0xd4, 0x0b, 0x03, 0xfc, 0x8d, 0xfa, 0x74, 0x75, 0x2a, - 0x78, 0x51, 0xb0, 0x03, 0x90, 0x74, 0x92, 0xcc, 0x5a, 0xae, 0xe9, 0x4d, 0x2d, 0x51, 0xd3, 0x8d, - 0x44, 0x41, 0x48, 0xa6, 0x5d, 0xb2, 0x69, 0xc4, 0xe2, 0x4c, 0xc1, 0x39, 0x87, 0xa6, 0x82, 0x80, - 0x6a, 0x46, 0x5c, 0x7e, 0xd8, 0xcc, 0x08, 0xba, 0xb1, 0xcf, 0x83, 0x55, 0x12, 0xb6, 0x5c, 0xea, - 0xbb, 0x2b, 0x9f, 0x26, 0x4c, 0xbb, 0xc3, 0x90, 0x0f, 0x0b, 0x75, 0x21, 0x65, 0xf4, 0xb5, 0x69, - 0x14, 0x2e, 0x30, 0xf4, 0xe8, 0x8b, 0x19, 0xcb, 0x3b, 0x8e, 0x83, 0x2f, 0x55, 0x8e, 0xc3, 0xda, - 0xe4, 0x0b, 0xed, 0xd1, 0x61, 0xe4, 0xcd, 0xe6, 0x09, 0x8b, 0x6a, 0x00, 0xba, 0xa3, 0x03, 0xd7, - 0xc5, 0x42, 0xc0, 0x3a, 0x0c, 0x3b, 0xa3, 0xe3, 0x55, 0xad, 0x4b, 0xd9, 0x1d, 0x9d, 0xd1, 0xfb, - 0xb2, 0xb7, 0x10, 0x26, 0x36, 0x65, 0x0e, 0xff, 0xfb, 0x7d, 0xe0, 0x41, 0x52, 0x1c, 0xb3, 0x28, - 0x39, 0x98, 0xfc, 0xa0, 0x2e, 0xa4, 0x71, 0x98, 0x1d, 0xeb, 0x64, 0xcc, 0x20, 0x21, 0x67, 0x2c, - 0x98, 0x10, 0xd3, 0x37, 0x9e, 0x65, 0x8a, 0xa6, 0x27, 0x5f, 0x5b, 0x2d, 0xfa, 0xad, 0x1d, 0xb1, - 0x45, 0x78, 0xcb, 0x74, 0xc3, 0x84, 0x5f, 0x72, 0x15, 0xae, 0x59, 0xca, 0x9f, 0xe9, 0x30, 0xcd, - 0xf1, 0x5a, 0x76, 0xf5, 0xe2, 0x4e, 0xab, 0xdc, 0x68, 0x54, 0x5e, 0x07, 0x0a, 0x9e, 0x9e, 0x78, - 0xc9, 0x44, 0x21, 0x17, 0x3d, 0x3a, 0x3f, 0xd3, 0x81, 0xc9, 0x90, 0x8c, 0xe2, 0xa6, 0xb4, 0x95, - 0xd5, 0xa4, 0xd5, 0xe5, 0xa3, 0x6e, 0xb8, 0xf8, 0x0b, 0x5e, 0x46, 0x0f, 0xd0, 0x67, 0x3e, 0x23, - 0x85, 0xa4, 0x0f, 0x97, 0x4a, 0x65, 0xde, 0x59, 0xc8, 0x2e, 0xb3, 0x26, 0x9b, 0x72, 0x4c, 0x4d, - 0xb8, 0xd8, 0x4d, 0x6a, 0xf3, 0xcf, 0x9c, 0x6f, 0xbd, 0x7f, 0x95, 0x6f, 0x7d, 0xdb, 0xeb, 0xed, - 0xf4, 0x72, 0xce, 0x95, 0x3d, 0xaf, 0x29, 0x56, 0xce, 0x79, 0x3a, 0x84, 0xa4, 0xde, 0xf3, 0x15, - 0x3e, 0xf1, 0x9f, 0x47, 0x39, 0x62, 0xdc, 0x8d, 0xfe, 0x71, 0x9d, 0x8a, 0xe0, 0xb9, 0xd0, 0xeb, - 0xba, 0xaa, 0x4b, 0x85, 0xfb, 0x5b, 0x71, 0x36, 0xa7, 0x42, 0x06, 0xe8, 0x92, 0xbe, 0xff, 0xff, - 0x62, 0x6e, 0xa5, 0x6c, 0xdc, 0x76, 0x48, 0xb5, 0x93, 0xfb, 0xc4, 0x42, 0xc2, 0x3c, 0x16, 0xf3, - 0xc5, 0xa9, 0x8d, 0x7a, 0xe8, 0x49, 0x55, 0xbb, 0x0f, 0x49, 0x93, 0xaa, 0x55, 0xf0, 0xc4, 0x1c, - 0x27, 0x01, 0x2a, 0x03, 0xc8, 0xa2, 0xac, 0x63, 0xca, 0xf4, 0x04, 0xf4, 0x14, 0x3f, 0x65, 0xa5, - 0x4c, 0xaf, 0x50, 0x0e, 0xd0, 0xa8, 0xb4, 0x4a, 0xd0, 0xda, 0x72, 0x70, 0xe3, 0x53, 0x67, 0x5f, - 0x83, 0x96, 0x9d, 0x53, 0x7b, 0xd9, 0x25, 0xbc, 0x14, 0x5d, 0x1a, 0xf9, 0x2e, 0x63, 0x96, 0x70, - 0xe5, 0x34, 0x1e, 0xd1, 0x62, 0xac, 0x95, 0xdc, 0xcb, 0x42, 0x0a, 0xac, 0x27, 0x61, 0xb8, 0xd6, - 0xfa, 0x2a, 0x92, 0x0c, 0x96, 0x76, 0x3d, 0x90, 0x5d, 0x17, 0x4a, 0x83, 0xc5, 0x2b, 0xe8, 0x30, - 0xe5, 0x29, 0x18, 0x88, 0x72, 0x3d, 0xd8, 0xb0, 0x48, 0x4b, 0xb5, 0x49, 0xc2, 0xd6, 0xd0, 0x59, - 0xb9, 0x75, 0xd9, 0x30, 0x15, 0xec, 0xd1, 0x61, 0x12, 0x88, 0xda, 0x64, 0x65, 0x89, 0x38, 0x36, - 0x20, 0x2d, 0xce, 0xaf, 0x3a, 0x9a, 0x1e, 0x2f, 0x15, 0x6d, 0x5e, 0xf1, 0x5d, 0xa2, 0x36, 0x3a, - 0x95, 0xa3, 0x39, 0x8d, 0x8e, 0xc2, 0x09, 0xd3, 0x71, 0xf9, 0xd0, 0xda, 0xdf, 0xdd, 0xeb, 0xf7, - 0x7a, 0x46, 0x13, 0xf8, 0x44, 0x9b, 0xce, 0xf7, 0xc3, 0x55, 0x92, 0x84, 0xbc, 0x24, 0xf1, 0x59, - 0x14, 0x7f, 0x6c, 0x52, 0xec, 0x9f, 0x1f, 0xbd, 0xf5, 0xa5, 0x2d, 0x23, 0x55, 0xed, 0xfb, 0xb8, - 0xa8, 0xc7, 0xa3, 0xef, 0x58, 0x43, 0xf2, 0x5d, 0xba, 0x84, 0x82, 0x3f, 0xfb, 0xf9, 0x91, 0x1c, - 0xbe, 0x7f, 0x15, 0x8d, 0x29, 0x9a, 0x92, 0xa6, 0x02, 0xc9, 0x96, 0x83, 0x5b, 0xc8, 0x6a, 0xd1, - 0x0c, 0xab, 0x56, 0x9e, 0x47, 0xc7, 0x72, 0x93, 0x26, 0x55, 0x92, 0xca, 0xe6, 0x5d, 0x6c, 0xde, - 0xad, 0x68, 0x7e, 0xb1, 0x8a, 0xe7, 0x63, 0xce, 0x92, 0xcd, 0x08, 0x76, 0x10, 0xc1, 0x4e, 0x0d, - 0x02, 0xcd, 0x93, 0x7b, 0xea, 0x9b, 0x71, 0xec, 0x22, 0x8e, 0xdd, 0x0a, 0x1c, 0x57, 0xbc, 0x4e, - 0x6f, 0x73, 0xe3, 0x1e, 0x36, 0xee, 0x55, 0x11, 0x70, 0x72, 0xa9, 0xc5, 0x2c, 0x88, 0xc3, 0x68, - 0x33, 0x82, 0xb7, 0x88, 0xe0, 0x6d, 0x05, 0x82, 0xeb, 0x70, 0xf5, 0x52, 0xe7, 0xbf, 0x61, 0xdb, - 0xdf, 0x2a, 0xda, 0x1e, 0x04, 0xd4, 0x0f, 0x67, 0x9b, 0x1b, 0xef, 0x61, 0xe3, 0xbd, 0xda, 0xc6, - 0x35, 0xcc, 0x23, 0xa9, 0xa9, 0x23, 0x02, 0x29, 0x0f, 0x69, 0xa5, 0x23, 0x80, 0x38, 0x06, 0xc6, - 0xdb, 0xd7, 0x96, 0xa1, 0x17, 0x40, 0xc4, 0x33, 0xe0, 0x32, 0xca, 0xab, 0x6e, 0x08, 0x9e, 0x56, - 0x79, 0x83, 0x72, 0xfb, 0xc6, 0x50, 0x3e, 0x6c, 0xfb, 0xa7, 0xfb, 0xee, 0x6f, 0x76, 0x6f, 0xa0, - 0x02, 0x73, 0x30, 0x99, 0x72, 0x6b, 0x69, 0x5d, 0x99, 0x9c, 0x5c, 0xa5, 0x5a, 0x32, 0xf3, 0xaf, - 0x3c, 0x34, 0x01, 0x7a, 0xe1, 0x08, 0x10, 0x33, 0x9e, 0x9e, 0xf4, 0xe2, 0x21, 0xa0, 0xf5, 0x62, - 0xcf, 0xf4, 0xdc, 0xc8, 0x23, 0x1a, 0x26, 0x61, 0x28, 0xb7, 0x6c, 0x8c, 0x2b, 0x06, 0xe0, 0xce, - 0x36, 0x2f, 0x6f, 0x2b, 0x3b, 0x19, 0x60, 0x59, 0x42, 0x79, 0x8b, 0x91, 0x1b, 0x48, 0xe3, 0x6f, - 0xac, 0xed, 0x07, 0xc5, 0x25, 0xfa, 0xad, 0x8a, 0x6d, 0xcb, 0x40, 0xe1, 0x43, 0xb3, 0x8c, 0x85, - 0xa1, 0xf9, 0x04, 0x3b, 0xf8, 0x86, 0x4b, 0xf3, 0x72, 0xef, 0x31, 0xb6, 0x08, 0x00, 0x59, 0x65, - 0x24, 0xb8, 0x97, 0x58, 0x8f, 0xc3, 0xe2, 0x38, 0x04, 0xc7, 0x63, 0x2f, 0x57, 0x39, 0xca, 0x4c, - 0xc5, 0xe4, 0x8c, 0x79, 0xab, 0x25, 0x9e, 0x6a, 0xf9, 0xe0, 0xf9, 0x78, 0xba, 0x48, 0x56, 0x1f, - 0x07, 0xec, 0x4e, 0xfb, 0xe7, 0xd9, 0xe9, 0xef, 0x49, 0xb2, 0xbc, 0x84, 0x58, 0x81, 0xc5, 0xc9, - 0x20, 0xa8, 0x3f, 0xc1, 0x93, 0x3b, 0x1e, 0x92, 0x1d, 0x5e, 0xc1, 0x54, 0x0a, 0x4c, 0x7e, 0xbc, - 0x0c, 0xc1, 0x23, 0x5e, 0xb3, 0xfb, 0xc4, 0xe4, 0x6f, 0x80, 0xcc, 0x64, 0x15, 0x63, 0x39, 0x0b, - 0x0c, 0xd2, 0x00, 0x4f, 0x55, 0x7f, 0x0c, 0x27, 0xc3, 0xcb, 0xf2, 0x88, 0xb1, 0x88, 0x9a, 0xba, - 0x37, 0xe6, 0x96, 0x42, 0x20, 0x0e, 0x75, 0x5d, 0x9c, 0xc3, 0x6c, 0x9a, 0xa4, 0x23, 0x86, 0x23, - 0xf7, 0xad, 0x12, 0x3e, 0x92, 0x0f, 0x61, 0xb4, 0xc0, 0xfa, 0x3d, 0xb5, 0x5d, 0x92, 0xc8, 0xd3, - 0x49, 0x3a, 0xc1, 0x12, 0x6e, 0x59, 0x53, 0xcc, 0xab, 0xb9, 0xf1, 0x5c, 0x4f, 0x0c, 0xec, 0xc3, - 0xa3, 0x3d, 0x41, 0x3b, 0x46, 0x98, 0xc4, 0x30, 0x2b, 0xaa, 0xbd, 0xb7, 0xd6, 0xce, 0x5e, 0x1d, - 0x4d, 0x67, 0x29, 0xf7, 0xcc, 0x64, 0x40, 0xd4, 0x47, 0x02, 0x5a, 0x08, 0x66, 0x1e, 0xbc, 0xa4, - 0x3c, 0x31, 0x86, 0x7c, 0xbe, 0x64, 0x14, 0x02, 0xa8, 0x7d, 0x18, 0x09, 0xef, 0x6f, 0x9f, 0xa5, - 0xfd, 0xee, 0xeb, 0xe8, 0xb9, 0x53, 0x2a, 0x74, 0x49, 0x7f, 0xda, 0x06, 0x8b, 0xdd, 0xb0, 0x3b, - 0x27, 0xcf, 0x1a, 0x51, 0xd8, 0xc9, 0xda, 0x20, 0x00, 0x20, 0x94, 0xc8, 0xf3, 0x95, 0x9f, 0xc8, - 0xe1, 0xf3, 0x33, 0x08, 0x5c, 0x78, 0xf4, 0x80, 0x6f, 0xc3, 0x24, 0xed, 0xf9, 0x1d, 0xdf, 0xe8, - 0xc2, 0x07, 0x90, 0xfd, 0x49, 0xa6, 0x33, 0x58, 0x12, 0x4a, 0xc1, 0x37, 0x80, 0xd7, 0x6a, 0x1a, - 0x6a, 0xab, 0x08, 0xa4, 0x79, 0xa0, 0x40, 0x31, 0xb8, 0x49, 0x2b, 0x3d, 0xa4, 0xa7, 0x74, 0x46, - 0x8f, 0x0a, 0xd4, 0x16, 0x71, 0x41, 0x86, 0x8a, 0x61, 0x71, 0x88, 0xd2, 0x2f, 0x44, 0x5a, 0xa5, - 0x35, 0xdf, 0x79, 0x3a, 0x8a, 0xfe, 0xec, 0x7b, 0xae, 0xa4, 0x8d, 0x37, 0xfd, 0x4a, 0xbf, 0x0d, - 0x6a, 0xf7, 0xc2, 0x82, 0x02, 0x34, 0x32, 0xd9, 0xac, 0xdd, 0xa3, 0x2b, 0xc2, 0x72, 0x4d, 0x31, - 0x5f, 0x53, 0x40, 0x2c, 0xa2, 0xa8, 0x6a, 0xd0, 0xa3, 0xf3, 0x75, 0xd0, 0x10, 0xc3, 0x62, 0xf3, - 0x35, 0x65, 0xc6, 0x48, 0x04, 0x64, 0xec, 0xd5, 0xb0, 0x97, 0x1f, 0x14, 0x6c, 0xaa, 0xb5, 0x30, - 0xa7, 0xd3, 0x1a, 0x2a, 0xfe, 0xa8, 0x02, 0xbe, 0x7d, 0x36, 0x9e, 0xd5, 0x14, 0x43, 0x30, 0x84, - 0xb5, 0x10, 0x2a, 0xa4, 0xc3, 0x93, 0x5f, 0xe2, 0x6d, 0xa1, 0x66, 0x47, 0x65, 0x63, 0x92, 0x39, - 0x62, 0xdc, 0x72, 0x48, 0x5c, 0xcd, 0x78, 0x2b, 0xb0, 0xde, 0x2a, 0xc9, 0x52, 0xbf, 0x07, 0x07, - 0x51, 0x44, 0x1f, 0xda, 0x5e, 0xcc, 0xff, 0xea, 0x3c, 0x11, 0x35, 0x54, 0x15, 0x68, 0xc9, 0xda, - 0x13, 0x88, 0x4d, 0xbd, 0x7a, 0x31, 0xc2, 0x00, 0x0c, 0xbb, 0xc5, 0xb9, 0x47, 0x25, 0xe4, 0xd3, - 0x8a, 0xa5, 0x42, 0x95, 0x63, 0xbf, 0x06, 0xeb, 0x9d, 0xb1, 0xd4, 0x6b, 0x27, 0xc9, 0x33, 0xa7, - 0xca, 0x8b, 0xea, 0x2a, 0x49, 0x4f, 0x2e, 0xf3, 0x2d, 0x24, 0x30, 0xf6, 0x56, 0xdd, 0xc1, 0xc9, - 0x75, 0x15, 0x38, 0xa7, 0x49, 0xf0, 0x23, 0x62, 0x10, 0x56, 0xd6, 0x75, 0x76, 0x79, 0x5a, 0x6a, - 0xcd, 0xe1, 0xeb, 0xfb, 0xbb, 0x3c, 0x23, 0x85, 0xa9, 0xcc, 0xb5, 0x01, 0x97, 0xad, 0x32, 0x03, - 0x13, 0x55, 0x9c, 0x4e, 0x0e, 0x62, 0x34, 0xaa, 0xa0, 0xd5, 0x46, 0x5f, 0x1e, 0x42, 0xbc, 0xf0, - 0x19, 0x56, 0xe8, 0xcb, 0x38, 0x90, 0x6a, 0xa8, 0xfb, 0xfc, 0xa4, 0xa2, 0x58, 0x19, 0xda, 0x22, - 0x29, 0xe4, 0x35, 0x58, 0x62, 0x6d, 0x1c, 0x85, 0x77, 0x90, 0xab, 0x68, 0x93, 0x90, 0xc5, 0x78, - 0x82, 0x0a, 0x4b, 0x00, 0xc2, 0x08, 0xc2, 0xd2, 0x39, 0xd3, 0xbe, 0x73, 0x13, 0xf4, 0x5d, 0x5b, - 0x46, 0x60, 0x5c, 0xc1, 0xa3, 0x60, 0x98, 0xcf, 0x31, 0xf1, 0xc8, 0x35, 0xc6, 0x03, 0x25, 0x2c, - 0xab, 0xfb, 0xcd, 0xd0, 0x32, 0x01, 0x75, 0x70, 0x71, 0xa2, 0x79, 0x79, 0xa4, 0x7c, 0x29, 0x56, - 0x4b, 0xf2, 0xdd, 0x3e, 0x80, 0xa9, 0xca, 0x9f, 0x8f, 0x2d, 0x1e, 0xd0, 0xe4, 0x46, 0x8d, 0x39, - 0x5f, 0x71, 0xca, 0x4c, 0x64, 0xe5, 0xb7, 0x41, 0x5e, 0xa2, 0x4a, 0xd5, 0x68, 0x6f, 0x44, 0x15, - 0x62, 0x21, 0xa4, 0xfe, 0xf6, 0x26, 0xab, 0x4b, 0x0b, 0x78, 0x5d, 0x1a, 0x2f, 0xb4, 0x0a, 0x78, - 0x9d, 0x17, 0x48, 0x55, 0x9a, 0xc5, 0x24, 0x22, 0x8b, 0x01, 0x23, 0xcf, 0xe4, 0x8c, 0x60, 0x21, - 0x9a, 0x42, 0xe3, 0x80, 0x09, 0xe7, 0x93, 0xbe, 0xbd, 0xcd, 0x60, 0x1e, 0x5c, 0x7f, 0x05, 0x89, - 0x07, 0xe8, 0x16, 0xc7, 0xa2, 0x08, 0x4d, 0xfd, 0x73, 0xa2, 0x8a, 0xda, 0xa9, 0x03, 0x02, 0xad, - 0x46, 0x24, 0xc1, 0x4d, 0x2b, 0x33, 0x91, 0x58, 0xce, 0x07, 0xd1, 0x49, 0xae, 0xd0, 0x4f, 0x84, - 0x20, 0xfc, 0x74, 0x11, 0x2f, 0xc5, 0x4b, 0xfb, 0x82, 0x39, 0x56, 0xf5, 0x64, 0x03, 0x71, 0x0c, - 0x02, 0xd7, 0x72, 0xf0, 0xa4, 0xe7, 0x2a, 0xc0, 0x43, 0x6f, 0x18, 0xdc, 0x35, 0x03, 0x79, 0xf2, - 0x1a, 0x9a, 0x4d, 0xd8, 0xfd, 0xf9, 0x14, 0x5a, 0x8d, 0x1c, 0x6b, 0x7b, 0x3b, 0xd8, 0x92, 0xcb, - 0x3e, 0x10, 0xe1, 0xf1, 0x23, 0x72, 0xc4, 0xc8, 0xce, 0x63, 0xe7, 0xfb, 0x50, 0x30, 0xfa, 0x65, - 0xe7, 0xdc, 0x20, 0xe2, 0x24, 0x84, 0x87, 0x83, 0x38, 0xe7, 0x41, 0xa2, 0x4e, 0xcd, 0xc4, 0x04, - 0x1f, 0x12, 0x38, 0x78, 0x1e, 0xc6, 0x4b, 0x8b, 0x47, 0x21, 0xd2, 0xe8, 0xa7, 0x3d, 0xe7, 0x91, - 0x79, 0xb9, 0x72, 0x2e, 0x70, 0xd5, 0xcf, 0x7f, 0xb7, 0x8c, 0x50, 0x2e, 0xc9, 0x4a, 0xfd, 0xaf, - 0x6c, 0xdb, 0x86, 0x08, 0x4e, 0x88, 0x64, 0x3b, 0xce, 0x55, 0xa0, 0x16, 0xd0, 0x60, 0x01, 0x9e, - 0xc3, 0xd2, 0x23, 0x65, 0xb2, 0x36, 0x11, 0x39, 0x03, 0xd6, 0x0e, 0x9d, 0x3a, 0x18, 0x46, 0x7c, - 0xa9, 0x60, 0x0a, 0x67, 0x71, 0x53, 0x1a, 0xa4, 0x93, 0xcd, 0xd5, 0x31, 0xe6, 0x9a, 0x1a, 0x83, - 0x4a, 0x4c, 0x72, 0xae, 0x98, 0x98, 0x7a, 0x0a, 0x71, 0xeb, 0xe0, 0xff, 0xc9, 0x38, 0x18, 0x4a, - 0xd0, 0xb0, 0xdb, 0xeb, 0xa5, 0x27, 0x2f, 0xb3, 0xa1, 0xc8, 0x59, 0x7c, 0x05, 0xef, 0x53, 0x6d, - 0xf0, 0x51, 0x1b, 0x3c, 0xc3, 0xe7, 0x27, 0x5b, 0x84, 0x75, 0xc7, 0xfc, 0x51, 0xf7, 0xdb, 0x22, - 0x5b, 0x88, 0x8b, 0x27, 0x30, 0x78, 0x13, 0x87, 0x66, 0x93, 0x9f, 0x9e, 0xb6, 0x50, 0x4f, 0xfc, - 0x68, 0x6a, 0xfa, 0x2c, 0x69, 0x7b, 0x7a, 0xf2, 0x51, 0x48, 0x5a, 0xf6, 0x96, 0x23, 0x3f, 0xed, - 0x03, 0x3c, 0xd6, 0xd3, 0xa9, 0xdf, 0x66, 0xd6, 0x7c, 0x4d, 0x9a, 0x6c, 0xc3, 0xd4, 0x6b, 0xf0, - 0x15, 0x84, 0xce, 0x14, 0x08, 0x51, 0xa8, 0x21, 0x30, 0xf7, 0xf7, 0x09, 0x84, 0x29, 0xa4, 0x9f, - 0x18, 0x95, 0x0a, 0x50, 0x3a, 0x2d, 0x22, 0xd0, 0x29, 0x04, 0x52, 0x2b, 0x8c, 0xbe, 0x24, 0x52, - 0xa9, 0x5e, 0x41, 0x5c, 0xf2, 0x1a, 0x9f, 0xca, 0x4c, 0xf9, 0x14, 0x3e, 0xe7, 0x3a, 0x70, 0x3c, - 0x10, 0xe7, 0xa7, 0x31, 0xf0, 0xc5, 0x28, 0x58, 0x27, 0x62, 0x22, 0xd4, 0xe1, 0xfd, 0x9a, 0xd3, - 0xff, 0x3c, 0x8a, 0xdb, 0xde, 0x26, 0x27, 0x9f, 0x2e, 0x3e, 0x5f, 0x4b, 0xeb, 0x44, 0x67, 0xf8, - 0x1d, 0x08, 0xe6, 0x47, 0xf5, 0x33, 0x93, 0xf5, 0xf4, 0x54, 0xb2, 0x62, 0xa9, 0xc9, 0x92, 0x96, - 0x6a, 0x20, 0x4c, 0xd3, 0x5a, 0xe8, 0x06, 0x04, 0xa9, 0xc3, 0xfd, 0xb1, 0x8a, 0xe0, 0x9a, 0x4d, - 0x9a, 0x79, 0xff, 0xec, 0x33, 0x46, 0x69, 0xe2, 0xa2, 0x80, 0x2d, 0x79, 0x10, 0x07, 0x88, 0xe3, - 0xa8, 0xf3, 0x2f, 0xf8, 0x48, 0xf3, 0x2f, 0x78, 0x62, 0x99, 0x7b, 0x11, 0x14, 0x6f, 0x14, 0x10, - 0xaf, 0x95, 0x0c, 0x18, 0xcf, 0xaa, 0xd2, 0x69, 0xed, 0xde, 0x01, 0x54, 0xbb, 0x16, 0x80, 0x10, - 0x15, 0xb1, 0xe7, 0x3f, 0xaa, 0x65, 0x14, 0xf0, 0x20, 0xf9, 0xfd, 0x1d, 0x7e, 0x7d, 0x01, 0x4c, - 0x37, 0x30, 0x56, 0xf2, 0x57, 0x9d, 0x5e, 0x17, 0xd7, 0x15, 0x60, 0x3c, 0x62, 0x06, 0x69, 0x8f, - 0x2b, 0xdf, 0x2f, 0xcc, 0xb0, 0x34, 0x87, 0x72, 0xa1, 0x08, 0x26, 0x03, 0x21, 0xd0, 0x28, 0xca, - 0xba, 0x31, 0x79, 0x84, 0xac, 0x34, 0xed, 0x42, 0x7b, 0x60, 0x7e, 0x69, 0xba, 0xec, 0x47, 0x85, - 0x2c, 0x61, 0xc8, 0x93, 0xbf, 0x2f, 0x81, 0x66, 0xca, 0x18, 0xc0, 0x6c, 0x04, 0x10, 0x48, 0xbb, - 0xf8, 0xe1, 0x53, 0x38, 0xc9, 0x66, 0x83, 0x3b, 0x8b, 0xfc, 0x07, 0xc8, 0x1c, 0x33, 0x9d, 0xc8, - 0x99, 0x23, 0x6e, 0xe8, 0x8a, 0xa5, 0xfe, 0x41, 0xca, 0xcf, 0x5c, 0xfa, 0x7d, 0x95, 0x7a, 0x5d, - 0x99, 0xaa, 0xf8, 0xa1, 0xcb, 0x0f, 0xa9, 0xf2, 0x6a, 0x6b, 0xf4, 0xeb, 0x7d, 0x82, 0xa8, 0xf9, - 0x2d, 0x1b, 0x6e, 0xe8, 0x1b, 0xfc, 0xe2, 0x0d, 0xcb, 0xd4, 0xf9, 0xf5, 0x1d, 0x0e, 0x42, 0xfb, - 0x57, 0x60, 0x59, 0xe8, 0x8c, 0xa1, 0xe8, 0x9e, 0x24, 0x6c, 0x81, 0x19, 0xa2, 0x7b, 0xb2, 0x04, - 0xb5, 0x81, 0x14, 0x5e, 0x80, 0x41, 0xeb, 0xc5, 0x12, 0xb8, 0x81, 0x39, 0x8d, 0x76, 0x06, 0x74, - 0xb7, 0x35, 0x19, 0xb7, 0x30, 0x5c, 0x58, 0xd0, 0xbe, 0x60, 0xd1, 0xe6, 0xc9, 0x05, 0x04, 0x2b, - 0x66, 0x01, 0x63, 0x5c, 0xc4, 0x68, 0x72, 0x6c, 0x06, 0x58, 0x5e, 0xac, 0x4a, 0x56, 0x19, 0xd0, - 0x92, 0x26, 0x73, 0x2e, 0x36, 0xc0, 0xd3, 0x76, 0xec, 0x7b, 0x2e, 0xd3, 0x6d, 0x90, 0x0a, 0x60, - 0x6c, 0xfc, 0xc5, 0x4b, 0xe6, 0x3a, 0xe9, 0x10, 0x63, 0xbf, 0x65, 0xf7, 0x6f, 0x43, 0x6f, 0xa2, - 0x59, 0x46, 0x3b, 0x5e, 0xfa, 0x5e, 0xc2, 0xdf, 0x0e, 0x54, 0x89, 0xdb, 0xa8, 0x8b, 0xc7, 0xd4, - 0xd4, 0x5d, 0x22, 0xd9, 0x68, 0x4d, 0x39, 0x5a, 0x31, 0x0a, 0xd6, 0x9e, 0x87, 0x71, 0x82, 0x5d, - 0x35, 0x81, 0xb9, 0x18, 0xe1, 0xec, 0x83, 0x13, 0x6e, 0x8a, 0x47, 0x2c, 0x1c, 0x6d, 0x02, 0xd2, - 0x66, 0x02, 0xda, 0x6a, 0x3c, 0xcb, 0xab, 0x39, 0x4a, 0xb7, 0x84, 0x74, 0xe2, 0xf6, 0x8f, 0x78, - 0x7f, 0xe9, 0x74, 0x09, 0x1e, 0x02, 0xe6, 0xc3, 0xe5, 0xa1, 0x24, 0xde, 0x77, 0xc1, 0x67, 0xc4, - 0x29, 0x37, 0x01, 0xbb, 0x16, 0x93, 0xfc, 0x52, 0xad, 0x04, 0x49, 0x2f, 0x16, 0x41, 0xd2, 0xf7, - 0x15, 0xf9, 0x40, 0x04, 0x50, 0xc1, 0x29, 0xe6, 0x34, 0xb1, 0xe7, 0xc6, 0xb0, 0x23, 0x2f, 0x7e, - 0x19, 0x72, 0xfd, 0x1b, 0xfd, 0x37, 0x6f, 0xc1, 0x83, 0xbe, 0x55, 0x84, 0xee, 0x40, 0x94, 0xe6, - 0xc6, 0x58, 0xf5, 0x09, 0x80, 0x1c, 0x60, 0xd8, 0x11, 0x37, 0xde, 0xe0, 0xa5, 0x1e, 0x9a, 0x4c, - 0x3e, 0xc9, 0x15, 0xdf, 0x14, 0x04, 0x19, 0x5d, 0x34, 0xf8, 0xe2, 0x3f, 0x3e, 0xfd, 0x15, 0xa7, - 0x1b, 0x8c, 0x53, 0xa2, 0x2d, 0x58, 0x32, 0x0f, 0x71, 0x8f, 0x16, 0xd8, 0x04, 0xa0, 0xb9, 0x0d, - 0x99, 0x24, 0x04, 0xda, 0xee, 0x8a, 0xef, 0xe6, 0xcc, 0x5f, 0x1e, 0x92, 0x51, 0x63, 0x28, 0x16, - 0x06, 0xe5, 0xca, 0xa8, 0xf8, 0x91, 0x5b, 0x69, 0xfa, 0x1d, 0xbb, 0xdd, 0x1f, 0x76, 0xc4, 0x87, - 0x74, 0x2f, 0xbf, 0xaa, 0x4d, 0x23, 0x6d, 0x74, 0x88, 0x8d, 0x0e, 0xa9, 0x7b, 0x93, 0xb5, 0x2b, - 0xb4, 0x90, 0x37, 0x89, 0x8c, 0xae, 0xe8, 0x2d, 0xcb, 0x40, 0xe6, 0x6a, 0x91, 0x7f, 0x38, 0xef, - 0x8e, 0x1a, 0x28, 0x93, 0xdb, 0x74, 0xb1, 0x1c, 0x68, 0xbf, 0xd3, 0x08, 0x6b, 0x99, 0x31, 0xca, - 0x4e, 0x56, 0x4b, 0x60, 0x4e, 0x77, 0x74, 0x1d, 0x26, 0xd4, 0x57, 0xdb, 0xae, 0xe9, 0x36, 0xb0, - 0xef, 0x72, 0x52, 0x65, 0xc9, 0x46, 0xb6, 0x67, 0xed, 0xe2, 0x30, 0xb3, 0x65, 0xb1, 0xa1, 0x37, - 0xba, 0x64, 0x90, 0x8c, 0x81, 0x89, 0x98, 0x40, 0x90, 0xbc, 0x0c, 0xef, 0x40, 0x07, 0x64, 0x31, - 0x2e, 0x56, 0xd3, 0x8e, 0xc5, 0x16, 0x63, 0x9c, 0x88, 0xad, 0xcc, 0xfe, 0xb0, 0xe3, 0x89, 0x76, - 0x63, 0xb9, 0xe5, 0xdc, 0x10, 0x95, 0x22, 0xab, 0xac, 0x37, 0xac, 0x5e, 0x2e, 0x6e, 0x49, 0xf3, - 0xba, 0x59, 0xb9, 0x71, 0x91, 0xf6, 0xdc, 0x78, 0x1f, 0xa0, 0x9f, 0xd4, 0xe8, 0x2a, 0x09, 0xf1, - 0x06, 0x10, 0x57, 0xf6, 0x15, 0xb0, 0x38, 0xd6, 0x7c, 0xbc, 0xa8, 0x83, 0x45, 0x2f, 0xec, 0x59, - 0x1f, 0x1c, 0x32, 0xc9, 0x6a, 0xb9, 0x5a, 0x2d, 0x4f, 0x25, 0x8b, 0x7d, 0x29, 0x7e, 0x68, 0x59, - 0xf4, 0xaa, 0xb6, 0x70, 0xf1, 0x38, 0x38, 0x6e, 0x6b, 0xe2, 0x45, 0x46, 0xda, 0xd1, 0x2a, 0x42, - 0x13, 0x9c, 0xf6, 0x21, 0xaf, 0x2f, 0x3a, 0x3b, 0x20, 0x6b, 0x2b, 0xe3, 0x6b, 0x1b, 0x5b, 0xdd, - 0x5e, 0xb6, 0xc1, 0x66, 0x59, 0xa5, 0xcd, 0xea, 0x74, 0x73, 0x6b, 0xd4, 0xd0, 0x16, 0x07, 0xc5, - 0xee, 0xb3, 0xa3, 0xae, 0x0a, 0x29, 0xfe, 0xae, 0x29, 0x30, 0x6a, 0x6c, 0xff, 0xf4, 0x6e, 0x6f, - 0x6f, 0x6f, 0xa0, 0xfd, 0x67, 0xb8, 0x8a, 0x8a, 0x33, 0x03, 0x12, 0x7c, 0x8b, 0xdb, 0x0f, 0xda, - 0x1c, 0x38, 0xa6, 0xb9, 0x62, 0x20, 0x6d, 0xce, 0xd5, 0xeb, 0x50, 0x03, 0x95, 0x82, 0xef, 0x8c, - 0x27, 0x52, 0x31, 0x9d, 0x32, 0x91, 0x3e, 0x3d, 0x20, 0x16, 0x2e, 0x35, 0x26, 0x02, 0x2e, 0x85, - 0xd1, 0x83, 0x18, 0x02, 0xd3, 0x22, 0xf7, 0x46, 0x73, 0x91, 0x5f, 0x31, 0xff, 0xd6, 0x58, 0xac, - 0xfc, 0xc4, 0x03, 0x08, 0xd9, 0xab, 0x17, 0xfc, 0x60, 0x32, 0x1e, 0xc5, 0xe5, 0xd7, 0x58, 0xa3, - 0xc1, 0x04, 0xf2, 0xbb, 0x29, 0x34, 0xde, 0xca, 0xb6, 0xa3, 0x40, 0x94, 0x1a, 0x07, 0x6a, 0x32, - 0xa9, 0x0f, 0x64, 0xf2, 0x59, 0x8c, 0xf3, 0xf3, 0x9a, 0x84, 0xb8, 0x55, 0xf9, 0x00, 0xa3, 0x0f, - 0x63, 0x7e, 0x9b, 0x00, 0xd2, 0xc8, 0xc1, 0x04, 0xf5, 0xff, 0x60, 0x6c, 0xa9, 0xd1, 0x44, 0xdb, - 0xf6, 0x93, 0x81, 0x7d, 0xa0, 0x79, 0x53, 0x41, 0x01, 0x96, 0xc8, 0xf3, 0x22, 0xf8, 0x09, 0x30, - 0xd6, 0x4d, 0x50, 0x36, 0x71, 0x2b, 0x1d, 0x1b, 0x67, 0x55, 0xe8, 0x9c, 0x94, 0xc6, 0x09, 0x1f, - 0x29, 0xbf, 0xe0, 0x22, 0xbd, 0x84, 0x00, 0x7c, 0x1c, 0x8b, 0x02, 0x50, 0x92, 0x3c, 0x13, 0x4d, - 0x69, 0xf0, 0x91, 0x42, 0xbc, 0x2c, 0x27, 0x98, 0x09, 0x12, 0x74, 0x29, 0x17, 0x1a, 0x08, 0x3d, - 0x5e, 0x4d, 0x03, 0x5a, 0xb1, 0x8a, 0xc1, 0x03, 0x28, 0xe5, 0x92, 0x13, 0xb7, 0x44, 0x1b, 0xb2, - 0x0a, 0x6e, 0x02, 0x88, 0xb5, 0xa4, 0x54, 0x1b, 0x99, 0x72, 0x44, 0x42, 0x67, 0x6f, 0x43, 0x3f, - 0xc1, 0x5b, 0x76, 0xf4, 0x33, 0x3c, 0x0e, 0x20, 0xe7, 0x89, 0xeb, 0x15, 0xd5, 0x90, 0x38, 0xe0, - 0x30, 0x80, 0x19, 0x15, 0xf5, 0x00, 0xbc, 0xf4, 0x7e, 0x4d, 0xb6, 0xf1, 0x42, 0x81, 0x52, 0x69, - 0x19, 0xd6, 0x4d, 0xa4, 0xa9, 0x50, 0xb6, 0xdc, 0x3e, 0x02, 0x9e, 0xc8, 0xb3, 0xf0, 0x9a, 0xde, - 0xeb, 0x2d, 0x0e, 0x8c, 0x46, 0x6d, 0xe9, 0x58, 0x8f, 0x43, 0xb3, 0xe9, 0xd4, 0x73, 0xf1, 0x60, - 0x87, 0xa6, 0xef, 0x20, 0xfc, 0xa6, 0xd2, 0xe4, 0x06, 0x56, 0xf1, 0xeb, 0x3b, 0xd6, 0x06, 0x30, - 0x2c, 0xe8, 0x18, 0xc9, 0x9a, 0x7f, 0xdd, 0xee, 0x6e, 0x80, 0xc4, 0x9a, 0xe0, 0xc6, 0x11, 0x5f, - 0x71, 0xaf, 0x28, 0x4e, 0x2b, 0x18, 0x12, 0x71, 0xa0, 0xbf, 0x46, 0x5d, 0x04, 0x0a, 0x71, 0xf2, - 0x42, 0xb1, 0x1a, 0x0f, 0x4d, 0x00, 0x87, 0x53, 0x1d, 0x57, 0xcc, 0x5d, 0x57, 0xf1, 0x72, 0x2d, - 0x0a, 0xb7, 0x6b, 0x3e, 0xad, 0xd7, 0x6e, 0xa5, 0xdc, 0xaa, 0xf6, 0x27, 0x13, 0x5e, 0xc5, 0x77, - 0x2f, 0x27, 0x8a, 0x41, 0xbc, 0x82, 0x3f, 0x74, 0x1c, 0x02, 0x11, 0x5c, 0x13, 0xb1, 0x7f, 0x54, - 0x4b, 0x14, 0xeb, 0x76, 0x2a, 0x38, 0xd2, 0xe4, 0xef, 0x8c, 0x1a, 0x25, 0x43, 0xbf, 0x93, 0xd9, - 0x11, 0xac, 0x69, 0xe7, 0xb7, 0xaa, 0x89, 0xf3, 0x20, 0x71, 0x5f, 0xb5, 0x2b, 0x56, 0x17, 0x28, - 0x3f, 0xd3, 0x28, 0xba, 0x26, 0xc4, 0xd0, 0xcc, 0x79, 0xb5, 0x74, 0xf9, 0x14, 0xa3, 0x00, 0x32, - 0x6a, 0xa6, 0x4e, 0x48, 0xab, 0x71, 0x6d, 0x88, 0xa0, 0x55, 0x81, 0xa0, 0x25, 0x31, 0xb4, 0x72, - 0x9e, 0x2e, 0xe2, 0x74, 0x9e, 0xf1, 0x43, 0x30, 0xda, 0xe7, 0xbc, 0x1e, 0xf1, 0x81, 0xc0, 0xd4, - 0x5b, 0xca, 0x1d, 0x69, 0x9d, 0xfc, 0x17, 0x3b, 0xe7, 0xbe, 0x0e, 0x0b, 0x56, 0x94, 0x1f, 0x50, - 0xd2, 0x1a, 0x95, 0x15, 0x02, 0xad, 0x31, 0x56, 0x65, 0x0e, 0xf8, 0x0d, 0x76, 0x7d, 0xdb, 0xb2, - 0x96, 0xf7, 0x83, 0x39, 0x43, 0xeb, 0x03, 0x3f, 0xe0, 0x79, 0xcc, 0xd7, 0x13, 0x5b, 0x78, 0x82, - 0x69, 0x15, 0xf7, 0xbb, 0xf0, 0x4a, 0xd5, 0xf9, 0x34, 0x0a, 0x5d, 0xe4, 0x0e, 0x0c, 0xfd, 0x4d, - 0x43, 0x0d, 0x92, 0x04, 0xbd, 0x69, 0xd1, 0x0a, 0x86, 0x11, 0x08, 0x6b, 0x37, 0xf6, 0x20, 0xc8, - 0x03, 0x13, 0x1c, 0x69, 0x3e, 0x9d, 0x69, 0x5e, 0x1c, 0xaf, 0x20, 0x88, 0xc6, 0xee, 0x3e, 0x83, - 0x09, 0xf4, 0xb9, 0x55, 0x04, 0x15, 0xd7, 0x72, 0xee, 0x54, 0x9d, 0x30, 0x1a, 0x55, 0x1c, 0xfe, - 0x51, 0x3c, 0x41, 0x23, 0x82, 0xf6, 0x6f, 0x8c, 0xbe, 0x99, 0xdd, 0x03, 0x00, 0xe8, 0xae, 0x5b, - 0xb0, 0xc7, 0x20, 0x0e, 0x8d, 0xbc, 0x3c, 0x9c, 0xd1, 0x1b, 0x86, 0x86, 0x87, 0xcd, 0x16, 0xca, - 0x0c, 0x31, 0xc8, 0xa2, 0x25, 0xe2, 0x17, 0x7c, 0xed, 0xd9, 0x15, 0x11, 0x4c, 0x92, 0x6a, 0x36, - 0x5e, 0xc5, 0xa2, 0xea, 0x04, 0xc6, 0x39, 0x81, 0x40, 0x37, 0xae, 0x6d, 0x9f, 0xb3, 0x61, 0x62, - 0xf3, 0x87, 0xef, 0xc3, 0xc8, 0x35, 0x46, 0xe9, 0xab, 0x63, 0x4f, 0x78, 0x6a, 0x64, 0xc9, 0xcc, - 0x0f, 0xc7, 0x22, 0xa0, 0x81, 0x4e, 0xa6, 0xd3, 0x5c, 0x14, 0xd0, 0xa8, 0x26, 0xed, 0xf4, 0xb8, - 0xb4, 0x63, 0x2d, 0xb4, 0x69, 0x5d, 0x1f, 0x70, 0x7a, 0x1b, 0xa2, 0x9a, 0xdb, 0x0f, 0xa3, 0xbf, - 0xb8, 0x30, 0xfc, 0xb5, 0x80, 0xcc, 0x07, 0x27, 0x3a, 0x5f, 0x5b, 0xa2, 0xa9, 0x0d, 0xfe, 0x7e, - 0xae, 0x00, 0x3c, 0xab, 0xb2, 0xa8, 0x63, 0x70, 0xb5, 0xbe, 0xa8, 0xd6, 0x58, 0x4f, 0x50, 0x50, - 0x1a, 0xbe, 0x1c, 0x5e, 0x50, 0xb8, 0xc6, 0x66, 0x0c, 0x58, 0x53, 0x90, 0x61, 0x50, 0x85, 0x19, - 0xeb, 0x0a, 0x57, 0x47, 0x9c, 0x1a, 0x09, 0x5f, 0xc2, 0x94, 0x50, 0x72, 0x2f, 0x5d, 0xe3, 0x9b, - 0xaa, 0xdc, 0x43, 0x42, 0x2e, 0xd9, 0x5a, 0x2d, 0x3b, 0xb8, 0x84, 0xf0, 0x12, 0xdf, 0x4f, 0x2e, - 0x04, 0x9f, 0xf9, 0x76, 0x32, 0x08, 0x23, 0x16, 0xda, 0x85, 0xfe, 0xa4, 0xa6, 0xbe, 0x20, 0x2b, - 0x7d, 0x6c, 0x14, 0xac, 0xad, 0x8d, 0x21, 0x94, 0x40, 0x78, 0x7d, 0x9d, 0xb3, 0xaf, 0x88, 0xf9, - 0xe4, 0x72, 0x53, 0xc5, 0x02, 0x47, 0xd3, 0xb2, 0x11, 0x21, 0x22, 0xda, 0xdd, 0x4b, 0x09, 0xbb, - 0xdc, 0x54, 0xc2, 0xb0, 0xe6, 0x69, 0x4f, 0xae, 0xcb, 0xd2, 0xd3, 0x28, 0x57, 0x0d, 0x5d, 0x82, - 0x09, 0x4b, 0x98, 0x36, 0x59, 0x2f, 0x3e, 0x28, 0xd7, 0x0f, 0x75, 0x77, 0x5b, 0x37, 0xec, 0xa1, - 0x70, 0x4a, 0xa3, 0x51, 0xae, 0x22, 0x92, 0x50, 0xfc, 0xe4, 0x5c, 0xfd, 0x91, 0x8f, 0x1d, 0x3c, - 0xbd, 0xc3, 0x01, 0xc7, 0xf0, 0xbb, 0x16, 0x1f, 0x1e, 0xf2, 0x29, 0xf7, 0x5a, 0x2e, 0x2d, 0xea, - 0xda, 0x2f, 0x92, 0xf6, 0x96, 0x8c, 0xde, 0xca, 0x0e, 0x79, 0xce, 0x52, 0x8d, 0xeb, 0x37, 0x32, - 0x7a, 0xc7, 0xa1, 0xa2, 0x1c, 0x2b, 0x1a, 0xa5, 0x32, 0x80, 0x11, 0xdf, 0x02, 0x88, 0x38, 0xeb, - 0x2a, 0x7c, 0x7b, 0xc5, 0x06, 0xbf, 0xdc, 0xdf, 0xcf, 0x25, 0x50, 0x6f, 0x70, 0x7f, 0x9f, 0xef, - 0x9c, 0xbc, 0xa9, 0xdf, 0xdd, 0x6f, 0x1c, 0xf0, 0xb8, 0x18, 0xe4, 0x45, 0x4c, 0x24, 0x86, 0x96, - 0x0b, 0xea, 0x05, 0xa9, 0xb1, 0xc3, 0x6b, 0xce, 0x5e, 0xb4, 0x70, 0xe7, 0x59, 0xba, 0x20, 0xf2, - 0x4a, 0x7e, 0xa6, 0xaf, 0xda, 0xe8, 0xa7, 0x9b, 0x1b, 0x6b, 0x58, 0xf9, 0xcd, 0x8c, 0x12, 0x23, - 0xdf, 0xdd, 0xd5, 0x1a, 0xd4, 0x75, 0xd9, 0x12, 0x02, 0x88, 0x36, 0x47, 0x57, 0x63, 0x25, 0x72, - 0xaa, 0x9a, 0x1b, 0x7b, 0x6e, 0x6f, 0x9c, 0x74, 0xbc, 0x48, 0x60, 0x00, 0x46, 0x7c, 0xe6, 0xef, - 0xab, 0xd4, 0x9e, 0x6a, 0x0d, 0x50, 0xc4, 0xa9, 0x53, 0x79, 0xc9, 0x28, 0xe7, 0xed, 0x94, 0x82, - 0xb5, 0x86, 0xc7, 0x69, 0x04, 0xe1, 0xc5, 0xa4, 0x03, 0xa1, 0x10, 0xdf, 0xb7, 0x75, 0xc8, 0x5f, - 0x30, 0xe5, 0xc1, 0x0d, 0x41, 0xad, 0x83, 0xaf, 0xe1, 0xb0, 0x43, 0x05, 0x6f, 0x2f, 0x71, 0x07, - 0xe8, 0x55, 0x8a, 0xb8, 0xa6, 0x87, 0x97, 0xa7, 0x65, 0x3d, 0x6c, 0xe4, 0x14, 0x51, 0x13, 0x37, - 0x53, 0x6c, 0x9e, 0x96, 0xcb, 0x33, 0xa2, 0x52, 0xcd, 0x1a, 0x51, 0x29, 0x4a, 0x0a, 0x6e, 0x7b, - 0x6d, 0x90, 0x94, 0xb2, 0x5d, 0x84, 0xc8, 0x4a, 0x5e, 0x99, 0x16, 0xf3, 0x30, 0xeb, 0x1a, 0xd7, - 0xa5, 0xb8, 0xd7, 0xc5, 0xf5, 0xb6, 0x29, 0xe6, 0x08, 0x22, 0x6f, 0x00, 0xb3, 0xc8, 0xb7, 0x31, - 0x5f, 0xb2, 0x8b, 0x87, 0x52, 0x8e, 0x24, 0xd6, 0x5c, 0xfe, 0xb3, 0x16, 0x87, 0x1e, 0x41, 0x1c, - 0xda, 0xa8, 0xb4, 0x92, 0x8b, 0xaa, 0x90, 0x34, 0x0b, 0x3d, 0x75, 0xab, 0x05, 0x6f, 0x0c, 0x95, - 0x6b, 0x1c, 0xc8, 0xa4, 0x10, 0x89, 0x03, 0x1f, 0x92, 0xef, 0xe2, 0xf0, 0xa2, 0x26, 0x9b, 0x2d, - 0xf7, 0x60, 0x15, 0x52, 0x57, 0x88, 0x63, 0xc7, 0x61, 0x08, 0xc9, 0x80, 0x85, 0x39, 0x62, 0xac, - 0x82, 0xda, 0x38, 0xed, 0x14, 0x5d, 0xf5, 0x47, 0xba, 0x58, 0x50, 0xcd, 0x0d, 0xa3, 0x48, 0xe6, - 0x87, 0x18, 0x53, 0x70, 0xe7, 0xfa, 0x12, 0x8f, 0x3e, 0x42, 0x04, 0xab, 0xe9, 0x71, 0x12, 0x85, - 0x90, 0x05, 0xa1, 0x19, 0x49, 0xd7, 0x20, 0x78, 0x07, 0x8d, 0x5a, 0xec, 0x15, 0xcc, 0xac, 0xe9, - 0x01, 0x17, 0x74, 0x34, 0x3d, 0x80, 0x31, 0xac, 0x63, 0xcf, 0x90, 0x73, 0x4b, 0xb5, 0x36, 0x2b, - 0x1f, 0xff, 0xa8, 0x67, 0x59, 0x83, 0x2f, 0xd3, 0xa2, 0x97, 0x63, 0x11, 0xf0, 0xac, 0xbd, 0xb7, - 0x56, 0xec, 0xba, 0x83, 0xd6, 0x82, 0x2d, 0x81, 0xad, 0x6d, 0x7b, 0xcd, 0x97, 0xf1, 0x61, 0x1d, - 0x66, 0xa9, 0x30, 0xa8, 0x61, 0x92, 0xe3, 0x93, 0x9c, 0xae, 0x0f, 0x2f, 0x4c, 0x97, 0x5d, 0xc8, - 0x51, 0x32, 0x89, 0xf8, 0x05, 0xc5, 0xf8, 0x3a, 0xa2, 0x41, 0xec, 0xf1, 0x3d, 0x12, 0x2e, 0xc9, - 0x47, 0x51, 0x18, 0xc7, 0x53, 0x3a, 0x61, 0x2f, 0xb0, 0xea, 0xfa, 0x83, 0x10, 0xd8, 0x46, 0x86, - 0x40, 0xc3, 0xbb, 0x57, 0xd7, 0x88, 0xbb, 0x3e, 0xae, 0x21, 0xee, 0xde, 0x2f, 0x57, 0x1e, 0xe3, - 0x2d, 0xd3, 0x0d, 0x6d, 0x11, 0x23, 0x5e, 0xb9, 0xd2, 0x73, 0x41, 0x7d, 0x96, 0x80, 0x0f, 0x4d, - 0x32, 0x32, 0x5f, 0x20, 0xec, 0x42, 0x12, 0x86, 0xd9, 0xd5, 0x25, 0x0d, 0x26, 0x10, 0x77, 0x1e, - 0x3d, 0xb8, 0x3e, 0xc3, 0x7c, 0x29, 0x45, 0x57, 0x45, 0xe9, 0xc5, 0xcb, 0x6c, 0x6c, 0xa4, 0x7c, - 0x1c, 0x69, 0xb1, 0xb0, 0x0c, 0xc0, 0x41, 0xc0, 0x35, 0xd1, 0x7c, 0x9c, 0x24, 0xce, 0x41, 0xa5, - 0xc2, 0xc7, 0xf2, 0x3e, 0xdd, 0xf5, 0x7e, 0x4e, 0x5f, 0x52, 0x60, 0xbb, 0x5a, 0x81, 0xe1, 0x1b, - 0x67, 0xb8, 0xc2, 0x7f, 0xcd, 0x4d, 0x70, 0xbd, 0xa5, 0xb8, 0x3e, 0x7c, 0x59, 0x8d, 0x1b, 0x15, - 0x1d, 0x61, 0x27, 0xb8, 0xc8, 0xbd, 0x7e, 0x4e, 0xed, 0xfa, 0x4b, 0xd5, 0x19, 0xb5, 0x2f, 0xd4, - 0x4b, 0xf8, 0xda, 0x0e, 0xd8, 0x91, 0xc6, 0x86, 0x08, 0xe7, 0x03, 0x88, 0xd4, 0x86, 0x93, 0x6a, - 0xf8, 0x59, 0xe3, 0xd1, 0x74, 0x6d, 0x68, 0x00, 0x71, 0xcd, 0xd5, 0x2a, 0x88, 0xbc, 0xb8, 0x2a, - 0x2c, 0x00, 0xbe, 0xf3, 0xa3, 0xb2, 0x78, 0xfd, 0x24, 0x24, 0x8c, 0xe8, 0xbf, 0xf9, 0x64, 0x34, - 0xc4, 0xdb, 0x43, 0x0a, 0x6e, 0xca, 0x65, 0x39, 0xc3, 0xf0, 0xd2, 0xd1, 0x96, 0xa3, 0xeb, 0xb5, - 0x75, 0xc0, 0x3b, 0x5c, 0x05, 0xfd, 0x28, 0xf2, 0x8c, 0x50, 0x86, 0xfa, 0xdc, 0xba, 0x54, 0x1d, - 0xdf, 0xa8, 0x3c, 0xad, 0x91, 0xb1, 0xaf, 0x91, 0x5f, 0xf0, 0x38, 0x7e, 0x21, 0x3c, 0x7c, 0xf9, - 0x74, 0x63, 0xe3, 0x85, 0x43, 0x1d, 0xc8, 0xe0, 0x17, 0x8e, 0x75, 0x20, 0x77, 0xf1, 0x60, 0x47, - 0x63, 0xc3, 0x69, 0xc0, 0xca, 0xb3, 0x1d, 0x3c, 0xbd, 0x4b, 0x07, 0x0f, 0x6c, 0xcb, 0x4e, 0xac, - 0xa4, 0x6e, 0xa5, 0x86, 0xc5, 0x97, 0x82, 0xc3, 0xd8, 0x06, 0x32, 0x1b, 0x50, 0xee, 0x5b, 0x48, - 0x4d, 0x7d, 0x30, 0xb9, 0x90, 0x5a, 0xad, 0xfb, 0x82, 0x72, 0x46, 0x50, 0x97, 0x10, 0x1c, 0x1d, - 0xe6, 0x95, 0xe6, 0x97, 0xdc, 0xf2, 0xc8, 0xc1, 0xe4, 0x16, 0x85, 0x60, 0xc2, 0x05, 0x43, 0x59, - 0x82, 0x5c, 0x87, 0x85, 0xe9, 0xba, 0x38, 0xac, 0x92, 0xf6, 0xc6, 0x29, 0xbf, 0xd0, 0x44, 0xd3, - 0xef, 0x22, 0xba, 0xc4, 0xc5, 0x9a, 0x45, 0x78, 0x0b, 0x8d, 0x8d, 0x0d, 0x93, 0xa3, 0x5a, 0x50, - 0xff, 0x8e, 0x3e, 0xc4, 0x1a, 0x36, 0x34, 0x36, 0x05, 0xf9, 0x0a, 0x3e, 0xc0, 0xa3, 0x58, 0x6b, - 0xe0, 0xe5, 0x39, 0x6b, 0xa0, 0x68, 0x54, 0x78, 0xac, 0xca, 0x79, 0x92, 0x16, 0x23, 0x12, 0xe7, - 0x9b, 0x70, 0x05, 0x93, 0xbd, 0x92, 0xcf, 0xca, 0x24, 0xd9, 0xdd, 0x94, 0xcf, 0x1f, 0x2e, 0xf3, - 0x7c, 0xfe, 0x70, 0x71, 0x55, 0x9f, 0x3d, 0xba, 0x53, 0x9e, 0x2a, 0xe3, 0x1d, 0xe3, 0x5a, 0xc2, - 0x16, 0x4b, 0x3f, 0xdf, 0x71, 0x75, 0x08, 0xdc, 0xfd, 0xbf, 0x89, 0x81, 0xd3, 0x34, 0x57, 0x55, - 0x37, 0xa6, 0x45, 0x90, 0x5d, 0x4c, 0xd0, 0x78, 0xc8, 0x53, 0x9d, 0xf6, 0x8e, 0x5e, 0xd8, 0xc5, - 0x29, 0x6f, 0xc8, 0x34, 0x5e, 0xb3, 0x23, 0xd3, 0xc1, 0x4d, 0xa6, 0x8c, 0x0f, 0xe2, 0x22, 0x74, - 0xd5, 0x6b, 0x07, 0xb7, 0xa7, 0x70, 0xaf, 0x0a, 0xff, 0x3f, 0x1b, 0xfe, 0x0f, 0xea, 0x81, 0x78, - 0x0d, 0xc3, 0x61, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_dmx.htm, do not edit!! -const uint16_t PAGE_settings_dmx_length = 1751; -const uint8_t PAGE_settings_dmx[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x95, 0x57, 0x5b, 0x73, 0xdb, 0x36, - 0x16, 0x7e, 0xd7, 0xaf, 0x40, 0xf0, 0x50, 0x93, 0x63, 0x86, 0x94, 0x9c, 0x55, 0xb7, 0x91, 0x44, - 0x7a, 0x63, 0xc7, 0x6b, 0x7b, 0xc7, 0x76, 0x3d, 0x51, 0xd2, 0x74, 0xa7, 0xe9, 0x74, 0x20, 0x12, - 0x12, 0x51, 0x93, 0x04, 0x17, 0x00, 0x25, 0xbb, 0x69, 0xfe, 0xfb, 0x7e, 0x00, 0xa9, 0x8b, 0x6f, - 0x6d, 0xf2, 0x22, 0x8a, 0xc0, 0xb9, 0x5f, 0xbe, 0x73, 0x38, 0x79, 0xf1, 0xf6, 0xc7, 0xe3, 0xf7, - 0xff, 0xbd, 0x3e, 0x21, 0xb9, 0x29, 0x8b, 0x64, 0x62, 0x7f, 0x49, 0xc1, 0xaa, 0x45, 0x4c, 0x79, - 0x45, 0xf1, 0xce, 0x59, 0x96, 0x4c, 0x4a, 0x6e, 0x18, 0xa9, 0x58, 0xc9, 0x63, 0xba, 0x14, 0x7c, - 0x55, 0x4b, 0x65, 0x28, 0x49, 0x65, 0x65, 0x78, 0x65, 0x62, 0xba, 0x12, 0x99, 0xc9, 0xe3, 0x61, - 0xbf, 0x4f, 0x93, 0x5e, 0x4b, 0xda, 0x7b, 0x70, 0x97, 0xf1, 0xa5, 0x48, 0xf9, 0x4b, 0xf7, 0x12, - 0x88, 0x4a, 0x18, 0xc1, 0x8a, 0x97, 0x3a, 0x65, 0x05, 0x8f, 0x07, 0x41, 0xc9, 0x6e, 0x45, 0xd9, - 0x94, 0x9b, 0xf7, 0x46, 0x73, 0xe5, 0x5e, 0xd8, 0x0c, 0xef, 0x95, 0xa4, 0xa4, 0xf7, 0x40, 0x75, - 0x67, 0x50, 0x9a, 0x33, 0xa5, 0x39, 0x94, 0x34, 0x66, 0xfe, 0xf2, 0x07, 0x9c, 0x1a, 0x61, 0x0a, - 0x9e, 0xbc, 0xbd, 0xfc, 0x99, 0x4c, 0xb9, 0x31, 0xa2, 0x5a, 0xe8, 0x49, 0xd4, 0x9e, 0x4d, 0x74, - 0xaa, 0x44, 0x6d, 0x92, 0xde, 0x92, 0x29, 0x52, 0xc8, 0x54, 0xd4, 0x41, 0x16, 0x67, 0x32, 0x6d, - 0x4a, 0x58, 0x19, 0xe0, 0x20, 0x7e, 0x31, 0xb0, 0x8f, 0x5a, 0x49, 0x23, 0x63, 0x9a, 0x1b, 0x53, - 0x8f, 0xe8, 0x78, 0xde, 0x54, 0xa9, 0x11, 0xb2, 0x22, 0x67, 0x9e, 0xff, 0x79, 0x25, 0xaa, 0x4c, - 0xae, 0x42, 0x59, 0xf3, 0xca, 0x73, 0x04, 0x7a, 0x14, 0x45, 0x0b, 0x61, 0xf2, 0x66, 0x16, 0xa6, - 0xb2, 0x8c, 0xde, 0x08, 0x95, 0x4a, 0x29, 0x6f, 0x04, 0x8f, 0x3e, 0x5e, 0x9c, 0xbc, 0x8d, 0x56, - 0xe2, 0x46, 0x44, 0xb0, 0x85, 0xfa, 0x5f, 0x36, 0x72, 0x8e, 0x1e, 0xc8, 0x59, 0x70, 0xf3, 0xe1, - 0xdd, 0x85, 0x47, 0x23, 0xdd, 0xd9, 0x4b, 0xfd, 0x80, 0xfe, 0xa6, 0x79, 0x31, 0xdf, 0xe5, 0x3a, - 0x3d, 0x3e, 0xf3, 0x8c, 0xff, 0x79, 0x2e, 0x95, 0x97, 0x85, 0x60, 0x39, 0x29, 0xb8, 0x35, 0xfb, - 0xe8, 0xee, 0x3c, 0xf3, 0x68, 0x56, 0xde, 0x22, 0x0e, 0x55, 0xc5, 0x0b, 0x30, 0x87, 0x02, 0x7f, - 0xd4, 0xd9, 0xfb, 0xcb, 0x8b, 0xfd, 0x98, 0xd2, 0x40, 0xc4, 0xfd, 0xb1, 0x98, 0x98, 0xb1, 0xd8, - 0xdf, 0xf7, 0xbf, 0x85, 0x73, 0xa2, 0x6b, 0x56, 0x11, 0x91, 0xc5, 0xc7, 0x67, 0x74, 0xdf, 0x13, - 0xfb, 0x03, 0x7f, 0x9f, 0x6a, 0x92, 0x1c, 0xb7, 0xd4, 0x64, 0x73, 0x36, 0x22, 0x13, 0xd8, 0xca, - 0x53, 0xd3, 0xd6, 0xc6, 0x96, 0x7a, 0xcf, 0x32, 0xd3, 0xe3, 0xb3, 0xbd, 0xf5, 0x3b, 0x92, 0x23, - 0x6b, 0xe7, 0xcc, 0x92, 0x15, 0x0d, 0x8f, 0xfb, 0x09, 0x32, 0x44, 0x8c, 0x24, 0xfd, 0x49, 0xd4, - 0x5e, 0x3c, 0x20, 0x18, 0x24, 0xef, 0x78, 0xf6, 0xcc, 0xdd, 0x41, 0x72, 0xaa, 0x38, 0xaf, 0x9e, - 0xb9, 0x7d, 0x95, 0x1c, 0xe1, 0xf1, 0xcc, 0xe5, 0x3f, 0x92, 0x8f, 0xb9, 0x30, 0xcf, 0xdd, 0x0e, - 0x93, 0x69, 0xde, 0x18, 0xc3, 0x15, 0xf1, 0x8e, 0x94, 0x58, 0xe4, 0xa6, 0xe2, 0x5a, 0xfb, 0xcf, - 0x10, 0x7f, 0xbf, 0x76, 0xe1, 0x60, 0x38, 0xdc, 0x92, 0x44, 0x6d, 0x40, 0xec, 0x1f, 0xc4, 0x30, - 0x99, 0xcc, 0x14, 0x89, 0x92, 0x4f, 0xd5, 0xde, 0x36, 0x9b, 0xe5, 0x25, 0xab, 0xbd, 0x36, 0x9b, - 0x55, 0x53, 0x1e, 0xe7, 0x9b, 0x32, 0x0c, 0xa7, 0xf3, 0xf0, 0xf8, 0x2a, 0x74, 0xd2, 0x03, 0x5c, - 0x9d, 0xb2, 0xfa, 0xfe, 0xdd, 0x69, 0x77, 0x57, 0xdb, 0xb2, 0x3f, 0xaf, 0x4c, 0xcb, 0xef, 0x27, - 0xbb, 0xef, 0x60, 0xf2, 0x0f, 0x1f, 0xe7, 0x7a, 0xc1, 0xea, 0x15, 0x53, 0x15, 0x4a, 0x0c, 0xa9, - 0xd6, 0xe6, 0xae, 0xe0, 0x61, 0x26, 0x74, 0x5d, 0xb0, 0xbb, 0x98, 0xce, 0x50, 0xf7, 0x37, 0x74, - 0xf4, 0x6d, 0x4c, 0x95, 0xac, 0xf8, 0xba, 0xc0, 0x06, 0x43, 0x57, 0x61, 0x22, 0x89, 0x9d, 0x41, - 0x87, 0x4f, 0x54, 0xe9, 0x6e, 0x21, 0x6d, 0x84, 0xc9, 0x9a, 0xa5, 0xc2, 0x40, 0x58, 0x3f, 0x1c, - 0xd2, 0xe0, 0x2f, 0x98, 0x7c, 0xab, 0xd7, 0xa2, 0x41, 0x16, 0xbf, 0xe8, 0xfb, 0xa3, 0x6f, 0x96, - 0x3f, 0xf8, 0x6a, 0xe9, 0x83, 0x9d, 0xb6, 0x2b, 0x24, 0xcb, 0xfe, 0x33, 0xf5, 0x4c, 0xc0, 0xad, - 0xd6, 0xcf, 0x05, 0xb2, 0x2d, 0xe3, 0x2c, 0x4c, 0x15, 0x67, 0x86, 0x77, 0xa2, 0x3c, 0xda, 0x02, - 0x0b, 0xf5, 0xc7, 0x32, 0x44, 0x13, 0xbf, 0x31, 0x46, 0x89, 0x59, 0x63, 0x38, 0x2e, 0x54, 0x4a, - 0x03, 0xe3, 0x07, 0x0f, 0xcf, 0xcd, 0x5d, 0x8d, 0xc8, 0x51, 0xc3, 0x6f, 0x4d, 0xf4, 0x3b, 0x5b, - 0xb2, 0xb5, 0x80, 0x47, 0x84, 0x4c, 0xdf, 0x55, 0x10, 0xc1, 0x7d, 0x18, 0x3f, 0x93, 0xd9, 0x5d, - 0xc8, 0x6a, 0x60, 0x46, 0x76, 0x9c, 0x8b, 0x22, 0xf3, 0xa4, 0xa5, 0x67, 0x59, 0x76, 0xb2, 0x84, - 0x15, 0x17, 0x42, 0x03, 0x6d, 0xb9, 0xf2, 0xa8, 0xb5, 0x99, 0x06, 0x9e, 0x1f, 0x27, 0x9f, 0x2d, - 0x6a, 0x0c, 0x86, 0x7e, 0x70, 0xca, 0xcd, 0x4f, 0x9e, 0x1f, 0xb4, 0x65, 0xf7, 0xe5, 0x69, 0x36, - 0xae, 0x94, 0x54, 0xb0, 0x16, 0x6c, 0x40, 0x6e, 0x2d, 0x11, 0xbc, 0x42, 0x2e, 0x3c, 0x7a, 0x62, - 0xcf, 0x49, 0x17, 0x0b, 0xd4, 0x01, 0x99, 0x8b, 0x82, 0x3b, 0xaf, 0x00, 0xd5, 0x0a, 0xde, 0x5f, - 0x74, 0xe7, 0x72, 0x6e, 0xc7, 0xc1, 0x5c, 0x2c, 0x1a, 0xc5, 0x5c, 0xf0, 0x5a, 0xaf, 0xc8, 0x9c, - 0x81, 0x21, 0x0b, 0x3f, 0x55, 0xe7, 0x15, 0x30, 0xb2, 0x46, 0x0c, 0x39, 0xa9, 0xd9, 0x82, 0x93, - 0x8c, 0x19, 0xf6, 0x02, 0x20, 0xb7, 0x13, 0xef, 0xa9, 0xd7, 0x06, 0xd9, 0xc4, 0x1d, 0x44, 0xa2, - 0x2e, 0x9d, 0xb0, 0xb1, 0x98, 0x7b, 0xd4, 0x6a, 0x1e, 0xd1, 0x38, 0x36, 0xa1, 0xc3, 0xe8, 0x54, - 0x16, 0xbe, 0x83, 0xed, 0x7e, 0xe0, 0x39, 0x3c, 0x8f, 0x2d, 0x75, 0x31, 0x35, 0x52, 0x41, 0xbc, - 0x4d, 0xf6, 0xb9, 0xe1, 0xa5, 0x0d, 0x48, 0x7a, 0x5e, 0x53, 0xdf, 0xff, 0xf3, 0xcf, 0x8e, 0x0c, - 0xdc, 0x65, 0x0d, 0xcb, 0xff, 0x0d, 0x79, 0xe4, 0x52, 0x66, 0x3c, 0x24, 0xd7, 0x05, 0x67, 0x9a, - 0x13, 0x44, 0x04, 0x9d, 0x6f, 0xb1, 0x9b, 0x9c, 0x5f, 0xc3, 0xb6, 0xe0, 0x9e, 0x44, 0x7d, 0x5f, - 0x62, 0xe0, 0xa4, 0xf9, 0xfe, 0x18, 0xe8, 0xc9, 0x9d, 0xd9, 0xdc, 0x9a, 0xc6, 0x4c, 0x6e, 0xa1, - 0x30, 0x90, 0x31, 0x38, 0x0a, 0xcc, 0x3c, 0x6f, 0x10, 0xf0, 0x10, 0x59, 0xd3, 0x1f, 0x31, 0x29, - 0x00, 0xf4, 0xd4, 0x3f, 0x7c, 0x39, 0x18, 0x2d, 0xa5, 0xc8, 0x48, 0x1f, 0x75, 0x5a, 0x17, 0xc2, - 0xb8, 0x53, 0x94, 0x4f, 0xc1, 0xab, 0x85, 0xc9, 0x93, 0x83, 0xef, 0xbe, 0xf3, 0x36, 0x93, 0x68, - 0xeb, 0x6d, 0xd0, 0x79, 0xdb, 0x7a, 0x61, 0xc2, 0x5c, 0x6a, 0x63, 0x55, 0xed, 0x7b, 0xa0, 0xc1, - 0x50, 0x3c, 0xa4, 0x23, 0xba, 0xdf, 0xfe, 0x1d, 0x51, 0x8a, 0x3e, 0x88, 0xe8, 0xbe, 0xfc, 0xa5, - 0xff, 0xab, 0xff, 0xa5, 0xab, 0xe3, 0x47, 0xb3, 0x26, 0xd2, 0xe1, 0xef, 0xfa, 0xb0, 0x8e, 0xff, - 0x09, 0x57, 0x51, 0xf8, 0x56, 0x32, 0x54, 0x67, 0x16, 0x6a, 0x98, 0xcb, 0x48, 0xfc, 0x98, 0x05, - 0x33, 0x03, 0xc1, 0xdc, 0xe6, 0xac, 0xa3, 0xc0, 0x74, 0x52, 0xdc, 0x34, 0xaa, 0xb2, 0x96, 0x1f, - 0xae, 0xad, 0x87, 0x0d, 0x30, 0xc2, 0x19, 0xec, 0x4c, 0x32, 0x5f, 0x7a, 0x80, 0xc5, 0x76, 0x10, - 0x4f, 0x5c, 0x8b, 0x26, 0xff, 0x12, 0xa5, 0xb5, 0x98, 0x34, 0xaa, 0x40, 0xc7, 0xb8, 0xae, 0x4d, - 0x35, 0x3a, 0x78, 0x0c, 0x42, 0x47, 0x30, 0x89, 0xda, 0x0d, 0xc4, 0x36, 0x00, 0x0a, 0xd1, 0xfa, - 0x12, 0x53, 0x54, 0x0a, 0x06, 0x0a, 0x10, 0xb4, 0xec, 0xb9, 0x41, 0x63, 0xff, 0xfd, 0xa6, 0x69, - 0xb7, 0xa1, 0x4c, 0xe7, 0x94, 0x60, 0x3f, 0xc8, 0x25, 0x6e, 0x6a, 0x44, 0x09, 0xa4, 0x99, 0x58, - 0x92, 0xb4, 0x60, 0x5a, 0xc7, 0xd4, 0x48, 0xd8, 0xb6, 0xba, 0x7f, 0x96, 0xf3, 0xa2, 0x3e, 0xb2, - 0xcb, 0x0b, 0x1a, 0xcf, 0xc0, 0x2b, 0xdb, 0xa2, 0xc0, 0x45, 0xf7, 0x42, 0xa1, 0x35, 0x45, 0x26, - 0x6f, 0x62, 0x7a, 0x66, 0xd5, 0x1e, 0x4e, 0xa2, 0xf6, 0x02, 0xa6, 0x41, 0x44, 0xf2, 0x34, 0x4f, - 0x6f, 0xc3, 0x74, 0x64, 0x99, 0x8e, 0x58, 0x7a, 0xb3, 0xe5, 0xbb, 0xc7, 0xa1, 0x9b, 0x59, 0x29, - 0x60, 0xe3, 0x94, 0x2d, 0xf9, 0x96, 0x24, 0x57, 0x6b, 0xf1, 0xf9, 0x41, 0xd2, 0x3b, 0x2f, 0x4b, - 0x86, 0xd6, 0x53, 0x02, 0xd3, 0x83, 0x61, 0x3b, 0xfb, 0xc3, 0x4e, 0x28, 0x31, 0x27, 0xc2, 0x90, - 0x9c, 0x69, 0x62, 0x17, 0x1e, 0xdd, 0xd4, 0x36, 0x90, 0x18, 0x56, 0x60, 0xb8, 0x56, 0xf2, 0xf6, - 0x8e, 0x7c, 0xa8, 0xc4, 0x92, 0x63, 0x32, 0x90, 0x89, 0xa8, 0xea, 0xa6, 0x9b, 0xd1, 0xf4, 0xfa, - 0x03, 0xac, 0x6b, 0x55, 0x03, 0xad, 0x67, 0x5c, 0x21, 0x58, 0xa2, 0x02, 0x06, 0xe3, 0xc9, 0x6e, - 0x63, 0xfa, 0xfd, 0xab, 0xd7, 0xaf, 0x5f, 0x53, 0xa2, 0xf8, 0xff, 0x1a, 0xa1, 0x78, 0x96, 0x90, - 0x39, 0x1a, 0x86, 0x9c, 0x0c, 0xc2, 0x57, 0x03, 0x3b, 0xec, 0xac, 0x2e, 0xaf, 0x1f, 0xaf, 0x11, - 0xd3, 0xc7, 0x80, 0x43, 0xdc, 0x44, 0xf2, 0x3e, 0x17, 0x9a, 0xac, 0x44, 0x51, 0x90, 0xee, 0x8a, - 0x98, 0x9c, 0x13, 0xdb, 0x4b, 0xb6, 0xd3, 0x89, 0x6c, 0x8c, 0x35, 0xa1, 0x13, 0xb0, 0x81, 0x0a, - 0x4b, 0x37, 0xe3, 0x85, 0x5c, 0x4d, 0x22, 0x61, 0x67, 0x65, 0xb2, 0x16, 0x77, 0xe5, 0x4c, 0xb3, - 0xb0, 0x32, 0x17, 0xb7, 0x28, 0x2c, 0xae, 0x09, 0xe4, 0x1b, 0x76, 0xc3, 0xab, 0xd6, 0x20, 0x2b, - 0xb9, 0x15, 0xe3, 0xf0, 0x64, 0xcd, 0xdf, 0xeb, 0x76, 0x14, 0x4d, 0x6a, 0xb0, 0x77, 0xbc, 0x04, - 0x38, 0x68, 0x9d, 0xf3, 0x47, 0xeb, 0x50, 0x3c, 0xe1, 0xff, 0xa0, 0xf3, 0x7f, 0x30, 0x5c, 0xd7, - 0xd1, 0xf1, 0x15, 0x22, 0x85, 0xb3, 0xb6, 0x2f, 0x63, 0x7a, 0xe0, 0x4a, 0x01, 0xf2, 0x17, 0xb8, - 0x6c, 0xe1, 0x94, 0x3a, 0xa5, 0x53, 0xc3, 0x50, 0xc2, 0xdd, 0x2e, 0xf5, 0x37, 0x3a, 0x7a, 0x4e, - 0xc9, 0x70, 0x70, 0xb0, 0xd1, 0x32, 0x75, 0x8a, 0xb7, 0x4a, 0x5a, 0x91, 0x76, 0x74, 0x01, 0x57, - 0x67, 0xdc, 0xac, 0xb0, 0xea, 0x10, 0xbd, 0xab, 0x42, 0x6f, 0x74, 0xf4, 0xfe, 0xc2, 0x91, 0x5d, - 0x1d, 0xa7, 0x0f, 0x74, 0x3c, 0xe1, 0x08, 0xf9, 0x85, 0x4c, 0xb0, 0xb8, 0xe7, 0x8a, 0xcf, 0x63, - 0xba, 0x9d, 0x4b, 0xa3, 0x16, 0xe8, 0xf7, 0x50, 0x6d, 0xba, 0x5d, 0x77, 0x06, 0xfd, 0xc0, 0xd6, - 0xa2, 0x36, 0x9b, 0xf0, 0xba, 0xb4, 0xb7, 0x16, 0x32, 0x63, 0xef, 0x3f, 0x55, 0x9a, 0x23, 0x39, - 0xd9, 0x83, 0x9b, 0x83, 0x3e, 0xe1, 0x26, 0xc5, 0x30, 0x78, 0xc7, 0x17, 0x4c, 0x65, 0x05, 0x96, - 0x2b, 0x9b, 0x61, 0x5b, 0x28, 0x9d, 0x67, 0x48, 0x69, 0x83, 0x65, 0xe7, 0x53, 0x75, 0x89, 0x4c, - 0x6b, 0x74, 0x71, 0x29, 0x95, 0xf8, 0xc3, 0x06, 0x62, 0x4d, 0xd0, 0xba, 0xaa, 0x09, 0x10, 0x5b, - 0x70, 0x15, 0xee, 0xf9, 0x63, 0xf4, 0xad, 0xa8, 0xe6, 0x72, 0x12, 0xb1, 0x84, 0xfc, 0xea, 0x6a, - 0xc8, 0x76, 0xb6, 0x85, 0x85, 0x9d, 0xfd, 0x85, 0x38, 0x34, 0x89, 0x29, 0x80, 0x54, 0xaa, 0x11, - 0x10, 0x1d, 0xbe, 0x8f, 0xbb, 0x65, 0x66, 0xe4, 0x76, 0x99, 0xa4, 0xf7, 0xf1, 0xcd, 0xbb, 0xab, - 0xf3, 0xab, 0xd3, 0x11, 0x59, 0xef, 0xb9, 0xe0, 0xb7, 0x55, 0x87, 0xf2, 0x44, 0x2d, 0x19, 0x1c, - 0x6e, 0x12, 0xb0, 0x5b, 0x5d, 0xa1, 0xab, 0xbb, 0x6d, 0xfd, 0xa7, 0x0c, 0x1f, 0x30, 0x44, 0xa2, - 0xf5, 0x0a, 0x56, 0x87, 0x5f, 0x05, 0x12, 0x7b, 0xeb, 0x49, 0x17, 0xb6, 0xe1, 0xb7, 0x30, 0x5b, - 0xb2, 0x9a, 0xee, 0xb9, 0x6f, 0x19, 0x24, 0x68, 0x07, 0x3b, 0x94, 0x3b, 0xdb, 0x74, 0x45, 0x1b, - 0x5c, 0x74, 0xc3, 0x88, 0xf4, 0x9e, 0x2f, 0xbc, 0xfe, 0xa6, 0xb8, 0xf1, 0x91, 0xb6, 0x86, 0xc9, - 0x0b, 0xfb, 0x79, 0xf7, 0x6a, 0xb3, 0xd5, 0xaf, 0x31, 0x1d, 0xdf, 0x4c, 0x38, 0xb5, 0x41, 0x6c, - 0xc1, 0x75, 0xf7, 0x33, 0x61, 0x03, 0x4a, 0x2a, 0xf9, 0x1b, 0xac, 0x7c, 0x0c, 0x7b, 0xbd, 0xaf, - 0xc1, 0xbd, 0xc8, 0x42, 0x39, 0x1e, 0x16, 0xee, 0x2d, 0xf6, 0xdb, 0x6f, 0xd2, 0xff, 0x03, 0x0b, - 0xfc, 0xa9, 0xee, 0xa3, 0x0e, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_ui.htm, do not edit!! -const uint16_t PAGE_settings_ui_length = 3327; -const uint8_t PAGE_settings_ui[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x5a, 0x6b, 0x73, 0xdb, 0xb8, - 0x15, 0xfd, 0xae, 0x5f, 0x81, 0x60, 0x77, 0xbc, 0xe2, 0x98, 0xa1, 0xe5, 0x6c, 0x3b, 0x4d, 0x24, - 0x51, 0x6e, 0xe2, 0x64, 0x37, 0xee, 0x78, 0x37, 0x69, 0xe4, 0x74, 0xdb, 0x49, 0x33, 0x5e, 0x88, - 0x84, 0x24, 0x6c, 0x28, 0x82, 0x25, 0x40, 0x3f, 0xaa, 0xd5, 0x7f, 0xef, 0xb9, 0x00, 0x29, 0x51, - 0xb2, 0x2d, 0xa7, 0x9d, 0x7e, 0xb1, 0x48, 0x3c, 0xee, 0x1b, 0xe7, 0xde, 0x0b, 0x7a, 0xf8, 0xe4, - 0xf5, 0xbb, 0xd3, 0x8b, 0x7f, 0xbc, 0x7f, 0xc3, 0xe6, 0x76, 0x91, 0x8d, 0x86, 0xf5, 0x5f, 0x29, - 0x52, 0x96, 0x89, 0x7c, 0x16, 0x73, 0x99, 0xf3, 0xd1, 0x70, 0x21, 0xad, 0x60, 0xc9, 0x5c, 0x94, - 0x46, 0xda, 0x98, 0x57, 0x76, 0xfa, 0xf4, 0x79, 0x33, 0xda, 0xc9, 0xc5, 0x42, 0xc6, 0xfc, 0x4a, - 0xc9, 0xeb, 0x42, 0x97, 0x96, 0xb3, 0x44, 0xe7, 0x56, 0xe6, 0x58, 0x76, 0xad, 0x52, 0x3b, 0x8f, - 0xff, 0xd8, 0xeb, 0xad, 0x97, 0xee, 0x4c, 0xa5, 0xf2, 0x4a, 0x25, 0xf2, 0xa9, 0x7b, 0x09, 0x55, - 0xae, 0xac, 0x12, 0xd9, 0x53, 0x93, 0x88, 0x4c, 0xc6, 0xc7, 0xe1, 0x42, 0xdc, 0xa8, 0x45, 0xb5, - 0x58, 0xbf, 0x57, 0x46, 0x96, 0xee, 0x45, 0x4c, 0xf0, 0x9e, 0x6b, 0x7e, 0x87, 0xf3, 0x68, 0x68, - 0x95, 0xcd, 0xe4, 0xe8, 0xe3, 0x19, 0x1b, 0x4b, 0x6b, 0x55, 0x3e, 0x33, 0xc3, 0x23, 0x3f, 0x34, - 0x34, 0x49, 0xa9, 0x0a, 0x3b, 0xea, 0x5c, 0x89, 0x92, 0x65, 0x3a, 0x51, 0x45, 0xc3, 0xef, 0x32, - 0x35, 0xeb, 0x47, 0x63, 0x37, 0x8f, 0x55, 0x68, 0xd5, 0x42, 0xea, 0xca, 0x86, 0x69, 0x9c, 0xea, - 0xa4, 0x5a, 0x40, 0xee, 0x10, 0x3b, 0xe3, 0x27, 0xc7, 0xf4, 0x53, 0x94, 0xda, 0xea, 0x98, 0xcf, - 0xad, 0x2d, 0xfa, 0x3c, 0x84, 0x55, 0x6c, 0x9c, 0x57, 0x59, 0x16, 0x66, 0xf1, 0x32, 0xd1, 0x8b, - 0xa2, 0xbf, 0x84, 0x98, 0x32, 0x33, 0x7d, 0x3e, 0x9e, 0xeb, 0x6b, 0x36, 0xa9, 0xac, 0xd5, 0x39, - 0xf3, 0x63, 0x3c, 0x4c, 0x74, 0xa6, 0x4b, 0xd3, 0x5f, 0x9e, 0xbf, 0x7c, 0xf5, 0xe6, 0xbc, 0xcf, - 0x4f, 0xe9, 0x95, 0x19, 0x99, 0xc9, 0xc4, 0x2a, 0x2c, 0x83, 0xad, 0xe6, 0x3a, 0xc5, 0xba, 0x42, - 0x25, 0x5f, 0x64, 0xd9, 0x2c, 0xf8, 0x65, 0x2e, 0x65, 0xc6, 0xc3, 0x72, 0x36, 0xe9, 0xf3, 0x0f, - 0x3f, 0xbe, 0x62, 0x26, 0x53, 0xa9, 0x2c, 0xb1, 0xec, 0x5f, 0x15, 0xd6, 0xf5, 0xf9, 0x5f, 0xe9, - 0x87, 0x25, 0x2d, 0x62, 0x9a, 0x66, 0xe7, 0xf2, 0xa6, 0xcf, 0xdf, 0xbe, 0xf9, 0x7b, 0x3d, 0xa3, - 0xf2, 0xa2, 0xb2, 0x7c, 0x15, 0x16, 0xc9, 0x62, 0xa2, 0x6d, 0x23, 0x9f, 0x86, 0x7c, 0x0b, 0x66, - 0xc5, 0x84, 0x4d, 0x04, 0xad, 0x61, 0xef, 0x4f, 0xd9, 0x42, 0xa7, 0x92, 0x64, 0x48, 0xeb, 0x45, - 0x45, 0x29, 0xa1, 0x27, 0x3b, 0x7b, 0x6d, 0x48, 0xe1, 0x59, 0x26, 0x73, 0x4c, 0x60, 0x00, 0xcf, - 0x64, 0x1c, 0x86, 0x81, 0x99, 0x9d, 0x63, 0xb3, 0xb1, 0x14, 0x3d, 0x7a, 0xca, 0x8c, 0xd5, 0x05, - 0x3b, 0x7f, 0xf3, 0xda, 0xad, 0x2f, 0xae, 0xa1, 0xc9, 0x5b, 0x88, 0xbc, 0xde, 0x50, 0xe8, 0x6b, - 0x59, 0xb2, 0x03, 0xb1, 0x28, 0x06, 0x6c, 0x52, 0xaa, 0xd9, 0xdc, 0xe6, 0xd2, 0x78, 0xe2, 0xf2, - 0x06, 0x66, 0x7d, 0x99, 0x5d, 0x8b, 0x5b, 0xc3, 0xf0, 0x2c, 0xf2, 0x94, 0x4d, 0x55, 0x69, 0xd6, - 0xcc, 0x60, 0x43, 0x03, 0xe3, 0xbe, 0xc9, 0x29, 0x18, 0x58, 0x52, 0x19, 0x12, 0xff, 0x74, 0x3c, - 0x86, 0xba, 0x29, 0xf6, 0xec, 0xce, 0xbc, 0xd5, 0xb0, 0x15, 0xd1, 0xca, 0x94, 0xc1, 0xde, 0xe9, - 0x4d, 0x2a, 0xa7, 0x7d, 0xfe, 0xd1, 0x48, 0x26, 0xa7, 0x53, 0x18, 0x8a, 0xe1, 0x5d, 0x54, 0x19, - 0x44, 0x12, 0x25, 0x62, 0xca, 0x92, 0x59, 0x57, 0xa1, 0x9d, 0xcb, 0x85, 0xec, 0x2f, 0x45, 0x56, - 0xcc, 0x45, 0x7f, 0x39, 0x99, 0xf5, 0xf9, 0x2b, 0x91, 0x7c, 0x99, 0x95, 0xba, 0x82, 0x38, 0xba, - 0x10, 0x89, 0xb2, 0xb7, 0x3c, 0x84, 0xd1, 0x30, 0xe1, 0x1d, 0xdc, 0x0c, 0xae, 0x42, 0xac, 0x5e, - 0x56, 0x65, 0x86, 0x99, 0x1f, 0x99, 0x5a, 0x88, 0x99, 0x64, 0x1f, 0x3f, 0x9c, 0xc3, 0x79, 0xd0, - 0x44, 0x2f, 0xe0, 0x3f, 0xf7, 0xcb, 0x9a, 0x49, 0x6c, 0x70, 0xde, 0xa9, 0xb9, 0xfc, 0xc8, 0xd6, - 0xfe, 0xe2, 0xab, 0xd5, 0x6a, 0x30, 0xad, 0x72, 0x1f, 0x19, 0xb3, 0xb3, 0xb4, 0x2b, 0x83, 0x65, - 0x29, 0x6d, 0x55, 0xe6, 0x2c, 0x8d, 0x66, 0xd2, 0xbe, 0xc9, 0x24, 0x19, 0xe4, 0xd5, 0xad, 0x9b, - 0x5a, 0xad, 0x97, 0x5a, 0x3d, 0x83, 0x8b, 0x68, 0xb5, 0xdf, 0x14, 0x25, 0x99, 0x30, 0xe6, 0x1c, - 0xfa, 0x47, 0xf5, 0x14, 0x9f, 0xc3, 0x19, 0x3c, 0x08, 0x69, 0x9e, 0xff, 0xac, 0xf9, 0xe1, 0x9e, - 0x45, 0x1b, 0xba, 0xca, 0xbc, 0x9b, 0xfc, 0x06, 0x93, 0xb5, 0xe4, 0x90, 0x07, 0x07, 0x5c, 0xbb, - 0x41, 0x1e, 0xc7, 0xf6, 0xb6, 0x90, 0x70, 0x3d, 0xc6, 0x9e, 0xbc, 0x2c, 0x4b, 0x71, 0x1b, 0x29, - 0xe3, 0x7e, 0xb7, 0x84, 0x43, 0x1c, 0x75, 0x65, 0x88, 0xd3, 0x16, 0x2c, 0xa7, 0xba, 0xec, 0xd2, - 0xa1, 0xd4, 0xb1, 0x0d, 0xf3, 0x58, 0x46, 0xa6, 0xc8, 0x94, 0xed, 0xf2, 0x4b, 0x08, 0x96, 0xc5, - 0x79, 0xe4, 0x83, 0x2a, 0x34, 0x71, 0x6f, 0x60, 0x86, 0xd9, 0xd3, 0xe3, 0x81, 0x39, 0x3c, 0x0c, - 0x96, 0xb4, 0x41, 0xc4, 0xf9, 0x27, 0xf3, 0x79, 0xa0, 0x3f, 0x89, 0xcf, 0xbf, 0xff, 0xde, 0xa5, - 0x9f, 0x78, 0xb9, 0x0a, 0x42, 0x1d, 0xd3, 0xe3, 0x4a, 0x7f, 0xca, 0x3f, 0x61, 0xf9, 0xe7, 0xcf, - 0xb1, 0x6a, 0xb1, 0x45, 0x18, 0x5f, 0x68, 0x61, 0x1c, 0x73, 0x1c, 0x64, 0x4f, 0x48, 0xc5, 0xce, - 0x02, 0x96, 0x26, 0x78, 0x30, 0x50, 0x91, 0xca, 0x73, 0x59, 0xbe, 0xbd, 0xf8, 0xe9, 0x3c, 0x96, - 0xa1, 0x6a, 0x99, 0x44, 0xa4, 0x69, 0xd7, 0x9e, 0x70, 0x59, 0x96, 0xf0, 0x4b, 0x9f, 0x13, 0x35, - 0x48, 0x99, 0x64, 0x52, 0x94, 0x17, 0x1e, 0x2b, 0xba, 0x35, 0x66, 0x04, 0xd8, 0x67, 0xec, 0x6d, - 0x26, 0x23, 0x91, 0xc3, 0xc1, 0xc4, 0x3c, 0xe6, 0xb9, 0xce, 0x71, 0x9e, 0xea, 0x15, 0x31, 0x4c, - 0xd0, 0x6c, 0xea, 0x36, 0x02, 0x76, 0x83, 0x65, 0x9b, 0x5f, 0x29, 0x17, 0xfa, 0x0a, 0x2e, 0xf0, - 0x8c, 0xa0, 0xdb, 0xb3, 0x17, 0xbd, 0x5e, 0xcb, 0x8a, 0x90, 0xe7, 0x83, 0x4c, 0x9c, 0x2e, 0x9c, - 0x43, 0x71, 0x02, 0x20, 0xaf, 0x12, 0xb8, 0xf1, 0x01, 0x59, 0x56, 0xd1, 0x59, 0x96, 0x7e, 0x30, - 0x8b, 0xed, 0x21, 0xc9, 0x7f, 0x09, 0xd9, 0x79, 0x70, 0xa8, 0x06, 0x6a, 0xda, 0xdd, 0x78, 0xf3, - 0x93, 0xfa, 0x1c, 0x04, 0xfa, 0xe0, 0x40, 0xe3, 0xc1, 0xff, 0x8d, 0x1c, 0x3c, 0x1d, 0x1c, 0x74, - 0xf3, 0xc3, 0xf8, 0xd7, 0xe1, 0xfc, 0xfb, 0xd1, 0xb7, 0xcb, 0xcd, 0xf0, 0x6a, 0x78, 0x84, 0x91, - 0x5f, 0x83, 0x10, 0x93, 0x8d, 0x1c, 0x98, 0x0c, 0xb3, 0x50, 0x9f, 0xd0, 0xaa, 0xbe, 0x13, 0x66, - 0x00, 0xb8, 0x93, 0x8e, 0xb9, 0x89, 0x33, 0xe2, 0x57, 0x33, 0x38, 0x31, 0xb1, 0x5b, 0x84, 0x2d, - 0x87, 0xdc, 0xd1, 0xe3, 0x60, 0xda, 0x35, 0x71, 0x7b, 0x80, 0x8c, 0xa8, 0xf2, 0x54, 0xde, 0xbc, - 0x9b, 0x76, 0xeb, 0xb1, 0x60, 0xd4, 0x0b, 0x28, 0x87, 0xa8, 0xbc, 0x92, 0x03, 0x1f, 0x04, 0x4d, - 0xbc, 0x81, 0xdc, 0x80, 0xfc, 0x98, 0x05, 0x27, 0x5d, 0x3e, 0xd1, 0x1a, 0x5e, 0xc9, 0x11, 0x8e, - 0xb1, 0x38, 0xf1, 0xa3, 0x51, 0x32, 0x97, 0x40, 0xd3, 0x94, 0x58, 0x7c, 0xee, 0xd7, 0x63, 0x57, - 0x22, 0xab, 0xa4, 0x1b, 0x09, 0xeb, 0x11, 0x80, 0xdc, 0x95, 0xd2, 0x95, 0xa9, 0x8f, 0xd5, 0x58, - 0x4d, 0x32, 0xe4, 0x91, 0x08, 0x3e, 0xc4, 0x7e, 0xd3, 0xe5, 0x51, 0xc6, 0x03, 0x48, 0xba, 0x7f, - 0xf5, 0x26, 0x80, 0x4c, 0x10, 0xf4, 0xb7, 0xa5, 0x21, 0x63, 0x7e, 0xbb, 0x34, 0xab, 0x3e, 0x1b, - 0x3a, 0x28, 0x66, 0xce, 0xdf, 0x31, 0x17, 0x33, 0xc5, 0x92, 0x09, 0x67, 0xa4, 0x4f, 0xcc, 0x9d, - 0xb0, 0x13, 0x7d, 0xc3, 0x99, 0x4a, 0xe3, 0x6f, 0x97, 0xd9, 0x8a, 0x7d, 0xbb, 0x24, 0x31, 0x4f, - 0x78, 0xad, 0x06, 0xf9, 0x70, 0x35, 0x1a, 0x4e, 0xca, 0xd1, 0xaf, 0x7d, 0x9e, 0x57, 0x8b, 0x89, - 0x2c, 0x1f, 0xa5, 0xdf, 0x10, 0xaf, 0x97, 0xaf, 0x49, 0x7b, 0x2b, 0x78, 0x06, 0x6b, 0x9a, 0xc6, - 0x96, 0x50, 0xc5, 0xd1, 0xac, 0x43, 0xc0, 0x51, 0xa5, 0xd9, 0x7b, 0x08, 0xef, 0x21, 0x15, 0xac, - 0x56, 0x35, 0x4e, 0xe4, 0x9b, 0xd0, 0x9d, 0xc9, 0xfc, 0x07, 0x5d, 0x2e, 0xba, 0x75, 0x68, 0xda, - 0x81, 0x5d, 0x47, 0x51, 0x88, 0x58, 0xce, 0x6a, 0x54, 0xc2, 0x32, 0x1e, 0xb4, 0xcc, 0x69, 0x37, - 0x14, 0x7e, 0x94, 0xf6, 0x7c, 0x8c, 0x03, 0xd3, 0x75, 0xb9, 0x17, 0x19, 0x59, 0x64, 0x63, 0x24, - 0x3c, 0x80, 0x29, 0xa1, 0xe2, 0x99, 0x95, 0x8b, 0x2e, 0xbf, 0xce, 0x64, 0xfa, 0x51, 0x9d, 0x4e, - 0x67, 0x3c, 0x08, 0x80, 0x11, 0x8e, 0x24, 0x02, 0xb2, 0x2c, 0x41, 0xd4, 0x1f, 0xcf, 0x54, 0x01, - 0x6f, 0xc4, 0x6d, 0xcc, 0x55, 0x0e, 0xcf, 0x01, 0xe8, 0x06, 0xb6, 0xbc, 0x5d, 0x3a, 0x92, 0x7f, - 0x19, 0xbf, 0xfb, 0x39, 0x2a, 0xa8, 0xe2, 0x71, 0x2c, 0x82, 0x55, 0x42, 0x31, 0x40, 0x12, 0xbb, - 0xe9, 0xe5, 0x2a, 0xfc, 0x0a, 0x7a, 0xdb, 0x6b, 0x36, 0x8a, 0xf0, 0x83, 0x6f, 0x5e, 0x3c, 0x7f, - 0xfe, 0x7c, 0xb0, 0x2e, 0x54, 0x18, 0xb1, 0xa3, 0xf4, 0x63, 0xf0, 0xc6, 0xa6, 0x42, 0x41, 0xf4, - 0x88, 0x75, 0x01, 0xca, 0x87, 0x3c, 0xe0, 0xab, 0xc6, 0x5e, 0x4e, 0x12, 0x4f, 0x34, 0x5d, 0xf0, - 0x4d, 0x50, 0xf3, 0x8c, 0xd2, 0x27, 0x79, 0xcb, 0x63, 0x19, 0x65, 0xae, 0xcb, 0x89, 0x30, 0xd0, - 0xc8, 0x07, 0xf9, 0xc6, 0x70, 0xe3, 0xda, 0x70, 0x0d, 0xf0, 0xca, 0x38, 0x8d, 0xfe, 0x55, 0xc9, - 0xf2, 0x76, 0x5c, 0xd7, 0x0c, 0x2f, 0xb3, 0x0c, 0x71, 0x4e, 0x6e, 0x0d, 0x80, 0x2c, 0xbd, 0x81, - 0x1d, 0xca, 0x1a, 0x86, 0x07, 0xb6, 0x01, 0x5f, 0x85, 0x43, 0x63, 0x3f, 0x03, 0x73, 0xda, 0x78, - 0x45, 0x27, 0x53, 0x20, 0xfd, 0x77, 0x39, 0x02, 0x39, 0x38, 0x51, 0x8d, 0x74, 0x7d, 0xe5, 0x65, - 0x18, 0x10, 0xec, 0xe3, 0x4c, 0xa7, 0xae, 0x5e, 0x0a, 0x35, 0xb0, 0x53, 0xe7, 0x06, 0x67, 0x23, - 0xca, 0xf4, 0xac, 0x8b, 0xf8, 0xa2, 0xb9, 0x15, 0x25, 0x07, 0x64, 0x2f, 0x04, 0xbc, 0x5e, 0x21, - 0x78, 0xc8, 0x1f, 0x5b, 0xde, 0x35, 0x77, 0xbd, 0x1b, 0x3a, 0x5f, 0xf9, 0x88, 0x55, 0xd3, 0x5b, - 0x6f, 0xa5, 0xa0, 0xb1, 0xbd, 0xa9, 0x92, 0x07, 0xfd, 0x53, 0x3b, 0x55, 0xf9, 0x2c, 0xf9, 0xd0, - 0x62, 0x8f, 0xdc, 0xff, 0x7f, 0x77, 0x1b, 0x71, 0xb5, 0xe3, 0x6d, 0xe5, 0xbc, 0xbd, 0x71, 0x56, - 0xe2, 0x5c, 0xb5, 0xa5, 0xbf, 0xcf, 0x0a, 0x1b, 0x13, 0xbc, 0xa7, 0x4c, 0xb9, 0x77, 0xc1, 0xc2, - 0x3e, 0xba, 0x44, 0x64, 0x37, 0x58, 0xb3, 0xc9, 0x8f, 0xfc, 0x94, 0xb2, 0x1a, 0x84, 0x6a, 0xa7, - 0xfe, 0xb1, 0x40, 0x36, 0x0a, 0x96, 0x75, 0x00, 0x85, 0x69, 0x34, 0x9e, 0x46, 0xaf, 0xc7, 0x35, - 0x88, 0xc6, 0x9b, 0x7a, 0xfa, 0xe0, 0xc0, 0x4d, 0x8d, 0x2f, 0xd6, 0xe1, 0x19, 0x6f, 0x2a, 0xec, - 0x66, 0xf2, 0xe3, 0x3d, 0x93, 0xd5, 0xef, 0xbf, 0xbb, 0x49, 0x53, 0x4d, 0x16, 0x28, 0x02, 0x5a, - 0xac, 0x33, 0x2d, 0xd2, 0xbf, 0x8c, 0x7d, 0xda, 0xee, 0xc1, 0x20, 0x08, 0x11, 0x85, 0xb8, 0x4d, - 0x4a, 0x29, 0xac, 0xac, 0xd1, 0x17, 0x89, 0xd2, 0x15, 0xf9, 0x2e, 0x87, 0x23, 0x04, 0x5e, 0x5a, - 0x04, 0x04, 0x2a, 0x6f, 0xca, 0xa0, 0x65, 0xc2, 0x43, 0xe9, 0xb2, 0xf2, 0xd6, 0x38, 0xe1, 0x21, - 0x0f, 0xb9, 0x95, 0x37, 0xf6, 0xe8, 0x37, 0x71, 0x25, 0x1a, 0x02, 0x77, 0x16, 0x0a, 0x73, 0x9b, - 0x83, 0x84, 0x25, 0xad, 0x27, 0x3a, 0xbd, 0x8d, 0x44, 0x51, 0xc8, 0x3c, 0x3d, 0x9d, 0xab, 0x2c, - 0x45, 0xf4, 0x60, 0x3d, 0xe0, 0xeb, 0xcd, 0x15, 0xa4, 0xa0, 0x93, 0x20, 0xe1, 0x77, 0x84, 0x01, - 0x64, 0xe6, 0x61, 0x37, 0x88, 0x47, 0x4b, 0x80, 0xd5, 0xdf, 0x60, 0xb1, 0x8d, 0x89, 0xe2, 0x2d, - 0xe3, 0xb5, 0x1a, 0x90, 0x78, 0xc7, 0x74, 0xad, 0x86, 0x24, 0xde, 0x31, 0x5c, 0x58, 0x43, 0xe0, - 0xea, 0x7e, 0xf6, 0xbe, 0x4c, 0x09, 0x25, 0xd8, 0xb7, 0x8f, 0x19, 0x7f, 0x43, 0xe3, 0xac, 0xb6, - 0xa9, 0x0b, 0x3f, 0x44, 0x9f, 0xb3, 0x0e, 0xfa, 0xac, 0x12, 0x56, 0x3c, 0xaf, 0xc7, 0x91, 0x55, - 0xb1, 0x71, 0xaa, 0x66, 0x55, 0x29, 0x7c, 0xf9, 0xe4, 0xac, 0xd3, 0x84, 0xeb, 0x3f, 0xf3, 0xb3, - 0x9c, 0x5a, 0x1d, 0xf8, 0x42, 0x02, 0xb8, 0x50, 0xe1, 0xa6, 0xc2, 0x8a, 0x27, 0x54, 0xa8, 0xb4, - 0x42, 0xa6, 0xeb, 0x9d, 0x25, 0xe3, 0x6b, 0xa4, 0x72, 0x7d, 0x1d, 0x51, 0x18, 0xd2, 0x0c, 0x15, - 0x03, 0x9c, 0x38, 0xf7, 0x01, 0x5a, 0x32, 0x72, 0xed, 0x14, 0x0a, 0xde, 0xc0, 0x75, 0x58, 0xbd, - 0xb0, 0xeb, 0x7a, 0xb4, 0x07, 0x60, 0x1d, 0xa3, 0x67, 0x85, 0x87, 0x74, 0xbf, 0x0c, 0xbb, 0x17, - 0x05, 0x24, 0xff, 0x01, 0xf4, 0xd8, 0x4f, 0x68, 0x5b, 0x22, 0xf6, 0x1e, 0xf1, 0x4b, 0xe5, 0x3d, - 0xfa, 0x4d, 0x74, 0x4e, 0xe8, 0x41, 0xd8, 0xd9, 0xfb, 0x27, 0xbb, 0xc7, 0xc0, 0x6c, 0x53, 0x0c, - 0x1d, 0xb5, 0xa0, 0xae, 0x5a, 0x48, 0x6c, 0x4b, 0xa2, 0x09, 0x3b, 0xa7, 0x46, 0x33, 0x54, 0xb1, - 0x8d, 0xd0, 0x73, 0x25, 0xb2, 0x7b, 0x1c, 0xda, 0x08, 0xde, 0x37, 0xbf, 0x28, 0x3b, 0xef, 0xf2, - 0x23, 0x60, 0xdd, 0xd3, 0xe3, 0xfe, 0x95, 0x56, 0x29, 0xeb, 0x05, 0x4d, 0x01, 0x7b, 0xe4, 0xc2, - 0xd0, 0xe3, 0xe6, 0xe8, 0x19, 0x52, 0xe8, 0xba, 0x69, 0xdc, 0x68, 0x1b, 0xd6, 0xda, 0x7a, 0x2d, - 0x64, 0x34, 0xd7, 0xc6, 0x12, 0xab, 0xc3, 0x2e, 0xd6, 0xa0, 0xa3, 0x3d, 0x41, 0x96, 0x3f, 0xf4, - 0x8f, 0xae, 0x64, 0x03, 0xd1, 0x43, 0xf5, 0xa9, 0xf7, 0x39, 0x58, 0xd5, 0xe7, 0x01, 0x26, 0x41, - 0x5b, 0x01, 0x66, 0xa6, 0xc6, 0x95, 0x23, 0x13, 0xfd, 0x66, 0x4e, 0x8a, 0xf8, 0x7b, 0xa8, 0x8a, - 0xfa, 0x96, 0x28, 0x83, 0xb5, 0x0b, 0x1c, 0xe1, 0x3c, 0x12, 0xdf, 0xdd, 0x52, 0x01, 0xe8, 0x83, - 0x76, 0x6a, 0x76, 0x0b, 0xd6, 0xe5, 0x3d, 0x09, 0x7e, 0xd2, 0x08, 0x0f, 0x11, 0x20, 0x83, 0x93, - 0xd7, 0x49, 0xd4, 0xca, 0x2b, 0x6f, 0xe1, 0xea, 0xda, 0xc9, 0x1a, 0x67, 0xa3, 0xeb, 0x7a, 0x63, - 0xd3, 0x3f, 0x3a, 0xfa, 0x92, 0xeb, 0x88, 0x40, 0x06, 0x0e, 0x3c, 0x9a, 0xe2, 0xbc, 0x56, 0xe8, - 0x23, 0x37, 0xdc, 0xbf, 0x71, 0x7d, 0xbd, 0x22, 0x3f, 0x4d, 0x45, 0x22, 0x9f, 0x36, 0x13, 0x6d, - 0xe0, 0x79, 0xb5, 0x43, 0xfa, 0x8e, 0x0e, 0xd0, 0x96, 0x5f, 0xa2, 0xe7, 0x9d, 0xb6, 0x77, 0x7d, - 0x3c, 0xeb, 0xd6, 0xb0, 0xae, 0x52, 0x64, 0xa6, 0x39, 0x90, 0xe2, 0x56, 0x57, 0x77, 0xb0, 0xfb, - 0x4e, 0x32, 0x3d, 0x69, 0xd0, 0xbc, 0xef, 0x81, 0x7f, 0xe0, 0xb3, 0xe4, 0x9d, 0xc4, 0x3a, 0x40, - 0x8f, 0x03, 0x47, 0x79, 0xf8, 0xbb, 0x87, 0x8a, 0x4f, 0xc9, 0x7d, 0x9e, 0x8a, 0xf2, 0x0b, 0xdf, - 0x6e, 0x7e, 0x7c, 0xfb, 0xf7, 0x6a, 0xd6, 0x08, 0x58, 0x93, 0x9d, 0x5d, 0xfa, 0xfe, 0xb0, 0x45, - 0x65, 0x7b, 0x1a, 0x1d, 0x65, 0x93, 0xd0, 0xe3, 0xb5, 0x7d, 0x0b, 0x95, 0x98, 0x6a, 0x11, 0x15, - 0x73, 0xf8, 0xc7, 0x1c, 0x1d, 0xbf, 0x78, 0xd6, 0x3b, 0x3a, 0xee, 0x3d, 0xef, 0xf1, 0xfe, 0x9e, - 0xbd, 0xbc, 0x95, 0x62, 0x88, 0x53, 0x4b, 0xa0, 0x47, 0xe9, 0xee, 0x14, 0x19, 0x5b, 0x94, 0x4f, - 0xf6, 0xab, 0x83, 0x60, 0xef, 0x3f, 0xb6, 0xe2, 0x78, 0x23, 0x5a, 0x55, 0x50, 0x9c, 0xd3, 0xa9, - 0x26, 0xe4, 0x6f, 0x2a, 0x8f, 0x5c, 0x5e, 0xb3, 0xbf, 0xff, 0x74, 0xfe, 0x16, 0x62, 0x7e, 0x90, - 0xa8, 0x5c, 0x8c, 0x1d, 0xec, 0x81, 0xdf, 0x56, 0x6f, 0xb5, 0x49, 0x6f, 0x76, 0xae, 0x0c, 0x92, - 0xa0, 0x29, 0x00, 0x8c, 0xf2, 0x02, 0xe8, 0x1f, 0xba, 0x11, 0x63, 0x11, 0x9d, 0x66, 0x14, 0xff, - 0x81, 0xda, 0xac, 0x60, 0x2f, 0xac, 0x6e, 0xe8, 0xca, 0x36, 0x61, 0x49, 0x34, 0x92, 0x2f, 0xe1, - 0x93, 0x86, 0x80, 0x3f, 0x0a, 0xef, 0xdf, 0x8d, 0x2f, 0x90, 0x67, 0x8e, 0xbc, 0x42, 0x08, 0x1d, - 0xdf, 0xf1, 0x92, 0x26, 0x54, 0xd6, 0xbd, 0x06, 0x70, 0x0e, 0xea, 0x22, 0x59, 0xd7, 0xa9, 0x05, - 0xd1, 0x84, 0x51, 0xe0, 0x72, 0x44, 0x28, 0x69, 0x70, 0xea, 0x43, 0xdf, 0x56, 0xd2, 0x1c, 0x4a, - 0x27, 0xb9, 0x76, 0x25, 0x0e, 0xfa, 0xaa, 0x33, 0x3c, 0xaa, 0x6f, 0xb8, 0x86, 0x2e, 0xba, 0x47, - 0x7f, 0x56, 0x0b, 0x82, 0x0d, 0x06, 0xdf, 0x20, 0xfd, 0xb9, 0x80, 0x4f, 0x0c, 0xce, 0xc9, 0x00, - 0x0b, 0xdd, 0x02, 0xf4, 0x6f, 0x52, 0xa4, 0x28, 0xd1, 0x91, 0xcd, 0x90, 0x0d, 0x48, 0xae, 0x98, - 0x03, 0xae, 0xf9, 0x68, 0x88, 0xca, 0x70, 0xd1, 0xa1, 0x92, 0x9e, 0xd3, 0xd3, 0xa5, 0xe1, 0xcc, - 0x5f, 0xb4, 0x8d, 0xa7, 0xbc, 0xbe, 0x9b, 0x8a, 0x79, 0x01, 0xa8, 0xc2, 0xd2, 0x54, 0x5d, 0x35, - 0x7d, 0x80, 0xd5, 0x40, 0x88, 0xeb, 0xed, 0xb1, 0xb9, 0xcc, 0x8a, 0x57, 0x7c, 0xd4, 0x19, 0xd6, - 0x17, 0x60, 0xbe, 0xff, 0xf0, 0x2f, 0x1c, 0x5c, 0x13, 0xc0, 0xe9, 0x97, 0x98, 0xbf, 0x25, 0xb6, - 0x27, 0xc3, 0x23, 0x3f, 0x01, 0xd1, 0x40, 0x62, 0x74, 0xff, 0x9e, 0xce, 0x7a, 0xd3, 0x2b, 0xda, - 0x44, 0x17, 0x32, 0x9b, 0x7d, 0xfb, 0xb9, 0xf8, 0xf2, 0x85, 0x8f, 0xe8, 0x77, 0xbd, 0xa7, 0xe3, - 0x1a, 0x1a, 0x53, 0x88, 0xdc, 0x29, 0xec, 0x0b, 0x40, 0xe6, 0x4c, 0x84, 0x2e, 0xcc, 0xdd, 0xc9, - 0xcc, 0x4a, 0x29, 0xf3, 0x41, 0x0d, 0x17, 0x7d, 0x07, 0x09, 0xa3, 0xce, 0xc1, 0x37, 0xc7, 0xbd, - 0x5e, 0xef, 0x0f, 0x03, 0x76, 0x4e, 0x09, 0x05, 0x58, 0xc3, 0x1a, 0x2c, 0xa2, 0xaa, 0x4e, 0xa6, - 0x4f, 0x60, 0x67, 0x10, 0x1d, 0xb1, 0x36, 0x6d, 0x2a, 0x0b, 0x59, 0x67, 0x8b, 0x38, 0x6a, 0xac, - 0xbb, 0xa4, 0x7d, 0xad, 0x78, 0xaa, 0xab, 0x2c, 0x65, 0xb9, 0xb6, 0x4c, 0x24, 0x89, 0x34, 0x86, - 0xb9, 0xdc, 0x45, 0x97, 0x6a, 0x2e, 0x79, 0xb1, 0x9f, 0xc4, 0x17, 0xc9, 0x0c, 0xd0, 0x94, 0x29, - 0x54, 0x43, 0x06, 0xb9, 0x8e, 0xae, 0xbc, 0x52, 0xea, 0xf8, 0x81, 0x73, 0x25, 0x9b, 0xc0, 0x1d, - 0x60, 0x19, 0x75, 0x6a, 0x51, 0x86, 0xf3, 0xb2, 0x31, 0xed, 0xfc, 0xd9, 0xe8, 0x17, 0x39, 0xa1, - 0x6a, 0xb4, 0x2a, 0x10, 0x08, 0xcf, 0x46, 0x63, 0x59, 0x5e, 0x21, 0x51, 0xa6, 0xd2, 0x47, 0x11, - 0xe2, 0x7a, 0xdd, 0x3f, 0x7a, 0x6b, 0x52, 0x89, 0xb4, 0xbe, 0x71, 0x7d, 0x3d, 0x46, 0x20, 0x88, - 0x1b, 0x9f, 0xdc, 0x62, 0xfe, 0xfd, 0x33, 0xee, 0x5a, 0xbd, 0x31, 0x6a, 0xa4, 0xe6, 0xaa, 0xd3, - 0x5f, 0x1f, 0x19, 0xba, 0x59, 0x9c, 0x33, 0x8a, 0x59, 0x46, 0x77, 0x78, 0xa5, 0x4c, 0xa4, 0xba, - 0x92, 0x6b, 0xda, 0x9d, 0xdd, 0x6e, 0xb7, 0x0e, 0xb4, 0x0b, 0x4f, 0xd0, 0x85, 0x12, 0x99, 0xee, - 0x67, 0x3d, 0x56, 0x54, 0x69, 0xf0, 0x75, 0x60, 0xd1, 0xad, 0x14, 0x1a, 0xd1, 0xe6, 0xfd, 0x5a, - 0x94, 0x39, 0x4c, 0x77, 0x81, 0x53, 0x4c, 0x17, 0x85, 0x0b, 0xbc, 0x4b, 0x88, 0x82, 0xea, 0x8c, - 0xa5, 0x1a, 0x62, 0x90, 0x15, 0x15, 0x02, 0xa1, 0xa2, 0xeb, 0x47, 0x22, 0xa5, 0xa6, 0x0a, 0xa6, - 0x22, 0xb7, 0x55, 0x05, 0x1d, 0x94, 0xc8, 0xf1, 0x3b, 0x52, 0x8d, 0x85, 0x88, 0x73, 0x87, 0x58, - 0xd7, 0x8c, 0x47, 0xf5, 0x85, 0xe2, 0xd6, 0xe6, 0x1d, 0x1b, 0xdd, 0x51, 0xe3, 0x63, 0xad, 0x86, - 0x27, 0xa9, 0x48, 0x3e, 0xc9, 0xa6, 0x3a, 0xcb, 0xf4, 0x35, 0x15, 0x58, 0xe0, 0xee, 0xef, 0x27, - 0xd5, 0xbf, 0x45, 0x93, 0x19, 0x7c, 0x08, 0x91, 0xf4, 0x55, 0xae, 0x00, 0x6e, 0xde, 0x80, 0x68, - 0x87, 0x80, 0x98, 0xbe, 0x8e, 0xf1, 0x97, 0xe6, 0xce, 0x9c, 0x04, 0x5a, 0x2d, 0x37, 0x83, 0x55, - 0xe7, 0x1f, 0xba, 0x62, 0xd7, 0x2a, 0xcb, 0x58, 0x2e, 0x21, 0x22, 0xf6, 0xb9, 0x6e, 0x0a, 0x68, - 0xcb, 0xc4, 0x0c, 0xbd, 0x19, 0x53, 0x53, 0x56, 0xb9, 0x16, 0x53, 0xb0, 0x54, 0x4d, 0xa7, 0xb2, - 0xa4, 0x8b, 0xd8, 0x9a, 0x44, 0xd8, 0xd0, 0xd6, 0xeb, 0x92, 0x89, 0xee, 0x98, 0x80, 0x93, 0xc6, - 0x53, 0xff, 0x20, 0xa7, 0x78, 0x99, 0x3b, 0x59, 0x16, 0x44, 0x0d, 0x1a, 0x80, 0x05, 0x00, 0x2b, - 0xbb, 0xa5, 0xaf, 0x03, 0xf9, 0x4c, 0x9a, 0xc8, 0x19, 0xb1, 0xed, 0x3c, 0x6a, 0xe2, 0x47, 0x9d, - 0xa6, 0xaa, 0x6c, 0x74, 0x8c, 0xa2, 0xa8, 0x09, 0xc6, 0xef, 0xe9, 0xc6, 0xfe, 0x25, 0x50, 0x4f, - 0x20, 0x1b, 0x24, 0xd2, 0xdd, 0x2c, 0xf9, 0x63, 0x53, 0x7b, 0x37, 0x83, 0x1d, 0x7d, 0x0c, 0x3f, - 0x1c, 0x39, 0xc4, 0x89, 0xca, 0xd1, 0xcb, 0xfa, 0x92, 0x7d, 0xe7, 0x5e, 0x65, 0xb4, 0x39, 0xe7, - 0xf7, 0x10, 0xed, 0x3c, 0xe0, 0xc7, 0x35, 0x51, 0x7f, 0x5b, 0xfe, 0x55, 0x44, 0x3b, 0xbb, 0xa2, - 0x3e, 0x4c, 0x54, 0xa5, 0x7b, 0x28, 0x76, 0x1e, 0x56, 0xfe, 0x41, 0x8a, 0xfe, 0x5a, 0xfe, 0x5e, - 0xa2, 0x9d, 0xc7, 0x2c, 0xba, 0x8f, 0x68, 0x71, 0x5d, 0xde, 0x21, 0xda, 0xd9, 0x6b, 0xd1, 0xaf, - 0x20, 0x2a, 0x6f, 0x0a, 0xbe, 0xd6, 0xb2, 0x2d, 0xea, 0x19, 0xa3, 0x5a, 0x8d, 0x51, 0xdd, 0xe4, - 0x3e, 0x42, 0xec, 0xa5, 0x86, 0x9a, 0xcb, 0x25, 0x05, 0x17, 0x7d, 0x31, 0xa7, 0xa2, 0xaf, 0x6d, - 0x45, 0x5a, 0xb2, 0x55, 0xfe, 0x35, 0xd8, 0xbe, 0x0d, 0xba, 0x74, 0x38, 0x7f, 0x99, 0xdf, 0xb2, - 0x6b, 0x87, 0xb9, 0x58, 0x77, 0xc2, 0x28, 0x8e, 0x0f, 0xbe, 0xb9, 0x39, 0xfe, 0xe1, 0xc5, 0x9f, - 0x5e, 0x0e, 0xfc, 0x31, 0xf6, 0x30, 0xfa, 0x75, 0x91, 0xd9, 0x5c, 0xb2, 0x2d, 0x54, 0x1e, 0xf3, - 0x5e, 0xd4, 0x73, 0x88, 0x19, 0xf3, 0x63, 0x7a, 0x42, 0x2d, 0x51, 0xb8, 0xc1, 0x63, 0xaf, 0x83, - 0xaf, 0x86, 0xdc, 0x77, 0x86, 0x4b, 0x2b, 0x26, 0x6d, 0x53, 0xff, 0x57, 0x76, 0xde, 0xc7, 0xb3, - 0xb3, 0x8f, 0xe9, 0x64, 0xb6, 0xcd, 0xf3, 0x6b, 0x58, 0x76, 0xda, 0x89, 0x61, 0x43, 0xd0, 0xa5, - 0x35, 0x47, 0xb0, 0x95, 0x21, 0x5e, 0x3c, 0x4e, 0xbe, 0xd3, 0xfe, 0x50, 0x72, 0xbf, 0x7a, 0xbb, - 0xac, 0xea, 0xd2, 0x73, 0xeb, 0x22, 0x12, 0xa1, 0xe0, 0xb6, 0xd4, 0x61, 0xb2, 0xa9, 0x6b, 0xef, - 0xe7, 0xba, 0xf3, 0x1d, 0xe6, 0xab, 0x50, 0x66, 0xb7, 0x76, 0xdd, 0xbd, 0xc1, 0xdd, 0x04, 0xe3, - 0x56, 0xa5, 0xdf, 0x78, 0xd2, 0x53, 0x6e, 0x11, 0xa2, 0x66, 0x62, 0x4b, 0x87, 0x7b, 0x23, 0x94, - 0xfd, 0xef, 0x38, 0x43, 0x85, 0xdf, 0xbd, 0x38, 0xd3, 0x20, 0xb4, 0xf9, 0xa2, 0x08, 0xa2, 0x4f, - 0xd7, 0x9f, 0xd1, 0x76, 0x68, 0xba, 0x1b, 0x82, 0x3a, 0xa9, 0xb9, 0xaa, 0xd4, 0x55, 0x24, 0x05, - 0x8c, 0xec, 0x8a, 0xca, 0xd1, 0xf6, 0xea, 0x75, 0xa9, 0x56, 0x17, 0xa8, 0x1f, 0x7d, 0xd1, 0xbb, - 0x2e, 0xc4, 0xbe, 0x6b, 0x95, 0xf5, 0xae, 0x33, 0x25, 0x92, 0x28, 0x8e, 0x49, 0x0a, 0x5f, 0xa4, - 0x7e, 0xd7, 0x4e, 0x9b, 0xff, 0x33, 0x18, 0xba, 0x2f, 0x81, 0x0f, 0x60, 0x61, 0xa3, 0xf9, 0xbc, - 0xfe, 0x30, 0xc8, 0x47, 0xcd, 0x27, 0xc2, 0x47, 0x54, 0x7f, 0xd6, 0xd2, 0xfd, 0x37, 0x03, 0x35, - 0x47, 0x3b, 0xc9, 0xa3, 0xd1, 0x7e, 0x47, 0xf9, 0xce, 0x5e, 0xed, 0x9f, 0x41, 0xfd, 0x46, 0x14, - 0x4f, 0x76, 0xdb, 0x06, 0x8d, 0xb8, 0xfe, 0x1b, 0x15, 0xb9, 0xde, 0x67, 0xce, 0xf2, 0xb1, 0x9a, - 0xd7, 0xdd, 0x1f, 0xf2, 0x91, 0xbb, 0xcd, 0xdb, 0xae, 0x1f, 0x37, 0x55, 0xf3, 0xbc, 0x7c, 0xb4, - 0x40, 0xff, 0xda, 0x5a, 0xbb, 0xb3, 0xbf, 0xd8, 0x1e, 0x1e, 0x51, 0x43, 0x81, 0x1f, 0x6a, 0x3a, - 0xa8, 0x03, 0xa1, 0xff, 0x35, 0xf8, 0x0f, 0x91, 0x75, 0x4f, 0x79, 0x81, 0x20, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_sync.htm, do not edit!! -const uint16_t PAGE_settings_sync_length = 3474; -const uint8_t PAGE_settings_sync[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x9d, 0x1a, 0x6b, 0x53, 0xdb, 0x48, - 0xf2, 0xbb, 0x7e, 0xc5, 0x44, 0x57, 0x95, 0xb5, 0x17, 0xe3, 0x07, 0x60, 0x42, 0xc0, 0x52, 0x0e, - 0x30, 0x01, 0xdf, 0x41, 0xe2, 0xd8, 0xb0, 0xc9, 0xd6, 0xdd, 0xd5, 0xd6, 0x58, 0x1a, 0xdb, 0x03, - 0x92, 0x46, 0xab, 0x19, 0xf1, 0xa8, 0x6c, 0xfe, 0xfb, 0x75, 0xcf, 0x48, 0xb2, 0x2d, 0xfc, 0xca, - 0x7e, 0x40, 0x96, 0x46, 0xdd, 0x3d, 0xfd, 0x7e, 0x8c, 0xe8, 0xbc, 0xe9, 0x7e, 0x3e, 0xbf, 0xfd, - 0xbd, 0x7f, 0x41, 0xa6, 0x2a, 0x0c, 0xdc, 0x0e, 0x5e, 0x49, 0x40, 0xa3, 0x89, 0x63, 0xb3, 0xc8, - 0x86, 0x67, 0x46, 0x7d, 0xb7, 0x13, 0x32, 0x45, 0x49, 0x44, 0x43, 0xe6, 0xd8, 0x8f, 0x9c, 0x3d, - 0xc5, 0x22, 0x51, 0x36, 0xf1, 0x44, 0xa4, 0x58, 0xa4, 0x1c, 0xfb, 0x89, 0xfb, 0x6a, 0xea, 0xb4, - 0x9b, 0x4d, 0xdb, 0xb5, 0x0c, 0xa8, 0x55, 0x7a, 0xe7, 0xb3, 0x47, 0xee, 0xb1, 0x5d, 0xfd, 0x50, - 0xe3, 0x11, 0x57, 0x9c, 0x06, 0xbb, 0xd2, 0xa3, 0x01, 0x73, 0x5a, 0xb5, 0x90, 0x3e, 0xf3, 0x30, - 0x0d, 0x8b, 0xe7, 0x54, 0xb2, 0x44, 0x3f, 0xd0, 0x11, 0x3c, 0x47, 0xc2, 0x26, 0x56, 0x69, 0xeb, - 0x8c, 0x21, 0x6f, 0x4a, 0x13, 0xc9, 0x60, 0x93, 0x54, 0x8d, 0x77, 0x8f, 0x60, 0x55, 0x71, 0x15, - 0x30, 0x77, 0xf8, 0x12, 0x79, 0x64, 0xc8, 0x94, 0xe2, 0xd1, 0x44, 0x76, 0x1a, 0x66, 0xb1, 0x23, - 0xbd, 0x84, 0xc7, 0xca, 0xb5, 0x1e, 0x69, 0x42, 0x02, 0xe1, 0xf1, 0xb8, 0xe6, 0x3b, 0xbe, 0xf0, - 0xd2, 0x10, 0xd8, 0xac, 0xc1, 0x82, 0xf3, 0xa6, 0x85, 0x3f, 0x71, 0x22, 0x94, 0x70, 0xec, 0xa9, - 0x52, 0xf1, 0xb1, 0x7d, 0x32, 0x4e, 0x23, 0x4f, 0x71, 0x11, 0x91, 0x49, 0xcf, 0xaf, 0xb0, 0xea, - 0xf7, 0x84, 0xa9, 0x34, 0x89, 0x88, 0x5f, 0x9f, 0x30, 0x75, 0x11, 0x30, 0xc4, 0x3d, 0x7b, 0xd1, - 0xaf, 0x7e, 0x14, 0xa0, 0x4a, 0x4c, 0x26, 0x01, 0x43, 0x68, 0x83, 0x54, 0xf7, 0x02, 0x2a, 0xe5, - 0x35, 0x97, 0xaa, 0x9e, 0xbd, 0xb2, 0xa7, 0xdc, 0x67, 0x76, 0xb5, 0x86, 0xef, 0xed, 0x4f, 0xc2, - 0xde, 0x59, 0x03, 0x34, 0xa3, 0x7b, 0x55, 0xa9, 0x7e, 0x7f, 0xe2, 0x91, 0x2f, 0x9e, 0xea, 0x22, - 0x66, 0x51, 0x45, 0xf3, 0x28, 0x8f, 0x1b, 0x8d, 0x87, 0x48, 0xd4, 0x9f, 0x02, 0x86, 0x4c, 0x35, - 0x38, 0xa8, 0x3d, 0x19, 0x53, 0x8f, 0xc9, 0x46, 0xea, 0xc7, 0xbb, 0x91, 0x50, 0x7c, 0xcc, 0x59, - 0xd2, 0x98, 0x27, 0x74, 0x56, 0x22, 0x04, 0xb2, 0xdc, 0x0d, 0xae, 0x2b, 0x76, 0x43, 0x66, 0x3a, - 0x03, 0xd6, 0xec, 0x3f, 0x24, 0x0b, 0xc6, 0xf3, 0x58, 0xd4, 0xbf, 0x07, 0xbc, 0xc3, 0x83, 0xf6, - 0x81, 0xe3, 0xf8, 0xf5, 0xe1, 0xb8, 0xde, 0xed, 0xd5, 0x1f, 0x69, 0x90, 0xb2, 0x0f, 0xad, 0x6c, - 0xe1, 0xe2, 0xce, 0x2c, 0xbc, 0x7d, 0x5b, 0x59, 0x78, 0x76, 0x9a, 0xd5, 0xe3, 0x76, 0xfb, 0xf0, - 0xa8, 0x84, 0x07, 0x60, 0xcd, 0x7c, 0xe9, 0x74, 0x11, 0x33, 0x7f, 0x76, 0x5a, 0xd5, 0x5a, 0x73, - 0x13, 0xf5, 0x56, 0x75, 0x8e, 0xcb, 0x40, 0x50, 0xff, 0x5f, 0xc3, 0x0a, 0xab, 0x29, 0xe7, 0x4d, - 0xb3, 0xfa, 0x3d, 0x60, 0x8a, 0x08, 0xc0, 0xf7, 0x12, 0x46, 0x15, 0xcb, 0x2c, 0x56, 0xb1, 0x8d, - 0x2f, 0xd8, 0xd5, 0x13, 0x51, 0x07, 0x99, 0x4f, 0x95, 0x4a, 0xf8, 0x28, 0x55, 0xa0, 0x73, 0x99, - 0x78, 0x76, 0x8d, 0x55, 0x6b, 0xe5, 0x75, 0xf5, 0x12, 0x33, 0xbb, 0x66, 0x2b, 0xf6, 0xac, 0x1a, - 0xf7, 0xf4, 0x91, 0xe6, 0x04, 0x5e, 0x01, 0x52, 0x09, 0xce, 0x67, 0xd7, 0x54, 0xb5, 0xe6, 0xd7, - 0x47, 0xc2, 0x7f, 0xa9, 0xd3, 0x18, 0x54, 0xec, 0x9f, 0x4f, 0x79, 0xe0, 0x57, 0x04, 0xc2, 0x53, - 0xdf, 0xbf, 0x78, 0x04, 0x2e, 0xd0, 0xd6, 0x2c, 0x62, 0x49, 0xc5, 0x46, 0x9e, 0xed, 0x5a, 0xa5, - 0xea, 0xb8, 0xdf, 0x2f, 0x99, 0xfa, 0xad, 0x52, 0xad, 0x81, 0xf3, 0xfe, 0x46, 0x83, 0x4a, 0xf5, - 0xc7, 0x72, 0x04, 0x96, 0x24, 0x22, 0x01, 0x3e, 0x01, 0x01, 0xe2, 0x4c, 0x8a, 0x80, 0xd5, 0x03, - 0x31, 0xa9, 0xd8, 0x17, 0xb8, 0x4e, 0x32, 0x2d, 0x80, 0x21, 0xc9, 0x98, 0x07, 0x4c, 0xcb, 0x03, - 0x81, 0x95, 0x80, 0xdc, 0xd7, 0xd9, 0xba, 0x18, 0x63, 0xf0, 0x8e, 0xf9, 0x24, 0x4d, 0xa8, 0x56, - 0x9b, 0x91, 0x87, 0x8c, 0x29, 0x47, 0x3f, 0xfa, 0x6f, 0xd4, 0x8b, 0x3c, 0x11, 0xc6, 0xa0, 0x3d, - 0x46, 0x62, 0x3a, 0x61, 0xc4, 0xa7, 0x8a, 0xbe, 0x01, 0x6f, 0x98, 0xd3, 0xf4, 0xc7, 0x73, 0x70, - 0x87, 0xb1, 0x48, 0x2a, 0xf7, 0x4e, 0xf3, 0xe4, 0xbe, 0x73, 0x74, 0x72, 0xbf, 0xb3, 0x53, 0xd5, - 0x1e, 0x7d, 0x69, 0xef, 0x54, 0xee, 0x77, 0xc0, 0x2c, 0x75, 0x6f, 0xca, 0xbc, 0x07, 0xe6, 0x3b, - 0x66, 0x79, 0x68, 0x57, 0x8d, 0xc9, 0x5c, 0xf7, 0xfe, 0x6d, 0xcb, 0x78, 0xff, 0x60, 0x05, 0xec, - 0x60, 0x01, 0x76, 0xb6, 0xeb, 0x25, 0xee, 0x8a, 0x21, 0x0c, 0x5e, 0x05, 0x36, 0x6e, 0xd6, 0x84, - 0xd3, 0x3a, 0x29, 0x73, 0xc1, 0x76, 0x9c, 0xe5, 0x8c, 0xfc, 0x2a, 0x6a, 0x2a, 0x7b, 0x37, 0x58, - 0xf2, 0x4e, 0xfc, 0xea, 0xec, 0x9d, 0x94, 0x78, 0x75, 0x58, 0xad, 0xc4, 0x91, 0xa3, 0x66, 0xec, - 0x0c, 0xfb, 0x05, 0x3b, 0x0b, 0xbe, 0x6d, 0xa8, 0x3c, 0xc7, 0x80, 0x23, 0xd5, 0x0b, 0xd8, 0xc7, - 0xe7, 0x32, 0x0e, 0xe8, 0x8b, 0xc3, 0xdc, 0xe6, 0x07, 0x3b, 0x12, 0x11, 0xb3, 0x8f, 0xed, 0x11, - 0xa4, 0x9b, 0x07, 0x30, 0x8f, 0xdb, 0x2c, 0x7c, 0xba, 0x9f, 0x6f, 0x3a, 0xa7, 0xe8, 0xdc, 0x19, - 0xbe, 0xcb, 0x27, 0xae, 0xbc, 0x69, 0x25, 0xc6, 0xa4, 0xd7, 0x03, 0x37, 0x5e, 0x40, 0xa9, 0x56, - 0xbf, 0x7b, 0x54, 0x32, 0x82, 0x81, 0x76, 0xbc, 0xc0, 0x8b, 0x83, 0x4b, 0x27, 0x23, 0x88, 0x80, - 0x87, 0x13, 0x0d, 0x82, 0x31, 0x5c, 0x02, 0xc1, 0xa5, 0x79, 0x90, 0x83, 0xe6, 0x41, 0x99, 0x0a, - 0x2e, 0xfd, 0x40, 0x79, 0x6b, 0x68, 0xf9, 0x39, 0xf6, 0x2a, 0x26, 0xcc, 0x98, 0x93, 0xe5, 0x14, - 0x90, 0x4a, 0x3b, 0xd5, 0x09, 0x1f, 0x57, 0x6c, 0xf4, 0xc0, 0x63, 0xdb, 0x71, 0x58, 0x5d, 0x27, - 0x56, 0x4f, 0x04, 0x55, 0x9d, 0x6b, 0x9b, 0xb5, 0x8a, 0x4e, 0xc2, 0x0e, 0x42, 0x07, 0x43, 0x25, - 0x12, 0x70, 0x33, 0xcc, 0xaa, 0x3d, 0xc5, 0x42, 0x0c, 0x09, 0xaf, 0x07, 0xca, 0xab, 0xfe, 0xf5, - 0x57, 0x06, 0x06, 0xd8, 0x61, 0x0c, 0x1e, 0xfc, 0x11, 0xe8, 0x91, 0x1b, 0xe1, 0xb3, 0x3a, 0xe9, - 0x07, 0x0c, 0x59, 0x65, 0x98, 0xf1, 0xc8, 0xd7, 0xeb, 0x8b, 0x2e, 0xe9, 0xf5, 0xc1, 0x47, 0x6b, - 0x0b, 0x14, 0xe5, 0x22, 0xc5, 0x9a, 0xa6, 0x56, 0xad, 0x9e, 0xb0, 0x40, 0x32, 0xcd, 0xb6, 0x42, - 0xd6, 0xa8, 0x9a, 0x62, 0x85, 0xa9, 0xcb, 0x00, 0xaa, 0x54, 0xa5, 0x55, 0x9b, 0x5b, 0x82, 0xe0, - 0x95, 0x5f, 0xb9, 0x9a, 0x42, 0x7a, 0xb4, 0xab, 0x1f, 0x76, 0x5b, 0xc7, 0x8f, 0x82, 0xfb, 0xa4, - 0x09, 0x76, 0x8d, 0x03, 0xae, 0xf4, 0xea, 0x89, 0xaa, 0x07, 0x2c, 0x9a, 0xa8, 0xa9, 0xbb, 0x07, - 0x86, 0x2c, 0x6a, 0xc8, 0x4c, 0xe4, 0x5a, 0x26, 0xb2, 0x11, 0x85, 0xd5, 0xa7, 0x42, 0x2a, 0x24, - 0xbe, 0x53, 0x01, 0x18, 0xa8, 0x67, 0x1f, 0xc0, 0x19, 0x76, 0xcc, 0xed, 0xb1, 0x6d, 0x57, 0x77, - 0x80, 0xe8, 0x8e, 0xfa, 0x4f, 0xf3, 0x7f, 0xd5, 0x1f, 0x59, 0x3a, 0x7b, 0x95, 0xa1, 0x1b, 0xb2, - 0x7e, 0x2f, 0x3f, 0xc4, 0xce, 0x01, 0xc8, 0xfb, 0xa6, 0xa5, 0x65, 0xce, 0x7d, 0x88, 0x6a, 0xb3, - 0x38, 0x4b, 0x50, 0x30, 0x33, 0xcd, 0xe7, 0xca, 0x0c, 0xa4, 0x28, 0x6b, 0xc8, 0xfa, 0x87, 0x9c, - 0x7d, 0x60, 0x02, 0xb8, 0xd0, 0x1c, 0x6b, 0x9e, 0xd8, 0x0f, 0xab, 0xd3, 0xc8, 0x6a, 0x68, 0x47, - 0xfb, 0xb4, 0xfb, 0x4f, 0x1e, 0x22, 0xcb, 0x24, 0x4d, 0x02, 0xc8, 0x9c, 0xda, 0xcd, 0x3d, 0x09, - 0xc5, 0xe3, 0x04, 0x00, 0x35, 0x40, 0xa7, 0x61, 0xba, 0x07, 0x4c, 0x84, 0x90, 0x96, 0x50, 0x18, - 0xc7, 0x06, 0x7f, 0x81, 0x4a, 0x0d, 0x21, 0x1b, 0x5a, 0x84, 0xc3, 0x33, 0xde, 0xfd, 0x21, 0xed, - 0xac, 0xbb, 0x18, 0x8e, 0x6d, 0x02, 0xb5, 0x7d, 0x2a, 0xe0, 0x4d, 0x0c, 0x6a, 0xb2, 0x01, 0x4f, - 0xa6, 0xa3, 0x90, 0x43, 0x95, 0xc7, 0xd8, 0x07, 0x54, 0x9f, 0x3f, 0x12, 0x5d, 0x2d, 0x1d, 0x5b, - 0x09, 0xe0, 0xf5, 0x29, 0x5b, 0xb3, 0xb2, 0xc5, 0x29, 0x0b, 0xe2, 0x33, 0x58, 0x83, 0x84, 0xac, - 0xb0, 0x1c, 0x43, 0xea, 0x76, 0x6c, 0xf3, 0x80, 0xd4, 0x3c, 0xb0, 0xf1, 0x83, 0x63, 0x5f, 0x21, - 0xad, 0x0f, 0x9d, 0x86, 0x79, 0x01, 0xac, 0x02, 0x89, 0x02, 0xc7, 0x5a, 0x81, 0x74, 0x86, 0x48, - 0x67, 0xd4, 0x7b, 0x98, 0xe1, 0x2d, 0xec, 0x62, 0x38, 0xb5, 0xdd, 0x21, 0x7d, 0x64, 0x33, 0x90, - 0x69, 0x02, 0x6d, 0x91, 0xa1, 0x3f, 0xdd, 0x33, 0xdd, 0x09, 0x18, 0x25, 0x8d, 0x41, 0x3d, 0x7b, - 0xb0, 0xb4, 0xef, 0x6a, 0xe7, 0x3d, 0x4b, 0x40, 0x3d, 0x10, 0x7c, 0x0a, 0x96, 0xf7, 0xdd, 0xbb, - 0x6e, 0x9f, 0xf4, 0xd1, 0x1f, 0x48, 0x87, 0x47, 0x71, 0xaa, 0x32, 0xf5, 0xdc, 0xf5, 0xed, 0x9c, - 0xb9, 0x28, 0x0d, 0x47, 0x2c, 0x01, 0x6d, 0xf1, 0xc8, 0xb1, 0x5b, 0xf0, 0x4b, 0x9f, 0x1d, 0xfb, - 0xb0, 0xdd, 0xde, 0x6f, 0xdb, 0xb9, 0x7a, 0x7c, 0xb8, 0x4d, 0xd8, 0x9f, 0x29, 0x4f, 0x18, 0x5a, - 0x21, 0x71, 0xf7, 0x22, 0x7f, 0x91, 0x6a, 0xd6, 0x58, 0xdd, 0xed, 0xd9, 0xe4, 0xef, 0x53, 0x45, - 0x11, 0x2c, 0x2d, 0xd6, 0x24, 0x11, 0x69, 0x2c, 0xb5, 0x00, 0x0b, 0x6c, 0x43, 0x3a, 0xd5, 0xb6, - 0xc6, 0xdf, 0xc5, 0x7d, 0xb4, 0xa3, 0x00, 0x4d, 0x93, 0x1e, 0x8f, 0x75, 0x66, 0x74, 0x89, 0xb5, - 0x88, 0x3d, 0xc8, 0xb0, 0x07, 0x5b, 0x61, 0x77, 0x14, 0xf6, 0x8d, 0xc4, 0xca, 0x5e, 0x86, 0x34, - 0x99, 0xf0, 0xe8, 0xb8, 0x49, 0x68, 0xaa, 0x04, 0xbe, 0x05, 0x86, 0x15, 0x30, 0xde, 0xc0, 0x0b, - 0xfc, 0xb5, 0x8a, 0xbb, 0xbd, 0xe2, 0x6e, 0xbf, 0xb8, 0x3b, 0x28, 0xee, 0xda, 0x56, 0x71, 0x7b, - 0x58, 0xdc, 0xbd, 0x2b, 0xee, 0x8e, 0xcc, 0x5d, 0x43, 0x93, 0x37, 0x5b, 0x0c, 0x21, 0x77, 0x1c, - 0x17, 0x00, 0xb9, 0xc6, 0x8d, 0x04, 0xba, 0xe8, 0x8c, 0xc4, 0x73, 0x26, 0x59, 0x2b, 0xf7, 0x7f, - 0xb8, 0x73, 0xcb, 0x28, 0x4b, 0x31, 0xf6, 0x8a, 0xae, 0x18, 0x6e, 0xb7, 0x43, 0xd9, 0x2f, 0x36, - 0xd9, 0x7f, 0x8d, 0xb1, 0x9c, 0xaf, 0x83, 0x02, 0xe5, 0x60, 0xcb, 0x4d, 0xda, 0x33, 0xbe, 0xda, - 0x5b, 0xa2, 0x1c, 0x16, 0x9b, 0x1c, 0x6e, 0xcb, 0xd7, 0xbb, 0x02, 0xe5, 0xdd, 0x96, 0x9b, 0x1c, - 0xcd, 0xf8, 0x3a, 0xca, 0x51, 0xe6, 0x8d, 0x35, 0x60, 0x1e, 0xe3, 0x8f, 0xec, 0x78, 0x1b, 0x62, - 0x83, 0x56, 0x41, 0x6c, 0xb0, 0xa5, 0xbd, 0x06, 0x7b, 0x39, 0xc7, 0x83, 0xbd, 0x2d, 0x85, 0x1c, - 0x14, 0xf6, 0x1a, 0xec, 0x6f, 0xb9, 0xc9, 0xc1, 0x8c, 0xaf, 0x2d, 0xed, 0x35, 0x68, 0x17, 0x9b, - 0xb4, 0xb7, 0xe5, 0xab, 0xb0, 0xd7, 0xe0, 0x70, 0xcb, 0x4d, 0xde, 0xcd, 0xf8, 0xda, 0xd2, 0x5e, - 0x83, 0xa3, 0x62, 0x93, 0x45, 0x73, 0x35, 0x74, 0x74, 0x43, 0x42, 0x85, 0xc4, 0x53, 0xd8, 0x2c, - 0x12, 0x4f, 0x09, 0x8d, 0x57, 0xd1, 0xcb, 0xe8, 0x40, 0x4d, 0x38, 0x4b, 0xf8, 0x64, 0xaa, 0x22, - 0x26, 0x65, 0xad, 0xd3, 0xc8, 0x90, 0xac, 0xed, 0xb0, 0xcf, 0x6d, 0xf7, 0x5c, 0x04, 0x22, 0x99, - 0x21, 0xe6, 0x78, 0x14, 0x92, 0xea, 0x2a, 0x7d, 0x65, 0xc8, 0xdf, 0x6c, 0xf7, 0x62, 0x3c, 0x66, - 0x9e, 0x92, 0x33, 0x6c, 0x4c, 0x9c, 0xeb, 0x76, 0x1c, 0x7e, 0x86, 0x69, 0x1a, 0x9a, 0xbf, 0x09, - 0x8e, 0x2c, 0x44, 0xc4, 0x58, 0xb2, 0x65, 0x8d, 0xac, 0xc7, 0xb9, 0x84, 0xe4, 0x39, 0x12, 0x29, - 0xf4, 0x2c, 0x48, 0xdf, 0xc2, 0x0c, 0x44, 0xcc, 0x0c, 0x68, 0x7a, 0x32, 0x89, 0xd3, 0x81, 0x0f, - 0x99, 0xdb, 0x53, 0x38, 0x3d, 0x47, 0x13, 0x76, 0xbc, 0x81, 0x62, 0xd7, 0x76, 0xd7, 0x90, 0xca, - 0xaa, 0x5f, 0x9c, 0x80, 0x4a, 0x09, 0xcc, 0x1e, 0xbd, 0xc1, 0x26, 0x7a, 0x67, 0xf3, 0xf4, 0x4e, - 0x03, 0xf6, 0x4c, 0x17, 0xa9, 0x6e, 0xc2, 0x3f, 0x9d, 0xc7, 0xef, 0xc3, 0x58, 0xc5, 0x63, 0x49, - 0xae, 0x52, 0x96, 0x89, 0xf3, 0x73, 0xc4, 0xae, 0xe6, 0x89, 0xdd, 0x50, 0x2f, 0x11, 0x3f, 0x87, - 0x7f, 0x93, 0xe1, 0x63, 0xb5, 0x8e, 0xa1, 0x2d, 0x80, 0x7e, 0x12, 0x5a, 0xa9, 0x84, 0x46, 0x32, - 0xe4, 0x52, 0x2e, 0x50, 0xc8, 0x0a, 0xed, 0x60, 0x69, 0xa1, 0x6d, 0x66, 0x85, 0x76, 0x1f, 0x6e, - 0xac, 0x95, 0x65, 0x56, 0x7b, 0x0c, 0x38, 0xfd, 0x48, 0x08, 0x55, 0xbc, 0x22, 0x4a, 0x10, 0x98, - 0x31, 0x83, 0x97, 0x4c, 0x01, 0xb2, 0xde, 0x69, 0x70, 0xec, 0x39, 0x0a, 0x42, 0x32, 0x0c, 0x6c, - 0x5d, 0xa3, 0x7b, 0x91, 0x54, 0x34, 0xf2, 0x18, 0xc1, 0x49, 0x52, 0x17, 0xe9, 0x8b, 0x48, 0x97, - 0x4a, 0x9e, 0xbf, 0x08, 0xe0, 0xc5, 0x4a, 0x99, 0xb3, 0x08, 0xfe, 0x74, 0x6d, 0x84, 0xbe, 0xa1, - 0x0f, 0x8c, 0xa8, 0x29, 0x97, 0x33, 0x74, 0xa8, 0xc3, 0x9e, 0x78, 0x64, 0x09, 0x12, 0xdd, 0xa0, - 0xba, 0x4f, 0x67, 0x78, 0x56, 0x04, 0x5c, 0x96, 0x99, 0x1c, 0x30, 0x1a, 0x28, 0x1e, 0x32, 0xcd, - 0x5f, 0x16, 0xe0, 0x04, 0xf5, 0x9b, 0x64, 0x2f, 0x36, 0xf1, 0x37, 0xc8, 0x3c, 0xf6, 0x0e, 0x66, - 0x83, 0x90, 0x72, 0x98, 0x6d, 0xf3, 0x10, 0x8a, 0x82, 0x97, 0x0d, 0x5c, 0xdd, 0x7c, 0xb6, 0x0b, - 0x55, 0x43, 0x0f, 0xe2, 0x7e, 0x62, 0xea, 0x49, 0x24, 0x0f, 0xa4, 0x7b, 0xf3, 0x8d, 0x68, 0x3c, - 0xad, 0x5b, 0x78, 0x79, 0x0b, 0xe8, 0x40, 0x4b, 0xb2, 0x00, 0x23, 0xc9, 0x20, 0x77, 0x7b, 0xba, - 0x53, 0xd4, 0x56, 0x00, 0xdf, 0xc0, 0x49, 0x49, 0x9f, 0x99, 0xa0, 0xa0, 0x26, 0x7c, 0x89, 0x99, - 0xa4, 0x6c, 0x1c, 0xc8, 0x20, 0x23, 0xb4, 0xea, 0xfb, 0x2d, 0x52, 0x91, 0xa7, 0xe7, 0x9f, 0xaa, - 0x9d, 0x86, 0x81, 0x70, 0x4b, 0x90, 0x38, 0x97, 0xd9, 0xee, 0x69, 0xa2, 0x76, 0x81, 0x95, 0x02, - 0xa8, 0x4c, 0x0f, 0xbc, 0xc6, 0x70, 0x02, 0xe3, 0xb3, 0x9d, 0xdf, 0x41, 0xbe, 0x4a, 0xa5, 0x12, - 0x21, 0xc1, 0x1e, 0x7d, 0x46, 0xbf, 0x61, 0xde, 0x1b, 0x31, 0x75, 0xdb, 0x8c, 0xe9, 0x16, 0x26, - 0x55, 0x77, 0x49, 0xbb, 0x79, 0xd1, 0xdf, 0xa6, 0x2f, 0x9c, 0x97, 0x6a, 0x8d, 0xfb, 0xea, 0x0e, - 0xf8, 0x26, 0x05, 0x23, 0x62, 0x97, 0xbb, 0xc1, 0x12, 0x17, 0x79, 0x68, 0x0d, 0x15, 0xc5, 0x11, - 0x23, 0x02, 0x37, 0x80, 0xb1, 0xb7, 0xcc, 0xdf, 0xdd, 0xda, 0x70, 0x3a, 0xdc, 0x7f, 0xff, 0xfe, - 0x7d, 0x89, 0x0d, 0xeb, 0x75, 0x08, 0xe9, 0x88, 0x21, 0xe7, 0xc8, 0x01, 0x11, 0x40, 0xbb, 0x43, - 0xc9, 0x34, 0x61, 0x63, 0xa7, 0x38, 0x60, 0x9b, 0xc0, 0xfc, 0x97, 0x8e, 0xea, 0x9e, 0x08, 0x1b, - 0xd7, 0xcc, 0xff, 0xf8, 0x6c, 0xae, 0xd8, 0x89, 0x43, 0x6f, 0x89, 0xe7, 0x8f, 0x7f, 0x8c, 0x02, - 0x1a, 0x3d, 0xd8, 0xae, 0x5e, 0xef, 0x34, 0xa8, 0xfb, 0x06, 0xb7, 0x1a, 0x3e, 0xf0, 0x18, 0x09, - 0xee, 0x8a, 0xf1, 0xae, 0x84, 0xbd, 0x18, 0xc6, 0x88, 0x49, 0x13, 0xb3, 0xbc, 0xb0, 0xa2, 0x64, - 0x5c, 0x0c, 0x8d, 0xfc, 0xe8, 0x79, 0x52, 0xab, 0x80, 0xfa, 0x3e, 0x66, 0xd9, 0x92, 0x06, 0xba, - 0xa7, 0x65, 0x0d, 0x58, 0x0b, 0x26, 0x6a, 0xb7, 0x9a, 0x25, 0x05, 0x68, 0x8a, 0x59, 0x48, 0x48, - 0xe0, 0x06, 0x66, 0xc3, 0x12, 0xcd, 0x6f, 0xdf, 0x96, 0x0f, 0x19, 0xb9, 0x5a, 0x5b, 0xed, 0x32, - 0x4d, 0xe3, 0xca, 0x7a, 0x18, 0x8c, 0x13, 0x2e, 0x12, 0xae, 0x5e, 0xca, 0x23, 0x46, 0xff, 0xf7, - 0xb5, 0xa6, 0xda, 0x6b, 0x2e, 0xe3, 0x33, 0x84, 0x41, 0x7f, 0x16, 0x66, 0x19, 0xa5, 0x2e, 0xba, - 0x46, 0x39, 0x00, 0xdc, 0x2e, 0x97, 0x98, 0x76, 0xfc, 0x55, 0x91, 0x04, 0x7d, 0xda, 0x10, 0x44, - 0x85, 0x6c, 0x37, 0xb8, 0x3c, 0xb3, 0x56, 0x41, 0xed, 0x15, 0x50, 0x5d, 0x00, 0x5b, 0x05, 0xb5, - 0x9f, 0x97, 0xf3, 0x95, 0x11, 0xf9, 0x2e, 0x87, 0x20, 0x3b, 0xe4, 0xeb, 0x94, 0x2b, 0xb6, 0x8a, - 0xd4, 0x51, 0x01, 0x98, 0x55, 0xfa, 0x95, 0xac, 0xbd, 0x2f, 0x43, 0x6e, 0x22, 0x0d, 0x89, 0xc3, - 0xd2, 0xe1, 0x46, 0xd6, 0x88, 0xd2, 0x46, 0xcd, 0x85, 0x21, 0x4b, 0x80, 0xda, 0x6a, 0x60, 0x2b, - 0x4f, 0x47, 0xb6, 0x5b, 0x00, 0x7d, 0x5d, 0xa9, 0x69, 0xb0, 0x46, 0x1f, 0x5c, 0x95, 0xad, 0xca, - 0x3a, 0x94, 0x58, 0x8b, 0xf1, 0xb5, 0xe2, 0x00, 0x9b, 0xa1, 0x57, 0xed, 0xfa, 0xe1, 0x73, 0x03, - 0x5c, 0xa7, 0x14, 0x69, 0xc6, 0xe3, 0x78, 0x34, 0x16, 0x18, 0x6e, 0xba, 0x1b, 0xbc, 0x85, 0xe2, - 0x00, 0xd1, 0x56, 0x4e, 0x11, 0xb7, 0x1b, 0x52, 0x58, 0x73, 0xc1, 0xf3, 0x48, 0x68, 0x3a, 0xa7, - 0x8f, 0x22, 0xf1, 0xb0, 0x7e, 0x3c, 0x93, 0x51, 0xd1, 0x33, 0x6e, 0x48, 0x59, 0x1f, 0xf3, 0xd6, - 0x26, 0x73, 0xc5, 0xa2, 0x62, 0x91, 0x09, 0x0d, 0x43, 0x4a, 0x3c, 0x91, 0x60, 0xdf, 0x05, 0xfa, - 0xd8, 0x40, 0x68, 0x70, 0x99, 0x11, 0xca, 0x6b, 0x21, 0xc1, 0xf3, 0x01, 0x31, 0x1e, 0x83, 0x4a, - 0x4b, 0xd2, 0x7d, 0xfd, 0xbc, 0x54, 0xba, 0xdd, 0xbd, 0x76, 0x3b, 0x0f, 0x2c, 0xbc, 0xb3, 0x66, - 0x91, 0xb5, 0xa4, 0xe4, 0x9a, 0x2e, 0xec, 0x37, 0xc1, 0x41, 0xe2, 0x53, 0x68, 0x5b, 0xb0, 0x9a, - 0x9b, 0xfe, 0x40, 0x17, 0x08, 0xac, 0x0f, 0x9f, 0x84, 0x06, 0x9a, 0xa5, 0x77, 0xfd, 0x71, 0x02, - 0xda, 0x91, 0x9c, 0xd8, 0x13, 0x4d, 0x22, 0xdb, 0xbd, 0xc5, 0x76, 0x60, 0xcc, 0x93, 0x10, 0x1e, - 0x19, 0x34, 0x87, 0x3c, 0xf0, 0x89, 0x2f, 0x98, 0xc4, 0xae, 0x0a, 0x8c, 0xe5, 0x05, 0xa9, 0xcf, - 0xb2, 0xa6, 0x4f, 0xa6, 0x31, 0xe6, 0x8b, 0xba, 0x65, 0x6a, 0x03, 0x9f, 0xab, 0x11, 0xc5, 0xae, - 0x66, 0x4f, 0xf7, 0x22, 0x4c, 0x03, 0xaa, 0x72, 0x44, 0xf3, 0x29, 0x69, 0x53, 0x17, 0x70, 0x9a, - 0x75, 0x29, 0x06, 0x87, 0x47, 0x8f, 0xd9, 0xa1, 0xa4, 0xd6, 0x5b, 0x09, 0x19, 0x4f, 0xf5, 0x73, - 0xdd, 0x9f, 0xf6, 0x30, 0x83, 0xd2, 0x67, 0x73, 0xa0, 0x07, 0xa1, 0xbe, 0x97, 0xd3, 0x91, 0x82, - 0xb0, 0x8c, 0x11, 0xc3, 0x82, 0xc4, 0xd6, 0xcb, 0xa3, 0x41, 0x00, 0x5d, 0x10, 0x43, 0xa9, 0xa5, - 0x5a, 0x34, 0xce, 0xe9, 0xeb, 0xc3, 0x9a, 0x5c, 0xf5, 0xa5, 0xec, 0x37, 0x5f, 0xa4, 0x74, 0x33, - 0x0d, 0x15, 0xa2, 0x68, 0xf9, 0xb2, 0x93, 0xa3, 0x72, 0x43, 0x37, 0x77, 0x0c, 0x66, 0x94, 0xff, - 0xf6, 0x1f, 0xef, 0x8f, 0x8e, 0x8e, 0x4e, 0x48, 0x67, 0x04, 0x71, 0xff, 0xe5, 0xf6, 0x96, 0xe0, - 0x60, 0x82, 0x9d, 0x31, 0x1e, 0xfc, 0x11, 0xe4, 0xd3, 0x13, 0x51, 0x84, 0x09, 0x04, 0xf8, 0x06, - 0x91, 0x59, 0x12, 0xd1, 0x80, 0xe0, 0x59, 0xa4, 0xd4, 0xe5, 0xca, 0xd2, 0xd6, 0x0b, 0xe9, 0x0b, - 0xe1, 0x21, 0xd4, 0x05, 0xa5, 0xc5, 0x02, 0x5e, 0x62, 0x68, 0x63, 0xa1, 0xfa, 0x46, 0xba, 0xc5, - 0x1f, 0xeb, 0x93, 0x56, 0xa8, 0x98, 0xa3, 0x39, 0xe6, 0x30, 0x5a, 0xc8, 0x88, 0x49, 0x2c, 0xa9, - 0x12, 0xf2, 0x03, 0x8c, 0x29, 0xd8, 0x6c, 0x91, 0x14, 0x5a, 0x30, 0x11, 0x31, 0xc4, 0x02, 0x5a, - 0xf0, 0x20, 0x59, 0x62, 0x34, 0x47, 0xa1, 0x9e, 0x11, 0x74, 0xed, 0xba, 0xde, 0xb9, 0x02, 0x7e, - 0x8e, 0xec, 0x28, 0xd8, 0x27, 0x78, 0xa9, 0x15, 0x8c, 0x82, 0x9b, 0x30, 0xb8, 0xf7, 0xc9, 0xc5, - 0xb0, 0x8f, 0x5c, 0x03, 0x95, 0x50, 0x8b, 0x85, 0x94, 0x91, 0x3d, 0x6c, 0x0c, 0x51, 0xbc, 0xea, - 0xd2, 0x86, 0x17, 0xb5, 0x50, 0xf6, 0x63, 0x5c, 0x2b, 0xec, 0xb0, 0xdc, 0x8b, 0xad, 0xad, 0xdc, - 0x58, 0xab, 0x38, 0xf7, 0xe2, 0xc2, 0x89, 0x17, 0x1d, 0x58, 0x6f, 0xe6, 0x5a, 0x59, 0x9b, 0x8d, - 0x4f, 0x9b, 0x1a, 0xd0, 0x2f, 0xc6, 0xdd, 0xce, 0x12, 0xf1, 0xc0, 0x92, 0xa5, 0x7e, 0x9a, 0x39, - 0xf8, 0xcd, 0x50, 0xfb, 0xce, 0xbc, 0x9f, 0x2e, 0x3b, 0x30, 0xbc, 0xf9, 0xd2, 0xff, 0x3c, 0x58, - 0x99, 0x02, 0xad, 0xe5, 0xc7, 0x7b, 0x59, 0x0f, 0x8c, 0x8a, 0xc8, 0xe4, 0xf4, 0xc0, 0x33, 0xa1, - 0xe4, 0x70, 0x1a, 0x80, 0xed, 0x12, 0x34, 0x24, 0x36, 0xd4, 0xd0, 0x92, 0x81, 0x35, 0xa0, 0x39, - 0x03, 0x2b, 0xa5, 0x38, 0x8b, 0x64, 0x76, 0x83, 0x38, 0x33, 0x76, 0xfd, 0xc4, 0x10, 0x24, 0x37, - 0x96, 0xa6, 0x14, 0xc3, 0x26, 0xd0, 0x53, 0xfb, 0x64, 0x2c, 0x10, 0x59, 0xc0, 0x8b, 0x24, 0xf7, - 0x8b, 0x37, 0xb9, 0x5b, 0x41, 0xef, 0x9e, 0x2c, 0x04, 0xaa, 0xf5, 0x3a, 0x52, 0x6f, 0xbe, 0xdc, - 0x0d, 0x2f, 0x06, 0x0b, 0x4a, 0x38, 0x68, 0x1a, 0xd6, 0xfb, 0xd9, 0x1e, 0x25, 0xfd, 0xe5, 0x5b, - 0xcf, 0x74, 0xf8, 0xa5, 0x7f, 0x3a, 0x5c, 0xd4, 0xe3, 0xe1, 0x81, 0x21, 0x71, 0x1e, 0x70, 0x14, - 0xb1, 0xd7, 0x5d, 0x93, 0x2b, 0x6e, 0xbe, 0x9c, 0xf7, 0xba, 0x8b, 0xe9, 0x22, 0xe7, 0xa0, 0xab, - 0x33, 0x04, 0xb9, 0x15, 0x31, 0xf7, 0xd6, 0x51, 0xe8, 0xbe, 0x32, 0xa2, 0xce, 0x87, 0x97, 0x78, - 0x8e, 0xba, 0x19, 0xfb, 0xf2, 0x15, 0xb6, 0xd6, 0x7a, 0x3f, 0x1d, 0xc1, 0x20, 0x37, 0x2d, 0xcf, - 0xe7, 0x1b, 0x5c, 0xef, 0xec, 0xa6, 0xa8, 0x3a, 0x0a, 0xc7, 0xa6, 0x59, 0xdd, 0x23, 0x6f, 0xc1, - 0xb0, 0x01, 0x98, 0x2b, 0x84, 0x07, 0x0a, 0x23, 0xe6, 0xa6, 0xfa, 0x75, 0x6b, 0xe7, 0xc3, 0xaa, - 0xb5, 0x71, 0x5a, 0x25, 0x3a, 0x6c, 0xb6, 0x6d, 0x09, 0xc2, 0x3f, 0x95, 0x5a, 0xd2, 0x0d, 0x68, - 0xcf, 0xca, 0x9b, 0x81, 0x2c, 0x27, 0x61, 0x02, 0x98, 0x3b, 0x1f, 0x28, 0xe7, 0x01, 0x58, 0x2a, - 0xa7, 0x01, 0xc8, 0x2d, 0x7f, 0x23, 0x0f, 0xcc, 0x9f, 0x41, 0x2c, 0xa6, 0x03, 0x16, 0xce, 0xe7, - 0x03, 0x3d, 0x67, 0xe1, 0xae, 0x5a, 0x2f, 0xbf, 0x8b, 0x14, 0x6a, 0x47, 0x04, 0xd4, 0x21, 0x9b, - 0x61, 0x70, 0x80, 0xba, 0xfd, 0x09, 0x23, 0xbd, 0xbe, 0xce, 0x6f, 0xb8, 0x12, 0xa0, 0xfe, 0x89, - 0x09, 0x59, 0xd8, 0x4d, 0xaf, 0xfd, 0x72, 0x3a, 0x82, 0x16, 0xe7, 0x17, 0x4c, 0x8b, 0xba, 0x9a, - 0x99, 0xcc, 0x4a, 0xa6, 0xb0, 0x37, 0xa8, 0x15, 0x8a, 0x69, 0x56, 0x48, 0xfb, 0x02, 0xd2, 0x3d, - 0x72, 0x64, 0x88, 0x2c, 0xa4, 0x84, 0xab, 0xeb, 0xb5, 0x1d, 0x11, 0x4c, 0x4c, 0x2e, 0xc1, 0xb8, - 0x7d, 0x29, 0x1d, 0xc3, 0x5f, 0xf5, 0x96, 0xe3, 0x35, 0x9b, 0x0b, 0xbd, 0x14, 0xb6, 0x50, 0x9b, - 0xa6, 0x9b, 0xab, 0xbe, 0xf1, 0x10, 0xc8, 0x2f, 0x51, 0x0d, 0x9c, 0xc3, 0x4c, 0xf9, 0x6b, 0x9d, - 0xea, 0x4a, 0x1f, 0x87, 0x7d, 0x8e, 0x1a, 0x9f, 0xc7, 0xe3, 0x0d, 0xa7, 0x60, 0x57, 0xd0, 0x88, - 0x91, 0xb9, 0xa3, 0x3e, 0xb2, 0xf9, 0x84, 0xee, 0xea, 0x1c, 0x50, 0xf4, 0xf9, 0x1e, 0xb2, 0x85, - 0x8a, 0x3b, 0xcb, 0xed, 0x71, 0x3c, 0x77, 0x52, 0x97, 0x01, 0x37, 0xb7, 0xad, 0xeb, 0xd8, 0x7c, - 0xb9, 0xa4, 0x5e, 0xd2, 0x7f, 0xeb, 0xd5, 0xc8, 0xf6, 0x53, 0xe8, 0xaf, 0xbe, 0xd5, 0xbc, 0xc6, - 0xb6, 0xd6, 0xa0, 0xef, 0x6f, 0x46, 0x9f, 0x61, 0xe7, 0x85, 0xa0, 0xaf, 0x0f, 0xf8, 0xd0, 0xd5, - 0xe2, 0x54, 0x4e, 0x03, 0x1e, 0x3d, 0xe4, 0xa9, 0x45, 0x44, 0x73, 0xee, 0x0b, 0xaa, 0x1e, 0xe3, - 0xd7, 0x58, 0x35, 0x85, 0x02, 0x2f, 0xe9, 0x63, 0x76, 0x40, 0x84, 0xff, 0x42, 0x50, 0xe4, 0x76, - 0xab, 0xf2, 0x04, 0x56, 0xcf, 0xfa, 0xa5, 0xbc, 0x60, 0x44, 0x93, 0x6a, 0xae, 0x78, 0xe8, 0x3e, - 0x55, 0x8a, 0x1e, 0x04, 0xc3, 0x69, 0x54, 0x30, 0xc7, 0xe3, 0xd9, 0x88, 0x67, 0x82, 0x01, 0xe8, - 0xea, 0x88, 0xc4, 0xcf, 0x92, 0x00, 0x59, 0xf4, 0x49, 0xfb, 0xee, 0x90, 0x25, 0x50, 0xa8, 0x74, - 0xc0, 0x9f, 0xd1, 0xd4, 0x27, 0x09, 0xf4, 0x6c, 0xe5, 0xc3, 0x9a, 0xb3, 0xee, 0xab, 0x21, 0xb2, - 0xd5, 0x6a, 0x63, 0xfe, 0xc5, 0x9f, 0x66, 0x73, 0xe5, 0x80, 0xb8, 0xdf, 0x84, 0x0a, 0x81, 0xd7, - 0xd5, 0x30, 0x07, 0x87, 0x4d, 0x18, 0xeb, 0xf0, 0xda, 0x6c, 0xae, 0x1c, 0xe7, 0x4c, 0xac, 0xe0, - 0x75, 0x35, 0xa1, 0xf6, 0xbb, 0x43, 0x84, 0x81, 0xeb, 0x1a, 0x42, 0xef, 0xf7, 0x5a, 0x30, 0x96, - 0xe1, 0x75, 0x35, 0xa1, 0x56, 0x53, 0xef, 0xa6, 0x7f, 0xd6, 0x90, 0x6a, 0x19, 0xa6, 0x5a, 0x65, - 0xae, 0x16, 0xa6, 0x37, 0x48, 0x5e, 0xff, 0x66, 0x2c, 0xc6, 0x16, 0xce, 0xa8, 0x0a, 0x73, 0x3a, - 0x96, 0xf8, 0x5e, 0x18, 0x27, 0xe2, 0xb1, 0x4e, 0x86, 0x02, 0x26, 0x96, 0x91, 0xa0, 0x89, 0x6f, - 0xba, 0x49, 0x4c, 0x96, 0x59, 0x62, 0x24, 0x53, 0x08, 0x4a, 0x6d, 0x8f, 0xe2, 0x98, 0x12, 0x0b, - 0xde, 0xda, 0x0f, 0xb5, 0x3f, 0xf3, 0xcd, 0xd5, 0x9a, 0xfb, 0x9e, 0x8b, 0xdf, 0x95, 0xe1, 0x07, - 0xbf, 0x3d, 0xe3, 0x87, 0x68, 0xfc, 0xe7, 0xb6, 0xff, 0x03, 0x77, 0xe7, 0x10, 0x48, 0xec, 0x26, - 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_time.htm, do not edit!! -const uint16_t PAGE_settings_time_length = 3444; -const uint8_t PAGE_settings_time[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xd5, 0x1a, 0x6b, 0x57, 0xdb, 0x38, - 0xf6, 0x7b, 0x7e, 0x85, 0x50, 0x7b, 0x18, 0x7b, 0x70, 0x9e, 0x90, 0x16, 0x92, 0xd8, 0x6c, 0x08, - 0x69, 0xa1, 0x4d, 0x02, 0xa7, 0x49, 0x87, 0xdd, 0x3e, 0xce, 0x54, 0x89, 0x95, 0xc4, 0xe0, 0x48, - 0x59, 0x5b, 0x26, 0xb0, 0x94, 0xff, 0xbe, 0x57, 0x92, 0xe3, 0x3c, 0x0d, 0x6d, 0x67, 0xf6, 0xc3, - 0x9e, 0x9e, 0x1a, 0x5b, 0xba, 0xba, 0x2f, 0xdd, 0x97, 0xae, 0x52, 0xdb, 0x39, 0xbd, 0x68, 0xf4, - 0xfe, 0x75, 0xd9, 0x44, 0x63, 0x31, 0xf1, 0x9d, 0x9a, 0x7c, 0x22, 0x9f, 0xb0, 0x91, 0x8d, 0x29, - 0xc3, 0xf0, 0x4d, 0x89, 0xeb, 0xd4, 0x26, 0x54, 0x10, 0xc4, 0xc8, 0x84, 0xda, 0xf8, 0xd6, 0xa3, - 0xb3, 0x29, 0x0f, 0x04, 0x46, 0x03, 0xce, 0x04, 0x65, 0xc2, 0xc6, 0x33, 0xcf, 0x15, 0x63, 0xbb, - 0x5c, 0x28, 0x60, 0x27, 0xa3, 0x41, 0x33, 0x6b, 0x73, 0x2e, 0xbd, 0xf5, 0x06, 0x34, 0xab, 0x3e, - 0x2c, 0x8f, 0x79, 0xc2, 0x23, 0x7e, 0x36, 0x1c, 0x10, 0x9f, 0xda, 0x45, 0x6b, 0x42, 0xee, 0xbc, - 0x49, 0x34, 0x49, 0xbe, 0xa3, 0x90, 0x06, 0xea, 0x83, 0xf4, 0xe1, 0x9b, 0x71, 0x8c, 0x32, 0x6b, - 0xa4, 0x63, 0x86, 0x06, 0x63, 0x12, 0x84, 0x14, 0x88, 0x44, 0x62, 0x98, 0x3d, 0x84, 0x51, 0xe1, - 0x09, 0x9f, 0x3a, 0x3d, 0x6f, 0x42, 0x51, 0x97, 0x0a, 0xe1, 0xb1, 0x51, 0x58, 0xcb, 0xeb, 0xc1, - 0x5a, 0x38, 0x08, 0xbc, 0xa9, 0x70, 0x32, 0xb7, 0x24, 0x40, 0x3e, 0x1f, 0x78, 0x53, 0xcb, 0xb5, - 0x5d, 0x3e, 0x88, 0x26, 0xc0, 0xa6, 0x05, 0x03, 0xf6, 0x4e, 0x51, 0xfe, 0x99, 0x06, 0x5c, 0x70, - 0x1b, 0x8f, 0x85, 0x98, 0x56, 0xb0, 0x45, 0x7d, 0x39, 0x3c, 0x09, 0xed, 0xcf, 0xf8, 0x1d, 0x61, - 0xd8, 0xc2, 0x6f, 0x68, 0x1f, 0x9e, 0x6d, 0x12, 0xc0, 0xb3, 0x3e, 0x0d, 0xd4, 0xfb, 0x3d, 0x3c, - 0xdf, 0x45, 0x4c, 0x3d, 0x7d, 0x39, 0x1e, 0x8d, 0xe0, 0xd9, 0xa5, 0x53, 0x78, 0x5e, 0x0c, 0x04, - 0x3c, 0x3b, 0xfc, 0x16, 0x9e, 0xa7, 0x74, 0x80, 0xbf, 0x56, 0x87, 0x11, 0x1b, 0x08, 0x8f, 0x33, - 0x74, 0x66, 0x98, 0x0f, 0x33, 0x8f, 0xb9, 0x7c, 0x96, 0xe3, 0x53, 0xca, 0x0c, 0x45, 0x33, 0xac, - 0xe4, 0xf3, 0x37, 0x8c, 0xe7, 0x66, 0x3e, 0x75, 0x73, 0x23, 0x9a, 0x1f, 0x52, 0x22, 0xa2, 0x80, - 0x86, 0xf9, 0x30, 0x96, 0x27, 0xff, 0x42, 0x80, 0x78, 0xd9, 0xf9, 0x27, 0x36, 0x1f, 0x13, 0x84, - 0x27, 0x6b, 0x08, 0x47, 0x54, 0x7c, 0xfc, 0xd0, 0x32, 0x70, 0x7e, 0x01, 0x6c, 0xe1, 0x3f, 0x43, - 0xea, 0x0f, 0x97, 0x57, 0x8d, 0xce, 0x5d, 0x43, 0x98, 0x0f, 0x01, 0x05, 0x3a, 0x0c, 0x49, 0xa2, - 0xa2, 0xe9, 0x53, 0xa9, 0x95, 0x93, 0x7b, 0x35, 0xb5, 0x04, 0xda, 0x49, 0x81, 0x0c, 0x4f, 0xee, - 0x3b, 0xb0, 0x43, 0x30, 0xfb, 0xb9, 0xf0, 0x75, 0x01, 0xef, 0x73, 0xe2, 0xbe, 0xeb, 0x1a, 0xc2, - 0xa2, 0xf6, 0x4e, 0xc1, 0x7c, 0xf0, 0xa9, 0x40, 0xcc, 0x76, 0x73, 0x83, 0x00, 0x84, 0xa2, 0xf1, - 0x52, 0x03, 0xeb, 0x8d, 0xc1, 0x66, 0x95, 0xe5, 0x80, 0xd1, 0xba, 0x10, 0x81, 0xd7, 0x8f, 0x04, - 0x85, 0x89, 0x60, 0x80, 0x2d, 0x61, 0x5a, 0xeb, 0xe3, 0xe2, 0x7e, 0x4a, 0x41, 0x9d, 0x82, 0xde, - 0x89, 0xfc, 0x35, 0xb9, 0x25, 0x73, 0x04, 0x1b, 0x80, 0x24, 0xbc, 0x67, 0x80, 0x82, 0x9a, 0x96, - 0x9b, 0xeb, 0x73, 0xf7, 0x3e, 0x47, 0xa6, 0xa0, 0x17, 0xb7, 0x31, 0xf6, 0x7c, 0xd7, 0x60, 0x12, - 0x9e, 0xb8, 0x6e, 0xf3, 0x16, 0xb8, 0x68, 0x79, 0x21, 0x98, 0x2b, 0x0d, 0x0c, 0x2c, 0x79, 0xc6, - 0x96, 0x61, 0xda, 0xce, 0xc3, 0x49, 0x8f, 0x18, 0xa6, 0xf5, 0x96, 0x8a, 0x3f, 0xe0, 0x4f, 0x34, - 0x75, 0x5b, 0x7c, 0x00, 0x2f, 0x8d, 0x10, 0x1e, 0x6f, 0x1a, 0x86, 0xf9, 0xb8, 0x1d, 0x01, 0x0d, - 0x02, 0x0e, 0x76, 0x21, 0x00, 0x01, 0x38, 0x41, 0xc8, 0x7d, 0x9a, 0xf3, 0xf9, 0xc8, 0xc0, 0x4d, - 0x39, 0x8e, 0x62, 0xad, 0xc0, 0x6e, 0xa0, 0xa1, 0xe7, 0x53, 0x25, 0x1f, 0x58, 0x7d, 0x00, 0x7a, - 0x68, 0xc5, 0xe3, 0x7c, 0x28, 0x3d, 0x6b, 0xe8, 0x8d, 0xa2, 0x80, 0x28, 0x35, 0x6a, 0xf9, 0xd0, - 0x90, 0x78, 0xd2, 0x28, 0xbe, 0xb0, 0x73, 0x36, 0xe0, 0x93, 0x29, 0x68, 0x93, 0xa2, 0x29, 0x19, - 0x51, 0xe4, 0x12, 0x41, 0x76, 0x60, 0x4b, 0x97, 0x76, 0xaa, 0x6b, 0x68, 0x75, 0x0b, 0x3b, 0x36, - 0x08, 0xb0, 0x6c, 0x85, 0xac, 0xea, 0x0d, 0x0d, 0x2c, 0x29, 0x57, 0xb0, 0x6d, 0x8b, 0x9c, 0xb2, - 0xf6, 0x01, 0xf7, 0x4d, 0xe5, 0x00, 0x05, 0xcb, 0x50, 0x9e, 0x61, 0x4b, 0x68, 0xbf, 0x2b, 0x78, - 0x00, 0xe8, 0xe5, 0x36, 0x9f, 0x0b, 0x3a, 0x91, 0xaa, 0x19, 0x9c, 0x4f, 0xb1, 0x69, 0x7e, 0xff, - 0x1e, 0x83, 0xc1, 0xea, 0xc9, 0x14, 0x38, 0x7f, 0x03, 0xf8, 0x50, 0x9b, 0xbb, 0x34, 0x87, 0x2e, - 0x7d, 0x4a, 0x42, 0x8a, 0x40, 0x23, 0x34, 0x40, 0x57, 0xad, 0xe6, 0x29, 0x3a, 0xbf, 0x04, 0xde, - 0xac, 0x15, 0x8c, 0xe1, 0x2a, 0x46, 0x4b, 0x61, 0x33, 0xcd, 0x2a, 0xf5, 0x43, 0xaa, 0xd8, 0xa6, - 0x92, 0x35, 0x22, 0xc6, 0xd2, 0xed, 0x2d, 0x66, 0xc3, 0x0a, 0x1f, 0xc2, 0x87, 0x51, 0xb4, 0x68, - 0x0e, 0xf6, 0x2f, 0xbc, 0xf2, 0xc4, 0x18, 0xcc, 0x1a, 0x9b, 0xc7, 0xd9, 0x62, 0xe5, 0x96, 0x7b, - 0x2e, 0x2a, 0x98, 0xb9, 0x70, 0xea, 0x7b, 0x42, 0x8d, 0x82, 0x21, 0xf9, 0x94, 0x8d, 0xc4, 0xd8, - 0x29, 0xed, 0xee, 0x1a, 0x89, 0x4f, 0x2f, 0xa4, 0xb5, 0x62, 0x69, 0xb5, 0x14, 0x22, 0x37, 0xe6, - 0xa1, 0x90, 0xa4, 0xf6, 0x0c, 0x80, 0x81, 0xf8, 0x72, 0x8c, 0x2b, 0x78, 0x4f, 0xbf, 0x56, 0x30, - 0x36, 0xf7, 0x00, 0xe9, 0x1e, 0x03, 0xcb, 0x36, 0x1f, 0x63, 0x8b, 0xde, 0xf0, 0xac, 0x7c, 0x98, - 0xbb, 0x0e, 0x8f, 0xa7, 0x76, 0x19, 0x44, 0xdd, 0x29, 0x2a, 0x71, 0x81, 0xb4, 0x9b, 0xeb, 0x0e, - 0x73, 0x44, 0xed, 0x88, 0xbd, 0xb9, 0x44, 0xfa, 0x31, 0x68, 0x73, 0xc9, 0xbd, 0x34, 0x48, 0xe2, - 0x62, 0x92, 0xf5, 0xe3, 0x39, 0xfb, 0xc0, 0x04, 0x70, 0xa1, 0x38, 0x56, 0x3c, 0x89, 0xc5, 0x3a, - 0x7a, 0x37, 0x25, 0xcc, 0x95, 0x6e, 0x66, 0x3e, 0xc8, 0xe8, 0x06, 0xc4, 0xc0, 0x71, 0xf1, 0xd5, - 0x29, 0xde, 0xa3, 0xca, 0xab, 0xc4, 0x3d, 0x18, 0xa1, 0xeb, 0x81, 0x86, 0xc8, 0xbd, 0x8d, 0x19, - 0x67, 0x14, 0xef, 0xd8, 0xf6, 0xda, 0xc4, 0xb1, 0x9e, 0x00, 0xe4, 0x96, 0xc8, 0x79, 0x0c, 0x6c, - 0xf9, 0xac, 0xd7, 0x6e, 0xc5, 0xe0, 0xf6, 0x16, 0xf0, 0xdd, 0x17, 0xc5, 0xd2, 0x61, 0xf1, 0xe8, - 0x75, 0x15, 0xd6, 0xec, 0xbe, 0xb8, 0x2b, 0xbd, 0x2e, 0x96, 0xab, 0x78, 0xc1, 0x95, 0xf4, 0x93, - 0x07, 0xc5, 0xc8, 0x80, 0x0c, 0xb0, 0xb9, 0xc6, 0x05, 0x84, 0x12, 0x7c, 0xd1, 0x82, 0xe1, 0xc1, - 0x98, 0x0e, 0x6e, 0xa8, 0x7b, 0x8c, 0xfb, 0x20, 0xdb, 0x0d, 0xa0, 0x52, 0xf4, 0x96, 0x82, 0x9a, - 0x74, 0x42, 0x25, 0x16, 0xc4, 0xf9, 0x9a, 0xd0, 0xe9, 0x48, 0x04, 0xf0, 0x7f, 0xec, 0x34, 0x59, - 0x0e, 0xc2, 0xfb, 0x58, 0xbd, 0x9f, 0xf1, 0x28, 0x48, 0x3e, 0xda, 0x1e, 0x83, 0x00, 0x90, 0x7c, - 0x5e, 0x42, 0x00, 0xa5, 0x22, 0xf9, 0xd4, 0x2f, 0x79, 0x89, 0x24, 0xaf, 0x11, 0xe2, 0xea, 0x90, - 0x07, 0x86, 0x67, 0x17, 0xaa, 0x5e, 0xed, 0xb0, 0xea, 0xed, 0xed, 0x99, 0x0f, 0x72, 0x40, 0xec, - 0xd9, 0xdf, 0x34, 0x2d, 0xa0, 0xe9, 0xb1, 0x69, 0x24, 0xe2, 0x1c, 0x78, 0xf5, 0xf2, 0xc1, 0x7b, - 0xc4, 0xc8, 0x73, 0x93, 0x57, 0x19, 0x93, 0x20, 0x6b, 0x78, 0xae, 0xab, 0xb2, 0xa6, 0x06, 0x4e, - 0xe6, 0x0b, 0x73, 0x00, 0x25, 0x6d, 0x9f, 0xdf, 0x61, 0x49, 0xda, 0x75, 0xbe, 0xb0, 0x0d, 0xd4, - 0x67, 0x1a, 0xdf, 0xc0, 0x27, 0x61, 0x68, 0xe3, 0xbb, 0x70, 0xbe, 0x92, 0x45, 0x93, 0x3e, 0x0d, - 0x30, 0x9a, 0x78, 0xcc, 0xc6, 0x80, 0x0f, 0x92, 0xa6, 0x8d, 0x4b, 0x07, 0xe9, 0x88, 0x3a, 0x3f, - 0x83, 0xa8, 0x7c, 0x94, 0x8e, 0xa8, 0xb7, 0x82, 0xe8, 0x19, 0x86, 0xca, 0x85, 0x55, 0x44, 0xae, - 0x77, 0xab, 0xd4, 0xd0, 0x38, 0xd1, 0x58, 0x38, 0x1b, 0x80, 0x2b, 0xdf, 0x40, 0x71, 0x11, 0x1b, - 0xed, 0xd8, 0x0b, 0x2d, 0x39, 0x65, 0x26, 0x14, 0x20, 0x50, 0x60, 0x27, 0x31, 0xae, 0x5a, 0x1e, - 0x50, 0x68, 0x94, 0x6a, 0xcb, 0xbe, 0x59, 0x4b, 0xbb, 0x02, 0x81, 0xd2, 0x0f, 0x01, 0x8f, 0x5d, - 0x5e, 0x50, 0xba, 0x3a, 0xd5, 0x94, 0x94, 0xbd, 0xd9, 0x38, 0x36, 0xb8, 0x8a, 0x34, 0xab, 0x6a, - 0x9f, 0x0c, 0x6e, 0x46, 0x01, 0x8f, 0x98, 0x9b, 0x85, 0x95, 0x3c, 0xa8, 0xbc, 0x38, 0x38, 0x38, - 0xa8, 0xca, 0x2a, 0x27, 0x70, 0x3e, 0x44, 0x4c, 0x46, 0xe7, 0x19, 0xa5, 0x37, 0x2e, 0xb9, 0x0f, - 0x15, 0x1d, 0x30, 0x38, 0x59, 0x83, 0x24, 0x06, 0xd7, 0x4e, 0x6c, 0xa8, 0x97, 0xbc, 0x5d, 0x6d, - 0x19, 0x7b, 0x93, 0xbc, 0x75, 0xd7, 0xdf, 0x94, 0xd9, 0xc1, 0x7f, 0x6c, 0x5d, 0xdb, 0xc5, 0xea, - 0x35, 0x98, 0xdb, 0x35, 0x98, 0x9b, 0x96, 0xc9, 0xdd, 0x30, 0x9c, 0x97, 0x0f, 0xd7, 0x8f, 0x29, - 0xb6, 0xf3, 0xad, 0x9a, 0x98, 0x68, 0x6c, 0xca, 0x8a, 0xd5, 0x21, 0xc4, 0x64, 0x54, 0x83, 0x24, - 0x4f, 0x07, 0xf3, 0x0d, 0x6c, 0x2b, 0x85, 0x80, 0xe6, 0xae, 0xc1, 0xc0, 0xaf, 0x6b, 0xc5, 0xd2, - 0x82, 0x24, 0x9f, 0x2a, 0x27, 0xbb, 0x25, 0x7e, 0x04, 0x80, 0x40, 0x6d, 0xaf, 0x08, 0x90, 0x2f, - 0x1f, 0x26, 0xe1, 0xe7, 0xeb, 0xaf, 0x8f, 0xb5, 0xbc, 0x9e, 0x5f, 0xa1, 0xa5, 0x51, 0xaf, 0x9a, - 0xc8, 0xe9, 0x8f, 0xd8, 0x5a, 0x31, 0xb6, 0x91, 0xfd, 0xa2, 0x94, 0x40, 0x2d, 0x77, 0x90, 0xe0, - 0x6b, 0xcc, 0x5e, 0xfe, 0x0d, 0xcc, 0xa6, 0x33, 0xda, 0xfc, 0x55, 0x46, 0xbf, 0xb0, 0x2f, 0xe2, - 0x8b, 0x90, 0x76, 0xb2, 0x61, 0x90, 0x8f, 0xb1, 0x6e, 0x7e, 0xdb, 0x1e, 0x2a, 0x0e, 0xe3, 0x38, - 0x71, 0xf8, 0x54, 0x90, 0x38, 0x7c, 0x3a, 0x42, 0x74, 0x23, 0x16, 0x78, 0x21, 0x5d, 0x0d, 0x14, - 0x80, 0x30, 0x56, 0x45, 0xa9, 0x5c, 0xde, 0x40, 0x9e, 0x16, 0x15, 0x0e, 0x9f, 0x93, 0x3e, 0x0b, - 0xb1, 0xe0, 0x07, 0x82, 0xc2, 0xe1, 0x5f, 0x8f, 0x08, 0x87, 0x29, 0xe1, 0xe0, 0xf0, 0x47, 0x63, - 0xc1, 0x66, 0x14, 0xf8, 0xcd, 0x52, 0x1b, 0xb1, 0x88, 0x05, 0x87, 0x3f, 0x1f, 0x08, 0xfe, 0x77, - 0x3e, 0xff, 0xdb, 0xb3, 0x3e, 0x7f, 0xf8, 0x23, 0x0e, 0x8f, 0x57, 0x1c, 0x7e, 0x9b, 0x4d, 0x62, - 0x2b, 0xdd, 0x1e, 0x8f, 0x62, 0x7b, 0x3c, 0x7a, 0xca, 0x1e, 0x8f, 0x9e, 0xb5, 0x47, 0x99, 0x50, - 0x57, 0xcc, 0xf1, 0xe8, 0x97, 0xcc, 0xf1, 0xe8, 0x6f, 0x32, 0xc7, 0xa3, 0xbf, 0x6e, 0x8e, 0x47, - 0x29, 0xe6, 0x78, 0xf4, 0x37, 0x9a, 0xe3, 0xd1, 0xff, 0x97, 0x39, 0x1e, 0x3d, 0x69, 0x8e, 0x3f, - 0x68, 0x8a, 0xaa, 0x06, 0xec, 0xb5, 0x7b, 0x50, 0xec, 0x2d, 0xca, 0xca, 0xa5, 0xf2, 0x55, 0x9e, - 0xa5, 0x1e, 0x16, 0xf5, 0x57, 0xb1, 0xa0, 0x0b, 0x30, 0x7d, 0x7c, 0xd1, 0x95, 0x2c, 0xde, 0xf3, - 0xcc, 0x9c, 0xb2, 0x2e, 0xe5, 0x03, 0x3a, 0x35, 0x68, 0xb6, 0x13, 0x80, 0xbd, 0xeb, 0xa4, 0x98, - 0xb4, 0x85, 0xe3, 0x5c, 0xef, 0x16, 0xab, 0x46, 0xa9, 0x7c, 0xb0, 0x63, 0xcb, 0xe7, 0xae, 0x80, - 0x53, 0x0b, 0xd4, 0x76, 0x50, 0x94, 0x17, 0x77, 0x54, 0xf1, 0xd9, 0x5e, 0xe0, 0xfc, 0xfe, 0x3d, - 0x1e, 0x3b, 0x5d, 0x19, 0x2b, 0xe9, 0xc1, 0xcb, 0xe5, 0xc1, 0xfd, 0x18, 0xb2, 0xb9, 0x18, 0x34, - 0xcd, 0xdd, 0xdd, 0xd8, 0x5c, 0x14, 0x2f, 0x8d, 0x13, 0x39, 0x67, 0x79, 0xe6, 0xe3, 0x42, 0xc4, - 0x2b, 0x37, 0x16, 0x91, 0xd8, 0x9f, 0x0b, 0xd6, 0xc6, 0xbf, 0xaf, 0xd6, 0xaa, 0xe8, 0x12, 0x72, - 0x62, 0x17, 0xad, 0x65, 0x39, 0xc9, 0x67, 0xef, 0xeb, 0x9e, 0xbd, 0x4d, 0xda, 0xdf, 0x27, 0xd6, - 0xe4, 0x77, 0xbb, 0x54, 0x5d, 0x57, 0x95, 0x2d, 0x97, 0x3c, 0xe2, 0xae, 0x2c, 0xde, 0xd5, 0x49, - 0xa4, 0xd5, 0xfb, 0xa0, 0x67, 0xe6, 0x47, 0x93, 0x56, 0x2f, 0x86, 0xcc, 0x16, 0x7f, 0x9f, 0xca, - 0x56, 0xca, 0x1b, 0x38, 0xdf, 0x88, 0xd5, 0x39, 0xd3, 0xb4, 0x00, 0x69, 0x82, 0xa2, 0xb3, 0x8e, - 0xa2, 0xf3, 0x04, 0x8a, 0xce, 0x1c, 0xc5, 0x42, 0x13, 0x70, 0x5e, 0xfe, 0xc0, 0x67, 0xf2, 0xac, - 0x62, 0x31, 0xd0, 0x91, 0x2a, 0xec, 0x89, 0x16, 0x6b, 0x42, 0x06, 0x01, 0x97, 0x3d, 0x0a, 0xd7, - 0x26, 0xb9, 0x80, 0xcf, 0xc2, 0xf8, 0x14, 0x67, 0xf9, 0xf0, 0xed, 0x41, 0xc0, 0x09, 0x84, 0x5c, - 0xea, 0x9a, 0x16, 0xb7, 0xbb, 0x70, 0xc6, 0x67, 0xa3, 0x9c, 0x2c, 0x76, 0x1a, 0x63, 0x12, 0x34, - 0xe0, 0xec, 0x69, 0x18, 0x02, 0x14, 0x78, 0x7c, 0x70, 0x58, 0x29, 0x97, 0xe1, 0x78, 0x64, 0x56, - 0xe7, 0xcd, 0x9d, 0xf5, 0x7e, 0x83, 0x70, 0xe1, 0x88, 0xe8, 0xc7, 0x18, 0x1b, 0xd4, 0xf7, 0x8d, - 0xc2, 0xb2, 0x65, 0x7e, 0x3b, 0x89, 0x84, 0x00, 0x4e, 0x5f, 0x3e, 0x88, 0xc7, 0xca, 0x37, 0x6b, - 0x05, 0xb0, 0xb8, 0x02, 0xb8, 0x12, 0x81, 0xda, 0x50, 0xb8, 0xf0, 0xc7, 0xf5, 0xd8, 0xb3, 0x88, - 0x49, 0x1b, 0x51, 0x68, 0x51, 0xc7, 0x50, 0x58, 0x16, 0xd0, 0x7f, 0x47, 0x5e, 0x40, 0xc1, 0xad, - 0x56, 0x29, 0x96, 0x9e, 0xa0, 0xd8, 0xfa, 0x65, 0x8a, 0xec, 0x09, 0x8a, 0xfb, 0x4f, 0x50, 0x3c, - 0xfd, 0x65, 0x8a, 0xde, 0x0a, 0xc5, 0x95, 0x33, 0xaf, 0x6a, 0xab, 0x3c, 0x50, 0xff, 0xfb, 0x77, - 0x23, 0x6e, 0x56, 0x6c, 0x36, 0x55, 0x26, 0x34, 0x0c, 0xc9, 0x88, 0xea, 0xb6, 0x4a, 0xd2, 0x28, - 0x53, 0x4d, 0x0d, 0xaa, 0x7b, 0x65, 0x13, 0x75, 0x48, 0x15, 0x39, 0x1e, 0x78, 0x23, 0x8f, 0xed, - 0xee, 0x8a, 0x9c, 0x6c, 0x8b, 0x20, 0x10, 0x4c, 0x10, 0x36, 0xa0, 0x7c, 0x88, 0x2e, 0xfa, 0xd7, - 0x50, 0x0f, 0x6e, 0xd8, 0xbe, 0x06, 0xcc, 0xf9, 0x44, 0x58, 0xab, 0x16, 0x3d, 0x9f, 0xe0, 0x2c, - 0x69, 0xfe, 0x98, 0x8f, 0xea, 0x74, 0x2f, 0xbb, 0x82, 0x05, 0xd3, 0xda, 0xda, 0xbc, 0x5b, 0xe3, - 0xc9, 0xc2, 0x7f, 0xf6, 0x7d, 0xc2, 0x6e, 0x96, 0x3b, 0x6e, 0x31, 0x36, 0x38, 0xe7, 0xa7, 0x3a, - 0x5d, 0xad, 0x70, 0x6c, 0xac, 0xfa, 0xac, 0x0d, 0x8e, 0x6c, 0xfd, 0x84, 0xd7, 0x56, 0xd6, 0x97, - 0x77, 0xb0, 0x95, 0xea, 0xa0, 0x0b, 0x72, 0x9d, 0x04, 0xfe, 0x0a, 0x5b, 0x3f, 0xe1, 0xe1, 0x95, - 0xf5, 0xe5, 0x4d, 0xfc, 0x98, 0x81, 0x1a, 0x5c, 0x37, 0x5d, 0x6b, 0x2a, 0xe9, 0x39, 0xff, 0xf0, - 0x26, 0xb2, 0xa7, 0x82, 0xa2, 0xc0, 0x37, 0xb0, 0xee, 0x07, 0x0c, 0x42, 0xf0, 0x78, 0xc8, 0xa4, - 0x1a, 0xa0, 0x96, 0xd7, 0xe7, 0x7b, 0xd9, 0xac, 0x83, 0x64, 0x2c, 0xbb, 0x2d, 0x20, 0xb7, 0x61, - 0x42, 0xca, 0x81, 0x98, 0x38, 0xc9, 0xa8, 0xac, 0x24, 0xdf, 0xfe, 0x04, 0x6b, 0xd3, 0x36, 0xd9, - 0x1d, 0x82, 0xbd, 0x51, 0x31, 0xe6, 0x30, 0x33, 0xe5, 0xa1, 0x90, 0x49, 0x3c, 0x8c, 0xfa, 0x13, - 0x4f, 0x80, 0x08, 0xae, 0x5a, 0x2a, 0xd3, 0x6f, 0x6c, 0xa4, 0x82, 0x4f, 0x21, 0xb2, 0xc4, 0x63, - 0x99, 0x78, 0x70, 0x4c, 0xfd, 0xe9, 0x09, 0x8c, 0xf5, 0xb5, 0xe3, 0x6b, 0xeb, 0xd6, 0x1f, 0x4b, - 0x25, 0xc1, 0x99, 0xc4, 0x75, 0x5c, 0xcb, 0xeb, 0x89, 0x79, 0x9e, 0x8b, 0xd7, 0x64, 0x52, 0x16, - 0x9d, 0xc8, 0x45, 0x27, 0x90, 0xdd, 0x17, 0xeb, 0x56, 0xa8, 0x68, 0x4e, 0xb1, 0xd3, 0x25, 0xb7, - 0x74, 0x01, 0x02, 0x69, 0x34, 0x13, 0xe3, 0x1f, 0x97, 0x74, 0x3b, 0x1b, 0xca, 0xad, 0x68, 0x0a, - 0xea, 0x29, 0x39, 0x6f, 0x65, 0x5e, 0x94, 0x43, 0xea, 0xa4, 0xd7, 0xe9, 0x5d, 0xc2, 0x5c, 0x70, - 0x4b, 0x83, 0x0a, 0x8a, 0x7d, 0x75, 0x2d, 0x5b, 0xcf, 0x9b, 0xe7, 0x9d, 0x9e, 0x14, 0x31, 0x70, - 0x56, 0xa0, 0x64, 0x0f, 0x75, 0xae, 0xc9, 0x4e, 0x57, 0x79, 0xae, 0x0e, 0xba, 0x70, 0xfa, 0x29, - 0x69, 0xf8, 0x8f, 0x21, 0x45, 0xa5, 0x83, 0x31, 0x92, 0x6a, 0x27, 0xa2, 0x82, 0x32, 0x29, 0x64, - 0x34, 0x92, 0xc6, 0x1b, 0xbd, 0x4a, 0x31, 0xfd, 0x1f, 0xa8, 0x6d, 0x2a, 0x6b, 0xe7, 0xbb, 0xde, - 0x27, 0x00, 0x88, 0x4f, 0x72, 0x99, 0xd8, 0x56, 0x20, 0x50, 0x68, 0x18, 0x48, 0xdd, 0x78, 0xfe, - 0x86, 0x9d, 0xb7, 0xed, 0x9e, 0xf1, 0xb1, 0xd7, 0x30, 0x93, 0x93, 0xdd, 0xda, 0x09, 0xb0, 0xa8, - 0x40, 0xf2, 0x27, 0xdd, 0x5e, 0x26, 0x0d, 0x04, 0x64, 0x68, 0x34, 0x7b, 0xf9, 0x46, 0xb3, 0xdb, - 0x4b, 0x03, 0xd9, 0xc7, 0x4e, 0x13, 0x40, 0x9a, 0xcb, 0x20, 0x99, 0x35, 0x98, 0x03, 0xec, 0x7c, - 0xec, 0x66, 0x01, 0x22, 0xdf, 0x3c, 0x4d, 0x45, 0x54, 0x56, 0x40, 0x0d, 0x00, 0x6a, 0x9c, 0xa6, - 0xa3, 0x7a, 0xa5, 0xa0, 0xda, 0x00, 0xd5, 0x4e, 0x47, 0xf5, 0x5a, 0x01, 0xd5, 0x3f, 0x6d, 0xcc, - 0xcf, 0x35, 0x76, 0xa8, 0x00, 0x2e, 0x01, 0xcb, 0x65, 0x3a, 0x16, 0xa8, 0x97, 0x81, 0x1b, 0xa3, - 0x7e, 0xd5, 0xed, 0x99, 0xa9, 0x98, 0x8a, 0x50, 0x0f, 0xbf, 0x03, 0xa8, 0xf7, 0xdb, 0x80, 0xe6, - 0x30, 0xa0, 0xe9, 0xba, 0x94, 0xbe, 0xbe, 0x4d, 0xfc, 0x04, 0x13, 0x28, 0xbb, 0xf3, 0x09, 0xa0, - 0x3a, 0x9f, 0xd2, 0x79, 0x2a, 0x82, 0xba, 0x3b, 0x10, 0x03, 0xc6, 0xe8, 0x3d, 0x87, 0xb4, 0x9c, - 0x8e, 0x0c, 0x54, 0x7e, 0xde, 0xed, 0x21, 0xe3, 0x9c, 0xb9, 0x1e, 0x49, 0xe7, 0x0c, 0x94, 0xde, - 0xa8, 0x67, 0xbb, 0x24, 0xbc, 0x21, 0x02, 0x6c, 0x71, 0x46, 0x58, 0xaa, 0xe6, 0x8b, 0xa0, 0xfa, - 0x7a, 0x23, 0xdd, 0x10, 0x8a, 0xaf, 0xf5, 0x7c, 0xbe, 0xde, 0x78, 0x4a, 0x4a, 0x50, 0xfd, 0x99, - 0x64, 0xec, 0x8c, 0xcc, 0x88, 0xe7, 0xa5, 0x73, 0x06, 0xda, 0xef, 0x5c, 0xfc, 0x01, 0x80, 0x1d, - 0x7e, 0xcb, 0x43, 0xaf, 0xef, 0x05, 0xe1, 0x8d, 0x99, 0xca, 0x5c, 0x09, 0xb6, 0xa1, 0xfe, 0x5e, - 0x12, 0x7f, 0x7f, 0x0a, 0x6b, 0xea, 0x6c, 0x30, 0x56, 0xbd, 0xf2, 0x54, 0xfc, 0x25, 0xd8, 0x93, - 0xf6, 0x3f, 0xa5, 0xb9, 0xa5, 0x1b, 0x3f, 0x6c, 0xc8, 0xe5, 0x7b, 0xc0, 0x76, 0x49, 0x6e, 0x3c, - 0x99, 0x06, 0x97, 0x90, 0x25, 0xdd, 0x11, 0xe9, 0xe1, 0xbd, 0x06, 0xe2, 0xc3, 0x21, 0x84, 0x98, - 0x85, 0x77, 0x6b, 0x67, 0xfd, 0x78, 0xb1, 0xfd, 0x4c, 0xf6, 0xaa, 0x2c, 0x2f, 0xfb, 0x74, 0x9e, - 0x8f, 0xdf, 0x93, 0xe4, 0x9e, 0x01, 0x5f, 0x1e, 0x70, 0xe6, 0x86, 0xc8, 0x80, 0xf9, 0x1c, 0x2a, - 0x1e, 0xa2, 0x31, 0x8f, 0x82, 0xd0, 0x94, 0xa4, 0x1a, 0x51, 0x10, 0x40, 0x62, 0x47, 0xea, 0x3a, - 0x40, 0x87, 0x31, 0x2f, 0x84, 0x08, 0x01, 0xe5, 0x73, 0x12, 0xa2, 0x61, 0x30, 0xc4, 0x4e, 0xc4, - 0x6e, 0x18, 0x9f, 0x31, 0x99, 0x43, 0x60, 0xd2, 0xc9, 0xc9, 0xd5, 0x2d, 0x22, 0x3c, 0x11, 0xb9, - 0x1b, 0x31, 0x05, 0xb2, 0x1c, 0x5e, 0x17, 0xbe, 0x03, 0xea, 0x4f, 0xdd, 0xc4, 0x2e, 0x96, 0x67, - 0xa1, 0x0d, 0x5d, 0x2c, 0x8b, 0xde, 0xea, 0xa5, 0xd4, 0x39, 0x77, 0xfe, 0xa2, 0xd0, 0xc9, 0x68, - 0x0d, 0xbc, 0xca, 0xbd, 0x92, 0xe7, 0x3a, 0x3a, 0x85, 0xc1, 0x5c, 0xa1, 0xa8, 0x23, 0x60, 0x8b, - 0xb3, 0xd1, 0x76, 0x6e, 0x3b, 0x9b, 0xdc, 0x36, 0x21, 0x08, 0xa5, 0xee, 0xe3, 0x15, 0x96, 0x27, - 0xbc, 0xa7, 0xb9, 0xed, 0xac, 0x73, 0x9b, 0xd9, 0xc2, 0xae, 0xe2, 0xb6, 0x28, 0x7b, 0x4d, 0xeb, - 0xcc, 0x6e, 0xcf, 0x7d, 0x32, 0xdb, 0xc2, 0x4e, 0xf5, 0x05, 0xbc, 0x67, 0x92, 0x9c, 0x36, 0x2f, - 0xd9, 0xb0, 0x4a, 0x45, 0xf3, 0x8b, 0xa5, 0x45, 0xf6, 0x52, 0x79, 0xcb, 0x73, 0x32, 0x86, 0x2c, - 0x8c, 0x42, 0xc4, 0xe8, 0x0c, 0xc1, 0xf1, 0xd0, 0x92, 0xf9, 0xfc, 0x1e, 0xcd, 0x78, 0x70, 0x13, - 0x42, 0x55, 0x86, 0xfa, 0xb2, 0xc2, 0xa7, 0x01, 0x98, 0xa4, 0x37, 0xcf, 0xa5, 0xf3, 0x63, 0x72, - 0x18, 0x31, 0xbc, 0x66, 0x0d, 0x49, 0x3a, 0xdc, 0x77, 0x1a, 0xf2, 0x9e, 0x00, 0x32, 0xe1, 0xbe, - 0x53, 0x67, 0xc4, 0xe7, 0x23, 0xa4, 0x06, 0x10, 0x87, 0x14, 0x28, 0xcf, 0xd3, 0xe8, 0xc9, 0xf4, - 0x74, 0xd1, 0xd2, 0x92, 0x8c, 0x09, 0x1b, 0xc9, 0x6c, 0x15, 0xaa, 0x02, 0x41, 0x2a, 0x60, 0x4e, - 0x5c, 0x5e, 0x56, 0x38, 0x6f, 0xc0, 0x59, 0x05, 0x6a, 0x35, 0x4f, 0x13, 0x74, 0xf1, 0xf2, 0xe2, - 0x86, 0x9a, 0xd7, 0x6a, 0xde, 0xf2, 0x92, 0x27, 0xa0, 0x16, 0xd9, 0x8e, 0xa5, 0x94, 0xd6, 0xa2, - 0xc8, 0x6c, 0xc1, 0x22, 0xb9, 0x2b, 0x96, 0xc6, 0xdb, 0xf0, 0xb4, 0x7f, 0x16, 0x4f, 0x77, 0xcc, - 0x67, 0xa8, 0x0c, 0x50, 0xc0, 0x2e, 0xec, 0xc3, 0x73, 0xca, 0x2a, 0x6b, 0xdd, 0x64, 0xba, 0x73, - 0x87, 0x26, 0x21, 0x12, 0x01, 0xf1, 0x7c, 0xf3, 0xb9, 0x95, 0xdd, 0x58, 0xab, 0x6a, 0xd7, 0x1a, - 0x3c, 0x62, 0x02, 0x2a, 0x65, 0xa6, 0xee, 0x08, 0x9f, 0xad, 0x20, 0x9a, 0x7a, 0xed, 0x62, 0xd5, - 0x5b, 0x4e, 0xfc, 0x8a, 0x1c, 0x3a, 0x85, 0xca, 0xba, 0xb2, 0xcb, 0xfa, 0xe1, 0xb4, 0x5a, 0x83, - 0xe0, 0x10, 0x90, 0xa9, 0x53, 0x2a, 0xac, 0x46, 0xac, 0xc6, 0xbf, 0x7e, 0xf4, 0xca, 0xe3, 0xe8, - 0x68, 0x49, 0x39, 0xd9, 0x18, 0x49, 0x5c, 0x2b, 0x35, 0xce, 0x7f, 0xb4, 0x47, 0x0c, 0x49, 0x6f, - 0x13, 0x4b, 0x8c, 0xe4, 0x74, 0xc9, 0x0b, 0x9f, 0xed, 0x34, 0x2f, 0x6d, 0x54, 0x3e, 0x96, 0x6d, - 0x5e, 0x47, 0xc5, 0x22, 0x67, 0xe6, 0x32, 0xaf, 0x52, 0x39, 0xfb, 0xe1, 0xcb, 0xa2, 0xfd, 0x25, - 0x22, 0x95, 0x35, 0xb5, 0xb5, 0x7f, 0xe2, 0xa6, 0x68, 0x09, 0xcb, 0x9a, 0xda, 0xba, 0xbf, 0x84, - 0x65, 0x45, 0x60, 0xe9, 0xe2, 0x99, 0xb6, 0x6c, 0x05, 0xa0, 0xa9, 0xba, 0xb6, 0x0b, 0x95, 0xaf, - 0xd7, 0xfa, 0x8e, 0x1a, 0x0c, 0xd1, 0x18, 0x4a, 0x65, 0x34, 0x01, 0x77, 0x77, 0x77, 0x20, 0xe6, - 0xc4, 0x25, 0xad, 0x93, 0xd1, 0x77, 0x7c, 0x10, 0x6e, 0xc0, 0xc2, 0x89, 0x1f, 0x72, 0x34, 0x80, - 0x94, 0xd2, 0xa7, 0x28, 0x0a, 0xa9, 0x8b, 0xc0, 0x6e, 0x75, 0x77, 0x41, 0xde, 0x37, 0x84, 0x12, - 0x41, 0x9f, 0x43, 0x09, 0xf2, 0xae, 0x7b, 0xd1, 0x41, 0x84, 0xb9, 0xe8, 0xac, 0x07, 0x65, 0x74, - 0xfd, 0xf2, 0x1c, 0x0d, 0xf8, 0x64, 0x02, 0x03, 0x61, 0x2e, 0x23, 0xf1, 0xbe, 0x8b, 0xc0, 0x7f, - 0xf5, 0x55, 0xb6, 0x18, 0xd3, 0x98, 0x1f, 0x74, 0x7e, 0x0a, 0x78, 0x7d, 0x3e, 0xdb, 0x91, 0xa1, - 0x0b, 0x49, 0xda, 0xb2, 0x44, 0x2e, 0xc8, 0x02, 0x59, 0x81, 0xb9, 0x74, 0x48, 0x22, 0x5f, 0x20, - 0x7d, 0xf1, 0xab, 0x4e, 0xa0, 0x70, 0xa8, 0x91, 0xd7, 0xfa, 0x24, 0x46, 0xa1, 0x62, 0x1e, 0xe0, - 0xaf, 0xfb, 0xf4, 0x8e, 0xa0, 0x0b, 0x96, 0xbf, 0x18, 0x0e, 0x91, 0x16, 0x60, 0x3d, 0x03, 0xd7, - 0x0b, 0x89, 0x4a, 0x27, 0xcf, 0x36, 0x36, 0x97, 0x42, 0xcf, 0xea, 0xc6, 0xd4, 0x8b, 0xbf, 0x84, - 0x45, 0x39, 0x7f, 0xe2, 0x87, 0xd9, 0x0b, 0x08, 0xb1, 0x09, 0x9b, 0xab, 0x8d, 0x81, 0xc6, 0xf3, - 0xf8, 0x33, 0x29, 0x04, 0xa4, 0x85, 0xbb, 0xd9, 0x96, 0x37, 0x1a, 0x8b, 0x65, 0x0a, 0xe1, 0x3a, - 0x89, 0xce, 0x32, 0x89, 0xcc, 0x4f, 0xc9, 0x20, 0x6d, 0x2a, 0xee, 0xea, 0xe8, 0x4d, 0x89, 0x6d, - 0x4a, 0x75, 0x2d, 0x51, 0x26, 0xee, 0xc8, 0x42, 0x48, 0x1c, 0x79, 0xac, 0x52, 0x40, 0x24, 0x12, - 0x5c, 0x27, 0xbf, 0xb8, 0x25, 0xe5, 0xac, 0xdc, 0x3b, 0xbb, 0xce, 0x34, 0x0a, 0xc7, 0x12, 0x6f, - 0x38, 0xf3, 0xa0, 0xe8, 0xd4, 0xbd, 0x4e, 0xf8, 0x1f, 0x42, 0xc9, 0x26, 0x94, 0xe1, 0x70, 0x96, - 0xdd, 0x1d, 0x89, 0x2a, 0x14, 0x55, 0xc9, 0xa4, 0x0f, 0xe5, 0x80, 0x9a, 0x1a, 0x0e, 0xf5, 0x1c, - 0x4b, 0xa6, 0x5c, 0x1e, 0x01, 0x1f, 0x72, 0xb2, 0x93, 0xaf, 0x2f, 0x3a, 0xa7, 0x99, 0xf9, 0xed, - 0x74, 0x4d, 0xc8, 0xf3, 0xb0, 0x1c, 0x9c, 0xff, 0xd5, 0xdd, 0x56, 0x82, 0x32, 0xe3, 0x80, 0x0e, - 0xed, 0xa7, 0x7f, 0x38, 0xa4, 0x65, 0xc8, 0xbf, 0x20, 0x2a, 0x5b, 0x66, 0xe7, 0xb9, 0x5d, 0x80, - 0xb4, 0xf2, 0xa7, 0x53, 0x71, 0x7b, 0xc2, 0xc9, 0xc4, 0xd9, 0x34, 0xd6, 0x53, 0x7c, 0xde, 0x24, - 0x4a, 0x77, 0x72, 0x8b, 0xb2, 0xf2, 0x17, 0x5d, 0x01, 0xf7, 0x01, 0xfd, 0xaa, 0x63, 0xaa, 0x93, - 0xf4, 0x5a, 0x53, 0xdb, 0x63, 0xbe, 0xc7, 0x68, 0x56, 0x5f, 0xe9, 0xcf, 0xf5, 0x2c, 0x15, 0x2a, - 0xdb, 0xc0, 0xf3, 0x0e, 0x38, 0x6c, 0x9a, 0xfe, 0x41, 0x58, 0x65, 0x7f, 0xbf, 0x30, 0xd5, 0x6d, - 0x65, 0x25, 0x58, 0x92, 0xec, 0x83, 0xe7, 0xce, 0xe4, 0xe9, 0xc7, 0xeb, 0xcc, 0x53, 0xe7, 0xeb, - 0xbc, 0x3c, 0xcb, 0xc2, 0x9f, 0x58, 0x9d, 0xea, 0x87, 0x6f, 0xff, 0x05, 0xfa, 0xb4, 0x61, 0x24, - 0x08, 0x27, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_sec.htm, do not edit!! -const uint16_t PAGE_settings_sec_length = 2563; -const uint8_t PAGE_settings_sec[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x9d, 0x58, 0x6d, 0x73, 0xdb, 0xb8, - 0x11, 0xfe, 0xae, 0x5f, 0x01, 0xe1, 0x66, 0x72, 0x64, 0x43, 0x53, 0xb2, 0x93, 0xde, 0xe4, 0x6c, - 0x51, 0xae, 0x1d, 0x3b, 0x8d, 0x3b, 0x76, 0xec, 0xb1, 0xe4, 0x4b, 0x3b, 0x69, 0x26, 0x43, 0x91, - 0x90, 0x88, 0x88, 0x22, 0x78, 0x00, 0x68, 0x45, 0xcd, 0xe5, 0xbf, 0xf7, 0x59, 0x90, 0xd4, 0x8b, - 0x63, 0xdf, 0xf5, 0xfa, 0xc1, 0x16, 0x89, 0xb7, 0xdd, 0x7d, 0x76, 0xf7, 0xd9, 0x05, 0x07, 0xdd, - 0xb3, 0xeb, 0xd7, 0xe3, 0x7f, 0xdd, 0x9c, 0xb3, 0xcc, 0x2e, 0xf2, 0xe1, 0x80, 0xfe, 0xb3, 0x3c, - 0x2e, 0x66, 0x11, 0x17, 0x05, 0xc7, 0xbb, 0x88, 0xd3, 0xe1, 0x60, 0x21, 0x6c, 0xcc, 0x8a, 0x78, - 0x21, 0x22, 0x7e, 0x2f, 0xc5, 0xb2, 0x54, 0xda, 0x72, 0x96, 0xa8, 0xc2, 0x8a, 0xc2, 0x46, 0x7c, - 0x29, 0x53, 0x9b, 0x45, 0x7f, 0xed, 0xf7, 0xf9, 0xb0, 0x53, 0x2f, 0xed, 0x3c, 0x98, 0x4b, 0xc5, - 0xbd, 0x4c, 0xc4, 0x9e, 0x7b, 0x09, 0x64, 0x21, 0xad, 0x8c, 0xf3, 0x3d, 0x93, 0xc4, 0xb9, 0x88, - 0xf6, 0x83, 0x45, 0xfc, 0x45, 0x2e, 0xaa, 0xc5, 0xfa, 0xbd, 0x32, 0x42, 0xbb, 0x97, 0x78, 0x82, - 0xf7, 0x42, 0x71, 0xd6, 0x79, 0x20, 0xba, 0x51, 0x28, 0xc9, 0x62, 0x6d, 0x04, 0x84, 0x54, 0x76, - 0xba, 0xf7, 0x0a, 0xa3, 0x56, 0xda, 0x5c, 0x0c, 0xaf, 0xa4, 0x49, 0xd8, 0x48, 0x58, 0x2b, 0x8b, - 0x99, 0x19, 0xf4, 0xea, 0xc1, 0x81, 0x49, 0xb4, 0x2c, 0xed, 0xb0, 0x73, 0x1f, 0x6b, 0x96, 0xab, - 0x44, 0x96, 0x81, 0x95, 0x0b, 0xa1, 0x2a, 0x1b, 0xa4, 0x51, 0xaa, 0x92, 0x6a, 0x01, 0x75, 0x03, - 0x4c, 0x44, 0xdd, 0x7d, 0xfa, 0x29, 0xb5, 0xb2, 0x2a, 0xe2, 0x99, 0xb5, 0xe5, 0x21, 0x3f, 0x9a, - 0x56, 0x45, 0x62, 0xa5, 0x2a, 0xd8, 0x5b, 0xcf, 0xff, 0xba, 0x94, 0x45, 0xaa, 0x96, 0xa1, 0x2a, - 0x45, 0xe1, 0xb9, 0x05, 0xe6, 0xb0, 0xd7, 0x9b, 0x17, 0x2a, 0x5c, 0xe6, 0x22, 0x0d, 0x67, 0xa2, - 0x37, 0x15, 0xb1, 0xad, 0xb4, 0x30, 0x3d, 0xd3, 0x28, 0xd1, 0xfb, 0xc1, 0x88, 0xa4, 0xd2, 0xd2, - 0xae, 0xf6, 0xda, 0x21, 0xee, 0x7f, 0x5b, 0x1f, 0x7a, 0xfa, 0xe0, 0xd0, 0x99, 0xb0, 0x77, 0xb7, - 0x97, 0x1e, 0xef, 0x6d, 0x16, 0x07, 0xfc, 0x93, 0x11, 0xf9, 0x74, 0x7b, 0xd7, 0xdd, 0x53, 0xbb, - 0xaa, 0x32, 0x8d, 0xad, 0x78, 0x74, 0xcf, 0xec, 0x22, 0xf5, 0xac, 0xff, 0x55, 0x0b, 0xe8, 0x57, - 0x30, 0x52, 0xd6, 0x9e, 0xe7, 0x82, 0x4c, 0x3f, 0x5d, 0xb9, 0xa9, 0xcd, 0x52, 0x69, 0xae, 0x27, - 0x9f, 0xb7, 0x16, 0xdb, 0x67, 0xcf, 0xb8, 0x9a, 0x7c, 0x16, 0x89, 0xe5, 0x51, 0x64, 0x57, 0xa5, - 0x50, 0x53, 0x1a, 0xeb, 0x9e, 0x68, 0x1d, 0xaf, 0x42, 0x69, 0xdc, 0xef, 0xce, 0x09, 0xb9, 0x8a, - 0xd3, 0x7f, 0x8c, 0x3c, 0x1b, 0x88, 0xa8, 0xdb, 0xf7, 0xbf, 0xe6, 0xc2, 0x32, 0x15, 0xa5, 0x61, - 0xa2, 0x01, 0x8f, 0x68, 0xc4, 0x7a, 0xbc, 0xf6, 0x0b, 0xf7, 0x8f, 0x54, 0x08, 0x73, 0x4f, 0xac, - 0xd5, 0x72, 0x52, 0x59, 0x81, 0x09, 0x9d, 0xf0, 0xc0, 0xfa, 0xc1, 0xc3, 0x71, 0x92, 0xcd, 0x03, - 0x6e, 0xc5, 0x17, 0xdb, 0xfb, 0x1c, 0xdf, 0xc7, 0xed, 0x01, 0xdf, 0x2d, 0x8c, 0xcd, 0xaa, 0xc0, - 0x11, 0xc2, 0x0f, 0xd2, 0x70, 0xa2, 0xd2, 0x55, 0x18, 0x97, 0xc0, 0x29, 0x7d, 0x9d, 0xc9, 0x3c, - 0xf5, 0x14, 0xad, 0x8f, 0xd3, 0xf4, 0xfc, 0x1e, 0x5a, 0x5c, 0x4a, 0x83, 0x68, 0x15, 0xda, 0xe3, - 0xa4, 0x33, 0x0f, 0x3c, 0x3f, 0x1a, 0x7e, 0xfd, 0xbb, 0xb0, 0xbf, 0x78, 0x7e, 0x80, 0x33, 0x4f, - 0x93, 0xf9, 0x1b, 0x99, 0x0b, 0x0a, 0x42, 0x8f, 0x10, 0xe4, 0x93, 0x64, 0x9e, 0x4c, 0x67, 0xdc, - 0x7f, 0x72, 0xb6, 0x84, 0xf7, 0x85, 0x85, 0xdf, 0xfc, 0x6f, 0x8f, 0xcb, 0x11, 0x5a, 0x2b, 0x0d, - 0xf3, 0x20, 0x07, 0xa9, 0x62, 0x54, 0x2e, 0xc2, 0x5c, 0xcd, 0x3c, 0x7e, 0x4e, 0xe3, 0xac, 0x01, - 0x0f, 0xae, 0x67, 0x53, 0x1c, 0xed, 0x60, 0x40, 0x6e, 0x68, 0xc0, 0x75, 0xd9, 0x8c, 0x03, 0x7d, - 0x6c, 0x9c, 0xca, 0x59, 0xa5, 0x63, 0x87, 0x76, 0x0d, 0x03, 0x9b, 0xc6, 0x92, 0xa2, 0xf0, 0xdf, - 0xc5, 0x45, 0x91, 0xa8, 0x45, 0x09, 0xd0, 0x05, 0x2b, 0xe3, 0x99, 0x60, 0x88, 0x89, 0xb8, 0x8b, - 0x58, 0xd8, 0x72, 0x90, 0xc9, 0xd4, 0x72, 0xac, 0x62, 0x63, 0x6b, 0x1f, 0xed, 0xfb, 0x5f, 0x29, - 0x39, 0x54, 0xe4, 0xac, 0xb0, 0x34, 0xe1, 0xdc, 0x22, 0x0b, 0xa8, 0xfc, 0x76, 0x7c, 0x75, 0x19, - 0x59, 0xd8, 0x92, 0xe4, 0xb1, 0x31, 0x64, 0x08, 0x59, 0xe5, 0x89, 0xe3, 0xc6, 0x94, 0x43, 0x4e, - 0xa7, 0xc1, 0x0b, 0x49, 0x2e, 0x62, 0x3d, 0xae, 0x53, 0xcb, 0x6b, 0x52, 0xcc, 0xf9, 0xc6, 0xae, - 0x60, 0x64, 0x5c, 0xc8, 0x85, 0xd3, 0x37, 0xe2, 0x85, 0x2a, 0xc8, 0xb2, 0x7a, 0x45, 0x04, 0xb8, - 0xda, 0x4d, 0x5e, 0xab, 0x20, 0x02, 0x7c, 0x5b, 0x9e, 0x16, 0x0b, 0x75, 0x4f, 0x81, 0xe1, 0x04, - 0x01, 0xd8, 0x83, 0x9f, 0xfb, 0xfd, 0x2d, 0x73, 0xaa, 0x92, 0x40, 0x23, 0x5f, 0x90, 0x3d, 0xad, - 0x31, 0x85, 0x58, 0xb2, 0x7f, 0x5e, 0x5d, 0xbe, 0x45, 0x9e, 0xde, 0x8a, 0x5f, 0x2b, 0x61, 0xec, - 0xd1, 0xef, 0x38, 0x7e, 0x4b, 0xf4, 0x16, 0x3a, 0x99, 0x34, 0x90, 0x6e, 0x4a, 0x78, 0x4a, 0x8c, - 0x11, 0x77, 0x81, 0x1b, 0x31, 0x16, 0x69, 0x6e, 0x86, 0xd1, 0x4b, 0xd2, 0xc2, 0xff, 0x5d, 0x3f, - 0x6f, 0xce, 0xb5, 0x3b, 0x07, 0xd3, 0x19, 0xc9, 0x3c, 0xe8, 0xb6, 0x07, 0xd4, 0x9c, 0x72, 0x73, - 0x3d, 0x1a, 0xf3, 0x60, 0x2b, 0x9f, 0x9d, 0x72, 0xbe, 0x7f, 0x44, 0x16, 0x15, 0xce, 0xa2, 0x37, - 0x4a, 0x2f, 0xce, 0xe0, 0xd1, 0xa3, 0x26, 0x3b, 0x8b, 0x26, 0xb8, 0x3d, 0x4e, 0x7e, 0x06, 0xac, - 0x21, 0x05, 0x8e, 0xf9, 0xd0, 0xff, 0x48, 0xf1, 0x4f, 0x99, 0x81, 0xb9, 0xc2, 0xc7, 0xf8, 0x7d, - 0x9c, 0x57, 0xe0, 0x52, 0x1e, 0x74, 0xf7, 0x37, 0xd0, 0x25, 0x99, 0x48, 0xe6, 0xef, 0xaa, 0xc5, - 0x26, 0xdf, 0xbb, 0x5e, 0x57, 0x90, 0x29, 0xe1, 0x5c, 0xac, 0x42, 0xb8, 0x2c, 0xc9, 0xbc, 0xde, - 0x87, 0xfe, 0xde, 0xcf, 0x1f, 0x7b, 0x3e, 0x92, 0xfe, 0x03, 0x3f, 0x85, 0xde, 0xa6, 0x8c, 0x13, - 0x4a, 0xc5, 0x71, 0x3c, 0xc1, 0xff, 0x73, 0x30, 0x3e, 0x4c, 0xe5, 0xa3, 0x4c, 0x4e, 0x2d, 0x7e, - 0x5f, 0xa3, 0x04, 0x68, 0x95, 0xe3, 0xe9, 0x24, 0xa7, 0xf7, 0x9b, 0x18, 0xc4, 0x4e, 0xe3, 0x71, - 0x69, 0x2e, 0x55, 0x32, 0xa7, 0x2d, 0x60, 0x79, 0x97, 0xcc, 0xa3, 0xe6, 0xa4, 0x1b, 0x44, 0xea, - 0x5d, 0xd9, 0x3c, 0x9c, 0xa9, 0x65, 0xe1, 0xce, 0x85, 0x63, 0xf8, 0x5b, 0xb5, 0xa0, 0x05, 0x60, - 0x19, 0xb5, 0xbc, 0x14, 0x4e, 0x80, 0x7b, 0x76, 0xab, 0xdd, 0xd3, 0xad, 0x9c, 0x65, 0xeb, 0xe1, - 0x66, 0xef, 0x05, 0x1c, 0xa6, 0x69, 0xf0, 0x4c, 0x50, 0x26, 0xf0, 0x8f, 0x08, 0xe6, 0x24, 0xaf, - 0x52, 0x61, 0xbc, 0xb5, 0x75, 0xbe, 0xff, 0xdb, 0x6f, 0xcd, 0x1b, 0xd2, 0x96, 0x7e, 0xcf, 0xc4, - 0x34, 0xae, 0x72, 0x8b, 0xe4, 0x47, 0x4e, 0x6c, 0xa5, 0xcb, 0x6e, 0xae, 0x03, 0x2a, 0xfb, 0x80, - 0x71, 0xc0, 0xc5, 0x45, 0x1d, 0x48, 0x9c, 0x6a, 0xc1, 0x27, 0xfe, 0xdc, 0x12, 0xc5, 0x3e, 0xb6, - 0xc2, 0x7f, 0xee, 0xf1, 0xf7, 0x97, 0xe7, 0x67, 0x20, 0x53, 0x93, 0x1e, 0x73, 0xe4, 0x0f, 0x56, - 0x9b, 0xd4, 0xdf, 0x92, 0x37, 0xf2, 0x6a, 0xd2, 0xb4, 0x51, 0x43, 0xf3, 0x28, 0x4b, 0x2e, 0x77, - 0x8e, 0xe4, 0xd4, 0xe3, 0xe4, 0xdf, 0x43, 0xa2, 0xe2, 0xd0, 0x95, 0xaa, 0x44, 0xe5, 0xbe, 0xab, - 0x5e, 0xfd, 0xc0, 0x73, 0xe5, 0x2d, 0xa2, 0xd5, 0xf9, 0xc8, 0x2a, 0x0d, 0x28, 0x49, 0x8b, 0x0b, - 0x2b, 0x16, 0x14, 0xe7, 0xc9, 0x45, 0xc9, 0x9d, 0xcd, 0xf5, 0x32, 0xec, 0x5e, 0x94, 0x20, 0x16, - 0xb2, 0x8b, 0x5d, 0xa9, 0x54, 0x84, 0xec, 0x06, 0x29, 0x6c, 0x04, 0x13, 0xe4, 0x50, 0x46, 0x4a, - 0xb2, 0x8b, 0x1b, 0x50, 0x47, 0xb0, 0x73, 0xa2, 0xd9, 0x3d, 0x31, 0x70, 0xa7, 0x21, 0x46, 0x45, - 0x6e, 0x84, 0x53, 0x5b, 0x90, 0x6a, 0xb1, 0xcd, 0x08, 0xac, 0x40, 0x45, 0xd8, 0x91, 0xa3, 0x07, - 0xf0, 0xf6, 0x03, 0x11, 0x22, 0x18, 0xcd, 0x7b, 0x69, 0x33, 0x04, 0x37, 0xf7, 0x8f, 0xf7, 0xf6, - 0x0f, 0xef, 0x95, 0x4c, 0x59, 0xdf, 0x0f, 0x4d, 0x99, 0x4b, 0xeb, 0x46, 0x91, 0xa4, 0xc0, 0x79, - 0x66, 0xb3, 0xe1, 0xc1, 0xb3, 0x67, 0xde, 0xba, 0x20, 0x6f, 0xac, 0x0d, 0x1a, 0x6b, 0x6b, 0x2b, - 0x6c, 0x98, 0x29, 0x63, 0x49, 0xd4, 0x73, 0x64, 0x15, 0x35, 0x09, 0xc7, 0x80, 0xf4, 0x79, 0xfd, - 0x78, 0xc8, 0x01, 0x37, 0x0e, 0x7d, 0xae, 0x90, 0x0f, 0xfe, 0x37, 0xec, 0xc0, 0x91, 0x3b, 0x44, - 0xfe, 0xc0, 0x8f, 0x99, 0x16, 0xd3, 0x75, 0x02, 0xee, 0x2e, 0x6c, 0x2d, 0x42, 0xba, 0x7e, 0x47, - 0xf6, 0xff, 0xcb, 0x29, 0x9b, 0xc5, 0x9b, 0x93, 0x08, 0x59, 0x57, 0x2a, 0xbf, 0x2b, 0xfc, 0x3d, - 0x13, 0x7e, 0x36, 0xc7, 0x65, 0xf4, 0x13, 0x77, 0xb1, 0x18, 0xd4, 0xaa, 0xa7, 0xe1, 0x68, 0x1a, - 0xc6, 0x2e, 0x48, 0xa2, 0x47, 0xb6, 0x88, 0x84, 0x6f, 0x87, 0x51, 0xb3, 0x62, 0x9d, 0xd9, 0x04, - 0xe6, 0x71, 0x0b, 0x28, 0x60, 0x01, 0x2e, 0x0e, 0x43, 0x87, 0x92, 0xfd, 0xd6, 0x19, 0xf4, 0x9a, - 0x56, 0x69, 0xe0, 0x28, 0x7b, 0xf8, 0x37, 0xb9, 0x20, 0x10, 0x59, 0xa5, 0x73, 0x70, 0xaf, 0x63, - 0xf1, 0xc4, 0xc0, 0x80, 0x23, 0x2c, 0x74, 0x0b, 0x06, 0xbd, 0xba, 0x49, 0xa4, 0x1a, 0x8b, 0xd2, - 0x45, 0xb6, 0x44, 0x1c, 0xc1, 0x8b, 0x86, 0x6c, 0x0a, 0x9a, 0xea, 0x30, 0x89, 0x77, 0x7a, 0xfa, - 0x64, 0x78, 0xd3, 0x44, 0x8e, 0xa6, 0x9c, 0xa1, 0x85, 0xcb, 0x14, 0x66, 0x4a, 0x38, 0x0e, 0x4b, - 0x53, 0x79, 0xcf, 0x1c, 0xd7, 0x47, 0x28, 0x3d, 0xd0, 0x6d, 0xb9, 0x3b, 0x96, 0x89, 0xbc, 0x3c, - 0xa5, 0xfe, 0x12, 0xd8, 0x5a, 0x58, 0x45, 0x5d, 0x40, 0xc4, 0xeb, 0x17, 0x0e, 0xa9, 0x09, 0x82, - 0x6b, 0x1e, 0xf1, 0xb7, 0x24, 0xf6, 0x78, 0xd0, 0xab, 0x27, 0xa0, 0x1a, 0x8e, 0x18, 0x3e, 0xbe, - 0xa7, 0xb3, 0xde, 0x74, 0x4a, 0x9b, 0x88, 0xd0, 0x36, 0xfb, 0x76, 0x76, 0x98, 0x6a, 0xb2, 0x90, - 0xd0, 0x71, 0x14, 0xdf, 0x8b, 0xcd, 0x92, 0x4c, 0xb7, 0xc7, 0x67, 0x07, 0xc3, 0xce, 0xa8, 0x69, - 0xf0, 0xd8, 0x33, 0x76, 0xe7, 0xfa, 0x2f, 0xa2, 0x8b, 0xaa, 0x04, 0x36, 0x07, 0xc3, 0xb6, 0x17, - 0x65, 0x37, 0x17, 0xef, 0x0e, 0xd9, 0x40, 0x16, 0x65, 0x65, 0x9b, 0xa3, 0x4b, 0x18, 0xb7, 0x54, - 0x3a, 0xe5, 0x0e, 0x24, 0xcc, 0xaf, 0x9b, 0x5d, 0xf7, 0x6c, 0xe4, 0x7f, 0xf0, 0xf8, 0x12, 0x60, - 0xc5, 0x5f, 0xea, 0x74, 0xa8, 0xdf, 0x64, 0xb1, 0xf5, 0xa6, 0x0a, 0xb0, 0x18, 0x11, 0x4b, 0xc4, - 0x37, 0x3c, 0x8e, 0x02, 0xe5, 0xe3, 0x2c, 0x04, 0x19, 0x92, 0x18, 0x33, 0x8e, 0xbb, 0xff, 0x02, - 0x31, 0x24, 0x7c, 0x81, 0x34, 0x47, 0x01, 0x46, 0xcf, 0xab, 0x65, 0xc2, 0x99, 0xeb, 0x90, 0x21, - 0x71, 0x3b, 0xed, 0x63, 0xf6, 0x92, 0xa5, 0x72, 0x26, 0x2d, 0xc3, 0xb2, 0x09, 0x88, 0x1d, 0x98, - 0x68, 0xc0, 0xbf, 0xe5, 0x92, 0x65, 0xac, 0x71, 0x43, 0xe8, 0x3c, 0xfb, 0xe1, 0xe7, 0x57, 0xaf, - 0x5e, 0x1d, 0xb1, 0xbb, 0x42, 0x14, 0x89, 0x5e, 0x95, 0x56, 0xa4, 0xcc, 0xea, 0xb8, 0x30, 0x0b, - 0x69, 0x0c, 0x02, 0x30, 0x64, 0xa7, 0x68, 0x41, 0x34, 0x48, 0xb7, 0xb0, 0x6c, 0x99, 0x09, 0x22, - 0xd2, 0x1c, 0x6d, 0x24, 0x75, 0x31, 0x30, 0x32, 0x60, 0xa9, 0x62, 0xef, 0xae, 0xc7, 0x0c, 0xd5, - 0x81, 0xad, 0x54, 0xa5, 0xd9, 0x24, 0x2e, 0xe6, 0x98, 0xa4, 0x09, 0xa5, 0x03, 0x36, 0xba, 0xb8, - 0x0a, 0x98, 0xb0, 0x49, 0xc8, 0x4a, 0x59, 0x74, 0x3b, 0xad, 0x4b, 0xf5, 0x90, 0x8a, 0x08, 0x5b, - 0x4a, 0x8d, 0xd3, 0x8c, 0x61, 0xde, 0xf5, 0xf8, 0xc4, 0x67, 0x46, 0x4d, 0x2d, 0xf4, 0x12, 0xac, - 0x6e, 0x82, 0x1f, 0xa0, 0xed, 0xe0, 0x99, 0xa8, 0x2f, 0x6d, 0x18, 0xbe, 0xbb, 0x76, 0x11, 0xa5, - 0x87, 0x37, 0x30, 0xa8, 0xcc, 0x34, 0xcc, 0x7f, 0xd2, 0x3f, 0xf5, 0x8e, 0xeb, 0x9b, 0x1d, 0x5f, - 0xbc, 0x38, 0x68, 0x70, 0x19, 0x2b, 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, 0x5a, 0x71, 0x5d, 0xa7, 0xd5, - 0x38, 0x13, 0xeb, 0x11, 0x6a, 0xd6, 0xaa, 0x3c, 0x65, 0x13, 0x41, 0xd7, 0x9e, 0x62, 0x86, 0x63, - 0x1c, 0x96, 0x10, 0x87, 0x56, 0xbd, 0x11, 0x9e, 0x86, 0xb4, 0x6d, 0x30, 0x19, 0x76, 0xce, 0xa4, - 0x69, 0xb5, 0xa9, 0xd7, 0x15, 0xca, 0xc2, 0xf7, 0x04, 0x72, 0xc0, 0x14, 0x44, 0xea, 0xa5, 0x04, - 0xde, 0x71, 0xc1, 0x10, 0x20, 0x88, 0x7c, 0xe8, 0x91, 0xe0, 0x05, 0x8c, 0x05, 0xdf, 0x66, 0xac, - 0xbe, 0xaf, 0xad, 0xd1, 0x24, 0xd4, 0x27, 0xce, 0xd0, 0x81, 0xdc, 0x44, 0x33, 0xe5, 0x07, 0xc2, - 0xac, 0x6e, 0x2f, 0x09, 0x73, 0xe4, 0xfe, 0xaa, 0xd6, 0xce, 0xc9, 0x96, 0x53, 0x27, 0x3e, 0x27, - 0x37, 0x61, 0x59, 0x5a, 0xab, 0x94, 0x76, 0x07, 0x3d, 0x59, 0xa3, 0x7e, 0x26, 0x8a, 0x15, 0x8b, - 0x93, 0x84, 0xdc, 0x07, 0x4c, 0xde, 0xcb, 0x37, 0x92, 0xb5, 0x34, 0x46, 0xbb, 0x69, 0xa7, 0x48, - 0xff, 0xc0, 0x87, 0xd7, 0xef, 0x1b, 0x1f, 0xd2, 0xdf, 0x1b, 0xb0, 0xa2, 0xd2, 0x04, 0x39, 0xce, - 0xf9, 0x83, 0x8d, 0xb7, 0xa3, 0xc6, 0x77, 0x27, 0x79, 0xbe, 0x11, 0x1b, 0x17, 0x29, 0x6b, 0x38, - 0x1a, 0xb1, 0x85, 0x19, 0x00, 0x2e, 0x28, 0x30, 0x5a, 0x6c, 0xf5, 0xf0, 0xff, 0xca, 0x81, 0x93, - 0x2d, 0xa4, 0x1d, 0x70, 0x40, 0x17, 0x6a, 0x20, 0x20, 0x2c, 0xdc, 0x3b, 0x77, 0xe8, 0x4b, 0x8a, - 0x87, 0x44, 0x50, 0x17, 0x0f, 0xb6, 0xac, 0x3b, 0xf6, 0x36, 0xde, 0x89, 0x6d, 0xb2, 0x17, 0xc3, - 0x51, 0x1b, 0xdf, 0x35, 0xc9, 0x80, 0x5e, 0x5e, 0x0c, 0xff, 0x80, 0x12, 0xef, 0x88, 0xdd, 0x3a, - 0x57, 0x71, 0x51, 0xc5, 0xb9, 0x73, 0x48, 0xbb, 0x75, 0xcd, 0x75, 0x7a, 0x78, 0x5e, 0xc7, 0xee, - 0x89, 0x4e, 0x2b, 0x59, 0x28, 0x2c, 0x7a, 0x12, 0xbb, 0x86, 0x9d, 0x4e, 0xae, 0xf9, 0x5a, 0x27, - 0x62, 0xce, 0xaa, 0x04, 0xf1, 0xdd, 0xa2, 0xb9, 0x56, 0xba, 0x51, 0x2a, 0x6e, 0x21, 0x9a, 0x58, - 0xdc, 0x66, 0x8a, 0x79, 0xcd, 0x70, 0x4d, 0x1d, 0x65, 0x1d, 0x2a, 0x8e, 0x11, 0xef, 0x35, 0x50, - 0xa3, 0xca, 0x91, 0xce, 0x6d, 0x77, 0x84, 0xbc, 0x6b, 0xca, 0x64, 0x7b, 0x78, 0xf3, 0x3e, 0xe8, - 0xc5, 0x6b, 0x17, 0x0c, 0x3b, 0x8d, 0xbc, 0xf5, 0xa4, 0x8b, 0xcf, 0x2d, 0xad, 0xdd, 0xdd, 0xa9, - 0xf1, 0xb6, 0x6b, 0x8b, 0x5d, 0xb0, 0x95, 0x36, 0xe2, 0xb5, 0xbc, 0x21, 0x6b, 0xa1, 0xeb, 0x3c, - 0x8e, 0xdd, 0x8f, 0x5b, 0x57, 0x0a, 0x57, 0x74, 0xe9, 0x94, 0xe0, 0x81, 0xd6, 0xfe, 0x8f, 0xc3, - 0x3b, 0xb7, 0x6c, 0x8d, 0x68, 0x1d, 0x8e, 0x6b, 0x9e, 0x7a, 0x1a, 0x8a, 0xd6, 0x4a, 0xd6, 0xa0, - 0x01, 0x68, 0x1a, 0x24, 0x3a, 0x1b, 0x28, 0x08, 0xaf, 0x16, 0x86, 0x9d, 0x2b, 0xdf, 0x0e, 0x18, - 0x2d, 0x16, 0xbb, 0x2b, 0x36, 0x88, 0x74, 0x1e, 0x87, 0xe4, 0xe0, 0x69, 0x4c, 0x9e, 0xa8, 0x96, - 0x8f, 0x62, 0x72, 0x10, 0x6c, 0x29, 0xff, 0x3d, 0x20, 0x5b, 0x78, 0x50, 0xee, 0x74, 0x1e, 0x4f, - 0x9e, 0xda, 0x04, 0x2a, 0x0b, 0x0d, 0x2e, 0xbd, 0xdd, 0x1b, 0xae, 0x4b, 0xc7, 0xeb, 0x5f, 0xce, - 0x6f, 0xdf, 0xdf, 0x5e, 0x8c, 0xcf, 0xeb, 0x5a, 0x01, 0x8a, 0xd5, 0x54, 0x57, 0x1e, 0xdd, 0x11, - 0x3a, 0x47, 0x74, 0xe8, 0x26, 0x5c, 0xd3, 0xeb, 0xee, 0x79, 0x8b, 0x98, 0x88, 0xe2, 0xd7, 0x0a, - 0x15, 0x04, 0xe5, 0x6e, 0xba, 0x4d, 0x1d, 0x0c, 0xfc, 0xad, 0xc5, 0x9e, 0x23, 0xc3, 0xe6, 0xb6, - 0xed, 0xc4, 0x9d, 0x8f, 0x6e, 0xc2, 0x26, 0x23, 0xdf, 0x3c, 0x42, 0xf1, 0xc1, 0x9a, 0xae, 0x8d, - 0x23, 0x44, 0x22, 0xdd, 0x09, 0xe5, 0x7c, 0x8a, 0x7a, 0x14, 0xb6, 0xf9, 0x72, 0x32, 0xc1, 0x2d, - 0xb7, 0x4d, 0x92, 0x26, 0x11, 0xda, 0xcf, 0x48, 0x28, 0xb8, 0x59, 0x35, 0x09, 0x71, 0x75, 0xef, - 0x9d, 0x48, 0x9d, 0x28, 0xa5, 0xe6, 0x52, 0xf4, 0xa8, 0x07, 0xef, 0xa1, 0x4e, 0xc7, 0x7a, 0x46, - 0x9f, 0xbb, 0x3e, 0x4d, 0x72, 0x94, 0x48, 0x3e, 0xa4, 0x61, 0x0a, 0x82, 0x0e, 0xbb, 0x17, 0x9a, - 0x68, 0x86, 0xf5, 0xc3, 0xfd, 0x97, 0x61, 0x7f, 0x6f, 0xf2, 0x62, 0xcd, 0x55, 0x7f, 0x46, 0xc2, - 0x52, 0xce, 0x65, 0xcf, 0x5d, 0xdb, 0xa8, 0x83, 0x55, 0xda, 0xec, 0x81, 0x0d, 0xf7, 0x12, 0x2d, - 0x52, 0x49, 0x41, 0xda, 0x79, 0x28, 0x7f, 0x7b, 0x29, 0xaa, 0xb5, 0xa0, 0x0b, 0x28, 0xf8, 0x4f, - 0x8a, 0x9a, 0x46, 0x4d, 0x29, 0x12, 0x09, 0xce, 0xb1, 0xa8, 0x08, 0xf3, 0x75, 0xea, 0x76, 0x4e, - 0x58, 0x56, 0xa1, 0x60, 0xb8, 0x51, 0x57, 0x13, 0x41, 0xfd, 0xb8, 0x76, 0xe9, 0x95, 0x2a, 0x04, - 0x6a, 0x95, 0x62, 0xd4, 0xea, 0x01, 0x31, 0x90, 0x63, 0xfd, 0xa9, 0xc8, 0x5d, 0x41, 0xba, 0xad, - 0x45, 0x1d, 0x2f, 0xf1, 0xd9, 0x41, 0x7f, 0xff, 0xa7, 0xbd, 0x83, 0xfe, 0xc1, 0x0b, 0xf6, 0x3a, - 0xd3, 0xb8, 0x6c, 0x4b, 0xb0, 0xe7, 0x28, 0xc9, 0x96, 0xf4, 0xa9, 0xa2, 0x29, 0x53, 0x97, 0x28, - 0x60, 0xb8, 0xfd, 0x01, 0x79, 0x28, 0x55, 0x57, 0xd9, 0x3f, 0x05, 0xc6, 0x24, 0x57, 0x93, 0xde, - 0x02, 0xb7, 0x74, 0xa1, 0x7b, 0x97, 0x17, 0xaf, 0xcf, 0xdf, 0x8d, 0xce, 0xbf, 0xf7, 0x40, 0xe7, - 0xea, 0x62, 0xcc, 0xf2, 0x5a, 0x92, 0x33, 0x10, 0xa5, 0xad, 0x55, 0x74, 0x24, 0x34, 0xac, 0x82, - 0x19, 0xc6, 0xa0, 0x40, 0x82, 0x50, 0x71, 0x5d, 0x2e, 0x5a, 0x26, 0x30, 0xb2, 0xe4, 0x94, 0xb3, - 0xee, 0x93, 0x02, 0x73, 0x5f, 0x09, 0x88, 0xea, 0x69, 0x49, 0xcd, 0xab, 0x94, 0x27, 0xc4, 0x12, - 0xf5, 0x67, 0x98, 0xdf, 0x6d, 0x64, 0xbf, 0xef, 0x63, 0x3b, 0x7f, 0xaa, 0x91, 0xed, 0x51, 0xb5, - 0xc1, 0x0f, 0xf5, 0xef, 0xd4, 0xcc, 0xd3, 0x77, 0xe0, 0xff, 0x02, 0xe8, 0x93, 0xa8, 0x82, 0x17, - 0x16, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_um.htm, do not edit!! -const uint16_t PAGE_settings_um_length = 3306; -const uint8_t PAGE_settings_um[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xad, 0x59, 0x6d, 0x73, 0xdb, 0x36, - 0x12, 0xfe, 0xee, 0x5f, 0x41, 0xa3, 0x19, 0x99, 0x1c, 0xd1, 0x94, 0x9c, 0xb6, 0x33, 0x39, 0x49, - 0x94, 0x2e, 0x76, 0xdc, 0x46, 0x97, 0x17, 0x7b, 0xe2, 0xa4, 0x99, 0x1b, 0xc7, 0x17, 0x53, 0x22, - 0x24, 0x21, 0xa6, 0x08, 0x96, 0x00, 0xed, 0xf8, 0x64, 0xfd, 0xf7, 0x7b, 0x16, 0x20, 0x29, 0xca, - 0x76, 0x32, 0x6d, 0xe6, 0xbe, 0x58, 0x24, 0x08, 0x2c, 0x16, 0xbb, 0xcf, 0x3e, 0xbb, 0x0b, 0x0f, - 0x76, 0x5f, 0x9c, 0x1c, 0xbd, 0xff, 0xf7, 0xe9, 0xb1, 0xb3, 0xd0, 0xcb, 0x64, 0x38, 0x28, 0xff, - 0xf2, 0x28, 0x76, 0x92, 0x28, 0x9d, 0x87, 0x8c, 0xa7, 0x6c, 0x38, 0x58, 0x72, 0x1d, 0x39, 0xd3, - 0x45, 0x94, 0x2b, 0xae, 0x43, 0x56, 0xe8, 0xd9, 0xfe, 0xb3, 0x6a, 0x74, 0x27, 0x8d, 0x96, 0x3c, - 0x64, 0xd7, 0x82, 0xdf, 0x64, 0x32, 0xd7, 0xcc, 0x99, 0xca, 0x54, 0xf3, 0x14, 0xd3, 0x6e, 0x44, - 0xac, 0x17, 0xe1, 0xaf, 0xdd, 0x6e, 0x3d, 0xf5, 0xde, 0xa7, 0x98, 0x5f, 0x8b, 0x29, 0xdf, 0x37, - 0x2f, 0xbe, 0x48, 0x85, 0x16, 0x51, 0xb2, 0xaf, 0xa6, 0x51, 0xc2, 0xc3, 0x03, 0x7f, 0x19, 0x7d, - 0x15, 0xcb, 0x62, 0x59, 0xbf, 0x17, 0x8a, 0xe7, 0xe6, 0x25, 0x9a, 0xe0, 0x3d, 0x95, 0xec, 0xc1, - 0xce, 0xc3, 0x81, 0x16, 0x3a, 0xe1, 0xc3, 0x0f, 0x98, 0xb9, 0x94, 0xb1, 0x73, 0xc6, 0xb5, 0x16, - 0xe9, 0x5c, 0x0d, 0x3a, 0x76, 0x7c, 0xa0, 0xa6, 0xb9, 0xc8, 0xf4, 0x70, 0xe7, 0x3a, 0xca, 0x9d, - 0x38, 0x8c, 0xe5, 0xb4, 0x58, 0x42, 0x9b, 0x7e, 0x1c, 0x60, 0xaf, 0xcf, 0xf3, 0x4c, 0x48, 0x28, - 0xeb, 0xc7, 0x41, 0xb1, 0xfc, 0x9c, 0x85, 0xe7, 0x17, 0x78, 0xca, 0xd5, 0x75, 0x5c, 0x3e, 0x49, - 0x3b, 0xc1, 0xbc, 0xf0, 0xaf, 0x3a, 0x8f, 0xf0, 0xd8, 0x27, 0x41, 0xf2, 0x26, 0xe5, 0xb9, 0x9f, - 0xc8, 0xa9, 0xc8, 0xfc, 0x22, 0x97, 0x37, 0xca, 0x2f, 0x96, 0x47, 0xb3, 0x79, 0xb8, 0x5a, 0xfb, - 0x99, 0x48, 0x15, 0xad, 0xc0, 0xef, 0x09, 0xfd, 0x62, 0x52, 0xb8, 0x7b, 0x40, 0x3f, 0x59, 0x2e, - 0xb5, 0x0c, 0xd9, 0x42, 0xeb, 0xac, 0xc7, 0xfc, 0xb4, 0x58, 0xbe, 0x09, 0xbb, 0xfd, 0x59, 0x91, - 0x4e, 0xb5, 0x90, 0xa9, 0x33, 0x1f, 0xc7, 0x2e, 0xf7, 0x56, 0x39, 0xd7, 0x45, 0x9e, 0x3a, 0x71, - 0x30, 0xe7, 0xfa, 0x38, 0xe1, 0xa4, 0xeb, 0xe1, 0xad, 0xf9, 0xb4, 0xae, 0xa7, 0x0a, 0x75, 0xd2, - 0x98, 0xca, 0x5b, 0x2d, 0x26, 0x27, 0x5f, 0xf8, 0x54, 0xb3, 0x30, 0xd4, 0xb7, 0x19, 0x97, 0x33, - 0x1a, 0xdb, 0x7d, 0x9e, 0xe7, 0xd1, 0x6d, 0x20, 0x94, 0xf9, 0xdd, 0x5a, 0xff, 0xd2, 0xf5, 0x56, - 0x37, 0x22, 0x8d, 0xe5, 0x4d, 0x20, 0x33, 0x9e, 0xba, 0x46, 0x25, 0xd5, 0xeb, 0x74, 0xe6, 0x42, - 0x2f, 0x8a, 0x49, 0x30, 0x95, 0xcb, 0xce, 0x73, 0x91, 0x4f, 0xa5, 0x94, 0x57, 0x82, 0x77, 0x3e, - 0xbe, 0x3e, 0x7e, 0xd1, 0xb9, 0x11, 0x57, 0xa2, 0x53, 0x19, 0xf7, 0xa7, 0xc2, 0x5a, 0x7b, 0x5f, - 0x95, 0x03, 0xac, 0x21, 0xfd, 0xf0, 0x9e, 0x74, 0x1c, 0xe4, 0xc3, 0xbb, 0xd7, 0x2e, 0xeb, 0x6c, - 0x26, 0xfb, 0xec, 0xb3, 0xe2, 0xc9, 0xac, 0xb9, 0x2a, 0x91, 0x51, 0xfc, 0xaf, 0x33, 0x97, 0xfb, - 0x3a, 0xdc, 0xed, 0x7a, 0xab, 0x84, 0x6b, 0x27, 0x0d, 0xe3, 0x60, 0x9a, 0xf3, 0x48, 0xf3, 0xd2, - 0x10, 0x2e, 0xb3, 0xce, 0x64, 0x5e, 0x3f, 0x0d, 0x20, 0xed, 0xb9, 0xd6, 0xb9, 0x98, 0x14, 0x9a, - 0xe3, 0x43, 0x3e, 0x65, 0x3e, 0xf7, 0xfc, 0xfb, 0xe3, 0x64, 0x0f, 0xe6, 0x33, 0x0d, 0xef, 0x75, - 0xbe, 0x44, 0xd7, 0x51, 0x25, 0xe0, 0xc1, 0xc4, 0x48, 0xdd, 0xa6, 0x10, 0xa1, 0x3d, 0xb8, 0x7a, - 0x22, 0xe3, 0xdb, 0x20, 0xca, 0xa0, 0x7c, 0x7c, 0xb4, 0x10, 0x49, 0xec, 0xa6, 0x34, 0x3f, 0x8a, - 0xe3, 0xe3, 0x6b, 0x68, 0xf1, 0x5a, 0x28, 0xe0, 0x99, 0xe7, 0x2e, 0x23, 0x9d, 0x99, 0xef, 0x7a, - 0xe1, 0x70, 0xf5, 0x3b, 0xd7, 0x7f, 0xb8, 0x5e, 0x7f, 0x26, 0x73, 0x97, 0x54, 0xe7, 0x0e, 0x9c, - 0x60, 0xa1, 0xe4, 0x11, 0x20, 0x82, 0xac, 0x50, 0x0b, 0xf8, 0xc0, 0xa0, 0xc2, 0xbe, 0x30, 0xfa, - 0x88, 0x93, 0xec, 0x1f, 0x84, 0xa1, 0x85, 0xdf, 0x79, 0xf7, 0xa2, 0xd5, 0xb2, 0x8f, 0x81, 0x5a, - 0x88, 0x99, 0x76, 0x49, 0x99, 0xb3, 0x59, 0x70, 0xf6, 0xe2, 0x39, 0xa1, 0x35, 0xb4, 0x2f, 0x47, - 0xaf, 0x37, 0x2f, 0x6f, 0x4e, 0xce, 0xc6, 0x5b, 0x9f, 0x5e, 0x35, 0xbe, 0x8d, 0xcf, 0x4e, 0xca, - 0xb7, 0x0a, 0xea, 0xb4, 0xfd, 0x8b, 0x5c, 0x66, 0xf0, 0x4d, 0xaa, 0x5c, 0x6f, 0xfd, 0xf8, 0xb1, - 0x78, 0x9e, 0xcb, 0x1c, 0xd6, 0xc4, 0xb1, 0x10, 0xbb, 0x4a, 0x26, 0x3c, 0x48, 0xe4, 0xdc, 0x65, - 0xc7, 0x34, 0xee, 0x94, 0xbe, 0x82, 0x23, 0x9d, 0x99, 0x48, 0xb8, 0xb1, 0x3a, 0x82, 0x35, 0x87, - 0x77, 0x5e, 0x97, 0xe3, 0x38, 0x3b, 0x16, 0xce, 0xc4, 0xbc, 0xc8, 0x23, 0xe3, 0x5c, 0x6b, 0x75, - 0x67, 0x16, 0x61, 0x41, 0x1c, 0x7c, 0x4a, 0xc7, 0x29, 0x20, 0x96, 0xc1, 0x50, 0xdc, 0xc9, 0xa2, - 0x39, 0x77, 0xe2, 0x48, 0x47, 0xbb, 0x40, 0x43, 0x03, 0x0f, 0x67, 0xae, 0x05, 0x01, 0x0f, 0x4b, - 0x2c, 0x21, 0x80, 0x8c, 0xb0, 0xbe, 0x98, 0xb9, 0x8c, 0x76, 0xee, 0x01, 0xee, 0x3c, 0x30, 0x41, - 0x35, 0x95, 0x89, 0x67, 0xe2, 0xac, 0xeb, 0xbb, 0x26, 0x28, 0x43, 0x9a, 0x9d, 0x9c, 0x69, 0x99, - 0x43, 0x3c, 0x85, 0xd2, 0x58, 0xf3, 0x25, 0x39, 0x6c, 0x3a, 0xce, 0x98, 0xe7, 0xdd, 0xdd, 0x95, - 0xd3, 0xb0, 0x7a, 0x99, 0x41, 0xf3, 0xdf, 0x20, 0xcf, 0x79, 0x23, 0x63, 0x1e, 0x38, 0xa7, 0x09, - 0x8f, 0x14, 0x77, 0x60, 0x11, 0x9e, 0x3b, 0x04, 0x7d, 0x67, 0x7c, 0x0a, 0xdd, 0xfc, 0x2d, 0x89, - 0x6a, 0x5b, 0xa2, 0x65, 0x02, 0xcf, 0xeb, 0xf3, 0x44, 0x71, 0xa3, 0xb6, 0x26, 0xd5, 0x22, 0xbd, - 0x20, 0xb6, 0xf2, 0xd3, 0x50, 0x07, 0x2a, 0x01, 0xeb, 0xb9, 0x07, 0xbe, 0x0e, 0x80, 0x2a, 0xf5, - 0x11, 0x81, 0x86, 0x88, 0x60, 0xde, 0x68, 0xff, 0xa0, 0x77, 0x2d, 0x45, 0xec, 0x74, 0xbd, 0x40, - 0x65, 0x89, 0xd0, 0x66, 0x14, 0xf0, 0x4e, 0x78, 0x3a, 0xd7, 0x8b, 0xe1, 0xd3, 0x56, 0xcb, 0xad, - 0xa9, 0x63, 0x73, 0x5a, 0xbf, 0x3c, 0xad, 0x3d, 0x05, 0x0f, 0x16, 0x52, 0x69, 0xda, 0xaa, 0xed, - 0x62, 0x0e, 0x68, 0x71, 0xc4, 0x7a, 0xac, 0x6d, 0x1f, 0x7b, 0x8c, 0x79, 0x6d, 0x08, 0x6d, 0xa7, - 0xc0, 0x97, 0xb7, 0x4e, 0x62, 0x58, 0xd6, 0x90, 0x0f, 0x8c, 0x40, 0x9c, 0xc3, 0x8a, 0x25, 0xf3, - 0x02, 0x91, 0xc2, 0xf5, 0x2f, 0xdf, 0xbf, 0x79, 0x1d, 0xb2, 0xb7, 0xd2, 0x29, 0xc9, 0x54, 0x39, - 0x80, 0xae, 0x8e, 0x12, 0x72, 0x9a, 0xb5, 0x00, 0xb4, 0x31, 0xd8, 0x8a, 0x8c, 0x93, 0xc2, 0x07, - 0xa1, 0xdd, 0x21, 0x61, 0x0d, 0x2f, 0x96, 0x13, 0x6a, 0xb2, 0xa2, 0xb3, 0x8c, 0xaa, 0xf3, 0x40, - 0x2b, 0xa8, 0x65, 0x8e, 0x60, 0x94, 0xe4, 0x4d, 0x86, 0xfb, 0xad, 0xc9, 0x70, 0x61, 0x18, 0xb6, - 0x41, 0x69, 0x7c, 0x37, 0x0c, 0xdd, 0xee, 0xdd, 0x36, 0x15, 0x8e, 0x1f, 0x9b, 0x18, 0x3e, 0x98, - 0x38, 0x5d, 0xf0, 0xe9, 0x15, 0xd1, 0x8b, 0xb7, 0xda, 0x52, 0xef, 0x14, 0x47, 0x24, 0x09, 0x40, - 0x95, 0xa5, 0x55, 0x8f, 0x62, 0x98, 0x70, 0xaf, 0xcf, 0x53, 0x5f, 0x5c, 0x00, 0xcb, 0x27, 0x86, - 0x5c, 0xe1, 0x37, 0x90, 0x05, 0xa7, 0xc9, 0x5e, 0x39, 0x59, 0x78, 0x15, 0x46, 0x4d, 0x3e, 0xe8, - 0x9b, 0xbf, 0x61, 0xea, 0x57, 0x62, 0x85, 0xe7, 0xdb, 0x21, 0xbe, 0x26, 0x60, 0x38, 0x84, 0x5c, - 0x44, 0x20, 0x70, 0x9b, 0x06, 0x39, 0xcf, 0x92, 0x08, 0x88, 0x60, 0xe7, 0x17, 0xe0, 0x27, 0x78, - 0x40, 0x15, 0x13, 0xa5, 0x73, 0x77, 0xff, 0x67, 0x23, 0x7e, 0x9b, 0xbc, 0x85, 0xd5, 0x8a, 0x32, - 0x8f, 0x46, 0xce, 0xd0, 0x03, 0x51, 0xe2, 0xa3, 0xaf, 0xdb, 0x6d, 0x4f, 0x9c, 0xeb, 0x8b, 0x61, - 0xd8, 0x85, 0x6f, 0x36, 0x54, 0x43, 0x63, 0x4d, 0xb6, 0x31, 0x7a, 0x94, 0x00, 0x75, 0xc4, 0x83, - 0xd9, 0xdf, 0x9e, 0xfa, 0x0d, 0x55, 0x1e, 0x51, 0xa3, 0x3e, 0x35, 0x6d, 0xdd, 0xf0, 0x10, 0x52, - 0xfc, 0x51, 0x94, 0x6d, 0xbc, 0xc4, 0x70, 0x4c, 0x60, 0x85, 0xed, 0xd6, 0xc9, 0x6a, 0xc4, 0x58, - 0x8f, 0xd7, 0x16, 0xe9, 0x9c, 0x7f, 0xfa, 0xf8, 0xf9, 0xa2, 0x33, 0xf7, 0x99, 0x03, 0xb3, 0xd4, - 0xa3, 0xee, 0x7f, 0x3e, 0xdd, 0xac, 0x0e, 0xd6, 0xde, 0x9d, 0xfb, 0x49, 0xb5, 0xed, 0x23, 0xe6, - 0x80, 0xa4, 0x78, 0xa0, 0xe5, 0x07, 0x90, 0x75, 0x7e, 0x84, 0xb8, 0x75, 0x9b, 0xe8, 0x03, 0xb5, - 0xfd, 0x26, 0x38, 0xf8, 0x1b, 0x6e, 0xf7, 0xe1, 0x4c, 0xe4, 0xe1, 0xda, 0xd1, 0x29, 0x7c, 0x67, - 0x32, 0x77, 0x3b, 0xdc, 0x1b, 0x2c, 0x72, 0x67, 0x9a, 0x44, 0x4a, 0x85, 0x4c, 0x2d, 0x13, 0x36, - 0xdc, 0xf3, 0x59, 0x91, 0x5e, 0xa5, 0x30, 0x04, 0x5c, 0x15, 0xea, 0xbb, 0x3b, 0x8e, 0xf8, 0x98, - 0x26, 0x45, 0x0c, 0xef, 0x23, 0xb0, 0x88, 0x3e, 0xca, 0xa5, 0x97, 0x83, 0x6c, 0x38, 0x28, 0x86, - 0x4f, 0x56, 0xd5, 0x29, 0xb5, 0xb7, 0x1e, 0x74, 0x8a, 0xe1, 0xa0, 0x93, 0x0d, 0x2f, 0x6d, 0x3a, - 0xb0, 0x50, 0x12, 0xbe, 0x7c, 0x04, 0x4a, 0x50, 0xe2, 0xfb, 0x3b, 0x8d, 0x1a, 0x47, 0x80, 0x08, - 0xaf, 0xb7, 0x79, 0x6f, 0x53, 0x88, 0x6b, 0x33, 0xba, 0x7e, 0xdc, 0x55, 0xe9, 0x06, 0x35, 0x12, - 0xee, 0x92, 0x83, 0x8a, 0x55, 0xfa, 0x12, 0xee, 0xda, 0x36, 0xce, 0xb9, 0xbc, 0xf0, 0x91, 0x77, - 0x2d, 0x81, 0xd1, 0x0a, 0xe5, 0x27, 0x95, 0x7f, 0xd2, 0xbe, 0xba, 0x11, 0x7a, 0xba, 0x70, 0x13, - 0x6f, 0x35, 0x85, 0x8d, 0xd9, 0x44, 0x22, 0x27, 0x44, 0x29, 0xeb, 0x25, 0x21, 0x33, 0x71, 0x35, - 0x91, 0x5f, 0x99, 0xaf, 0xc2, 0xbd, 0xeb, 0x28, 0x29, 0x50, 0x9c, 0xe9, 0xbc, 0xe0, 0x6c, 0xaf, - 0xed, 0xa6, 0x23, 0x66, 0xe3, 0x8e, 0xc7, 0x8c, 0x22, 0xbc, 0x3f, 0x41, 0x36, 0xbf, 0xea, 0x1b, - 0x19, 0x60, 0xa0, 0x09, 0xcf, 0x59, 0x4f, 0x85, 0x97, 0xe5, 0xaa, 0x27, 0xab, 0x74, 0xcd, 0x2e, - 0xfd, 0x32, 0x42, 0x88, 0x32, 0xeb, 0x88, 0x18, 0xb9, 0x64, 0x6b, 0x87, 0x92, 0x19, 0xa6, 0x6d, - 0xf2, 0xd9, 0x9a, 0x39, 0x4b, 0x91, 0x86, 0x6c, 0xff, 0x80, 0xd5, 0x0e, 0x84, 0x08, 0xa8, 0x25, - 0x52, 0x24, 0xf9, 0x1e, 0x39, 0xd7, 0x41, 0x5a, 0xcb, 0x42, 0x16, 0xa5, 0xb7, 0xf5, 0x9c, 0xaf, - 0x5f, 0x13, 0xb6, 0x57, 0x2a, 0x13, 0xf3, 0x59, 0x54, 0x24, 0x9a, 0x8e, 0x42, 0x45, 0x02, 0x1d, - 0x63, 0x4b, 0x21, 0x2c, 0xbf, 0x45, 0xe9, 0x69, 0x8b, 0xd7, 0xde, 0xd3, 0x5f, 0xbb, 0xd9, 0xd7, - 0x3e, 0xbb, 0x5c, 0x57, 0xfe, 0x77, 0xb6, 0x5c, 0xef, 0x40, 0xfd, 0xda, 0x20, 0x61, 0x98, 0x8c, - 0x6a, 0x98, 0x88, 0x34, 0x2b, 0x90, 0x15, 0x60, 0x50, 0x14, 0x80, 0x22, 0x8e, 0x51, 0x60, 0x3b, - 0xb6, 0x92, 0x7d, 0xb2, 0xe2, 0xeb, 0xde, 0x93, 0x95, 0x5e, 0x43, 0xd2, 0x88, 0xd8, 0x00, 0x96, - 0xc2, 0xb6, 0xa5, 0x0e, 0xb3, 0x08, 0x0e, 0x61, 0xc3, 0xcb, 0x9e, 0x68, 0x82, 0xee, 0x47, 0xa5, - 0x3d, 0x59, 0x25, 0x6b, 0x08, 0xf3, 0xfc, 0x47, 0x25, 0x3d, 0x59, 0x19, 0xb3, 0x85, 0xa4, 0x78, - 0xed, 0x1f, 0x2c, 0xf8, 0xbe, 0xe8, 0x27, 0x2b, 0xb5, 0x46, 0x51, 0x60, 0x04, 0x95, 0x70, 0x70, - 0xf5, 0x42, 0x28, 0x7f, 0x0f, 0x0b, 0x2a, 0x1f, 0x12, 0xac, 0x63, 0xfe, 0xf5, 0x64, 0x66, 0x50, - 0xdd, 0x3e, 0xf0, 0xd6, 0x7b, 0x1e, 0x4a, 0xf7, 0x49, 0x3e, 0xbc, 0x5c, 0x6f, 0xe2, 0x75, 0xbb, - 0x3a, 0x59, 0x55, 0xc5, 0x94, 0xb6, 0xc5, 0x14, 0xd2, 0x0e, 0xb7, 0x75, 0xa0, 0x22, 0x86, 0xac, - 0x34, 0x34, 0x50, 0xa1, 0x03, 0x80, 0xd1, 0x74, 0x40, 0xaa, 0x36, 0x42, 0x88, 0xb0, 0x84, 0x70, - 0x3d, 0x67, 0x28, 0xa1, 0x40, 0xb3, 0x28, 0x90, 0xf0, 0x97, 0x8a, 0x26, 0xfa, 0x41, 0x7d, 0x64, - 0xc7, 0x5e, 0xb1, 0x8b, 0xcd, 0x1a, 0x2b, 0xc3, 0xf3, 0xaa, 0x1a, 0x34, 0xa3, 0xfe, 0x67, 0x8c, - 0xe2, 0x53, 0x07, 0xc6, 0x8a, 0x1e, 0x78, 0x04, 0xb1, 0x53, 0x29, 0x5a, 0xce, 0xf7, 0xbb, 0x36, - 0xda, 0x29, 0x74, 0x78, 0xb8, 0x7f, 0xd0, 0xe7, 0x83, 0x46, 0xdd, 0xd5, 0xe7, 0x08, 0x38, 0x62, - 0x1e, 0x5b, 0x12, 0x6e, 0x36, 0xc3, 0x3e, 0xd4, 0x1e, 0x89, 0xb4, 0xe0, 0x7d, 0x5b, 0x36, 0x18, - 0x52, 0xae, 0x8c, 0x85, 0xcd, 0x64, 0x48, 0x05, 0x62, 0x08, 0x8e, 0x2c, 0x52, 0x54, 0xdd, 0x26, - 0x90, 0xda, 0xbc, 0xaf, 0x0d, 0x85, 0x53, 0x42, 0x4c, 0x71, 0x6e, 0xd9, 0x0e, 0x41, 0x96, 0x6d, - 0x97, 0x89, 0x19, 0xec, 0x41, 0x54, 0x0e, 0x0e, 0x1e, 0xb1, 0x79, 0x22, 0x27, 0x51, 0xc2, 0x7a, - 0xe5, 0x80, 0xe7, 0x6d, 0x7a, 0x9a, 0xa6, 0x0a, 0x95, 0x00, 0xf7, 0x5d, 0xe7, 0xc4, 0x43, 0x94, - 0x92, 0x22, 0x8a, 0xce, 0x78, 0x92, 0x91, 0x5b, 0x5c, 0x50, 0x0c, 0x8a, 0xbc, 0x3e, 0x25, 0xd5, - 0x74, 0xa4, 0x50, 0xfb, 0x24, 0xe0, 0x30, 0x1e, 0xa3, 0xfe, 0xe8, 0x95, 0xda, 0x36, 0x45, 0xa9, - 0x20, 0x16, 0x8a, 0xda, 0x35, 0x9a, 0x80, 0x7a, 0x03, 0xc2, 0x64, 0x58, 0x3a, 0xa6, 0xac, 0x70, - 0x00, 0x01, 0xd4, 0x22, 0xfd, 0xb2, 0xa7, 0x0a, 0x60, 0xb7, 0xe3, 0x08, 0xf4, 0x42, 0x05, 0x27, - 0x07, 0x11, 0xe1, 0x5c, 0xf8, 0x1b, 0x40, 0xf6, 0xe6, 0x69, 0x6b, 0x92, 0xb5, 0x54, 0x53, 0x41, - 0x0e, 0x79, 0xf8, 0x73, 0x70, 0x01, 0x35, 0xf1, 0xd7, 0x5a, 0x45, 0x37, 0x55, 0xa5, 0xe2, 0xd2, - 0x6b, 0x60, 0xed, 0x83, 0xa9, 0x1b, 0x4a, 0x9b, 0x57, 0x2e, 0xe6, 0x01, 0x55, 0xa2, 0x28, 0x66, - 0xc8, 0xd5, 0x10, 0xd5, 0x7c, 0x45, 0x95, 0x65, 0xfc, 0xdf, 0xb7, 0xb0, 0xe0, 0x0f, 0x4e, 0xf4, - 0x60, 0xa4, 0x64, 0xdb, 0xfd, 0xa7, 0x17, 0x80, 0x8c, 0xc1, 0xef, 0x9f, 0x05, 0xcf, 0x6f, 0xcf, - 0x8c, 0x52, 0x32, 0x7f, 0x9e, 0x24, 0xe8, 0x5b, 0xcc, 0xcb, 0xb9, 0x25, 0xa6, 0x3d, 0x1c, 0x74, - 0xef, 0x82, 0x6d, 0xda, 0x08, 0x49, 0xc8, 0x17, 0x9e, 0xdc, 0x0d, 0x81, 0x6e, 0x4b, 0xee, 0x33, - 0x54, 0xac, 0xae, 0x44, 0x67, 0x45, 0xa7, 0x50, 0x5e, 0x6d, 0x17, 0x01, 0xbb, 0x08, 0xab, 0x21, - 0x12, 0x6b, 0xab, 0x55, 0x3f, 0x97, 0x6a, 0x83, 0x3e, 0xf6, 0x0f, 0x76, 0xc3, 0x72, 0x78, 0x54, - 0xfe, 0x0e, 0x0e, 0xba, 0x54, 0x09, 0x88, 0x80, 0xb8, 0xaf, 0xfa, 0xe8, 0x97, 0xbf, 0x21, 0xc9, - 0xc1, 0xb7, 0x8d, 0x3f, 0x0f, 0xbc, 0xcd, 0xb7, 0x52, 0xee, 0xbd, 0x19, 0x5d, 0xdf, 0xca, 0xb2, - 0x80, 0x4c, 0x1f, 0x45, 0x5c, 0x6d, 0xee, 0x52, 0x96, 0xe7, 0xd5, 0x2a, 0x34, 0x60, 0xe8, 0xf5, - 0x4a, 0xad, 0x2a, 0xe0, 0x6f, 0xb5, 0x07, 0xcd, 0x08, 0x34, 0x45, 0xdd, 0xb7, 0x1a, 0x46, 0x63, - 0x5f, 0x98, 0xb4, 0xaa, 0x3a, 0xea, 0x16, 0x59, 0x8f, 0x00, 0x90, 0x7b, 0x4c, 0xd1, 0x6a, 0xa5, - 0x81, 0x71, 0x05, 0x35, 0x43, 0xd4, 0x19, 0x95, 0xe3, 0x3e, 0x87, 0x62, 0x94, 0x6e, 0xbd, 0xde, - 0x86, 0x76, 0x2a, 0x39, 0xdf, 0x5a, 0x64, 0x80, 0x42, 0x8e, 0xdf, 0x74, 0xf2, 0xea, 0xf0, 0xf6, - 0x2d, 0x30, 0x62, 0xe3, 0xba, 0x62, 0x6e, 0x84, 0x95, 0x00, 0x7c, 0x0d, 0x87, 0x8d, 0x0e, 0x7a, - 0x5d, 0x6a, 0x70, 0x44, 0x5d, 0xff, 0x7b, 0x5b, 0x2d, 0xa5, 0x30, 0x2c, 0xd2, 0xa0, 0x3e, 0x6e, - 0x96, 0x79, 0x36, 0x97, 0x21, 0xad, 0xaf, 0x6d, 0xf0, 0x0a, 0x84, 0x0d, 0xc9, 0x51, 0xad, 0x16, - 0x1b, 0xbf, 0x3d, 0xfd, 0xf0, 0x9e, 0xe6, 0xaa, 0x40, 0x47, 0x73, 0xda, 0x1f, 0xe6, 0xb6, 0xc9, - 0xce, 0x0e, 0x42, 0xc0, 0xdd, 0x5d, 0x43, 0xa6, 0x1d, 0xaa, 0x6b, 0x5b, 0x55, 0xe2, 0x5e, 0x19, - 0x7c, 0xd7, 0x2c, 0x97, 0xa0, 0xa4, 0x48, 0x06, 0x2a, 0x88, 0xaa, 0x1e, 0x5a, 0x55, 0xd5, 0x45, - 0xbb, 0x8d, 0x42, 0x81, 0xa6, 0x44, 0x61, 0xf3, 0xf3, 0x79, 0x72, 0xd1, 0xb7, 0xfd, 0xf8, 0x6e, - 0x18, 0x19, 0x59, 0x50, 0xce, 0x88, 0x6e, 0x0e, 0x18, 0x4b, 0x36, 0x07, 0x4c, 0xfe, 0x6d, 0x0e, - 0x94, 0xb9, 0xa6, 0x39, 0x04, 0x9e, 0xdd, 0x7a, 0x85, 0xf9, 0x37, 0xaf, 0xf7, 0x3a, 0x7d, 0x3b, - 0xec, 0x47, 0x25, 0xf6, 0xd6, 0x65, 0xeb, 0x70, 0xff, 0x3e, 0x80, 0x22, 0x7f, 0x1f, 0x53, 0x1e, - 0xbd, 0x55, 0x90, 0xe9, 0x74, 0x11, 0xa5, 0x73, 0xba, 0x59, 0x00, 0x8f, 0x50, 0xb6, 0x03, 0x60, - 0x7d, 0x14, 0xd3, 0x51, 0x0e, 0x2f, 0x97, 0xce, 0xae, 0x4a, 0xd7, 0xf2, 0x0a, 0xc1, 0x57, 0x90, - 0x53, 0xef, 0x56, 0x24, 0xc9, 0x16, 0x98, 0x4b, 0x26, 0x33, 0xb5, 0x98, 0xf1, 0x31, 0xcd, 0x20, - 0xff, 0x7a, 0x76, 0x45, 0x0d, 0xa6, 0x7b, 0xf8, 0xb6, 0x3c, 0x00, 0xb0, 0x55, 0x71, 0x99, 0x96, - 0x01, 0x18, 0x6a, 0x9f, 0x6f, 0xdd, 0x61, 0x88, 0x0d, 0xad, 0xd8, 0xe2, 0x9d, 0x07, 0x53, 0xfa, - 0xf0, 0x16, 0x5d, 0xaf, 0x6a, 0xd6, 0xf1, 0xab, 0xe6, 0x07, 0xa4, 0x8d, 0x4d, 0xc0, 0x37, 0xd8, - 0x10, 0x10, 0xe2, 0x35, 0xbd, 0x8e, 0x29, 0x5d, 0x85, 0xba, 0xb6, 0xa5, 0xd8, 0x3a, 0xda, 0x38, - 0x9d, 0xc9, 0xba, 0x02, 0x47, 0x15, 0xb8, 0xb2, 0x29, 0xe1, 0xf1, 0xb8, 0xe8, 0xcb, 0x52, 0x15, - 0xc2, 0xe8, 0x83, 0x90, 0x6d, 0xb5, 0x24, 0x22, 0x65, 0x44, 0x7f, 0x02, 0x63, 0xdb, 0x85, 0x4c, - 0x62, 0xf4, 0x57, 0xba, 0x27, 0xa1, 0x28, 0x2d, 0x81, 0xdf, 0x53, 0x9a, 0xa5, 0x29, 0xa3, 0xa3, - 0x8b, 0xd5, 0xcf, 0xe3, 0x2f, 0x98, 0x97, 0x6a, 0xea, 0x6d, 0x5d, 0x16, 0xcd, 0xd0, 0xd5, 0xc3, - 0x24, 0x70, 0x5c, 0x2b, 0x9d, 0xa8, 0xac, 0x6f, 0x38, 0x8a, 0x56, 0x89, 0xef, 0xac, 0x9a, 0x70, - 0x58, 0x8e, 0x4f, 0xf8, 0x1c, 0xb8, 0xf2, 0x45, 0xbb, 0x5a, 0xea, 0xdd, 0xeb, 0x35, 0x5e, 0x1e, - 0x52, 0x4a, 0xa9, 0x4f, 0x8c, 0x02, 0x7d, 0xc1, 0x93, 0x8c, 0xf9, 0x5d, 0xff, 0x72, 0x00, 0xdc, - 0x68, 0xcc, 0x02, 0x70, 0x12, 0x31, 0xbd, 0x0a, 0x59, 0x75, 0x9b, 0x11, 0x2c, 0x72, 0x3e, 0x0b, - 0xf7, 0xaa, 0x0b, 0x38, 0xb4, 0x02, 0xc1, 0x0d, 0xb5, 0xdb, 0x73, 0xde, 0x29, 0xef, 0xd8, 0x54, - 0x87, 0x0a, 0xaf, 0x3d, 0x56, 0x16, 0x69, 0x56, 0x10, 0x1b, 0x8e, 0x06, 0x1d, 0xfb, 0x88, 0x72, - 0xae, 0x71, 0x8b, 0x46, 0xdd, 0xfd, 0x6a, 0xc6, 0xa9, 0x5a, 0xaf, 0x9b, 0xf3, 0xe9, 0x6c, 0x1e, - 0x7c, 0x51, 0x84, 0x12, 0x7f, 0xb5, 0xe4, 0x7a, 0x21, 0xe3, 0x1e, 0xc3, 0x47, 0xb6, 0xf6, 0x02, - 0xbd, 0xe0, 0x29, 0xa5, 0x54, 0x38, 0x53, 0x5e, 0x55, 0x17, 0x02, 0xa8, 0x38, 0xf3, 0x9c, 0x3a, - 0x52, 0x8a, 0x3c, 0xe2, 0x76, 0x98, 0xfa, 0x96, 0x4a, 0xea, 0x44, 0xa4, 0x9c, 0xc8, 0xd0, 0x48, - 0x43, 0xa7, 0xb5, 0x59, 0x4f, 0x88, 0xb5, 0x37, 0xa0, 0x3c, 0x28, 0x96, 0xfe, 0xa6, 0xaf, 0xb6, - 0x95, 0x26, 0xdc, 0xee, 0x53, 0xd3, 0x65, 0xa6, 0x34, 0x3b, 0x6c, 0xc0, 0xe2, 0x91, 0xb6, 0xa8, - 0x9c, 0x56, 0x17, 0xa9, 0x8b, 0x7c, 0x38, 0x58, 0xfc, 0x3c, 0x24, 0x3b, 0x0c, 0x3a, 0x78, 0xb8, - 0xf4, 0x1b, 0xcd, 0x4b, 0xdd, 0x40, 0x21, 0x0b, 0xf4, 0x19, 0xf1, 0x97, 0x59, 0x07, 0x30, 0x94, - 0x5b, 0xd7, 0x97, 0x19, 0xdb, 0x77, 0x52, 0xa9, 0xd4, 0xce, 0x4c, 0x16, 0x69, 0x1c, 0x50, 0x19, - 0x7a, 0x9a, 0x73, 0xa5, 0x9c, 0x81, 0x18, 0x9e, 0x45, 0xd7, 0x7c, 0xd0, 0x11, 0x43, 0x47, 0x4b, - 0xa7, 0xbc, 0x9d, 0x16, 0xff, 0xe5, 0x4e, 0xd9, 0x26, 0x28, 0xba, 0x07, 0x79, 0xec, 0xd6, 0xc4, - 0x5e, 0x02, 0x97, 0x97, 0x98, 0x0f, 0xaf, 0x45, 0x14, 0x4c, 0x36, 0xca, 0xc2, 0x67, 0x58, 0x8d, - 0x24, 0x0a, 0xc3, 0xc3, 0xfb, 0x65, 0x31, 0xf3, 0x17, 0x4c, 0xee, 0x37, 0xaf, 0xe1, 0xf8, 0x56, - 0x1e, 0x54, 0xd7, 0x67, 0x04, 0x3a, 0xba, 0x19, 0xe2, 0x74, 0x8b, 0xf7, 0xc2, 0xea, 0x59, 0xdd, - 0x1c, 0x9a, 0x72, 0xfc, 0x0f, 0x1c, 0x21, 0x16, 0xfa, 0xd6, 0xf5, 0xe8, 0x7a, 0x11, 0xa3, 0x28, - 0xca, 0x97, 0xa8, 0x51, 0xbc, 0xf5, 0xce, 0xa0, 0x53, 0x5e, 0x8f, 0x0f, 0xcc, 0xce, 0xc3, 0x7f, - 0x8a, 0x25, 0xdd, 0x19, 0x39, 0x45, 0x4e, 0xb5, 0x89, 0x51, 0x66, 0x0a, 0x3a, 0xf6, 0xfa, 0x98, - 0x68, 0x26, 0xc0, 0xfe, 0x3c, 0x8a, 0x51, 0xb9, 0xcb, 0xf8, 0x16, 0x68, 0xa6, 0x03, 0x87, 0x0c, - 0x98, 0x43, 0x31, 0x0f, 0xaf, 0x2e, 0x77, 0x1c, 0x81, 0x77, 0x7a, 0xfa, 0xac, 0xaa, 0xbe, 0xe1, - 0x6c, 0x86, 0x2e, 0xcd, 0xc0, 0x2e, 0x64, 0x99, 0x54, 0x9a, 0x61, 0x9d, 0xd5, 0x00, 0xdd, 0x1a, - 0xa9, 0x4f, 0x7a, 0x93, 0x80, 0x58, 0x5c, 0x57, 0x1d, 0x9a, 0x96, 0x19, 0x0c, 0xca, 0x86, 0x3b, - 0xcd, 0x41, 0x8a, 0xa6, 0x43, 0xea, 0x1a, 0x6c, 0x2c, 0x6d, 0xc5, 0xc3, 0x26, 0xb2, 0x5e, 0x92, - 0x32, 0x9b, 0xe8, 0x18, 0x74, 0x20, 0xa1, 0x5e, 0xb3, 0xf3, 0x8d, 0x45, 0x87, 0xb4, 0xe8, 0x30, - 0x9a, 0x5e, 0x6d, 0xd6, 0x6d, 0xed, 0x62, 0xf5, 0x65, 0x25, 0x3a, 0xea, 0x29, 0x39, 0x14, 0x54, - 0x59, 0x94, 0x9a, 0x53, 0x27, 0x4a, 0x15, 0xd3, 0xba, 0x5f, 0x9c, 0xca, 0x44, 0xe6, 0xbd, 0x79, - 0xce, 0x79, 0xda, 0x2f, 0xfd, 0xd9, 0x4b, 0x25, 0x9c, 0x39, 0x6c, 0xfd, 0x84, 0xa2, 0xab, 0xfb, - 0x4b, 0xdf, 0x39, 0xda, 0xbe, 0x23, 0x85, 0xe8, 0x78, 0x97, 0x3c, 0x02, 0x81, 0x43, 0xa7, 0x29, - 0x97, 0xb0, 0xb1, 0x2d, 0x37, 0xe7, 0xf1, 0x3d, 0xa9, 0x3b, 0xad, 0x9f, 0xfe, 0xf1, 0xec, 0xd9, - 0x33, 0x92, 0x5a, 0x24, 0xb1, 0x41, 0x37, 0x39, 0x67, 0x1b, 0xf4, 0x41, 0x29, 0xdd, 0x44, 0x94, - 0x35, 0xcc, 0xe2, 0x69, 0xf3, 0x5f, 0x27, 0x45, 0x06, 0x07, 0x3f, 0x1d, 0xee, 0xfc, 0x6e, 0x3a, - 0x07, 0x67, 0x3c, 0x50, 0x45, 0x36, 0x7c, 0x8a, 0x55, 0xf8, 0x39, 0x72, 0x7e, 0x3f, 0x1d, 0x9f, - 0x28, 0xc7, 0x7d, 0xf9, 0xd1, 0xa3, 0xa3, 0x0f, 0x44, 0xe5, 0x98, 0x9b, 0x28, 0x07, 0x23, 0xb9, - 0x36, 0x27, 0x3a, 0x39, 0xff, 0xb3, 0x10, 0x08, 0x27, 0x3c, 0x4c, 0xa4, 0xd4, 0xbb, 0xde, 0x0e, - 0xc5, 0x13, 0xad, 0x40, 0x13, 0xd6, 0xdb, 0xea, 0x38, 0xcb, 0x9a, 0x63, 0xd3, 0xc4, 0x9b, 0x0e, - 0xff, 0x97, 0x67, 0x35, 0x74, 0xd0, 0xb5, 0x39, 0x3b, 0x55, 0xb6, 0x0d, 0xf7, 0x1a, 0xdd, 0x25, - 0xb5, 0x3a, 0xde, 0xde, 0xa6, 0xeb, 0x77, 0x9a, 0xf9, 0xc0, 0x2c, 0x1c, 0x3a, 0x68, 0xed, 0xaa, - 0xfd, 0x76, 0xfe, 0xe2, 0x86, 0x68, 0x10, 0x9d, 0xef, 0xed, 0xb7, 0xf3, 0xad, 0x0d, 0xb1, 0x70, - 0x78, 0xff, 0x1e, 0xa9, 0xb4, 0xe2, 0xd9, 0xe9, 0xf8, 0xa1, 0xe9, 0x76, 0xb6, 0x6d, 0x87, 0x50, - 0xba, 0x75, 0xcc, 0xb6, 0x54, 0x48, 0xd3, 0x25, 0xfb, 0xf1, 0xd9, 0xe9, 0xcf, 0x4f, 0x7d, 0xe7, - 0x5b, 0x46, 0xad, 0x6c, 0x4a, 0xcd, 0x6c, 0x6f, 0xe7, 0x6f, 0x59, 0xd5, 0xf4, 0xbf, 0x3f, 0x74, - 0x4a, 0xb3, 0x72, 0xe8, 0x50, 0xe7, 0xfc, 0x57, 0x1d, 0x59, 0xfe, 0xbf, 0xce, 0x34, 0xdb, 0xce, - 0x0f, 0x78, 0xd2, 0x2c, 0x34, 0xae, 0x7c, 0xf5, 0x37, 0x8f, 0x69, 0x1a, 0xfb, 0x1f, 0x75, 0xe6, - 0xab, 0x87, 0xde, 0x7c, 0x67, 0x2c, 0xef, 0x98, 0x12, 0xc2, 0x44, 0xeb, 0xc8, 0xd9, 0x06, 0x57, - 0x7d, 0xf3, 0x53, 0x2a, 0xf0, 0xee, 0xf0, 0xbd, 0xbd, 0xe3, 0x30, 0x24, 0x46, 0xa1, 0x8c, 0xa4, - 0x31, 0xac, 0xfe, 0x49, 0x52, 0xe5, 0x86, 0x20, 0x08, 0xaa, 0x50, 0xcc, 0x2b, 0xd6, 0xd9, 0x71, - 0xfe, 0x9f, 0x3c, 0x85, 0xf8, 0x23, 0x46, 0x46, 0xc4, 0x13, 0x6b, 0x13, 0x85, 0xd3, 0xbf, 0x7b, - 0xff, 0x07, 0xab, 0x91, 0x94, 0x67, 0x04, 0x1e, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_2D.htm, do not edit!! -const uint16_t PAGE_settings_2D_length = 3296; -const uint8_t PAGE_settings_2D[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xc5, 0x5a, 0x5b, 0x77, 0xdb, 0x36, - 0x12, 0x7e, 0xd7, 0xaf, 0x80, 0xb1, 0x5d, 0x97, 0xb4, 0xa8, 0x9b, 0x9b, 0xf4, 0xb4, 0x92, 0x28, - 0x35, 0x8e, 0xd3, 0xd8, 0x7b, 0xec, 0x44, 0xc7, 0x72, 0xed, 0xe4, 0xb4, 0x3d, 0x0d, 0x4d, 0x42, - 0x12, 0x12, 0x0a, 0x60, 0x09, 0xd0, 0x97, 0x3a, 0xfe, 0xef, 0x3b, 0x03, 0xf0, 0xa6, 0x8b, 0x9d, - 0x74, 0xfb, 0xb0, 0x0f, 0xb1, 0x48, 0x5c, 0x66, 0x06, 0x33, 0xdf, 0xdc, 0xc0, 0x0c, 0x77, 0x0e, - 0xdf, 0xbe, 0x3c, 0x7f, 0x3f, 0x79, 0x45, 0x16, 0x7a, 0x19, 0x8f, 0x86, 0xf8, 0x97, 0xc4, 0x81, - 0x98, 0xfb, 0x94, 0x09, 0x0a, 0xef, 0x2c, 0x88, 0x46, 0xc3, 0x25, 0xd3, 0x01, 0x09, 0x17, 0x41, - 0xaa, 0x98, 0xf6, 0x69, 0xa6, 0x67, 0xad, 0x1f, 0x68, 0x3e, 0xda, 0x10, 0xc1, 0x92, 0xf9, 0xf4, - 0x9a, 0xb3, 0x9b, 0x44, 0xa6, 0x9a, 0x92, 0x50, 0x0a, 0xcd, 0x04, 0x2c, 0xbb, 0xe1, 0x91, 0x5e, - 0xf8, 0xcf, 0xbb, 0xdd, 0x72, 0xe9, 0xda, 0x54, 0xc4, 0xae, 0x79, 0xc8, 0x5a, 0xe6, 0xc5, 0xe3, - 0x82, 0x6b, 0x1e, 0xc4, 0x2d, 0x15, 0x06, 0x31, 0xf3, 0x7b, 0xde, 0x32, 0xb8, 0xe5, 0xcb, 0x6c, - 0x59, 0xbe, 0x67, 0x8a, 0xa5, 0xe6, 0x25, 0xb8, 0x82, 0x77, 0x21, 0xe9, 0x06, 0xe7, 0xd1, 0x50, - 0x73, 0x1d, 0xb3, 0xd1, 0xfe, 0x21, 0x99, 0x32, 0xdd, 0xca, 0x92, 0x61, 0xc7, 0x0e, 0x0c, 0x55, - 0x98, 0xf2, 0x44, 0x8f, 0x1a, 0xd7, 0x41, 0x4a, 0x62, 0x19, 0xf2, 0xc4, 0xd3, 0x7c, 0xc9, 0x64, - 0xa6, 0xbd, 0xc8, 0x8f, 0x64, 0x98, 0x2d, 0x41, 0x28, 0x0f, 0x26, 0xfc, 0x9d, 0x1e, 0xfe, 0x24, - 0xa9, 0xd4, 0xd2, 0xa7, 0x0b, 0xad, 0x93, 0x3e, 0x45, 0x41, 0x26, 0x81, 0x60, 0xb1, 0xf2, 0xbf, - 0x7f, 0xe6, 0x85, 0xfa, 0xd6, 0x17, 0x59, 0x1c, 0x0f, 0x66, 0x99, 0x08, 0x35, 0x97, 0x82, 0x1c, - 0x39, 0xee, 0xfd, 0x0d, 0x17, 0x91, 0xbc, 0x69, 0xcb, 0x84, 0x09, 0xc7, 0x6c, 0x53, 0xfd, 0x4e, - 0xe7, 0x93, 0x90, 0xed, 0x9b, 0x98, 0x45, 0xed, 0x39, 0xeb, 0xcc, 0x58, 0xa0, 0xb3, 0x94, 0xa9, - 0xce, 0xfe, 0x21, 0x75, 0x1f, 0xca, 0xbd, 0x07, 0x6b, 0x7b, 0xe7, 0x4c, 0xff, 0x72, 0x76, 0xe2, - 0xd0, 0x0e, 0xa8, 0x59, 0x73, 0x31, 0x57, 0xd4, 0xf5, 0xe8, 0x1f, 0x8a, 0xc5, 0xb3, 0xfa, 0xae, - 0xf9, 0x71, 0xe4, 0x30, 0xf7, 0x3e, 0x65, 0x40, 0x52, 0x10, 0xa4, 0xaf, 0x5f, 0xc5, 0x0c, 0xcf, - 0x70, 0x70, 0x67, 0xa6, 0xaa, 0xa5, 0xb3, 0x29, 0x70, 0x88, 0xda, 0xd3, 0x59, 0x5b, 0x65, 0x57, - 0x4b, 0xae, 0x9d, 0xda, 0x5c, 0x2c, 0x83, 0xe8, 0x3f, 0x53, 0x87, 0x79, 0xda, 0xdf, 0xe9, 0xba, - 0xf7, 0x31, 0xd3, 0x44, 0xf8, 0x51, 0x3b, 0x4c, 0x41, 0x56, 0x96, 0x13, 0x74, 0xa8, 0x55, 0x1d, - 0x75, 0x07, 0xa2, 0x0d, 0x42, 0xbd, 0xd0, 0x3a, 0xe5, 0x57, 0x99, 0x66, 0x30, 0x91, 0x86, 0xd4, - 0x63, 0xae, 0xb7, 0x3e, 0xae, 0xef, 0x12, 0x46, 0x3d, 0xaa, 0xd9, 0xad, 0xee, 0x7c, 0x0c, 0xae, - 0x83, 0x82, 0xc0, 0xc6, 0xc2, 0x40, 0xdd, 0x09, 0x20, 0xa1, 0x5d, 0x2f, 0x6a, 0x5f, 0xc9, 0xe8, - 0xae, 0x1d, 0x24, 0xa0, 0x83, 0xe8, 0xe5, 0x82, 0xc7, 0x91, 0x23, 0x70, 0x7d, 0x10, 0x45, 0xaf, - 0xae, 0x41, 0x8a, 0x13, 0xae, 0x00, 0x36, 0x2c, 0x75, 0x28, 0xca, 0x4c, 0x3d, 0xc7, 0xf5, 0x47, - 0xf7, 0xaf, 0x99, 0xbe, 0x70, 0x5c, 0xef, 0x97, 0x63, 0xf8, 0x03, 0xe7, 0x3b, 0x9d, 0xbc, 0x5c, - 0xa3, 0x0f, 0x76, 0xab, 0x19, 0xcf, 0x7d, 0xd8, 0x4e, 0x91, 0xa5, 0xa9, 0x4c, 0xe1, 0x20, 0x40, - 0x11, 0xd0, 0xa9, 0x64, 0xcc, 0xda, 0xb1, 0x9c, 0x3b, 0xf4, 0x15, 0x8e, 0x93, 0x5c, 0x4d, 0x60, - 0x0a, 0x32, 0xe3, 0x31, 0x33, 0x07, 0x06, 0x38, 0xa6, 0xa0, 0x98, 0x93, 0x7c, 0x5c, 0xce, 0x10, - 0xf1, 0x33, 0x3e, 0xcf, 0xd2, 0xc0, 0xe8, 0xd5, 0x1e, 0x98, 0xcc, 0x02, 0x8e, 0xc6, 0xff, 0x4d, - 0x1c, 0x8b, 0x50, 0x2e, 0x13, 0x50, 0x2f, 0x23, 0x49, 0x30, 0x67, 0x24, 0x0a, 0x74, 0xb0, 0x03, - 0xf6, 0xac, 0x99, 0x02, 0xad, 0x84, 0xfa, 0x67, 0x7e, 0x8e, 0x06, 0x00, 0xa1, 0x21, 0x36, 0xe0, - 0x33, 0x87, 0x22, 0xe7, 0x3e, 0xf5, 0x7d, 0xd6, 0x36, 0xc0, 0x0c, 0x65, 0xec, 0x1a, 0xac, 0x76, - 0x3d, 0xc7, 0x80, 0xd9, 0xc7, 0xd5, 0xf1, 0x54, 0xcb, 0x14, 0xc8, 0x23, 0x1a, 0x8e, 0x35, 0x5b, - 0xa2, 0xae, 0xc2, 0xe3, 0x84, 0xba, 0xee, 0xe7, 0xcf, 0xf9, 0x32, 0xd8, 0xbd, 0x4c, 0x40, 0xf2, - 0x9f, 0x81, 0x1e, 0x39, 0x95, 0x11, 0x6b, 0x93, 0x49, 0xcc, 0x02, 0xc5, 0x08, 0x68, 0x84, 0xa5, - 0xe4, 0xf2, 0xe4, 0xd5, 0x21, 0x39, 0x9e, 0x80, 0x6c, 0xde, 0x0a, 0x45, 0xb5, 0x4a, 0xd1, 0x33, - 0xd4, 0x5c, 0x77, 0x00, 0x5a, 0x65, 0x46, 0x6c, 0x8d, 0xa2, 0x05, 0x7a, 0x81, 0xfe, 0xe8, 0x09, - 0x5f, 0xb7, 0x55, 0x0c, 0x7e, 0xed, 0xf4, 0x3c, 0xdd, 0x06, 0x83, 0xaa, 0x4b, 0xae, 0x17, 0x80, - 0x69, 0xea, 0x8e, 0x5b, 0xbd, 0xfe, 0xb5, 0xe4, 0x11, 0xe9, 0xba, 0x6d, 0x95, 0xc4, 0x00, 0x47, - 0x1c, 0x05, 0x64, 0xc5, 0x4c, 0xcc, 0xf5, 0x62, 0xb4, 0xbf, 0xbb, 0xeb, 0x94, 0xee, 0x57, 0x9d, - 0xd6, 0xcb, 0x4f, 0x6b, 0x4f, 0xc1, 0xda, 0x0b, 0xa9, 0x34, 0xb2, 0x6a, 0x3a, 0xb0, 0x06, 0x1c, - 0x7f, 0x4c, 0xfb, 0xb4, 0x69, 0x1f, 0xfb, 0x94, 0xba, 0x4d, 0x20, 0xda, 0x14, 0xbf, 0x76, 0x7f, - 0x77, 0x1f, 0x72, 0x88, 0x6f, 0xb8, 0x55, 0x47, 0xb5, 0x3f, 0xaa, 0x71, 0xe2, 0xf7, 0xba, 0x70, - 0xd6, 0x9d, 0x9e, 0x39, 0x2f, 0xf0, 0x36, 0x8e, 0x12, 0x18, 0x93, 0xf8, 0x9b, 0x7b, 0xd0, 0x75, - 0xeb, 0x5e, 0x68, 0x17, 0x94, 0x8e, 0x88, 0x92, 0x8f, 0x0b, 0xe9, 0x41, 0x06, 0x10, 0xc2, 0x08, - 0x6c, 0x44, 0x62, 0xd5, 0x3e, 0x04, 0xec, 0x3d, 0x9a, 0xb5, 0x0b, 0x26, 0xf5, 0xd1, 0x97, 0xa9, - 0x02, 0xbb, 0x50, 0xb7, 0x7d, 0x1d, 0xc4, 0x19, 0x73, 0x73, 0xb7, 0x36, 0x13, 0xcb, 0x24, 0xe2, - 0xd7, 0x30, 0xa3, 0xf4, 0x1d, 0xe0, 0x32, 0xe2, 0xa0, 0xb4, 0xe0, 0xce, 0xa7, 0x42, 0x0a, 0x80, - 0xa2, 0xd1, 0x24, 0xc4, 0x14, 0xa6, 0x2d, 0xc2, 0x1d, 0x77, 0xf0, 0xd4, 0xa6, 0x2b, 0x90, 0xe6, - 0x13, 0xf5, 0xa2, 0x34, 0xb8, 0xa9, 0x47, 0x01, 0xb5, 0x90, 0x37, 0xe7, 0x32, 0x50, 0xda, 0x06, - 0x82, 0x9e, 0x7b, 0x8f, 0x41, 0x52, 0x58, 0xc1, 0x34, 0x4e, 0x18, 0x0b, 0x71, 0x01, 0xde, 0x72, - 0x74, 0x7e, 0x7a, 0xe2, 0x83, 0x85, 0xdb, 0x61, 0x1c, 0x28, 0xf5, 0x06, 0xa3, 0x2f, 0x28, 0xdf, - 0x7a, 0x50, 0x9f, 0x22, 0x25, 0xea, 0x85, 0x80, 0xa8, 0xf4, 0xdc, 0x46, 0x57, 0x27, 0x8f, 0xb2, - 0xc6, 0xf7, 0x8d, 0x34, 0x81, 0xe0, 0x4b, 0x03, 0xec, 0xe2, 0x10, 0xf9, 0x0a, 0x1f, 0x4e, 0x51, - 0x6c, 0x72, 0x0a, 0xd9, 0x40, 0x4f, 0x75, 0x56, 0xb5, 0xe7, 0x76, 0xca, 0xe0, 0x50, 0x21, 0x46, - 0x21, 0xc3, 0x94, 0xa2, 0x3b, 0x79, 0xfb, 0x3f, 0x76, 0xbb, 0xb5, 0x93, 0x65, 0x09, 0x9a, 0x1f, - 0xc1, 0x8e, 0x46, 0xc2, 0x53, 0x69, 0x5f, 0xb0, 0x1b, 0xf2, 0xee, 0xf4, 0xe4, 0x08, 0x42, 0xf4, - 0x19, 0xfb, 0x33, 0x63, 0x4a, 0x0f, 0xf4, 0xe3, 0x61, 0xa6, 0x26, 0x48, 0xa5, 0x26, 0xbd, 0xe0, - 0x0a, 0xf8, 0xab, 0x04, 0xa2, 0x05, 0x3b, 0x87, 0x28, 0xe7, 0x99, 0x11, 0xa5, 0x21, 0xc2, 0xab, - 0x91, 0xff, 0x0c, 0x65, 0x70, 0x5d, 0x4f, 0x3f, 0x1e, 0x6b, 0x2a, 0xba, 0xac, 0x4e, 0x98, 0x21, - 0x8d, 0xf0, 0x93, 0xb7, 0x53, 0x10, 0xb0, 0xe9, 0x64, 0xf2, 0x76, 0x7a, 0x0e, 0x27, 0xec, 0xd8, - 0xe3, 0x80, 0x31, 0xac, 0x7d, 0xf0, 0x24, 0x3f, 0xcb, 0x74, 0x79, 0x08, 0xd1, 0x64, 0x90, 0x63, - 0x46, 0xe4, 0x21, 0xd4, 0xa1, 0x18, 0x63, 0xc0, 0xd6, 0x88, 0x67, 0x7c, 0x6c, 0x63, 0x08, 0x51, - 0xe0, 0x12, 0x18, 0xbf, 0xc0, 0x3d, 0x71, 0x8d, 0x70, 0x6b, 0xf3, 0x06, 0x7a, 0x3e, 0xa5, 0xe0, - 0x0c, 0x95, 0x02, 0xe1, 0x00, 0x05, 0xb2, 0xf2, 0xe8, 0x94, 0x60, 0x01, 0x70, 0x0c, 0x69, 0xc1, - 0xec, 0xc4, 0x90, 0x6b, 0x31, 0x0b, 0xc8, 0x31, 0x78, 0x49, 0xcc, 0x72, 0xc0, 0x5e, 0x88, 0x41, - 0x3c, 0x65, 0x85, 0x67, 0x63, 0x18, 0xd3, 0x43, 0xe6, 0xce, 0x64, 0xea, 0xd8, 0x3c, 0xa3, 0x07, - 0x62, 0xc8, 0x06, 0xa2, 0xd9, 0x74, 0x0b, 0x2e, 0x20, 0x90, 0x59, 0x36, 0x5a, 0x5b, 0x36, 0x82, - 0x65, 0xad, 0x16, 0xb8, 0xc5, 0xd2, 0x2e, 0x73, 0x37, 0x05, 0x74, 0x98, 0x9f, 0x27, 0xb0, 0x35, - 0x39, 0x0c, 0xc1, 0x75, 0x61, 0x46, 0x7e, 0x95, 0x14, 0xac, 0xe2, 0x06, 0x96, 0xd9, 0x87, 0x21, - 0x38, 0x0e, 0xe1, 0x91, 0x4f, 0x13, 0x11, 0x7f, 0x73, 0xcf, 0x1e, 0xb0, 0xfc, 0x49, 0x89, 0x41, - 0x9d, 0x4f, 0xd5, 0x32, 0xa6, 0x23, 0xb3, 0x8d, 0xe0, 0xdc, 0xf0, 0x2a, 0x1d, 0xfd, 0x26, 0x7a, - 0x43, 0x95, 0x25, 0x23, 0xa5, 0x87, 0x1d, 0xfc, 0x25, 0x10, 0x40, 0xfb, 0x64, 0x08, 0xf9, 0x9a, - 0x85, 0x40, 0xd0, 0x54, 0x27, 0x13, 0x5c, 0x7c, 0x40, 0x21, 0x93, 0x70, 0x91, 0x00, 0xd0, 0x29, - 0xfa, 0x3f, 0x85, 0xad, 0xbf, 0xe9, 0xa1, 0x4c, 0xcc, 0x31, 0x72, 0xe5, 0x43, 0x99, 0x74, 0x2e, - 0xa1, 0x66, 0xb1, 0xa3, 0xdb, 0x56, 0xf4, 0xe8, 0xe8, 0x40, 0x6a, 0x2d, 0x97, 0xb5, 0x45, 0xc0, - 0xd9, 0xb0, 0x1b, 0x6d, 0x61, 0x7b, 0xf6, 0x95, 0x6c, 0x4f, 0xd8, 0x4c, 0x7f, 0x81, 0xef, 0x19, - 0x9f, 0x2f, 0xf4, 0x56, 0xb6, 0x46, 0x0f, 0x6f, 0x53, 0x0e, 0x48, 0x37, 0x9e, 0xbd, 0x55, 0x01, - 0x17, 0x5f, 0x29, 0xc9, 0x91, 0x4c, 0xf9, 0x5f, 0x50, 0x24, 0x06, 0xf1, 0x17, 0xe4, 0xb9, 0x80, - 0x1c, 0xcc, 0xc3, 0x95, 0x65, 0x6b, 0x22, 0x4d, 0x59, 0x0a, 0xbe, 0x00, 0xa1, 0x9b, 0x81, 0x44, - 0x86, 0x35, 0xc1, 0xd2, 0xc4, 0xa7, 0xe1, 0x82, 0x85, 0x9f, 0xae, 0xe4, 0x2d, 0xad, 0x0b, 0x38, - 0xdd, 0x10, 0xd0, 0x52, 0x39, 0x84, 0xa0, 0x24, 0x14, 0x30, 0x50, 0xc4, 0xb9, 0xbc, 0x3d, 0x72, - 0x4b, 0x5a, 0xb5, 0xbd, 0x97, 0x34, 0xa7, 0x2c, 0xb2, 0xe5, 0x15, 0x4b, 0x29, 0x59, 0x72, 0x81, - 0x42, 0x12, 0xc0, 0x99, 0x4f, 0xf7, 0x9f, 0x3f, 0xa7, 0x85, 0xe0, 0xdf, 0xdc, 0xaf, 0x7a, 0xd0, - 0xe4, 0x32, 0x77, 0xa0, 0x87, 0x0d, 0xf6, 0xe4, 0x76, 0x0b, 0xa7, 0xa3, 0xff, 0x9d, 0xd3, 0xd1, - 0xa3, 0x9c, 0x72, 0x0b, 0xce, 0x66, 0x10, 0x83, 0xc9, 0xbb, 0xfe, 0x26, 0xd7, 0x77, 0x5b, 0xb9, - 0x76, 0xb7, 0x70, 0xed, 0x6e, 0x31, 0xf3, 0xfb, 0x2d, 0x14, 0xdf, 0xff, 0x03, 0x8a, 0x28, 0xee, - 0x90, 0x8f, 0x1c, 0x69, 0x05, 0x9e, 0x41, 0x51, 0x43, 0xb4, 0x4c, 0x5a, 0x31, 0x80, 0x18, 0x2a, - 0xb1, 0x14, 0x22, 0x2d, 0xe1, 0x82, 0xfc, 0x0b, 0x9d, 0x51, 0xb9, 0xc3, 0x0e, 0x37, 0xd0, 0x00, - 0xcf, 0x1e, 0x7d, 0x80, 0x58, 0xcf, 0x21, 0x68, 0xa7, 0xfa, 0x45, 0xf4, 0x11, 0xb2, 0x87, 0xd0, - 0x98, 0xd0, 0x1c, 0x7a, 0xc5, 0x20, 0xe0, 0x30, 0x88, 0x89, 0xd4, 0x13, 0xb5, 0xe8, 0x52, 0x45, - 0x9c, 0x3c, 0xfa, 0x6d, 0x0f, 0x71, 0x03, 0x9b, 0x59, 0x58, 0x11, 0xea, 0xf4, 0xd0, 0xef, 0x7d, - 0xfe, 0xcc, 0x7e, 0xd5, 0xad, 0xde, 0xef, 0x90, 0x27, 0x96, 0xf2, 0x9a, 0x39, 0x2b, 0x54, 0x6b, - 0x09, 0xfb, 0x7e, 0x35, 0x8e, 0xfa, 0xbd, 0xc1, 0x93, 0x9c, 0x8a, 0xb8, 0x58, 0xe7, 0x36, 0xea, - 0x0e, 0x34, 0x84, 0xc7, 0x47, 0xf9, 0xcd, 0x19, 0xa6, 0xaf, 0xd5, 0x32, 0x01, 0x25, 0xae, 0x05, - 0x73, 0x23, 0xc2, 0x51, 0x15, 0xca, 0x57, 0x27, 0x2e, 0x8a, 0x09, 0xe1, 0xb3, 0x3d, 0x3d, 0x58, - 0x91, 0xd7, 0x1e, 0x3e, 0xf0, 0x11, 0x60, 0xd3, 0xb6, 0x71, 0x2c, 0x16, 0x79, 0x31, 0x42, 0x12, - 0x6a, 0x1b, 0x1c, 0xcd, 0x77, 0x7b, 0xb2, 0x36, 0x76, 0x90, 0x8f, 0xf1, 0xda, 0xd8, 0x59, 0x3e, - 0x96, 0xae, 0x70, 0x2f, 0xfd, 0xc3, 0x53, 0xab, 0xe3, 0xa5, 0xb4, 0xa1, 0x1f, 0x8f, 0x75, 0x9f, - 0x79, 0x50, 0x04, 0x8f, 0x59, 0x5f, 0x97, 0x2a, 0x82, 0x8c, 0x00, 0x27, 0xe9, 0x0e, 0xd8, 0x30, - 0x19, 0x30, 0xc8, 0x32, 0x55, 0x4a, 0xe9, 0x42, 0xe6, 0x09, 0x31, 0xf3, 0x78, 0x1a, 0xc6, 0xef, - 0xd9, 0x9e, 0x18, 0x96, 0xf9, 0x60, 0x77, 0xb7, 0x4c, 0x29, 0xda, 0xaa, 0x29, 0xf2, 0x9d, 0x78, - 0xcc, 0xfb, 0xd2, 0x1d, 0x27, 0x2d, 0x06, 0xe5, 0x2b, 0xf3, 0x32, 0x1c, 0x91, 0x7d, 0xee, 0x8e, - 0xc3, 0x96, 0x80, 0x11, 0x31, 0xc8, 0xfc, 0x60, 0x77, 0x97, 0xfd, 0x7b, 0x1f, 0x06, 0x32, 0x18, - 0xc8, 0xa0, 0x1d, 0xf9, 0xf5, 0x03, 0xe0, 0x5c, 0x3f, 0xbc, 0xfb, 0xf0, 0x7b, 0xae, 0x29, 0xd8, - 0x13, 0xf5, 0x33, 0x77, 0x2f, 0xad, 0x26, 0xdf, 0xd7, 0x27, 0xb3, 0x7e, 0xe4, 0xee, 0xa9, 0x6a, - 0xf2, 0xb2, 0x9c, 0xac, 0xed, 0x38, 0x2a, 0x07, 0xd5, 0x43, 0x65, 0x61, 0x76, 0x0b, 0x48, 0x89, - 0xb0, 0x7c, 0x73, 0xef, 0xf5, 0xd6, 0x52, 0x71, 0xc7, 0xf7, 0xd7, 0x26, 0xc6, 0x76, 0x02, 0x6a, - 0x53, 0x8f, 0xe5, 0x33, 0x50, 0xb6, 0x42, 0xdf, 0x97, 0xef, 0xf0, 0x1f, 0xdf, 0xf1, 0x63, 0x37, - 0x62, 0x73, 0x5a, 0xb1, 0xb7, 0x05, 0x25, 0x56, 0xb4, 0x3b, 0xd0, 0x1c, 0xdb, 0x42, 0x2b, 0x47, - 0x70, 0x18, 0x08, 0xe8, 0xff, 0x20, 0x0d, 0xb3, 0xb6, 0x6d, 0xf8, 0xf3, 0xee, 0xc6, 0x14, 0x93, - 0x97, 0x38, 0x32, 0xfa, 0xfe, 0x59, 0x77, 0x0c, 0xff, 0xfa, 0x50, 0x36, 0x81, 0x24, 0x0b, 0x86, - 0x69, 0xc6, 0xcf, 0x97, 0x9b, 0x66, 0xdb, 0x34, 0x34, 0x2f, 0xf1, 0xde, 0xe0, 0x16, 0xda, 0x85, - 0x7d, 0x28, 0x80, 0x1e, 0xac, 0xc3, 0x75, 0x3d, 0xb4, 0x65, 0xcd, 0xde, 0x60, 0xeb, 0xa7, 0x8b, - 0x10, 0xc4, 0xc1, 0xbd, 0x05, 0x6c, 0x0d, 0x4c, 0x46, 0xb7, 0xac, 0x32, 0x15, 0x34, 0x03, 0x5b, - 0xa6, 0xdf, 0x57, 0xd3, 0x72, 0xcb, 0xf4, 0x65, 0x35, 0xcd, 0xb7, 0x4c, 0x97, 0x86, 0x73, 0x07, - 0xda, 0x3f, 0x85, 0x4e, 0xa9, 0x0d, 0x90, 0x73, 0xb4, 0x17, 0x34, 0x25, 0xfa, 0x55, 0x39, 0x22, - 0xbc, 0xb8, 0xc9, 0xdd, 0x07, 0x38, 0x77, 0xdb, 0xea, 0xae, 0xd0, 0x48, 0x6d, 0xc4, 0xa8, 0xa6, - 0xa3, 0xf7, 0x84, 0x67, 0x06, 0xb1, 0xdc, 0x3e, 0x83, 0xac, 0xe7, 0x74, 0xbd, 0xae, 0xb7, 0xbe, - 0xcc, 0xdb, 0xa0, 0x64, 0x51, 0x9d, 0xfa, 0xce, 0xfa, 0xd2, 0x56, 0xd7, 0xed, 0xe8, 0x01, 0x8e, - 0xc6, 0x90, 0x32, 0x8d, 0x71, 0xfc, 0x9e, 0xd9, 0xaf, 0x74, 0x2a, 0x3f, 0xb1, 0x29, 0x82, 0xc1, - 0xa7, 0x77, 0x2c, 0x8e, 0x4d, 0x99, 0x5f, 0x4e, 0xfc, 0x2d, 0xe6, 0x7f, 0xdb, 0x5c, 0xff, 0x4f, - 0x53, 0xa1, 0xa6, 0x94, 0x17, 0x42, 0x6c, 0x31, 0x71, 0xaa, 0x5c, 0x72, 0x50, 0x2c, 0xf1, 0xa2, - 0xb5, 0x99, 0xb3, 0x72, 0x26, 0x5b, 0x9b, 0xb9, 0x28, 0x67, 0x66, 0xd5, 0xe0, 0x14, 0x06, 0x8b, - 0xa0, 0x79, 0xed, 0x07, 0x7b, 0x69, 0xb3, 0xeb, 0x2d, 0xfd, 0x18, 0x7f, 0xd7, 0x2c, 0xf1, 0xdd, - 0xa6, 0x25, 0x6e, 0x16, 0x5c, 0xb3, 0x0d, 0x43, 0x5c, 0x7b, 0x4b, 0x4f, 0x42, 0x94, 0xe1, 0x7b, - 0x29, 0x06, 0xc7, 0x64, 0xbc, 0x6c, 0xc2, 0x63, 0x2b, 0xed, 0xec, 0xf7, 0x97, 0x4d, 0xf8, 0x0b, - 0x81, 0x34, 0x1a, 0x5f, 0x37, 0x65, 0x3e, 0x76, 0x6d, 0xc6, 0x90, 0x06, 0x74, 0x08, 0x71, 0x4e, - 0x79, 0x8e, 0xc9, 0xd0, 0x52, 0xbe, 0x62, 0x73, 0x2e, 0x26, 0x00, 0x4f, 0xc7, 0x35, 0xef, 0x41, - 0x1a, 0x3a, 0xa8, 0x92, 0xf6, 0x73, 0xe0, 0xd1, 0xf5, 0xf6, 0xf7, 0x0c, 0x74, 0x27, 0xc7, 0x6e, - 0x49, 0x23, 0x5f, 0xb8, 0x0e, 0xa2, 0x75, 0x42, 0x98, 0xa6, 0xce, 0x25, 0xd2, 0xb2, 0x7a, 0x9e, - 0xf8, 0x4e, 0x66, 0xe2, 0x2c, 0x0a, 0xb6, 0x06, 0x13, 0x98, 0xc1, 0x78, 0x5b, 0xf9, 0xef, 0xc2, - 0x9f, 0x99, 0x80, 0xbb, 0x03, 0xd3, 0xd9, 0x38, 0x6c, 0xfa, 0x4e, 0x82, 0x57, 0x0b, 0x3d, 0x77, - 0x6f, 0xb2, 0xe7, 0x2c, 0xec, 0x63, 0x5f, 0xc1, 0x70, 0xb4, 0x31, 0x5c, 0x0a, 0x97, 0x33, 0xf7, - 0x4a, 0xf2, 0xad, 0xde, 0xee, 0x2e, 0x3c, 0xd6, 0xb7, 0xa5, 0xfd, 0x3a, 0xed, 0xd4, 0x9b, 0x8d, - 0xd7, 0x76, 0xf7, 0x9d, 0x82, 0x7d, 0xaf, 0xdf, 0xda, 0xc6, 0x7e, 0x7d, 0x78, 0xfd, 0xec, 0xae, - 0x75, 0x76, 0x6b, 0x40, 0xc7, 0x5d, 0xb7, 0x44, 0xca, 0xa2, 0x7f, 0x68, 0x87, 0x99, 0xc4, 0xeb, - 0xd6, 0x67, 0xdd, 0xe4, 0x96, 0xbc, 0x48, 0x79, 0x10, 0xd3, 0x75, 0x16, 0x32, 0x0d, 0xc4, 0x9c, - 0x55, 0xc3, 0xd8, 0xd1, 0x42, 0x2e, 0x01, 0x88, 0x74, 0xf6, 0xc1, 0x16, 0x3d, 0x40, 0x64, 0x93, - 0xe3, 0x63, 0xb3, 0x07, 0x7d, 0xa9, 0xf1, 0xd8, 0xd3, 0x43, 0xf0, 0xd6, 0xea, 0x42, 0x80, 0x02, - 0xef, 0x94, 0xdf, 0x92, 0x95, 0x52, 0x79, 0xef, 0xc8, 0x3f, 0x79, 0x09, 0xd5, 0x32, 0x6d, 0xea, - 0x26, 0x85, 0x5a, 0x96, 0x36, 0x05, 0xfc, 0xfa, 0xf8, 0xbe, 0x27, 0x1e, 0x1a, 0x50, 0xab, 0xdb, - 0x2b, 0xd9, 0xa1, 0x49, 0x32, 0xa3, 0x9f, 0xf8, 0x12, 0xaf, 0x6f, 0x48, 0x96, 0xc6, 0xd0, 0xd3, - 0x9b, 0xbc, 0x13, 0x2a, 0xcc, 0x1c, 0xb0, 0xd0, 0x2c, 0x18, 0x76, 0xec, 0x45, 0x34, 0x5e, 0x14, - 0x42, 0x45, 0x88, 0xad, 0xb0, 0x4f, 0xa7, 0xa6, 0x1e, 0x04, 0xb0, 0x2c, 0x1b, 0xa6, 0x6d, 0xc3, - 0xa7, 0x3f, 0x54, 0x51, 0xd7, 0x4f, 0x67, 0x50, 0x4f, 0x32, 0xbd, 0x90, 0xd8, 0xd0, 0x49, 0x85, - 0xf7, 0xc3, 0xd8, 0xdf, 0xe5, 0xed, 0x1c, 0x94, 0x8c, 0x29, 0x04, 0xb2, 0x95, 0xb1, 0x05, 0x8b, - 0x93, 0x03, 0x3a, 0x6a, 0x0c, 0xaf, 0x32, 0xe8, 0xb2, 0x44, 0x5e, 0xa3, 0xda, 0x17, 0xac, 0x43, - 0xc3, 0x98, 0x87, 0x9f, 0x7c, 0x7a, 0x84, 0x6c, 0xc7, 0xc3, 0x8e, 0x9d, 0x18, 0xd9, 0xe2, 0x72, - 0xfb, 0x9e, 0x46, 0xb9, 0xe9, 0x00, 0x37, 0x1d, 0x40, 0x7f, 0x5f, 0xed, 0x7b, 0x9a, 0xcb, 0xcc, - 0x9c, 0x6e, 0x1a, 0x5c, 0xb3, 0x72, 0x47, 0x03, 0xda, 0xd1, 0x82, 0xdd, 0x62, 0x1f, 0xef, 0xb9, - 0xa1, 0xaa, 0xc3, 0x6b, 0x6e, 0x78, 0x99, 0x82, 0x0d, 0x12, 0x22, 0x53, 0x62, 0xe2, 0x69, 0xd5, - 0x84, 0xa1, 0x5e, 0xcc, 0xfd, 0x52, 0xa1, 0x95, 0xb7, 0xa7, 0x13, 0x2b, 0xd7, 0x02, 0x0d, 0x8f, - 0x18, 0xab, 0x95, 0x86, 0x5e, 0xad, 0xe7, 0xf7, 0xf2, 0x7a, 0x7b, 0xa3, 0x49, 0xeb, 0x1d, 0x12, - 0xc3, 0xad, 0xec, 0xbd, 0x1a, 0x9b, 0xfd, 0x19, 0xc8, 0x66, 0x61, 0x51, 0x2e, 0x5a, 0x69, 0xcf, - 0xca, 0x4e, 0xdb, 0x5e, 0x56, 0x91, 0x86, 0xb2, 0x68, 0xcc, 0x8b, 0x8d, 0xbe, 0xa9, 0x35, 0x36, - 0xba, 0xef, 0xe1, 0xe2, 0xbb, 0x51, 0x0e, 0xb6, 0xd7, 0x78, 0xa3, 0x12, 0x68, 0x38, 0xef, 0x23, - 0x8a, 0x47, 0xe2, 0x50, 0x19, 0xc1, 0xba, 0x4a, 0xa7, 0xdf, 0xe6, 0xa5, 0x12, 0x5e, 0xd8, 0x78, - 0xf6, 0xae, 0xec, 0x16, 0x17, 0xb8, 0xee, 0xb7, 0xa3, 0xdd, 0xb9, 0x1e, 0xd4, 0x4c, 0x0a, 0x9c, - 0x8c, 0x8c, 0x86, 0x8e, 0x5d, 0x45, 0xb6, 0xca, 0x68, 0x6f, 0x04, 0xa2, 0x2f, 0xb4, 0x89, 0xd0, - 0x22, 0x36, 0x9e, 0xe8, 0xdc, 0x7a, 0xfb, 0x3f, 0x94, 0x1d, 0xcf, 0x0f, 0x5b, 0x7a, 0xbf, 0x8d, - 0xbe, 0xaf, 0xf1, 0xd4, 0x76, 0x54, 0x70, 0xd5, 0x48, 0x5b, 0x40, 0xa8, 0x35, 0x89, 0x4e, 0x91, - 0xe6, 0x53, 0x22, 0x55, 0x14, 0xc1, 0x9a, 0xa4, 0x68, 0xb7, 0x1f, 0x23, 0x76, 0xf1, 0x37, 0x88, - 0xa1, 0x78, 0x6b, 0xf7, 0x26, 0x6b, 0x98, 0xcd, 0x3f, 0xec, 0x4c, 0x0e, 0xb6, 0xa1, 0xaf, 0x7e, - 0x47, 0xf2, 0xc5, 0xfb, 0x91, 0xc6, 0x63, 0xd7, 0x23, 0x67, 0xdb, 0x48, 0xaf, 0xdc, 0x83, 0x6c, - 0xd2, 0x6e, 0xac, 0x5e, 0x82, 0xac, 0x00, 0xfa, 0xa9, 0x0b, 0x90, 0x8b, 0x6d, 0xbc, 0x1a, 0x5b, - 0xae, 0x3a, 0xbe, 0xe2, 0x9a, 0x63, 0x85, 0x69, 0xfd, 0x8a, 0xa3, 0xf1, 0xf4, 0x1d, 0xc7, 0xb4, - 0x68, 0x9c, 0x0b, 0x87, 0xba, 0x09, 0x52, 0x01, 0x52, 0x4c, 0xc0, 0xfd, 0x15, 0x7e, 0xc6, 0x98, - 0xc8, 0x24, 0x8b, 0xa1, 0x01, 0x20, 0x37, 0x90, 0x04, 0x88, 0xfd, 0x08, 0x84, 0x2d, 0xb4, 0xb5, - 0x0d, 0x01, 0xc0, 0x4b, 0xa0, 0x7e, 0xc3, 0xf5, 0x82, 0x24, 0x29, 0x6b, 0x05, 0xa9, 0xc9, 0x1b, - 0x11, 0xd8, 0x17, 0xfd, 0xb1, 0x8d, 0xc4, 0x1b, 0x17, 0x28, 0xb7, 0x22, 0xc1, 0x15, 0x24, 0x38, - 0x40, 0xc8, 0xc8, 0x90, 0x12, 0x52, 0x63, 0x13, 0x4e, 0x82, 0xd9, 0x0c, 0x75, 0x32, 0xe3, 0x22, - 0x28, 0xc8, 0xd9, 0x5d, 0x97, 0x2f, 0xce, 0xde, 0x1c, 0xbf, 0x79, 0xdd, 0x27, 0xef, 0x65, 0x06, - 0xe4, 0xee, 0x88, 0x60, 0x40, 0x57, 0x4b, 0x92, 0x25, 0x11, 0x0a, 0xc1, 0x82, 0x70, 0x91, 0x4b, - 0x01, 0xe5, 0x1a, 0x1c, 0x47, 0xb3, 0x14, 0x98, 0xcc, 0xf0, 0x93, 0x85, 0x5e, 0xb0, 0x3b, 0x12, - 0xa4, 0x0c, 0xdb, 0x5c, 0x8c, 0x07, 0x2c, 0x6a, 0x37, 0x90, 0x9b, 0x39, 0xeb, 0xd3, 0x11, 0xf9, - 0x5b, 0xd3, 0x19, 0x7b, 0x79, 0x48, 0x30, 0xd1, 0x20, 0x8f, 0x17, 0xee, 0x7a, 0x6c, 0x28, 0x74, - 0xb3, 0x1e, 0xf2, 0x21, 0x3c, 0x35, 0xd6, 0xe3, 0x93, 0x8d, 0x07, 0x2a, 0xff, 0xfe, 0x08, 0x03, - 0x6f, 0x8c, 0x43, 0xe0, 0x67, 0xa2, 0x47, 0x7c, 0xe7, 0xe5, 0xd3, 0xbe, 0xf3, 0xfd, 0xb3, 0x9a, - 0xf3, 0x54, 0x97, 0x21, 0x5b, 0x02, 0xb5, 0xbd, 0x18, 0x69, 0xbc, 0xc8, 0x6d, 0x42, 0xb8, 0x82, - 0xa7, 0x88, 0x21, 0xeb, 0x1e, 0x66, 0x86, 0xa5, 0x04, 0x45, 0x25, 0x8b, 0x3b, 0x65, 0x3c, 0xb9, - 0xb4, 0xad, 0xb2, 0x66, 0x78, 0x55, 0xa9, 0x19, 0x8a, 0x76, 0x72, 0x65, 0xf6, 0x45, 0x1c, 0xac, - 0x06, 0x35, 0xb9, 0x26, 0x8a, 0xff, 0xc5, 0x08, 0x68, 0xaa, 0x03, 0x84, 0x16, 0x90, 0x94, 0x6a, - 0x53, 0x48, 0x49, 0x56, 0xf8, 0x2f, 0x56, 0x29, 0x1d, 0xa4, 0xf8, 0xe5, 0x84, 0x24, 0x92, 0xc3, - 0xaa, 0x7c, 0x34, 0xb7, 0x7c, 0x65, 0x25, 0x50, 0xd1, 0x3a, 0xcc, 0xaa, 0xf0, 0x6b, 0x2e, 0x63, - 0x6d, 0x83, 0x50, 0x53, 0xfa, 0x8a, 0xce, 0xcb, 0x28, 0x0d, 0x65, 0x49, 0xb1, 0xc6, 0x76, 0x1d, - 0x66, 0x77, 0xde, 0x83, 0xc2, 0x8c, 0x7d, 0xaa, 0xe8, 0x7e, 0x54, 0x80, 0x87, 0xd1, 0xeb, 0x20, - 0x31, 0x9f, 0xf6, 0x4a, 0xb3, 0xe4, 0xb6, 0x30, 0x9f, 0xfb, 0x72, 0x1b, 0x99, 0xdb, 0x74, 0x12, - 0x84, 0x21, 0x4b, 0x40, 0xf3, 0x6d, 0xbb, 0x71, 0x3b, 0xbc, 0x6a, 0xa2, 0xd5, 0xa0, 0x56, 0xfb, - 0x14, 0x41, 0x3b, 0xfb, 0x51, 0x6b, 0x1e, 0x24, 0xca, 0x92, 0x01, 0x74, 0xfd, 0x62, 0x26, 0xd7, - 0xb1, 0x05, 0x86, 0x7c, 0x23, 0x35, 0x88, 0x55, 0x08, 0x88, 0xe6, 0x0c, 0x20, 0xdb, 0x8d, 0xcc, - 0x46, 0x58, 0x3e, 0x6a, 0xd8, 0x71, 0xfc, 0xa8, 0x1e, 0x70, 0x81, 0x9a, 0x06, 0xbb, 0xa1, 0x63, - 0xde, 0x59, 0x3f, 0x15, 0x25, 0xf2, 0x98, 0xfd, 0x9a, 0xab, 0x08, 0xfb, 0x33, 0x03, 0xd3, 0x83, - 0x6f, 0x81, 0xe3, 0x14, 0x30, 0x41, 0xcb, 0x5a, 0x08, 0xbc, 0xb0, 0x40, 0xc3, 0x1d, 0xad, 0x1e, - 0xd4, 0x4e, 0x01, 0xa4, 0x33, 0xbd, 0x08, 0x34, 0x49, 0xf8, 0x2d, 0x18, 0x07, 0x1e, 0xec, 0x9b, - 0x54, 0xdc, 0x18, 0x1a, 0x01, 0xc6, 0x4d, 0xf8, 0xf0, 0x40, 0xb4, 0x72, 0x6f, 0x37, 0xdf, 0x2a, - 0xd8, 0x35, 0xc3, 0x7a, 0x04, 0xad, 0x5f, 0x91, 0xf1, 0x10, 0x09, 0xa4, 0x20, 0x9f, 0xb2, 0x39, - 0xb8, 0x56, 0x6a, 0xa7, 0x72, 0x54, 0x14, 0x76, 0xfe, 0x52, 0x85, 0xf4, 0x78, 0x49, 0xd5, 0xf8, - 0xfa, 0x9a, 0x6a, 0xd8, 0xc1, 0xaa, 0xb1, 0x42, 0x85, 0xfd, 0xe4, 0x55, 0x08, 0xd1, 0xc1, 0x7a, - 0x13, 0xb3, 0x88, 0xf9, 0xcf, 0x11, 0xff, 0x05, 0x8e, 0xf7, 0x23, 0xf1, 0x2c, 0x21, 0x00, 0x00 -}; - - -// Autogenerated from wled00/data/settings_pin.htm, do not edit!! -const uint16_t PAGE_settings_pin_length = 473; -const uint8_t PAGE_settings_pin[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x5d, 0x52, 0x4d, 0x6f, 0x13, 0x31, - 0x10, 0xbd, 0xef, 0xaf, 0x30, 0x73, 0x69, 0x82, 0x92, 0xdd, 0x50, 0x81, 0x04, 0xaa, 0xbd, 0x42, - 0x81, 0x1e, 0xb8, 0x94, 0x48, 0xe5, 0x82, 0xaa, 0xaa, 0x72, 0xec, 0xd9, 0xc4, 0xaa, 0x3f, 0x16, - 0xdb, 0x9b, 0x10, 0x2a, 0xfe, 0x3b, 0xe3, 0xdd, 0x50, 0x50, 0x2f, 0x6b, 0xbf, 0x99, 0xf1, 0x9b, - 0x37, 0x6f, 0x96, 0xbf, 0xfa, 0xfc, 0xf5, 0xd3, 0xb7, 0xef, 0x9b, 0x6b, 0xb6, 0xcf, 0xce, 0xb6, - 0xbc, 0x7c, 0x99, 0x95, 0x7e, 0x27, 0x00, 0x3d, 0x10, 0x46, 0xa9, 0x5b, 0xee, 0x30, 0x4b, 0xe6, - 0xa5, 0x43, 0x01, 0x07, 0x83, 0xc7, 0x3e, 0xc4, 0x0c, 0x4c, 0x05, 0x9f, 0xd1, 0x67, 0x01, 0x47, - 0xa3, 0xf3, 0x5e, 0xbc, 0x5b, 0xad, 0xa0, 0xad, 0xa6, 0xd2, 0xea, 0x45, 0x4e, 0xe3, 0xc1, 0x28, - 0x5c, 0x8e, 0x60, 0x61, 0xbc, 0xc9, 0x46, 0xda, 0x65, 0x52, 0xd2, 0xa2, 0x78, 0xb3, 0x70, 0xf2, - 0xa7, 0x71, 0x83, 0x7b, 0xc6, 0x43, 0xc2, 0x38, 0x02, 0xb9, 0x25, 0xec, 0x03, 0xb0, 0xea, 0x45, - 0xeb, 0xb3, 0x20, 0xb5, 0x97, 0x31, 0x21, 0x35, 0x19, 0x72, 0xb7, 0x7c, 0x4f, 0xd1, 0x6c, 0xb2, - 0xc5, 0x76, 0xf3, 0xe5, 0x86, 0x45, 0xfc, 0x31, 0x98, 0x88, 0x9a, 0x37, 0x53, 0x8c, 0x27, 0x15, - 0x4d, 0x9f, 0xdb, 0xea, 0x20, 0x23, 0xd3, 0x42, 0x07, 0x35, 0x38, 0xd2, 0x77, 0xd5, 0x0d, 0x5e, - 0x65, 0x13, 0x3c, 0x5b, 0xcf, 0xe6, 0x4f, 0x47, 0xe3, 0x75, 0x38, 0xd6, 0xa1, 0x47, 0x3f, 0x83, - 0xba, 0x6e, 0x88, 0x3b, 0x1b, 0xbf, 0x4b, 0xb0, 0x80, 0x87, 0x84, 0xb6, 0x83, 0xf9, 0x6f, 0xde, - 0x9c, 0x89, 0x78, 0xca, 0x27, 0xe2, 0xad, 0x3e, 0x1a, 0x57, 0x24, 0xb1, 0x21, 0xda, 0x19, 0x8c, - 0xb1, 0x5a, 0xa5, 0x04, 0xf3, 0x2b, 0xaa, 0x1c, 0x2b, 0x78, 0x33, 0x59, 0xb8, 0x0d, 0xfa, 0xc4, - 0xaa, 0xe0, 0x6d, 0x90, 0x5a, 0x5c, 0xe8, 0x7a, 0x87, 0xf9, 0xda, 0x62, 0x11, 0x91, 0xd6, 0xa7, - 0x1b, 0x9a, 0x6f, 0x06, 0x24, 0x1c, 0xe6, 0x77, 0xab, 0xfb, 0xba, 0x23, 0x79, 0x69, 0x36, 0xbf, - 0x68, 0x79, 0x17, 0xa2, 0x63, 0x46, 0x0b, 0x28, 0x97, 0x87, 0x04, 0xe7, 0x25, 0xdc, 0x76, 0x64, - 0x0a, 0x79, 0xb0, 0x0f, 0x94, 0xea, 0x43, 0x2a, 0x96, 0xec, 0x2f, 0xdb, 0x8d, 0x45, 0x99, 0x90, - 0x11, 0x27, 0x46, 0xf6, 0x57, 0x3d, 0x2b, 0x7e, 0xa8, 0xa0, 0x91, 0x94, 0x5c, 0xb6, 0xdc, 0xf8, - 0x7e, 0xc8, 0x2c, 0x9f, 0x7a, 0xa2, 0xe9, 0x65, 0x4a, 0xc7, 0x10, 0xf5, 0xb3, 0xc3, 0x45, 0x01, - 0x4b, 0xe6, 0x17, 0x5d, 0xdf, 0x02, 0xa3, 0xc5, 0x58, 0xf4, 0x3b, 0xda, 0xdf, 0x88, 0x8c, 0xff, - 0x0f, 0xf5, 0x32, 0x53, 0x13, 0x2f, 0xe0, 0x6e, 0xb5, 0xfc, 0x70, 0xff, 0x9a, 0x18, 0x46, 0x62, - 0x47, 0x7d, 0x04, 0x78, 0x32, 0x37, 0x1a, 0x05, 0x4c, 0x0e, 0x39, 0x8c, 0xc3, 0x90, 0xbc, 0x48, - 0x1e, 0x0c, 0x39, 0x93, 0xd7, 0x53, 0xf3, 0x09, 0x00, 0x0b, 0x5e, 0x59, 0xa3, 0x1e, 0x05, 0xd0, - 0x0a, 0xa0, 0x5d, 0x4b, 0xf5, 0x58, 0xf1, 0x66, 0x4a, 0xbe, 0x78, 0x91, 0x86, 0xad, 0x33, 0x34, - 0xea, 0xed, 0x78, 0xfe, 0x2b, 0x6a, 0x8a, 0x39, 0x74, 0x14, 0x8b, 0x8b, 0xdf, 0xe5, 0x47, 0xfe, - 0x03, 0x79, 0x48, 0x7d, 0x51, 0xd8, 0x02, 0x00, 0x00 -}; - diff --git a/wled00/html_simple.h b/wled00/html_simple.h deleted file mode 100644 index f733e44b2..000000000 --- a/wled00/html_simple.h +++ /dev/null @@ -1,1141 +0,0 @@ -/* - * Binary array for the Web UI. - * gzip is used for smaller size and improved speeds. - * - * Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui - * to find out how to easily modify the web UI source! - */ - -// Autogenerated from wled00/data/simple.htm, do not edit!! -const uint16_t PAGE_simple_L = 18061; -const uint8_t PAGE_simple[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0xcd, 0x7d, 0x69, 0x77, 0xe2, 0xba, - 0xb2, 0xe8, 0xf7, 0xfc, 0x0a, 0xda, 0x7d, 0x4e, 0x1a, 0x1f, 0x1c, 0x30, 0xf3, 0xd4, 0x24, 0x87, - 0x90, 0x90, 0x79, 0x24, 0x73, 0xbf, 0x5e, 0xb7, 0x3d, 0x08, 0x70, 0x62, 0x6c, 0xc7, 0x36, 0x53, - 0x68, 0xee, 0x5a, 0xef, 0xbf, 0xbd, 0x1f, 0xf6, 0xaa, 0x24, 0xdb, 0xd8, 0x06, 0x92, 0xf4, 0xde, - 0xef, 0xac, 0xfb, 0x7a, 0xef, 0x80, 0xd1, 0x50, 0x92, 0x4a, 0xa5, 0x9a, 0x54, 0x92, 0xbf, 0x7f, - 0xd9, 0xbb, 0x68, 0xdd, 0x3c, 0x5e, 0xee, 0x27, 0xfa, 0xee, 0x40, 0xdf, 0x4e, 0x7c, 0xc7, 0xaf, - 0x84, 0x2e, 0x19, 0xbd, 0x06, 0x47, 0x0c, 0x0e, 0x13, 0x88, 0xa4, 0xc2, 0xd7, 0x80, 0xb8, 0x52, - 0xc2, 0x90, 0x06, 0xa4, 0xc1, 0x8d, 0x34, 0x32, 0xb6, 0x4c, 0xdb, 0xe5, 0x12, 0x1b, 0x8a, 0x69, - 0xb8, 0xc4, 0x70, 0x1b, 0xdc, 0x58, 0x53, 0xdd, 0x7e, 0x43, 0x25, 0x23, 0x4d, 0x21, 0x5b, 0xf4, - 0x87, 0xa0, 0x19, 0x9a, 0xab, 0x49, 0xfa, 0x96, 0xa3, 0x48, 0x3a, 0x69, 0x64, 0x85, 0x01, 0x24, - 0x0c, 0x86, 0x03, 0xff, 0x37, 0xe7, 0x03, 0xdd, 0x50, 0xfa, 0x92, 0xed, 0x10, 0x00, 0x32, 0x74, - 0xbb, 0x5b, 0x15, 0x2e, 0xda, 0x98, 0xdb, 0x27, 0x03, 0xb2, 0xa5, 0x98, 0xba, 0x69, 0x73, 0x89, - 0xa0, 0xb9, 0xaf, 0x39, 0xfa, 0x2f, 0x04, 0xc3, 0xcf, 0x99, 0x12, 0x87, 0xf3, 0xaa, 0x4a, 0x96, - 0xa5, 0x93, 0xad, 0x81, 0x29, 0x6b, 0xf0, 0x35, 0x26, 0xf2, 0x16, 0x24, 0x6c, 0x29, 0x92, 0x25, - 0xc9, 0x3a, 0xc1, 0x9a, 0xba, 0x66, 0xbc, 0x24, 0x6c, 0xa2, 0x37, 0x38, 0xa7, 0x0f, 0xc3, 0x51, - 0x86, 0x6e, 0x42, 0x03, 0x38, 0x30, 0xac, 0xbe, 0x4d, 0xba, 0x0d, 0x4e, 0x95, 0x5c, 0xa9, 0xa6, - 0x0d, 0xa4, 0x1e, 0xc9, 0x4c, 0xb6, 0x30, 0xa7, 0x2e, 0x4b, 0x0e, 0x29, 0x15, 0x84, 0x66, 0xb3, - 0xb9, 0xdb, 0x6c, 0xee, 0x37, 0xf7, 0xe1, 0x13, 0xbf, 0x0f, 0x9a, 0xad, 0x03, 0x7c, 0x6a, 0xf7, - 0xe0, 0xe3, 0x48, 0xbf, 0xba, 0x79, 0x51, 0xce, 0x5b, 0x7d, 0xf3, 0x04, 0xd3, 0xf6, 0x6e, 0xf5, - 0xa3, 0xeb, 0xf6, 0x11, 0x3e, 0x5e, 0xb1, 0xd2, 0x3d, 0x5a, 0xf6, 0x30, 0x73, 0x99, 0x79, 0xc4, - 0x94, 0xfd, 0xec, 0xf1, 0xf5, 0x7e, 0xfb, 0xf6, 0xe2, 0x28, 0xfb, 0x0c, 0x49, 0x99, 0xcb, 0xf1, - 0xc5, 0xa4, 0x77, 0x7e, 0x40, 0x9a, 0xb7, 0x67, 0x93, 0xfd, 0xea, 0x41, 0x49, 0xb9, 0x6a, 0x9d, - 0xec, 0xdd, 0x37, 0xfb, 0x56, 0x73, 0xef, 0x29, 0xd7, 0xad, 0x5c, 0x9e, 0x3d, 0xef, 0x76, 0xf2, - 0x57, 0xf7, 0x62, 0xe5, 0xea, 0x24, 0x27, 0x9e, 0x48, 0x4f, 0xad, 0x5c, 0xaf, 0xdb, 0xaa, 0xf6, - 0x5b, 0xc6, 0xab, 0x39, 0x34, 0xcf, 0x7b, 0xcd, 0xeb, 0xde, 0x63, 0xf9, 0xed, 0x6c, 0xd2, 0x9c, - 0x9e, 0xeb, 0xb7, 0xea, 0xd5, 0xa1, 0xfe, 0xa0, 0x35, 0xf5, 0x8b, 0xdc, 0xd9, 0x5e, 0x73, 0xaf, - 0x94, 0xdf, 0xbf, 0x7b, 0x3d, 0x3f, 0x6c, 0x12, 0xb1, 0x49, 0x3b, 0xa2, 0xb7, 0x6f, 0x5e, 0x3a, - 0xc3, 0xab, 0x41, 0xab, 0xc5, 0x6d, 0x6f, 0x24, 0xbe, 0xbb, 0x9a, 0xab, 0x93, 0xed, 0xfb, 0xd3, - 0xfd, 0xbd, 0xef, 0x19, 0xf6, 0x9c, 0xf8, 0xee, 0x28, 0xb6, 0x66, 0xb9, 0xdb, 0x1b, 0xdd, 0xa1, - 0xa1, 0xb8, 0x9a, 0x69, 0x24, 0xba, 0x84, 0xa8, 0xb2, 0xa4, 0xbc, 0x24, 0xf9, 0xd9, 0x7c, 0x24, - 0xd9, 0x09, 0x98, 0x72, 0x53, 0x19, 0x0e, 0x00, 0xf3, 0xe9, 0x1e, 0x71, 0xf7, 0x75, 0x82, 0x8f, - 0xce, 0xee, 0xf4, 0x46, 0xea, 0x9d, 0xc3, 0x1c, 0x24, 0x39, 0xa4, 0x1e, 0x8e, 0xff, 0x21, 0xfe, - 0x14, 0xf4, 0x45, 0x51, 0xc5, 0x26, 0x92, 0x4b, 0xbc, 0xd2, 0x49, 0x8e, 0xb5, 0xc2, 0xf1, 0x75, - 0x3d, 0xed, 0x4e, 0x2d, 0x6f, 0xe2, 0x34, 0x45, 0xc2, 0x16, 0x33, 0xcf, 0xd2, 0x48, 0xf2, 0x0a, - 0x08, 0x7a, 0xda, 0xb1, 0x95, 0x06, 0xa7, 0xd9, 0x66, 0xfa, 0xd9, 0xc1, 0x9f, 0x92, 0xaa, 0xee, - 0x8f, 0x00, 0xc6, 0xa9, 0xe6, 0xc0, 0xec, 0x13, 0x3b, 0xc9, 0xe9, 0x26, 0xb4, 0x27, 0x90, 0xc6, - 0xf6, 0x4c, 0xb1, 0x34, 0xe5, 0xa5, 0x61, 0x90, 0x71, 0x02, 0xcb, 0xb7, 0x90, 0x80, 0x2e, 0x21, - 0x05, 0x0b, 0x7d, 0xb5, 0xe8, 0x03, 0x27, 0xcc, 0x28, 0xa5, 0xd6, 0x72, 0x25, 0x51, 0x18, 0xf7, - 0x09, 0xd1, 0x4f, 0xb5, 0x5e, 0xdf, 0x35, 0x88, 0xe3, 0xd4, 0xbe, 0x64, 0x59, 0x4a, 0xd3, 0xe8, - 0xe9, 0xa4, 0x96, 0x2b, 0x7b, 0x05, 0xf6, 0x34, 0x9b, 0x50, 0x4c, 0xd4, 0x38, 0x45, 0x37, 0x95, - 0x97, 0xb1, 0xe6, 0x10, 0xe8, 0x88, 0x34, 0x35, 0x87, 0x6e, 0xed, 0xc7, 0x4c, 0x31, 0x07, 0x96, - 0x69, 0x40, 0x87, 0x6a, 0xd8, 0xe6, 0x50, 0x4b, 0xdf, 0x63, 0x25, 0xc1, 0xb4, 0xb0, 0x8a, 0x53, - 0x9b, 0xcd, 0xe7, 0x3f, 0xe7, 0xbc, 0x40, 0x7b, 0x96, 0x36, 0x8d, 0x24, 0xa7, 0x19, 0x16, 0xd4, - 0x23, 0x06, 0x74, 0x39, 0xc9, 0x43, 0x9f, 0x61, 0x15, 0xd0, 0x8e, 0x26, 0xb3, 0x7c, 0xa4, 0x1c, - 0x25, 0xff, 0x1a, 0xac, 0x13, 0xa3, 0x47, 0xbc, 0xa2, 0x43, 0x0b, 0xc8, 0x93, 0x5c, 0x76, 0x74, - 0x4d, 0x25, 0xb6, 0x93, 0x84, 0xf2, 0x75, 0x9c, 0x10, 0xf7, 0x63, 0x2c, 0xbb, 0x1f, 0x60, 0xd9, - 0x65, 0x58, 0xb6, 0xb1, 0x31, 0xd7, 0x1c, 0x2a, 0x7d, 0x8a, 0x6c, 0xf7, 0x5d, 0x64, 0xd3, 0xc2, - 0x4e, 0xe3, 0x1a, 0xbf, 0x6e, 0x68, 0x1d, 0x18, 0xca, 0xd0, 0x4a, 0x7e, 0xa3, 0x23, 0xfc, 0xc1, - 0x1a, 0xa4, 0x85, 0xb8, 0x9f, 0xdf, 0x84, 0x19, 0x74, 0x56, 0x27, 0x2e, 0x74, 0x16, 0x4a, 0x1d, - 0xc1, 0xc2, 0xb5, 0x47, 0x92, 0x9e, 0xa4, 0xc3, 0xe2, 0x10, 0x85, 0x90, 0x47, 0xb8, 0x46, 0x63, - 0x31, 0x14, 0x18, 0x89, 0x3a, 0xed, 0xb8, 0x30, 0x9c, 0xcd, 0xcd, 0xa4, 0xa2, 0x13, 0xc9, 0x0e, - 0x6a, 0xb9, 0xbc, 0x60, 0x1a, 0xa7, 0xd0, 0x91, 0x24, 0xcf, 0xcf, 0x85, 0xac, 0x28, 0x22, 0xe6, - 0x00, 0xec, 0x8d, 0x36, 0x20, 0x30, 0x29, 0xc9, 0xa4, 0x4f, 0xbb, 0x40, 0xb2, 0xfd, 0x34, 0x8c, - 0x19, 0xb0, 0xdd, 0xea, 0x6b, 0xba, 0x0a, 0x35, 0xa1, 0x64, 0xf1, 0xf3, 0xe5, 0x75, 0xaf, 0xfc, - 0xc6, 0xf7, 0x8c, 0xb7, 0x2e, 0x60, 0x81, 0xb8, 0x53, 0x58, 0x28, 0x1b, 0xff, 0xee, 0x02, 0xfb, - 0xd9, 0xea, 0x4a, 0x0a, 0x99, 0x79, 0x4f, 0x03, 0x4d, 0x9f, 0xd6, 0xee, 0x8f, 0x80, 0x69, 0x38, - 0x75, 0x40, 0x67, 0x6d, 0x68, 0xeb, 0x49, 0xca, 0x4f, 0x30, 0x3f, 0x33, 0x36, 0xbb, 0xdd, 0x5c, - 0xdd, 0xe7, 0x7b, 0x94, 0xed, 0xf9, 0xbc, 0x45, 0x15, 0xab, 0x07, 0x67, 0xbd, 0x26, 0xe5, 0x2c, - 0xcd, 0xa6, 0x71, 0xdb, 0x6c, 0x3a, 0x6c, 0xb9, 0x66, 0xf1, 0x73, 0xd0, 0x6e, 0x36, 0x0f, 0x9e, - 0x06, 0xbd, 0xe6, 0xda, 0x7f, 0xbb, 0x83, 0x66, 0xb3, 0xf7, 0x30, 0xbe, 0x6e, 0x35, 0x5f, 0x95, - 0xc7, 0xe3, 0xa7, 0xa3, 0xe6, 0xcd, 0x63, 0xeb, 0xb8, 0x79, 0x3e, 0x6e, 0xbd, 0x99, 0xcd, 0xdd, - 0x16, 0xb0, 0xa8, 0xf1, 0xe3, 0xe1, 0xd1, 0xae, 0x53, 0xde, 0xab, 0x68, 0x17, 0xe3, 0xb7, 0xde, - 0x20, 0x7f, 0xf6, 0x70, 0x66, 0xbc, 0x3d, 0xb5, 0x5e, 0x5c, 0xe3, 0x59, 0x91, 0xcf, 0x53, 0x57, - 0xfa, 0xf1, 0xa9, 0x74, 0x9c, 0x1f, 0xea, 0xb7, 0xa7, 0x96, 0x6e, 0xdd, 0x97, 0x6e, 0x5f, 0xef, - 0x35, 0x93, 0x74, 0xaa, 0xd9, 0xe3, 0x29, 0x11, 0x9f, 0x6f, 0xf5, 0xe3, 0xf1, 0x93, 0x5d, 0x34, - 0x6e, 0xd4, 0xfd, 0xfc, 0xa9, 0xe1, 0xaa, 0x97, 0xa3, 0x66, 0x2f, 0xd5, 0x75, 0x33, 0x5d, 0xd9, - 0x39, 0x75, 0x0e, 0xf4, 0xf3, 0xd3, 0x61, 0x5f, 0x1f, 0x5c, 0x3d, 0x9f, 0x68, 0xe5, 0xf3, 0xcb, - 0xbd, 0xfd, 0xa3, 0xde, 0xf8, 0x66, 0x00, 0x3c, 0x4d, 0x2a, 0x0d, 0x54, 0x3d, 0xd5, 0x39, 0xbc, - 0xdd, 0xed, 0xef, 0x1f, 0xa9, 0x87, 0xed, 0x89, 0xf4, 0x52, 0x76, 0x0a, 0xfb, 0x99, 0xe9, 0x5b, - 0xff, 0xb8, 0xf3, 0xdc, 0x2a, 0xef, 0x5e, 0x5d, 0x9d, 0x76, 0xf7, 0xc6, 0xa6, 0xd5, 0xce, 0x68, - 0x25, 0xe9, 0xb5, 0xb3, 0xaf, 0xef, 0xb7, 0xf7, 0x1e, 0x26, 0x95, 0xa7, 0xbb, 0xfb, 0xe7, 0x69, - 0xde, 0x9e, 0x0e, 0x0a, 0xe7, 0xa5, 0xb6, 0xfe, 0x74, 0x55, 0xe8, 0x0f, 0x53, 0xc6, 0x83, 0x73, - 0x70, 0xb4, 0x77, 0x76, 0xd5, 0xce, 0xf7, 0x9a, 0x13, 0x29, 0x5b, 0x68, 0xf6, 0x9a, 0xb6, 0x7b, - 0x77, 0xd6, 0xef, 0xbe, 0xf4, 0x9e, 0xbb, 0xfb, 0x4d, 0x59, 0x6b, 0xf5, 0xc7, 0xc3, 0xce, 0xd1, - 0x78, 0xff, 0xb6, 0x35, 0x18, 0xaa, 0x97, 0x7d, 0xed, 0x4a, 0xbd, 0x29, 0xd9, 0xa3, 0xa3, 0xe7, - 0xd3, 0xce, 0xf5, 0xd3, 0xfe, 0x78, 0xaf, 0xdf, 0xae, 0xee, 0x1e, 0x39, 0xa6, 0x79, 0x54, 0xcc, - 0xdf, 0x1c, 0x5d, 0x1f, 0x99, 0x47, 0xb7, 0x7b, 0x95, 0x97, 0xe9, 0xf9, 0xd3, 0x51, 0xf9, 0xf6, - 0xb9, 0x39, 0x3d, 0xb3, 0xaf, 0x33, 0xd2, 0x59, 0x66, 0x6f, 0x2c, 0x5d, 0x58, 0xe6, 0x9b, 0xd4, - 0xaf, 0x9e, 0x1e, 0xb4, 0x9c, 0xc7, 0xdc, 0xdb, 0x79, 0xee, 0xf1, 0xe2, 0xcd, 0xc9, 0x9d, 0xe6, - 0x27, 0xaf, 0xe4, 0xdc, 0x2a, 0xbc, 0x3d, 0x3c, 0xbf, 0x56, 0xe4, 0x87, 0x9b, 0x4c, 0xff, 0x6c, - 0xf7, 0xf4, 0x39, 0x53, 0xcc, 0x3f, 0xee, 0x35, 0x8f, 0x3a, 0xa9, 0xf2, 0xb0, 0x54, 0xaa, 0x18, - 0xf9, 0xc3, 0xd4, 0xe1, 0xf5, 0xa5, 0xfa, 0xa4, 0x66, 0x87, 0xf9, 0x9b, 0x37, 0xf5, 0xfa, 0x49, - 0xbd, 0x3b, 0xbb, 0xe9, 0x1e, 0xe9, 0xc5, 0xc3, 0xee, 0x49, 0x4f, 0xcd, 0xca, 0xe5, 0xce, 0xe8, - 0x55, 0xad, 0xde, 0x57, 0x87, 0x96, 0xad, 0x5e, 0x56, 0xae, 0x6e, 0x2e, 0x06, 0x44, 0x7a, 0x2b, - 0xde, 0x5c, 0x5e, 0x5c, 0x1f, 0xeb, 0x7b, 0x7b, 0xcf, 0x87, 0x77, 0xcf, 0x07, 0x62, 0xf3, 0xfc, - 0xec, 0xea, 0xd1, 0x19, 0x5c, 0xdb, 0x27, 0xfa, 0xc0, 0x9a, 0xbe, 0xde, 0x95, 0x5f, 0x86, 0xf2, - 0xd1, 0x55, 0x2b, 0x77, 0xd0, 0x39, 0x7a, 0x69, 0x77, 0x52, 0x67, 0x06, 0x69, 0x1d, 0x17, 0x2a, - 0xc7, 0xc7, 0xed, 0xbb, 0x56, 0xff, 0xaa, 0x3b, 0x1c, 0x9f, 0x9c, 0x59, 0xb9, 0xe9, 0x6d, 0xd5, - 0x1a, 0xbc, 0x66, 0xef, 0x4e, 0x6e, 0xaf, 0x4b, 0x36, 0x71, 0xc5, 0x03, 0x4b, 0xec, 0x3c, 0xdf, - 0x3d, 0x5e, 0x5f, 0xb7, 0x53, 0x0f, 0xcf, 0xe5, 0xd4, 0x85, 0x76, 0xdb, 0x79, 0xc9, 0x1c, 0x1c, - 0xbd, 0x0d, 0xb3, 0x03, 0xed, 0xf0, 0xe9, 0x7e, 0x92, 0xea, 0x55, 0x1e, 0xb3, 0xd7, 0xb7, 0x2f, - 0xee, 0xe5, 0xe0, 0xf5, 0x48, 0x73, 0xaf, 0x6f, 0x1e, 0xee, 0xce, 0xdf, 0xde, 0x5a, 0xee, 0xb0, - 0x7d, 0x79, 0xa2, 0x1c, 0x8a, 0x6f, 0xd7, 0xbb, 0x07, 0xa9, 0xc7, 0x6a, 0xa6, 0x65, 0xf4, 0x77, - 0xa5, 0x9c, 0x38, 0x2a, 0x9a, 0x87, 0x5d, 0x67, 0xff, 0xf6, 0xac, 0xf7, 0x70, 0x76, 0xb9, 0xdf, - 0xbd, 0x28, 0x3e, 0x29, 0xc7, 0x13, 0xb1, 0x7d, 0x74, 0xa9, 0xdd, 0x4d, 0xc7, 0xbd, 0x67, 0xb9, - 0x74, 0x76, 0x34, 0xbc, 0x4b, 0x99, 0x4f, 0x85, 0x51, 0xee, 0xe5, 0xa5, 0x94, 0x79, 0x33, 0x8e, - 0x26, 0x7b, 0x27, 0x76, 0x6f, 0x78, 0x96, 0xcb, 0x4d, 0x53, 0xf2, 0x7d, 0x65, 0x7c, 0x7b, 0xf0, - 0xaa, 0x95, 0xa5, 0xd3, 0x4a, 0xf7, 0xea, 0xf8, 0x6d, 0x6c, 0xb4, 0x9e, 0x2b, 0xee, 0x91, 0x65, - 0xa9, 0x47, 0x55, 0xf9, 0x71, 0xaf, 0x73, 0x77, 0x7c, 0xd7, 0xba, 0x3a, 0x32, 0x34, 0xeb, 0x5e, - 0x3c, 0x94, 0x5d, 0x45, 0x57, 0x6e, 0xca, 0xa3, 0xd6, 0xf4, 0x74, 0xf0, 0x20, 0x75, 0xee, 0xec, - 0xab, 0xce, 0xf9, 0xd9, 0x54, 0x96, 0x8e, 0x8f, 0x77, 0xfb, 0xb9, 0x4b, 0xed, 0xc1, 0x7e, 0x90, - 0x7b, 0x6a, 0xa9, 0x29, 0xbf, 0x12, 0x45, 0xdd, 0xbb, 0xb9, 0xa8, 0xee, 0x5f, 0xed, 0x1f, 0x91, - 0x7b, 0xf1, 0xee, 0xf2, 0xfe, 0x4a, 0x51, 0xaf, 0x2a, 0xba, 0x7b, 0x79, 0xb1, 0x3f, 0x4c, 0x95, - 0x4b, 0xaf, 0xb9, 0xa3, 0xc9, 0xed, 0x8d, 0x79, 0x4c, 0xee, 0xad, 0xee, 0xf3, 0x95, 0x76, 0x78, - 0x78, 0x58, 0x84, 0xa5, 0xb4, 0x77, 0xfa, 0x9c, 0x95, 0x0f, 0x7b, 0x57, 0x93, 0x07, 0xe7, 0x16, - 0x06, 0x74, 0xf2, 0x28, 0xf7, 0x52, 0xad, 0x09, 0xfc, 0x57, 0xaa, 0x92, 0x43, 0xe5, 0x62, 0x04, - 0x0c, 0xfb, 0x38, 0xab, 0x97, 0x64, 0xd1, 0xd8, 0x2b, 0x3f, 0x1f, 0xa4, 0xe4, 0x4e, 0x33, 0xab, - 0xb6, 0x9e, 0xee, 0x26, 0x83, 0x71, 0xe5, 0xe9, 0x38, 0x73, 0xf4, 0xe8, 0x4e, 0x2e, 0x5d, 0xf9, - 0x78, 0xa2, 0x5b, 0x57, 0x99, 0xd3, 0x83, 0xe7, 0xce, 0xab, 0x28, 0xde, 0x0c, 0xd4, 0xf3, 0xa3, - 0xa7, 0x89, 0x7d, 0x40, 0xf4, 0xd4, 0x34, 0x65, 0x3f, 0x1d, 0xdb, 0x66, 0xca, 0xb8, 0xed, 0xe7, - 0x2f, 0xed, 0xf3, 0xa3, 0x83, 0xf1, 0x49, 0xe9, 0xde, 0x7e, 0x38, 0x3f, 0xbb, 0xcb, 0x4d, 0x6e, - 0xc8, 0xf5, 0xfd, 0x61, 0xe7, 0xb9, 0xa3, 0xbc, 0xb8, 0xa7, 0xc7, 0x5d, 0x92, 0xb5, 0x95, 0xb2, - 0x63, 0x4d, 0x47, 0x2f, 0x79, 0xb9, 0x74, 0x57, 0x78, 0x29, 0x54, 0x3a, 0x76, 0xbe, 0x39, 0xc8, - 0x5e, 0x8e, 0x32, 0x57, 0x5a, 0xb7, 0xef, 0x1c, 0xe5, 0x86, 0x67, 0x23, 0xa5, 0x52, 0xca, 0x5f, - 0x68, 0x57, 0x57, 0xd7, 0xe7, 0x26, 0x51, 0xad, 0xcb, 0xee, 0xa1, 0xd1, 0x19, 0x2b, 0xc0, 0x1b, - 0x53, 0xd2, 0xde, 0xfe, 0x7e, 0xa9, 0xac, 0x9c, 0xbc, 0xdd, 0xf4, 0x76, 0xf5, 0xab, 0xde, 0xb3, - 0xf5, 0xdc, 0xbb, 0xd9, 0x33, 0x8e, 0xdd, 0x03, 0xe3, 0x21, 0xf7, 0x2a, 0x0f, 0x1e, 0x8e, 0x4b, - 0xed, 0x8b, 0xdd, 0xd3, 0xa7, 0xf2, 0xd8, 0xb1, 0x53, 0xc7, 0x4f, 0x6f, 0x8f, 0x86, 0xfc, 0xac, - 0xca, 0x2f, 0xad, 0xe1, 0x7e, 0xf7, 0x56, 0x3c, 0x1c, 0xe9, 0xe3, 0x57, 0xd9, 0xbd, 0xed, 0x1d, - 0x97, 0xdf, 0xae, 0x1f, 0xda, 0xe7, 0xc7, 0xce, 0xa8, 0x33, 0xd1, 0xc7, 0x6f, 0xb9, 0xfb, 0x47, - 0x57, 0x2a, 0x4c, 0x9e, 0x6d, 0x2d, 0xd3, 0x75, 0x86, 0xba, 0x61, 0xb4, 0xef, 0x2e, 0xa7, 0xa6, - 0x61, 0x5d, 0x8a, 0xd7, 0xa7, 0x45, 0xf3, 0xee, 0xfc, 0xe4, 0xe5, 0xa5, 0xbb, 0xaf, 0x1f, 0x14, - 0x14, 0xe7, 0x66, 0xef, 0xbc, 0xe9, 0xf4, 0xde, 0x5a, 0xf9, 0xca, 0x41, 0xb9, 0xd7, 0x39, 0xb9, - 0xeb, 0x75, 0x9e, 0xca, 0x83, 0x8c, 0xb2, 0x3f, 0x3a, 0x69, 0x9e, 0x0e, 0x26, 0x27, 0x6f, 0x99, - 0xcc, 0xb0, 0xdc, 0x2f, 0x91, 0xde, 0x61, 0xbb, 0x7c, 0x66, 0x1f, 0x16, 0x9e, 0x8f, 0xad, 0xcc, - 0xd3, 0xa4, 0xf0, 0x9a, 0xcf, 0x49, 0x95, 0x9b, 0x72, 0x76, 0x62, 0x1c, 0xde, 0x5d, 0xb7, 0x0e, - 0xf4, 0x6e, 0xfb, 0xe9, 0xdc, 0x75, 0xd5, 0x5c, 0x5b, 0xb9, 0x95, 0xa4, 0x69, 0x89, 0x54, 0x2f, - 0x5f, 0xfa, 0x43, 0x65, 0x7a, 0x2d, 0x9a, 0x97, 0xc3, 0xec, 0x5b, 0xf6, 0x2d, 0xb3, 0xb7, 0x9b, - 0xaa, 0x8c, 0xb5, 0x49, 0xb3, 0xad, 0x9e, 0xdd, 0x66, 0x7b, 0xc6, 0x60, 0xb7, 0x30, 0x69, 0x8e, - 0x4b, 0x15, 0x6b, 0x7c, 0xa8, 0xdc, 0x3f, 0xeb, 0x6d, 0x7b, 0xd7, 0x78, 0x98, 0x9c, 0x3e, 0x3f, - 0x97, 0xf2, 0xb7, 0x07, 0xbd, 0xd1, 0xf9, 0xc1, 0xdd, 0x41, 0xf3, 0xb8, 0xfd, 0x36, 0x69, 0x8f, - 0x53, 0xf7, 0xe6, 0xc0, 0x28, 0x9f, 0x35, 0x35, 0xf9, 0x4e, 0x1e, 0x96, 0x74, 0x72, 0x78, 0xbd, - 0x5b, 0x74, 0x94, 0xac, 0xd8, 0x3d, 0x75, 0x65, 0x5b, 0xb5, 0x33, 0xc7, 0xaf, 0x77, 0xa5, 0x47, - 0x3b, 0x65, 0x8e, 0xc6, 0x6d, 0xf7, 0xfa, 0x70, 0xbf, 0x7c, 0x56, 0x78, 0x3b, 0xa8, 0x8a, 0xaf, - 0xe7, 0xbb, 0xa5, 0xc7, 0xeb, 0x7d, 0xd3, 0x2c, 0x66, 0x5f, 0xda, 0xc7, 0x92, 0xfc, 0x9a, 0x3f, - 0x27, 0x87, 0x77, 0x27, 0x2a, 0xe9, 0x66, 0xfa, 0xce, 0x59, 0xbb, 0xdd, 0xb1, 0xdc, 0xe2, 0xa0, - 0xf2, 0x30, 0x38, 0x7e, 0xdd, 0xdb, 0x6b, 0x1a, 0xd7, 0xa2, 0x52, 0xc8, 0x56, 0x06, 0x93, 0xc1, - 0xc4, 0xbe, 0x7a, 0xbb, 0x1a, 0x4e, 0x2f, 0x0d, 0xc7, 0xba, 0x1e, 0x77, 0x9b, 0x8f, 0x2f, 0x96, - 0xdb, 0x7f, 0xb3, 0x01, 0x2d, 0x37, 0xd9, 0xc9, 0x79, 0xa7, 0x5b, 0xb8, 0x77, 0x77, 0xcf, 0xce, - 0xaa, 0x7b, 0x57, 0x37, 0xd9, 0xea, 0xf0, 0x34, 0xd5, 0x93, 0x0b, 0xe5, 0x5e, 0xfb, 0xf4, 0x32, - 0xaf, 0xdc, 0x88, 0x95, 0x76, 0xe5, 0xa8, 0xa0, 0x3e, 0x4d, 0x8e, 0xf5, 0x42, 0xf6, 0xc0, 0x99, - 0x54, 0xef, 0x0f, 0xdf, 0x4e, 0x77, 0x2f, 0x0e, 0xdf, 0xee, 0x9f, 0xaf, 0x3b, 0xd5, 0xf3, 0xd3, - 0xd6, 0xc5, 0xed, 0x6e, 0xab, 0x7d, 0x95, 0x1a, 0x1e, 0xf4, 0x77, 0x33, 0x77, 0xe5, 0xa7, 0xb7, - 0xdb, 0xf1, 0xc9, 0x7e, 0xe7, 0x66, 0xb0, 0x67, 0x6b, 0xc7, 0xa9, 0x5b, 0xa4, 0xfd, 0x8c, 0xdc, - 0x7e, 0x68, 0x9f, 0x9d, 0x9e, 0x3a, 0xcf, 0x3d, 0xad, 0xe9, 0x16, 0x2c, 0xab, 0x3c, 0xd4, 0xad, - 0x89, 0x9c, 0x73, 0xdf, 0xf6, 0x2b, 0x47, 0x95, 0x49, 0x7f, 0x7a, 0x78, 0xb1, 0xb7, 0x7b, 0x92, - 0xef, 0x1c, 0xf4, 0x4a, 0x57, 0x97, 0xd9, 0xdc, 0xae, 0x76, 0x99, 0x7f, 0x3c, 0x1b, 0xe7, 0xec, - 0xbd, 0xb6, 0x7b, 0x7f, 0xbb, 0xf7, 0x70, 0x9a, 0x22, 0x8e, 0x31, 0xca, 0x1f, 0x56, 0xaf, 0x26, - 0xaf, 0xdd, 0x81, 0xbc, 0x67, 0xc8, 0x67, 0xa7, 0xcf, 0x07, 0xb7, 0x6d, 0xeb, 0xf5, 0xf5, 0x49, - 0x36, 0xee, 0x3b, 0x3d, 0x51, 0xef, 0xdf, 0x8f, 0xaa, 0xe3, 0xdb, 0x7c, 0xf1, 0xf5, 0xe6, 0xf0, - 0xf5, 0xb2, 0xfa, 0xf6, 0x7a, 0x6b, 0x9f, 0x96, 0x5f, 0x5e, 0x4f, 0x9e, 0x2b, 0x8f, 0xcf, 0x4f, - 0x6f, 0x3d, 0x31, 0x6b, 0xc9, 0xd5, 0xd4, 0xf4, 0xaa, 0xe2, 0x3c, 0x3c, 0x59, 0x8f, 0x93, 0x93, - 0x03, 0xad, 0x7d, 0x7c, 0x73, 0xee, 0x1c, 0x8d, 0xc7, 0xd6, 0xf4, 0xba, 0x50, 0xe8, 0xed, 0x5f, - 0x18, 0x77, 0x99, 0x14, 0x01, 0x42, 0x52, 0x0f, 0xf7, 0x32, 0x39, 0xfd, 0x2a, 0x3f, 0xec, 0x14, - 0xa7, 0xd9, 0xd7, 0xb7, 0xa3, 0x37, 0xf7, 0xe1, 0xf6, 0xfc, 0x72, 0xbf, 0x64, 0xaa, 0x8f, 0xc7, - 0xe2, 0xe5, 0xeb, 0xad, 0x76, 0x7f, 0xec, 0xf6, 0x4e, 0x0e, 0x4e, 0xce, 0x8e, 0x4e, 0x1f, 0x4b, - 0xa2, 0x3a, 0x21, 0x8f, 0x53, 0x43, 0x96, 0x53, 0x4e, 0xfb, 0xe4, 0xe4, 0xf5, 0xdc, 0x10, 0xef, - 0xdf, 0x72, 0xf6, 0xa9, 0x7b, 0x26, 0xef, 0x5e, 0xdd, 0x5f, 0x1a, 0x8f, 0xee, 0xe0, 0x58, 0x2a, - 0xdc, 0xbf, 0xb6, 0xaf, 0x4d, 0x39, 0x53, 0x1d, 0x0c, 0x86, 0x53, 0xe5, 0xea, 0x6e, 0x54, 0xd6, - 0xba, 0xad, 0xf3, 0xd1, 0x83, 0xad, 0xf7, 0xdf, 0x7a, 0x7b, 0xa7, 0x7b, 0x23, 0x50, 0xc9, 0x53, - 0x95, 0xc3, 0xe2, 0xe4, 0xf9, 0xa4, 0x5a, 0xa8, 0x28, 0x7b, 0xc4, 0x4d, 0xb5, 0xa5, 0x87, 0x6e, - 0x27, 0x75, 0xfa, 0x62, 0x66, 0xee, 0xdd, 0xd4, 0xa8, 0xa3, 0xbc, 0x4a, 0xf6, 0x6b, 0xe9, 0xe5, - 0xe9, 0x46, 0x7e, 0x29, 0x9c, 0x4b, 0x27, 0xaf, 0xd6, 0x85, 0xfc, 0xb2, 0xbf, 0x6f, 0x39, 0x92, - 0x52, 0x3d, 0xcd, 0xda, 0xd7, 0xe7, 0x0f, 0xc7, 0xbd, 0x4b, 0xd9, 0xbe, 0x9f, 0xee, 0xa9, 0x8f, - 0xcf, 0xa4, 0xe4, 0xee, 0x5e, 0x35, 0xdf, 0xdc, 0x17, 0xf9, 0xb1, 0x25, 0x8e, 0xf7, 0x48, 0xe1, - 0xd6, 0x38, 0xd7, 0xac, 0x81, 0xf1, 0x04, 0xba, 0xcb, 0x30, 0x33, 0x7c, 0xee, 0x96, 0x4e, 0xba, - 0xe5, 0x11, 0xc9, 0x66, 0x73, 0x87, 0xc3, 0x6e, 0x35, 0xb7, 0x3f, 0xca, 0x94, 0x89, 0xb1, 0x9b, - 0x49, 0x19, 0x97, 0x65, 0x4b, 0x06, 0xa5, 0xf3, 0xea, 0xf8, 0x49, 0xd6, 0xc4, 0xe7, 0x56, 0xc7, - 0x32, 0xcf, 0xab, 0x30, 0xf0, 0x9b, 0x97, 0xe7, 0xf2, 0xf1, 0xd9, 0xd8, 0x92, 0xef, 0x7b, 0xa6, - 0xd5, 0x94, 0xfb, 0xae, 0x7c, 0x71, 0xff, 0x32, 0x75, 0x9b, 0xed, 0xfc, 0x49, 0x2a, 0xf3, 0x6a, - 0x8a, 0x9d, 0x66, 0xe7, 0xfc, 0x3e, 0x77, 0x90, 0x93, 0x4f, 0xbb, 0x86, 0xd3, 0xb7, 0x76, 0x0b, - 0x52, 0x55, 0x1d, 0xbc, 0x95, 0x33, 0x87, 0x93, 0x4c, 0x46, 0x55, 0xf2, 0x17, 0x0f, 0xe7, 0x4f, - 0x05, 0xa0, 0xd5, 0xe9, 0xc3, 0xed, 0x5d, 0x4e, 0x7d, 0xbc, 0x76, 0xf6, 0xaa, 0xe5, 0xd7, 0x93, - 0xd3, 0x72, 0xf5, 0x55, 0x7a, 0x1b, 0xc2, 0xd0, 0x8e, 0xb2, 0xa3, 0xcb, 0x87, 0x9b, 0x72, 0xbe, - 0x5c, 0x94, 0xef, 0x3b, 0x07, 0xa6, 0xb2, 0x6b, 0x76, 0xf7, 0x72, 0xe4, 0xe8, 0xfa, 0xed, 0x58, - 0x54, 0xce, 0x5a, 0x22, 0xe8, 0x6e, 0xe3, 0x2b, 0xb1, 0xd7, 0x1d, 0x0d, 0x3b, 0xea, 0x48, 0xcd, - 0x16, 0xba, 0xd9, 0x21, 0x50, 0xfd, 0xe9, 0xe5, 0x7e, 0xfe, 0xf8, 0xf8, 0xf0, 0xb4, 0x34, 0x6c, - 0xa9, 0x19, 0xa3, 0x68, 0x54, 0xd4, 0x7c, 0xf1, 0xf6, 0xe2, 0xe4, 0xd2, 0x28, 0x19, 0x7d, 0x1b, - 0x04, 0xa4, 0x7d, 0x97, 0x97, 0xd4, 0xbc, 0xf1, 0x96, 0xd3, 0x6e, 0xb4, 0xf3, 0xd3, 0x42, 0xb6, - 0xb0, 0x6f, 0x90, 0xee, 0x69, 0xe6, 0xf8, 0xe0, 0x54, 0xbf, 0x7f, 0x72, 0x9f, 0xee, 0xa5, 0x57, - 0x73, 0xbf, 0x5f, 0x98, 0x74, 0x9e, 0x47, 0xce, 0x81, 0x9c, 0x29, 0x0d, 0xaa, 0xb6, 0xd4, 0xd6, - 0x9d, 0xd3, 0x41, 0x61, 0x78, 0xf8, 0x72, 0x75, 0xaf, 0x8f, 0xca, 0x37, 0x99, 0x31, 0x79, 0x7a, - 0x7b, 0x3e, 0x3c, 0x24, 0xe5, 0xc9, 0x93, 0x76, 0xfb, 0x66, 0x1d, 0x17, 0xef, 0x9b, 0xf7, 0xbb, - 0xa7, 0x7b, 0xe7, 0xe3, 0xeb, 0x93, 0xc9, 0xf8, 0xfa, 0xd1, 0x68, 0x9b, 0x0f, 0x07, 0x13, 0x45, - 0x3a, 0x99, 0x9c, 0x97, 0xf6, 0xae, 0x2b, 0xbb, 0xe7, 0x46, 0xce, 0xac, 0x9e, 0xbf, 0xc2, 0x0c, - 0xbb, 0x23, 0x5b, 0x2a, 0xde, 0x18, 0x47, 0xcf, 0x0f, 0x67, 0xbb, 0xfa, 0xe0, 0xa8, 0xfd, 0x94, - 0x9f, 0x5e, 0x3e, 0x3e, 0xe4, 0xcf, 0xdc, 0xea, 0xa8, 0x38, 0x18, 0x1c, 0x0e, 0xc7, 0x8f, 0xa3, - 0xd1, 0xe4, 0x72, 0x44, 0xec, 0xd3, 0x2a, 0xe9, 0x8c, 0x9c, 0xb7, 0x87, 0xf3, 0xe7, 0xdb, 0x07, - 0xfb, 0x45, 0x7e, 0x55, 0x0e, 0x2e, 0xee, 0xee, 0x73, 0xf2, 0xbe, 0xbc, 0x77, 0x70, 0xa2, 0xe5, - 0xcf, 0x4e, 0xef, 0x6e, 0xee, 0xdf, 0xde, 0xee, 0x0f, 0xdb, 0xc5, 0xc2, 0xee, 0x30, 0x93, 0xb3, - 0x9b, 0xd9, 0xd7, 0x17, 0xb3, 0xa4, 0x57, 0xbb, 0xed, 0xde, 0x9d, 0xbc, 0x3b, 0xb4, 0xbb, 0x77, - 0xbb, 0xf7, 0xed, 0xb6, 0x7e, 0x77, 0x9f, 0x1d, 0xf6, 0x26, 0x17, 0x63, 0xc5, 0x49, 0x55, 0xee, - 0x33, 0x19, 0xe0, 0x4f, 0x4f, 0xc7, 0x1a, 0x39, 0xd5, 0xab, 0xf7, 0x0f, 0xcd, 0x0a, 0x39, 0x38, - 0x2d, 0x2a, 0xf6, 0x6e, 0xb9, 0xdb, 0xbf, 0x38, 0x9b, 0x4e, 0xf4, 0x8a, 0xfc, 0x7c, 0x75, 0x7f, - 0xf0, 0xbc, 0x9b, 0x95, 0xef, 0x33, 0xe6, 0x4b, 0xe9, 0x56, 0x79, 0x25, 0x86, 0x63, 0x97, 0xdb, - 0x95, 0xc3, 0xf2, 0xd0, 0x75, 0x06, 0xea, 0xab, 0x79, 0x38, 0x78, 0xab, 0x56, 0xed, 0xd1, 0x94, - 0xec, 0x67, 0x2e, 0xdf, 0x40, 0x41, 0x28, 0x0c, 0x46, 0x77, 0x0f, 0xa7, 0xcf, 0xd3, 0xc7, 0xca, - 0xa8, 0xf2, 0x5c, 0x7c, 0xe8, 0x3f, 0x91, 0xc3, 0xbc, 0x74, 0xf9, 0x50, 0x2e, 0xaa, 0x96, 0x76, - 0x51, 0x24, 0xe7, 0x99, 0x8b, 0xb7, 0xb1, 0x72, 0x50, 0x7e, 0x7b, 0xe9, 0xea, 0x6e, 0xc6, 0x51, - 0x8b, 0xa4, 0xfc, 0xa8, 0xbc, 0xca, 0x17, 0xe6, 0xb8, 0x7b, 0xdd, 0xcb, 0xe5, 0xae, 0x8b, 0xc5, - 0x4a, 0x51, 0x72, 0x73, 0xa3, 0x87, 0x87, 0x4a, 0xf9, 0x3e, 0xfb, 0x28, 0xf6, 0xae, 0xc4, 0x72, - 0xb5, 0x50, 0x2d, 0x93, 0xc7, 0x9b, 0xec, 0xfe, 0xcb, 0xd4, 0xdc, 0x7f, 0x3d, 0x7b, 0x04, 0x1d, - 0xf0, 0x50, 0xad, 0x5c, 0x8d, 0x4e, 0x0e, 0xec, 0xeb, 0x83, 0x92, 0x7c, 0xfc, 0x78, 0xb3, 0xd7, - 0x6a, 0x3d, 0x3d, 0x1e, 0xec, 0xdf, 0x2b, 0x83, 0xe2, 0x41, 0x16, 0xd0, 0x98, 0xd3, 0x8a, 0x85, - 0xc7, 0xea, 0xbd, 0xab, 0xed, 0x0e, 0x5f, 0xf4, 0xcb, 0x62, 0xf9, 0xd1, 0xdd, 0x7d, 0x3a, 0x6b, - 0xde, 0xeb, 0xc3, 0x5c, 0xf7, 0xf1, 0x6d, 0xef, 0xac, 0x7c, 0x95, 0x2a, 0xb6, 0x81, 0x93, 0x77, - 0xf2, 0x17, 0x6f, 0xc5, 0x67, 0x90, 0x61, 0x47, 0x92, 0xe2, 0xca, 0xf7, 0x97, 0xe6, 0x78, 0x78, - 0xd5, 0x3b, 0x9f, 0x1e, 0xea, 0xc3, 0x13, 0x5d, 0x1a, 0x57, 0xc7, 0x86, 0x7c, 0x31, 0x70, 0x87, - 0xd2, 0xb3, 0x99, 0xb9, 0xeb, 0x8c, 0xab, 0xc0, 0x91, 0x3b, 0xd7, 0xe3, 0x33, 0x65, 0x08, 0x64, - 0xf9, 0x34, 0x6e, 0xf7, 0xfb, 0x25, 0xa7, 0xdc, 0x77, 0x5e, 0x6d, 0xed, 0xbe, 0xe5, 0xf4, 0x9a, - 0x39, 0x27, 0x6f, 0xb4, 0x41, 0x6d, 0x2e, 0x1c, 0x95, 0x2f, 0x52, 0x92, 0x33, 0x19, 0x4f, 0x9e, - 0x64, 0xf7, 0xf4, 0x54, 0xcc, 0xef, 0x57, 0xe5, 0xbe, 0x72, 0x5d, 0x7a, 0x7c, 0xab, 0x0e, 0x8e, - 0xe4, 0xb6, 0x78, 0x5b, 0x2d, 0x9d, 0x88, 0x93, 0x83, 0x66, 0x59, 0x9e, 0x54, 0xa7, 0x29, 0x3d, - 0x97, 0xc9, 0x94, 0xf3, 0xcf, 0xa9, 0xc3, 0x9c, 0x26, 0xee, 0x1f, 0xa8, 0xb9, 0xf2, 0xb0, 0x79, - 0x77, 0x7e, 0x94, 0xb9, 0xef, 0xb7, 0x1e, 0x87, 0xf7, 0xaf, 0x47, 0x7b, 0xd2, 0xe3, 0x44, 0x52, - 0x1d, 0x51, 0x57, 0xee, 0xda, 0x77, 0x29, 0xf5, 0x42, 0x3f, 0x1c, 0xec, 0x4e, 0x32, 0xaf, 0x17, - 0x65, 0xa5, 0x94, 0x19, 0x3e, 0x3d, 0x88, 0xee, 0x35, 0xb9, 0x75, 0x8f, 0xaf, 0x46, 0xa5, 0xc2, - 0x14, 0xc8, 0xb7, 0x39, 0x7a, 0x28, 0x4d, 0xf6, 0xc8, 0x5b, 0xf3, 0x21, 0x53, 0xb9, 0x1f, 0x54, - 0x5a, 0xbd, 0x7e, 0xa6, 0x5a, 0xbc, 0xa8, 0x5e, 0x4c, 0x9c, 0xf3, 0xd6, 0xa3, 0xe1, 0x3c, 0xdc, - 0x5f, 0xa5, 0xca, 0x56, 0xeb, 0xad, 0x92, 0x39, 0x3f, 0x7b, 0x2a, 0x96, 0x9f, 0x9a, 0x47, 0x07, - 0xfb, 0xea, 0xcd, 0x38, 0x25, 0x59, 0x95, 0xbb, 0xd4, 0x51, 0xfe, 0xfc, 0xf6, 0x8e, 0xc0, 0x9a, - 0x1a, 0x6b, 0xa3, 0x94, 0xae, 0x28, 0xaf, 0xcf, 0xd9, 0x72, 0xee, 0xa1, 0xfc, 0x38, 0x2e, 0xf6, - 0x8e, 0x9b, 0xb7, 0x57, 0x07, 0x8f, 0x97, 0x57, 0xa5, 0xab, 0xe9, 0xe4, 0xba, 0xdb, 0x23, 0xad, - 0xd4, 0x95, 0x52, 0xbc, 0x37, 0x9a, 0x67, 0xad, 0xe6, 0x61, 0x7b, 0x54, 0xba, 0x39, 0x76, 0x89, - 0x9b, 0xb7, 0x8c, 0x4c, 0x25, 0x2f, 0x17, 0x1e, 0x5b, 0xcd, 0xa3, 0xdd, 0x51, 0xbe, 0x68, 0x76, - 0xad, 0x9b, 0xeb, 0xa9, 0x5b, 0xbc, 0x7c, 0x06, 0x9d, 0xf4, 0xa6, 0x72, 0xf2, 0xd8, 0xdc, 0xbf, - 0x3a, 0xa9, 0x18, 0xed, 0xde, 0xae, 0x02, 0x6a, 0xf1, 0xed, 0x18, 0x68, 0xff, 0xf5, 0xb0, 0xb3, - 0x7b, 0x62, 0xee, 0x1f, 0x94, 0x4f, 0x9e, 0xae, 0x4e, 0xcf, 0xac, 0x67, 0xb3, 0x38, 0xec, 0x4b, - 0x99, 0xcb, 0xa3, 0xdc, 0x74, 0xb8, 0x7b, 0x7f, 0xd1, 0xba, 0xe9, 0xec, 0x3d, 0x49, 0xcf, 0xd6, - 0xeb, 0x55, 0xa9, 0x92, 0x7a, 0x92, 0xb2, 0x95, 0xe7, 0xde, 0x41, 0xef, 0xf1, 0xec, 0xa6, 0x62, - 0xec, 0xf6, 0x9f, 0x4f, 0x94, 0xb6, 0x7d, 0xd2, 0x7a, 0x6c, 0x97, 0xa6, 0x27, 0x9d, 0xa7, 0xeb, - 0xd3, 0x76, 0xd1, 0xbd, 0x2e, 0x3e, 0x9e, 0xf4, 0x6f, 0xdf, 0xde, 0xce, 0xef, 0xcf, 0x8a, 0xb9, - 0xc1, 0xee, 0x68, 0x78, 0x79, 0xa6, 0x9d, 0x96, 0x27, 0x97, 0x93, 0xc2, 0xad, 0x74, 0xdd, 0x6b, - 0x6b, 0xc7, 0x4f, 0xcd, 0xbb, 0xb6, 0xa3, 0x3c, 0xe5, 0x0e, 0x6f, 0x8f, 0xfa, 0xb7, 0x97, 0xca, - 0xbe, 0x74, 0x58, 0xbc, 0xbf, 0xdf, 0x1b, 0x8d, 0x06, 0x23, 0xf5, 0xb2, 0xab, 0x17, 0x4f, 0xa4, - 0xd6, 0xe8, 0xa2, 0x62, 0x66, 0x53, 0xdd, 0x76, 0x6b, 0x57, 0x2e, 0xf5, 0x47, 0xc3, 0xd3, 0xb7, - 0x8a, 0x7e, 0x76, 0x7d, 0x31, 0xee, 0x3e, 0x5f, 0x9e, 0x57, 0x34, 0xc9, 0xae, 0x8a, 0xd7, 0xad, - 0x96, 0x76, 0xdd, 0x3a, 0xb6, 0xf3, 0xc3, 0xde, 0xeb, 0x61, 0xb7, 0x74, 0xfa, 0xda, 0xbb, 0x7d, - 0x7c, 0x74, 0x8a, 0xfd, 0xb7, 0xd1, 0xb0, 0xea, 0x9e, 0x1d, 0x5d, 0xdc, 0xda, 0x99, 0x89, 0x35, - 0xba, 0x76, 0xce, 0xef, 0x46, 0xea, 0x53, 0xc6, 0x4a, 0x0d, 0x76, 0x2b, 0x46, 0xf9, 0x2e, 0x07, - 0x5c, 0x51, 0xbc, 0x49, 0x49, 0xd7, 0xfd, 0x4b, 0xeb, 0xbc, 0xef, 0x9c, 0xb7, 0x2f, 0x5e, 0x27, - 0xe6, 0x7e, 0x6e, 0x28, 0x3a, 0xc3, 0xd7, 0x1b, 0xcd, 0xea, 0x4d, 0x8a, 0x95, 0xa3, 0xe3, 0x26, - 0x75, 0x59, 0x34, 0xf8, 0x44, 0xd7, 0xb4, 0x07, 0x92, 0x9b, 0xfc, 0x86, 0x06, 0xd4, 0x37, 0x7e, - 0x5e, 0xb3, 0x4d, 0xd3, 0x9d, 0x6d, 0x6d, 0x29, 0x5b, 0xd9, 0xda, 0xd7, 0x6c, 0x36, 0x5b, 0xc7, - 0xc7, 0x6e, 0xed, 0x6b, 0xb7, 0xdb, 0xa5, 0x8f, 0xb9, 0x1a, 0x3a, 0x8a, 0xe8, 0x63, 0xbe, 0xf6, - 0x35, 0x9f, 0xcf, 0xd3, 0xc7, 0x42, 0xed, 0x6b, 0xa1, 0x50, 0xa0, 0x8f, 0xc5, 0xda, 0xd7, 0x62, - 0xb1, 0x48, 0x1f, 0x4b, 0xb5, 0xaf, 0xa5, 0x52, 0x89, 0x3e, 0x56, 0x6a, 0x5f, 0x2b, 0x95, 0x0a, - 0x7d, 0x94, 0x6b, 0x5f, 0x65, 0x59, 0xa6, 0x8f, 0x4a, 0xed, 0xab, 0xa2, 0x28, 0xf4, 0x91, 0xd4, - 0xbe, 0x12, 0x42, 0xe8, 0xa3, 0x5a, 0xfb, 0xaa, 0xaa, 0x2a, 0x7d, 0xb4, 0x21, 0xb5, 0xc0, 0x5a, - 0xeb, 0x41, 0x13, 0x84, 0x3d, 0xea, 0xf0, 0x58, 0x91, 0xe0, 0xd1, 0x05, 0x60, 0x62, 0x9a, 0x35, - 0x66, 0xd6, 0xec, 0x9e, 0x2c, 0x25, 0xf3, 0x05, 0x21, 0xe1, 0xff, 0x89, 0xe9, 0x2a, 0x4f, 0xf3, - 0x5c, 0x79, 0x39, 0x13, 0x4c, 0xfb, 0x24, 0x85, 0xc0, 0xfb, 0x65, 0x24, 0x56, 0x28, 0x2b, 0xe6, - 0x84, 0xc4, 0xe2, 0x63, 0xb9, 0x5c, 0x9f, 0x95, 0x2b, 0x66, 0x85, 0x84, 0xff, 0x17, 0x2d, 0xe4, - 0xf6, 0x6b, 0x65, 0xd1, 0x9a, 0xe0, 0x93, 0xe5, 0x3f, 0x41, 0xad, 0x52, 0x9e, 0xa5, 0xc9, 0x56, - 0x2d, 0x5b, 0xb0, 0x26, 0x89, 0x0a, 0xfc, 0x65, 0xbd, 0x5c, 0x48, 0xab, 0xc2, 0x4f, 0x31, 0x51, - 0xc6, 0x4f, 0x5a, 0x5e, 0xad, 0x19, 0xa6, 0x81, 0x18, 0x91, 0x07, 0x6e, 0x0d, 0x8a, 0xcd, 0xd1, - 0x8f, 0x38, 0xa3, 0xee, 0x83, 0x2d, 0x89, 0x79, 0x4c, 0x06, 0x12, 0x28, 0xf8, 0x43, 0x9d, 0x3a, - 0x1c, 0xe6, 0xb2, 0xa9, 0x4e, 0x67, 0x03, 0xc9, 0xee, 0x69, 0x46, 0x4d, 0xac, 0xa3, 0x4b, 0xa9, - 0x67, 0x9b, 0x43, 0x43, 0x65, 0x9e, 0xbe, 0x1a, 0xeb, 0x22, 0x4c, 0x2b, 0x5f, 0x0f, 0x1b, 0xd4, - 0x87, 0x44, 0x1f, 0x11, 0x57, 0x53, 0x24, 0xe1, 0x8e, 0xd8, 0xaa, 0x64, 0x48, 0x82, 0x23, 0x19, - 0xce, 0x96, 0x43, 0x6c, 0xad, 0xcb, 0x0a, 0x3a, 0xda, 0x1b, 0xa9, 0x65, 0xa1, 0x5f, 0xf5, 0x28, - 0xa0, 0x2e, 0x5f, 0x77, 0xc9, 0xc4, 0xdd, 0x92, 0x74, 0xad, 0x67, 0xd4, 0x14, 0x82, 0xee, 0x83, - 0x3a, 0x3a, 0x05, 0x5f, 0x34, 0x77, 0x8b, 0x75, 0x53, 0x91, 0x74, 0x1d, 0xdd, 0x38, 0x6c, 0x20, - 0x5e, 0xd6, 0x10, 0x60, 0x03, 0x7c, 0x9d, 0x28, 0x7e, 0xc6, 0xc0, 0x7c, 0x5b, 0x95, 0xea, 0x2c, - 0x27, 0x2e, 0x97, 0xf2, 0xdb, 0x93, 0xac, 0xad, 0xbe, 0xd6, 0xeb, 0xeb, 0xe8, 0x6e, 0xf2, 0x46, - 0xec, 0xda, 0x30, 0x12, 0x4b, 0xb2, 0xa1, 0x67, 0x75, 0x47, 0xb1, 0x4d, 0x5d, 0x97, 0x25, 0x9b, - 0x79, 0x52, 0x6b, 0x25, 0x18, 0xce, 0x22, 0x2d, 0x3a, 0x30, 0x47, 0xe6, 0x13, 0xa1, 0xba, 0x14, - 0xb1, 0x02, 0x45, 0x7e, 0x9f, 0x20, 0xf8, 0x5a, 0x56, 0x14, 0xff, 0x59, 0x67, 0x70, 0xe8, 0xa3, - 0x65, 0x3a, 0x1a, 0x9d, 0x8f, 0xae, 0x36, 0x21, 0x6a, 0xdd, 0x04, 0xb9, 0xc9, 0x60, 0x6f, 0xc9, - 0xa4, 0x2f, 0x8d, 0x34, 0x80, 0x8d, 0x9d, 0x9d, 0x7f, 0x95, 0x7b, 0x21, 0x10, 0xa3, 0xfe, 0x02, - 0xc6, 0x68, 0x1c, 0x07, 0xf2, 0xb6, 0xa5, 0x19, 0x2a, 0x99, 0xd4, 0xb6, 0xb2, 0x91, 0xb9, 0x0c, - 0x4a, 0x79, 0xf8, 0x0e, 0x65, 0xd9, 0xc4, 0x22, 0x12, 0xa2, 0xc5, 0x7b, 0x0a, 0xe7, 0xd1, 0x39, - 0x54, 0xb0, 0x63, 0x75, 0xd3, 0x92, 0x14, 0xcd, 0x9d, 0x02, 0x89, 0xd0, 0x31, 0x32, 0x68, 0x5e, - 0x62, 0x22, 0xe7, 0xcc, 0x2d, 0x9f, 0x86, 0x90, 0x34, 0x81, 0x20, 0x73, 0xf8, 0x39, 0x97, 0x04, - 0xa9, 0x36, 0xd2, 0xa0, 0x34, 0x51, 0x05, 0x6b, 0x16, 0xc5, 0x97, 0xca, 0x87, 0xb3, 0x67, 0x94, - 0x28, 0x54, 0xa2, 0x98, 0x36, 0xa5, 0x4b, 0x36, 0x74, 0x79, 0xe8, 0xba, 0xa6, 0x31, 0x03, 0x62, - 0xd0, 0x35, 0x83, 0x40, 0xe3, 0xca, 0xd0, 0x76, 0x00, 0x86, 0x65, 0x6a, 0xf1, 0x71, 0x2c, 0x4f, - 0x9e, 0x6c, 0xda, 0x2a, 0x61, 0x38, 0x0c, 0x77, 0x9a, 0x16, 0x4c, 0xa4, 0xf3, 0x8e, 0x10, 0xaf, - 0x8d, 0x89, 0x61, 0xe2, 0xad, 0x2e, 0x11, 0xaf, 0xc2, 0xd7, 0x07, 0x9a, 0xe1, 0x11, 0x43, 0x01, - 0x17, 0x21, 0xfe, 0xf4, 0x26, 0x07, 0x7f, 0x7b, 0x3d, 0xae, 0xf5, 0x11, 0x69, 0xb3, 0x45, 0x03, - 0x01, 0x84, 0x02, 0x3f, 0x4f, 0xeb, 0x92, 0x4c, 0xf4, 0xc5, 0x9a, 0xb3, 0x24, 0x55, 0xd5, 0x8c, - 0x1e, 0x12, 0x17, 0x20, 0x4e, 0x9c, 0x7f, 0x45, 0xa7, 0x39, 0x2b, 0x13, 0x9b, 0x5d, 0xd9, 0x04, - 0xe0, 0x83, 0x1a, 0xac, 0x0f, 0x25, 0xc9, 0x00, 0xca, 0x7d, 0x3e, 0x91, 0x4a, 0x40, 0x4d, 0xbe, - 0x6e, 0xb3, 0x4e, 0x2c, 0xf5, 0xb9, 0xc4, 0xc7, 0xb1, 0x36, 0xb6, 0x01, 0xa8, 0xd1, 0x83, 0x05, - 0xa4, 0x92, 0x1a, 0xf4, 0x13, 0xd7, 0xb1, 0xbe, 0x65, 0xeb, 0xf3, 0xf4, 0xd8, 0x46, 0x3f, 0x9b, - 0x1d, 0x6f, 0xd7, 0x35, 0x2d, 0xe8, 0xa7, 0x4e, 0xba, 0xc0, 0x51, 0xbc, 0x76, 0xc2, 0xe4, 0x15, - 0x34, 0xe5, 0xca, 0x7c, 0x40, 0x81, 0xd9, 0x79, 0x9a, 0x11, 0x5b, 0x30, 0xd0, 0x84, 0x34, 0x74, - 0x4d, 0x8f, 0x78, 0xf3, 0x39, 0x44, 0x56, 0x1a, 0x7d, 0xf9, 0xce, 0x2a, 0x4f, 0x1d, 0x9b, 0x05, - 0xf4, 0xe9, 0xc1, 0xfc, 0x81, 0xa4, 0xd1, 0x43, 0xf3, 0x92, 0xc3, 0x31, 0x22, 0x3d, 0xf8, 0x88, - 0xcf, 0xd6, 0x55, 0xcd, 0xb1, 0x74, 0x69, 0x5a, 0xd3, 0x0c, 0x9a, 0x2e, 0xa3, 0x47, 0xb8, 0xee, - 0xb5, 0xbb, 0x45, 0x49, 0x31, 0x51, 0xa0, 0x1c, 0x92, 0x52, 0x99, 0xd3, 0x97, 0x54, 0x73, 0x0c, - 0x6b, 0x04, 0x92, 0xe8, 0x87, 0x98, 0xf0, 0x47, 0x90, 0xe7, 0x85, 0xd5, 0xa9, 0x34, 0x65, 0x65, - 0xd9, 0x78, 0xe2, 0x3c, 0xdd, 0x1f, 0xf6, 0x3c, 0xf7, 0x23, 0xed, 0x6f, 0x21, 0x47, 0x87, 0x6a, - 0x74, 0x41, 0x42, 0xba, 0xb8, 0xe5, 0xb1, 0xe5, 0xb9, 0xa9, 0x19, 0x72, 0x17, 0x1c, 0x61, 0x9e, - 0x7e, 0x21, 0x53, 0xd7, 0x5b, 0x0a, 0x8c, 0x3f, 0x22, 0xce, 0x7d, 0x02, 0xd9, 0xf2, 0xa6, 0xbf, - 0x82, 0xe0, 0x46, 0x92, 0x1e, 0x2d, 0x49, 0xa7, 0x65, 0x7d, 0xd1, 0x84, 0x16, 0xea, 0x91, 0x03, - 0x08, 0x85, 0xd9, 0x76, 0xa8, 0xcb, 0x9a, 0x6e, 0xa8, 0xcc, 0xe8, 0x02, 0x41, 0xa1, 0xce, 0x96, - 0x10, 0x08, 0x07, 0x92, 0x04, 0x94, 0x09, 0x79, 0x24, 0xad, 0xa5, 0x85, 0x9b, 0xd6, 0xf4, 0xd9, - 0x4a, 0x9c, 0x07, 0xd4, 0xc4, 0x3a, 0x35, 0xd0, 0x54, 0x55, 0x27, 0xf3, 0x34, 0x0c, 0x7b, 0xf6, - 0xee, 0x5a, 0x5d, 0x6e, 0x01, 0xaa, 0x24, 0xbc, 0xe5, 0xff, 0x6e, 0xcd, 0xae, 0x6e, 0x02, 0xfb, - 0xa2, 0x78, 0xfa, 0xdb, 0x0b, 0xbe, 0xfc, 0xc1, 0x82, 0x2f, 0x20, 0x3a, 0x61, 0x31, 0xf8, 0x1d, - 0xf3, 0x57, 0xae, 0x27, 0xc7, 0x65, 0x8b, 0xf7, 0x89, 0x4e, 0x0c, 0x0f, 0x60, 0x89, 0x1b, 0xc4, - 0x24, 0x07, 0xe8, 0x06, 0x71, 0x1c, 0x93, 0x08, 0x06, 0xd2, 0x28, 0xb8, 0x47, 0xe4, 0x3d, 0x08, - 0x12, 0xff, 0x45, 0x1b, 0xe0, 0x5e, 0xa0, 0xb4, 0x84, 0xcd, 0x2e, 0xc0, 0xfa, 0x08, 0x40, 0xe9, - 0xfd, 0xea, 0xb8, 0xa9, 0x27, 0xc1, 0x2c, 0xdb, 0xb3, 0x90, 0xfc, 0xf2, 0x56, 0x1f, 0xe5, 0x46, - 0x98, 0x90, 0xd8, 0xf2, 0x15, 0x1a, 0x8b, 0x0f, 0x9e, 0x61, 0x68, 0x3e, 0x52, 0xb6, 0x90, 0x8d, - 0x04, 0x25, 0xd6, 0xcb, 0x3b, 0x1c, 0xb8, 0xb7, 0x8b, 0xb8, 0x60, 0x44, 0x36, 0x41, 0x7d, 0x65, - 0x44, 0xc2, 0x02, 0x54, 0x36, 0x27, 0x38, 0x71, 0x38, 0x03, 0x6c, 0xea, 0x81, 0xec, 0x27, 0x3e, - 0x15, 0x88, 0xb4, 0x01, 0xa0, 0x8e, 0x71, 0x8d, 0xf2, 0x9d, 0xb0, 0x10, 0x5e, 0xdf, 0xb4, 0x33, - 0x00, 0x3d, 0xb6, 0x3f, 0x0b, 0x51, 0x4f, 0xb0, 0x30, 0x12, 0x21, 0xb6, 0xdb, 0x15, 0xb2, 0xfc, - 0xbf, 0xd2, 0x45, 0x87, 0x4f, 0x10, 0xc9, 0x21, 0x5b, 0xb0, 0x98, 0x69, 0xaf, 0xb7, 0xa2, 0x9c, - 0x1d, 0xd8, 0xc2, 0x56, 0x91, 0xb2, 0x9d, 0xd8, 0xb2, 0xa4, 0x74, 0x84, 0x9d, 0x80, 0xf5, 0x13, - 0xe7, 0xb5, 0x6b, 0x94, 0x85, 0x08, 0x0b, 0x5e, 0x3b, 0x8d, 0x79, 0x3e, 0xce, 0x27, 0xfd, 0x55, - 0xda, 0xd5, 0xc9, 0xa4, 0x4e, 0x17, 0xe5, 0x16, 0x88, 0xdb, 0x81, 0xe3, 0x6b, 0x02, 0xcf, 0x43, - 0xc7, 0xd5, 0xba, 0xd3, 0x2d, 0x0f, 0xe1, 0x7e, 0x72, 0xc0, 0xc5, 0xb3, 0x81, 0xe4, 0x4f, 0x57, - 0x8b, 0xe1, 0x55, 0x95, 0x2e, 0x3b, 0x75, 0x4f, 0xa0, 0x6c, 0x11, 0xdc, 0x8d, 0x72, 0x3c, 0x6d, - 0xc5, 0x35, 0x25, 0xc7, 0x9d, 0x2d, 0xf4, 0x85, 0xb5, 0x9d, 0x2d, 0x22, 0x61, 0x4c, 0xbc, 0xb5, - 0x55, 0x85, 0x31, 0x7e, 0x42, 0x51, 0xf4, 0xe6, 0xd9, 0x96, 0x54, 0x6d, 0xe8, 0xd4, 0x00, 0xb9, - 0x81, 0xf4, 0xcc, 0xa2, 0x6e, 0xb6, 0x46, 0x1b, 0x2a, 0x32, 0xc4, 0x15, 0x11, 0x8f, 0xcb, 0x7c, - 0xee, 0x21, 0xb9, 0x05, 0x39, 0xfc, 0x5a, 0xe9, 0x9a, 0xcb, 0x21, 0x0f, 0x8c, 0xb1, 0x89, 0xf5, - 0x43, 0x4f, 0x3b, 0x7d, 0x73, 0x1c, 0x8c, 0x3f, 0x5b, 0x07, 0x65, 0x7b, 0xc0, 0x54, 0x9a, 0xae, - 0xa4, 0x12, 0xcd, 0x48, 0x00, 0xdd, 0x08, 0x8b, 0xc7, 0x44, 0x0e, 0x3f, 0x6c, 0x82, 0x24, 0x19, - 0x80, 0x20, 0xb6, 0x6d, 0xda, 0x21, 0x18, 0x4b, 0x38, 0xfc, 0x2a, 0xe7, 0x56, 0x43, 0x9e, 0xa7, - 0x41, 0xaa, 0x4b, 0x4b, 0x9a, 0x83, 0x4f, 0x38, 0x6c, 0x88, 0x0b, 0x21, 0x8e, 0x64, 0x15, 0x1a, - 0xb0, 0xdb, 0xc7, 0x95, 0x9b, 0xc5, 0xf1, 0xae, 0x9d, 0x36, 0x93, 0x5f, 0x85, 0xc4, 0x47, 0xca, - 0x02, 0xf8, 0xfa, 0xca, 0x95, 0x93, 0x2e, 0x38, 0xc1, 0x3c, 0x81, 0x48, 0x0a, 0xd3, 0x28, 0xea, - 0x50, 0x91, 0x85, 0x3a, 0xff, 0x8a, 0x92, 0x52, 0xf8, 0x6a, 0x80, 0x72, 0xe2, 0xcc, 0xfc, 0x19, - 0xcc, 0xcf, 0xbf, 0xda, 0x94, 0x89, 0xfa, 0x09, 0x39, 0x50, 0x93, 0x54, 0xdd, 0x0d, 0xb4, 0x4e, - 0xa6, 0x6f, 0xb2, 0x42, 0x8e, 0x2b, 0xad, 0x54, 0x61, 0x62, 0x03, 0x4d, 0x25, 0x8a, 0x38, 0x50, - 0x8a, 0x9a, 0x6c, 0x68, 0xa9, 0x50, 0xf9, 0x11, 0x55, 0x99, 0xe6, 0x5f, 0x61, 0x7d, 0x18, 0xd0, - 0xf2, 0x67, 0x35, 0xb2, 0x05, 0xe4, 0x42, 0x88, 0x46, 0x91, 0x5e, 0x97, 0x29, 0x78, 0x79, 0x72, - 0xa5, 0xaa, 0xb8, 0xd0, 0xe4, 0x61, 0xa4, 0xda, 0xa0, 0x37, 0x9e, 0xbd, 0xa7, 0xe3, 0xa0, 0x9c, - 0xff, 0xfa, 0x62, 0x08, 0x5f, 0x5f, 0x46, 0x2b, 0xcb, 0x31, 0xa4, 0x26, 0xa8, 0xf6, 0xe1, 0xa1, - 0x96, 0xfd, 0xf8, 0x40, 0x21, 0xf1, 0xaa, 0xa9, 0x41, 0x1d, 0x75, 0xb6, 0x42, 0xc3, 0x60, 0xa5, - 0xd2, 0xb2, 0x6b, 0xf8, 0xd3, 0x51, 0x0c, 0x52, 0x29, 0x7c, 0x9a, 0x17, 0x69, 0x37, 0x52, 0x5a, - 0xf4, 0x9b, 0xac, 0x88, 0x41, 0x3d, 0x55, 0x1b, 0xf9, 0x15, 0xe0, 0xd1, 0x13, 0x3b, 0x85, 0x2a, - 0x55, 0xb9, 0xc3, 0xfa, 0x24, 0x0e, 0x7b, 0x45, 0xb7, 0x90, 0x1e, 0xe6, 0x5f, 0xfb, 0x44, 0xb2, - 0xdd, 0xd9, 0xb2, 0x2a, 0x50, 0x8d, 0x48, 0xfd, 0x52, 0x20, 0xf5, 0x6d, 0xa2, 0xce, 0x01, 0xd7, - 0xb3, 0x05, 0x5b, 0xa2, 0xbc, 0x17, 0x7f, 0x86, 0xd8, 0x32, 0xa8, 0xc9, 0xda, 0x8c, 0x46, 0xa3, - 0x80, 0xc9, 0x04, 0x73, 0x64, 0xe3, 0xd4, 0x5a, 0x80, 0x3a, 0x5c, 0x07, 0x6a, 0x3d, 0x9e, 0xa3, - 0xd8, 0x30, 0x21, 0x5b, 0x44, 0xed, 0x11, 0xc7, 0x1b, 0x67, 0x0e, 0x6d, 0xa4, 0xf9, 0xbf, 0x41, - 0xd9, 0xeb, 0xda, 0xa0, 0xea, 0x3b, 0x09, 0xb6, 0x7c, 0x67, 0x5d, 0xdb, 0x1c, 0xcc, 0x82, 0x25, - 0x1a, 0x70, 0xd0, 0xb9, 0x6b, 0xce, 0xde, 0xe7, 0x4d, 0x01, 0xa3, 0x98, 0xfb, 0x4a, 0x1d, 0x2a, - 0xf2, 0xbe, 0xd1, 0x98, 0x47, 0xa4, 0x79, 0x2d, 0x17, 0xc5, 0x30, 0x97, 0x0c, 0x84, 0xaa, 0x87, - 0xd2, 0x02, 0x5b, 0x44, 0x34, 0xf2, 0xc1, 0x49, 0x84, 0x41, 0x05, 0xe1, 0x19, 0x0b, 0xfc, 0x7b, - 0x86, 0x9e, 0xe8, 0x37, 0xe9, 0xd1, 0xdd, 0xcc, 0x97, 0x24, 0xdf, 0xbe, 0x2d, 0x1a, 0x92, 0x64, - 0xc7, 0xd4, 0x87, 0x2e, 0xa1, 0xcb, 0x90, 0x3a, 0x2f, 0xe8, 0xda, 0x40, 0x5e, 0xc0, 0x38, 0x11, - 0x3e, 0x79, 0xdd, 0xad, 0x44, 0x96, 0x44, 0xc8, 0x70, 0x8a, 0x2d, 0x1d, 0x8f, 0xe1, 0x2f, 0xb1, - 0xe1, 0x90, 0x0d, 0x1c, 0x1f, 0x8a, 0xdf, 0x45, 0xaf, 0xa5, 0x1c, 0x36, 0xc5, 0x04, 0x6b, 0x80, - 0xf5, 0xa8, 0x91, 0x03, 0x0c, 0x05, 0x87, 0x1f, 0xaf, 0x1f, 0xea, 0x1e, 0xae, 0x31, 0xc9, 0xde, - 0xea, 0x61, 0xa7, 0x30, 0xba, 0xa3, 0x2a, 0xaa, 0xa4, 0x27, 0x7c, 0x15, 0x45, 0xc0, 0x8c, 0x00, - 0xf4, 0xc4, 0xcf, 0xbf, 0xf6, 0xfe, 0x0e, 0x88, 0xaf, 0x62, 0x57, 0x04, 0x18, 0xf2, 0xdf, 0x83, - 0x21, 0x82, 0x12, 0xf7, 0x75, 0xfc, 0xb7, 0x60, 0x74, 0xbb, 0x08, 0xe3, 0xe5, 0xaf, 0xc1, 0xe8, - 0x76, 0x2b, 0xdd, 0x6c, 0xd7, 0x03, 0x93, 0x00, 0x69, 0x2b, 0x7c, 0x55, 0x64, 0x55, 0xa6, 0x20, - 0xc7, 0xb2, 0xa4, 0xff, 0x3f, 0x81, 0xa8, 0x16, 0x88, 0x88, 0x10, 0x3d, 0x58, 0xf2, 0x50, 0x46, - 0x06, 0xe7, 0x51, 0x6e, 0x61, 0x25, 0xdd, 0xaf, 0xe4, 0xa9, 0x31, 0x32, 0x13, 0x57, 0xd3, 0x63, - 0x9e, 0x5f, 0xd6, 0x57, 0x7c, 0x3e, 0x8f, 0xeb, 0x08, 0xff, 0x72, 0x11, 0x59, 0x87, 0xde, 0x3b, - 0x8f, 0xb0, 0xd0, 0xa5, 0x17, 0x62, 0x4b, 0xe8, 0x03, 0x91, 0x35, 0x1d, 0x5d, 0x29, 0xe9, 0x1c, - 0x68, 0x03, 0xa8, 0x54, 0x0a, 0xbe, 0x73, 0x25, 0x48, 0x09, 0xf9, 0x60, 0x16, 0x15, 0x6a, 0x7d, - 0x30, 0xb1, 0x88, 0x31, 0x07, 0xf6, 0x6d, 0x0d, 0xdd, 0xc8, 0xd0, 0xa9, 0x1e, 0x12, 0x2a, 0x49, - 0x1f, 0x75, 0x12, 0xe2, 0x16, 0x69, 0x56, 0x79, 0x16, 0x96, 0x7c, 0xf3, 0x50, 0xa0, 0x10, 0x8d, - 0x13, 0xfa, 0x39, 0xf3, 0xbd, 0x65, 0xe8, 0x1b, 0x90, 0x20, 0x4d, 0x21, 0x6c, 0xa1, 0x85, 0x7d, - 0x59, 0xde, 0xc8, 0xc5, 0xfa, 0x7a, 0x57, 0x62, 0xc4, 0xde, 0x8b, 0x89, 0x57, 0x6f, 0x9d, 0x2e, - 0xb7, 0xed, 0xf3, 0xad, 0x5c, 0x88, 0xf1, 0x2f, 0x77, 0xb1, 0x56, 0xf3, 0xfb, 0xe8, 0xd9, 0xb4, - 0xf6, 0xd0, 0x30, 0xa8, 0x64, 0x83, 0x46, 0x95, 0x97, 0x15, 0x56, 0x0b, 0x65, 0x8a, 0x6b, 0xbd, - 0x49, 0xa8, 0xbb, 0x7f, 0xa2, 0x15, 0xb7, 0x3f, 0x1c, 0x80, 0x61, 0xcb, 0x0c, 0x0e, 0xd4, 0x40, - 0x80, 0xcb, 0x69, 0x6a, 0x02, 0x97, 0x8c, 0xdf, 0x4e, 0x2e, 0xc4, 0x7c, 0xc5, 0x65, 0xf1, 0x8f, - 0x56, 0xcc, 0x32, 0x6d, 0x75, 0x97, 0x5c, 0x36, 0xeb, 0xa6, 0x20, 0x64, 0x59, 0xa1, 0x51, 0xb1, - 0xaa, 0xcb, 0xe8, 0x26, 0xa5, 0x3f, 0xde, 0xc7, 0xc5, 0x5a, 0x7d, 0x0f, 0xd8, 0xcf, 0x07, 0x60, - 0x57, 0x63, 0x21, 0xb4, 0x50, 0xfe, 0x26, 0x2e, 0x56, 0xaa, 0x9b, 0xa8, 0x61, 0xad, 0xa7, 0x9b, - 0x3f, 0x99, 0xaa, 0x77, 0xa1, 0x7c, 0x7a, 0x98, 0x59, 0xe8, 0xcd, 0xa5, 0x4d, 0x1c, 0xe2, 0x82, - 0xb8, 0xd1, 0x35, 0xc7, 0x9d, 0x85, 0xd4, 0x86, 0x5c, 0xb6, 0x18, 0xd2, 0x73, 0xb7, 0xa6, 0x35, - 0x66, 0x7d, 0x2e, 0x52, 0x26, 0xde, 0x3a, 0xf6, 0xd1, 0x53, 0x89, 0x28, 0x3a, 0xf8, 0x1f, 0xc5, - 0x18, 0x7a, 0xb7, 0x83, 0x3a, 0xbe, 0x7b, 0x0c, 0xc8, 0x20, 0xee, 0xa7, 0x66, 0xe6, 0x48, 0xa4, - 0x3b, 0x21, 0x8c, 0xf8, 0x85, 0xa3, 0xeb, 0xfe, 0x6b, 0x87, 0xf4, 0x68, 0xd0, 0xe8, 0x2a, 0xc1, - 0x9f, 0xa3, 0x1a, 0x1d, 0xe5, 0xfe, 0x82, 0x17, 0xb4, 0x29, 0x7c, 0xb5, 0x7b, 0x32, 0x4b, 0x18, - 0xb1, 0x2f, 0xe4, 0xe4, 0x02, 0x13, 0x33, 0x51, 0xd0, 0xe9, 0xbe, 0x1a, 0x24, 0xf8, 0xda, 0x0b, - 0x4a, 0x46, 0xd9, 0xd6, 0x68, 0x61, 0xe6, 0xc3, 0x61, 0x1e, 0xac, 0x25, 0x5f, 0x81, 0x3c, 0x70, - 0xa1, 0x28, 0x6b, 0x33, 0xac, 0x87, 0x80, 0x4e, 0xee, 0xe8, 0x8b, 0xce, 0x38, 0xa4, 0x87, 0x9a, - 0x47, 0xc4, 0x0d, 0x8d, 0x0a, 0x22, 0x2a, 0x28, 0x21, 0x5d, 0x33, 0x94, 0x1e, 0xc1, 0x75, 0xcc, - 0xed, 0xfb, 0x9e, 0x85, 0x1d, 0xf7, 0x55, 0x2d, 0xb1, 0x11, 0x46, 0x22, 0xd9, 0x55, 0x2b, 0x21, - 0x4a, 0xf2, 0x88, 0xd5, 0x90, 0x1c, 0xd8, 0x52, 0x87, 0x9e, 0xf3, 0x1b, 0xfd, 0x52, 0xfe, 0x74, - 0x61, 0x57, 0x30, 0xa0, 0x71, 0x6b, 0x89, 0xe9, 0x2f, 0xb6, 0x31, 0x96, 0x17, 0x48, 0x5e, 0x4d, - 0x8a, 0x02, 0xfc, 0xc7, 0x2f, 0xac, 0x2b, 0x45, 0xd7, 0x2c, 0x66, 0x52, 0x47, 0x93, 0x62, 0x2e, - 0xec, 0x88, 0x6b, 0x95, 0xfa, 0xb4, 0x11, 0x7f, 0x1f, 0xf9, 0xb0, 0x02, 0xf5, 0x6c, 0xc5, 0xb8, - 0xd1, 0xe7, 0x0d, 0x20, 0xb6, 0x26, 0x8e, 0xaf, 0xc7, 0xe7, 0x16, 0xea, 0x5e, 0x21, 0xc4, 0xd9, - 0xc3, 0xb6, 0x12, 0x2c, 0xcb, 0xee, 0x64, 0x17, 0xcd, 0x06, 0x4b, 0xd2, 0xe1, 0x7b, 0x7d, 0xd3, - 0xb9, 0x77, 0x9a, 0xce, 0xf1, 0x1e, 0x18, 0xd6, 0x7f, 0x1f, 0xd8, 0x47, 0xa3, 0xc9, 0xf3, 0xef, - 0xcd, 0x22, 0x1b, 0x0d, 0x75, 0x9b, 0x7a, 0xd4, 0xba, 0x50, 0x62, 0x57, 0x3a, 0x40, 0x57, 0xea, - 0x19, 0xf3, 0xf4, 0xab, 0xe2, 0xf8, 0x64, 0x99, 0x5b, 0x62, 0x87, 0xd9, 0xb0, 0xf7, 0x26, 0xa2, - 0x9f, 0xf8, 0x64, 0xbb, 0xc0, 0x21, 0x7d, 0x0e, 0x4f, 0x5b, 0x8e, 0x3a, 0x7e, 0x01, 0xbe, 0x1c, - 0xac, 0x98, 0x50, 0xe9, 0x52, 0xbc, 0x74, 0x29, 0x68, 0x7d, 0xc5, 0x78, 0x41, 0xa3, 0x62, 0x61, - 0xd3, 0xb3, 0xcf, 0x2f, 0x8a, 0x6e, 0x44, 0x66, 0x18, 0xc0, 0x38, 0x89, 0xfd, 0x53, 0x08, 0x25, - 0x21, 0x19, 0xfe, 0x9c, 0x7d, 0x52, 0xad, 0xf2, 0x3d, 0x7a, 0x4b, 0x1d, 0x7b, 0xc7, 0x1d, 0x54, - 0x59, 0x50, 0x15, 0xee, 0xab, 0xf8, 0x7f, 0x62, 0x7c, 0xa1, 0x87, 0xb4, 0xb0, 0x65, 0xef, 0x70, - 0xce, 0xa9, 0x2f, 0xb6, 0x9e, 0x18, 0x22, 0xa9, 0x01, 0xb5, 0x42, 0x1a, 0xe3, 0x80, 0xba, 0x1a, - 0xd1, 0x55, 0xb6, 0x2f, 0xb9, 0x32, 0x67, 0x55, 0xe2, 0xbc, 0x56, 0x63, 0x1b, 0x93, 0x51, 0x04, - 0x07, 0xc3, 0x97, 0x57, 0x61, 0xb2, 0xd6, 0x35, 0x95, 0xa1, 0xb3, 0x84, 0x4f, 0x96, 0xbc, 0x0a, - 0x4a, 0x69, 0x25, 0x94, 0x40, 0x22, 0x68, 0x86, 0x81, 0x1b, 0xa4, 0x16, 0x50, 0x32, 0x73, 0x38, - 0x0b, 0xef, 0x95, 0x06, 0x94, 0x44, 0x4b, 0xaf, 0x53, 0x10, 0xe7, 0x69, 0x4b, 0x0b, 0x79, 0x4c, - 0x22, 0x46, 0x60, 0x60, 0x69, 0x05, 0xfe, 0x3b, 0xb6, 0x4d, 0x23, 0x26, 0xb2, 0x31, 0xad, 0xb9, - 0x14, 0x55, 0x1a, 0x96, 0x7d, 0x82, 0x51, 0x7a, 0x01, 0x84, 0xa5, 0x27, 0xc0, 0x69, 0xd6, 0x0a, - 0x6a, 0x12, 0x76, 0x75, 0x2f, 0x1c, 0xfb, 0x01, 0x3f, 0x2a, 0x2c, 0x28, 0xa7, 0x18, 0xe1, 0x47, - 0x08, 0x76, 0x6b, 0xec, 0x01, 0xf6, 0xb7, 0x04, 0xac, 0x49, 0x08, 0x5a, 0x68, 0x31, 0x87, 0xa8, - 0xc5, 0x03, 0xcc, 0x4c, 0xef, 0x05, 0x34, 0x58, 0x9d, 0x02, 0xed, 0xe9, 0x47, 0x7b, 0x52, 0xa5, - 0x95, 0x7b, 0x52, 0xa5, 0x95, 0x7b, 0x52, 0xa5, 0x55, 0x7b, 0x52, 0x30, 0xfb, 0x69, 0xcb, 0x71, - 0x9d, 0xd9, 0xd2, 0xca, 0x5a, 0xac, 0x10, 0x28, 0x31, 0xb6, 0x67, 0x1f, 0xec, 0x1c, 0xd2, 0x7d, - 0x84, 0xd9, 0x8a, 0xed, 0x81, 0x3e, 0x51, 0x5e, 0x84, 0x34, 0x2e, 0x43, 0x73, 0xb5, 0x9f, 0x6a, - 0xd9, 0xf4, 0x8a, 0x09, 0xcd, 0xa5, 0x69, 0x05, 0x33, 0x4e, 0xe9, 0xbf, 0xe8, 0x61, 0xfb, 0x0d, - 0xe9, 0x66, 0x8b, 0x6e, 0xa6, 0xd1, 0x06, 0x99, 0xbe, 0xe6, 0x35, 0xcb, 0x7e, 0xac, 0x20, 0xb6, - 0x85, 0xd1, 0x14, 0x6b, 0xd1, 0x9b, 0x16, 0x7f, 0x61, 0x8b, 0x1e, 0x54, 0x40, 0x89, 0x3f, 0x14, - 0x7c, 0x5c, 0x4b, 0xbe, 0x71, 0x8f, 0xc1, 0x5f, 0x92, 0x25, 0x20, 0x9e, 0x42, 0x4d, 0xf9, 0xec, - 0xb8, 0xb0, 0xa0, 0xf8, 0xc2, 0x2a, 0x35, 0x39, 0xd4, 0xd3, 0xa0, 0x4e, 0x31, 0xe4, 0xe3, 0x59, - 0x96, 0x25, 0x62, 0x80, 0x34, 0x26, 0xf9, 0x18, 0xb6, 0xfe, 0x3b, 0x04, 0xe7, 0x1d, 0xc1, 0x1e, - 0x41, 0x77, 0x8d, 0x3e, 0x13, 0xf5, 0x53, 0x75, 0x4b, 0x7c, 0xa8, 0xab, 0x35, 0xa9, 0x0b, 0x68, - 0x0f, 0xa1, 0x96, 0x25, 0x04, 0xfe, 0x22, 0x8e, 0x5b, 0xe1, 0x2f, 0x8a, 0xaa, 0x91, 0xef, 0xf7, - 0x23, 0xd2, 0x40, 0xbc, 0x54, 0xbc, 0x55, 0x1f, 0xb0, 0x27, 0x8a, 0x19, 0xe4, 0x38, 0xac, 0x19, - 0x9d, 0xdb, 0xaa, 0x47, 0x7a, 0x0b, 0x14, 0x17, 0x17, 0xab, 0x3a, 0xbb, 0x30, 0x64, 0x6a, 0xeb, - 0xc4, 0x93, 0x47, 0x60, 0x09, 0xb0, 0xfa, 0xe9, 0x9f, 0xb8, 0x42, 0x71, 0xb3, 0x4d, 0x97, 0x6e, - 0xb9, 0x16, 0x55, 0xd2, 0xe3, 0xa9, 0x9e, 0xbf, 0x2e, 0x6f, 0x4d, 0xba, 0x47, 0x48, 0x89, 0xa5, - 0x91, 0x7a, 0xf6, 0x5e, 0x48, 0xe5, 0xa2, 0xcf, 0x74, 0x44, 0x60, 0x72, 0x05, 0x3b, 0x23, 0xfe, - 0x76, 0x79, 0xe9, 0xf3, 0x96, 0x19, 0x28, 0xf6, 0xa1, 0x5d, 0xe5, 0x6c, 0x7e, 0x69, 0xfb, 0x14, - 0x99, 0x31, 0xb5, 0x85, 0xd6, 0xed, 0xe3, 0x31, 0xe5, 0xfb, 0x5d, 0x21, 0x5c, 0x74, 0xfc, 0xae, - 0x51, 0xb5, 0x9d, 0x7e, 0xe4, 0x56, 0xa8, 0xec, 0x11, 0x8d, 0x86, 0xee, 0xb0, 0xe9, 0x8e, 0x7b, - 0x34, 0xfb, 0x28, 0x62, 0x24, 0xa4, 0x45, 0x06, 0x6a, 0xb1, 0xa7, 0x5e, 0xc7, 0x94, 0x75, 0x31, - 0xa4, 0x90, 0xad, 0xe3, 0x6a, 0xef, 0xac, 0xf4, 0xb0, 0x6a, 0xc2, 0x02, 0xb8, 0x22, 0x8e, 0xd4, - 0xb0, 0x1a, 0xce, 0xba, 0xcf, 0xf4, 0x02, 0xa2, 0xae, 0x12, 0xe8, 0x45, 0x9e, 0x0d, 0xef, 0x83, - 0x40, 0x13, 0x28, 0xe1, 0xef, 0xa4, 0x86, 0xcc, 0xfe, 0xd5, 0x3a, 0x6a, 0x20, 0x9a, 0x28, 0x76, - 0x41, 0x7c, 0x14, 0xa3, 0xd2, 0x16, 0x09, 0x85, 0x81, 0xc4, 0xf8, 0x94, 0xd9, 0xb8, 0xaf, 0xb9, - 0x04, 0xb4, 0x00, 0x89, 0x0a, 0x7b, 0x34, 0xe3, 0x96, 0x84, 0x05, 0x96, 0xb5, 0x6c, 0x32, 0x5a, - 0xe1, 0x72, 0xa8, 0x84, 0xdd, 0x71, 0xc1, 0x6a, 0x8f, 0xf1, 0xd4, 0x79, 0x5a, 0x55, 0xfd, 0x8d, - 0xc9, 0x88, 0x41, 0xb9, 0xa2, 0xaa, 0x4f, 0x4e, 0xc8, 0x30, 0x83, 0xcd, 0xcb, 0x85, 0xc6, 0x2b, - 0x7e, 0xd2, 0xfc, 0x5e, 0x20, 0x21, 0xbb, 0xd0, 0x20, 0xb7, 0x02, 0xaf, 0xf5, 0x1f, 0xd9, 0xdf, - 0xa1, 0xde, 0x7f, 0x68, 0x7c, 0xa7, 0xbb, 0xe1, 0xbd, 0x25, 0x07, 0xa6, 0xe7, 0x65, 0xea, 0x09, - 0x9a, 0xc5, 0x68, 0x56, 0xfa, 0x06, 0xe8, 0x26, 0x08, 0xd0, 0x8a, 0x64, 0x2b, 0x7d, 0x66, 0x93, - 0x7c, 0xe4, 0x75, 0xa7, 0xeb, 0x74, 0x95, 0xe3, 0x3c, 0x24, 0x73, 0xc2, 0xa2, 0x28, 0x84, 0x04, - 0xd4, 0x38, 0x22, 0x11, 0x3e, 0x78, 0x02, 0x70, 0x5d, 0xab, 0x91, 0x19, 0x0b, 0xba, 0xc0, 0x4c, - 0x25, 0xc6, 0x2b, 0xa2, 0x4b, 0x73, 0x7d, 0x3b, 0x71, 0x45, 0x97, 0x62, 0x2b, 0xba, 0x14, 0x3f, - 0x0c, 0x0b, 0x08, 0xaf, 0xbe, 0x42, 0xc5, 0x8b, 0xa3, 0x2c, 0x54, 0x22, 0xca, 0x9e, 0xef, 0x18, - 0x88, 0x07, 0xe0, 0xac, 0xb0, 0xda, 0xff, 0x92, 0x35, 0x5a, 0xe0, 0x57, 0x0e, 0x65, 0x49, 0x6f, - 0x5f, 0x16, 0xc1, 0x2b, 0xab, 0x31, 0x93, 0x76, 0x65, 0x96, 0x61, 0xba, 0xc9, 0x1a, 0xa0, 0x47, - 0x21, 0x7d, 0x53, 0xc7, 0xbe, 0xa3, 0x33, 0xd8, 0xe0, 0xdf, 0x33, 0xe1, 0x60, 0x36, 0x05, 0xe0, - 0xe7, 0xcb, 0x8a, 0xd8, 0x2a, 0xe2, 0x0d, 0xc2, 0x21, 0x57, 0xe5, 0x7a, 0x8e, 0xc6, 0x98, 0x3b, - 0x75, 0x65, 0x41, 0xe6, 0x53, 0x5b, 0xe6, 0x5e, 0x8e, 0xbc, 0xd8, 0xd5, 0x4a, 0xe7, 0x96, 0xed, - 0xbc, 0xf5, 0xd0, 0xd6, 0x73, 0x44, 0x47, 0xee, 0xf3, 0xf3, 0x7f, 0x0f, 0x88, 0xaa, 0x49, 0x09, - 0xc0, 0x4f, 0x42, 0xd2, 0xf5, 0x84, 0x64, 0xa8, 0x89, 0x24, 0xad, 0x41, 0xc9, 0x94, 0x9f, 0x85, - 0x7c, 0x5f, 0x0c, 0x52, 0x6a, 0x85, 0x67, 0xfd, 0x7d, 0xaf, 0xba, 0xdf, 0x46, 0x00, 0x7f, 0xb1, - 0x9d, 0x98, 0xcf, 0xa3, 0xdb, 0x72, 0x16, 0x05, 0x16, 0x61, 0x04, 0xef, 0x54, 0x2e, 0xa2, 0x05, - 0xc1, 0x7b, 0xa9, 0x41, 0x50, 0x52, 0xbe, 0x5c, 0x40, 0x90, 0x8b, 0x3d, 0x58, 0x7f, 0xdb, 0x94, - 0x7a, 0xbd, 0xbc, 0x65, 0x51, 0xfc, 0x60, 0x63, 0x95, 0x85, 0xe3, 0xbd, 0xd7, 0x36, 0x3a, 0x82, - 0xa0, 0xe3, 0xa1, 0xe0, 0x27, 0x0f, 0x74, 0x29, 0x5d, 0xfa, 0x67, 0x64, 0x71, 0x79, 0xa1, 0x76, - 0x2b, 0xa0, 0x05, 0x7d, 0x2e, 0x16, 0xb2, 0x8b, 0x91, 0x04, 0x6d, 0x94, 0x51, 0x8c, 0xaf, 0x6c, - 0xa3, 0x90, 0xce, 0x7d, 0xb6, 0x8d, 0x25, 0x68, 0x21, 0xd7, 0x23, 0x22, 0x78, 0x61, 0xad, 0x2d, - 0xdc, 0x8f, 0x21, 0xc6, 0x23, 0x86, 0xac, 0x39, 0xe6, 0x95, 0x64, 0xb3, 0x82, 0x47, 0x8d, 0xe9, - 0x09, 0xe3, 0xc4, 0xf7, 0x8c, 0x77, 0x0f, 0x03, 0xc6, 0xf7, 0xc2, 0x17, 0x20, 0x31, 0xa1, 0xa9, - 0x0d, 0x4e, 0x19, 0x71, 0x09, 0x45, 0x97, 0x1c, 0xa7, 0xc1, 0x79, 0x91, 0x3d, 0xdc, 0x36, 0x9e, - 0x86, 0x86, 0x2e, 0x27, 0xf0, 0x2c, 0x7f, 0xe2, 0xf6, 0x28, 0x9d, 0x4e, 0x7f, 0xcf, 0x40, 0xf9, - 0xed, 0xc4, 0xc6, 0x77, 0xc3, 0xf4, 0x8e, 0x2e, 0x53, 0x00, 0xb1, 0x8a, 0x09, 0xda, 0x16, 0xfc, - 0xf6, 0x69, 0x8a, 0xdb, 0xde, 0xe8, 0x98, 0xb6, 0x3d, 0x15, 0x7c, 0x50, 0x09, 0x83, 0x10, 0xd5, - 0x49, 0x1c, 0x4b, 0x23, 0xa9, 0x43, 0xe1, 0x7c, 0x61, 0x90, 0xbf, 0x67, 0x02, 0xc0, 0x8b, 0xae, - 0xc9, 0x3d, 0x6e, 0xdb, 0x6b, 0x98, 0xa6, 0x6d, 0x78, 0xcd, 0x79, 0xd1, 0x9e, 0x1c, 0x2d, 0x04, - 0xa3, 0xe7, 0xbc, 0x7c, 0x2f, 0x1b, 0xe3, 0xcf, 0x96, 0x53, 0x81, 0xaa, 0xb0, 0x1e, 0xa6, 0xb2, - 0x49, 0x4a, 0x6c, 0xd0, 0x36, 0xe8, 0xf3, 0xa5, 0x39, 0x46, 0x78, 0xa6, 0xa1, 0xe8, 0x78, 0xe6, - 0x1f, 0x80, 0xf6, 0x7a, 0x3a, 0xa1, 0xa9, 0x49, 0x1e, 0x3a, 0xa1, 0xf9, 0x50, 0x68, 0xe0, 0x27, - 0xb7, 0xbd, 0xf9, 0x75, 0x42, 0xc4, 0x4a, 0xb7, 0xfe, 0x3d, 0xa3, 0x6d, 0x7f, 0xb7, 0x82, 0x8e, - 0x05, 0xa1, 0x54, 0xdc, 0x36, 0xad, 0xfb, 0x3d, 0x63, 0xc1, 0x00, 0x58, 0x13, 0x8b, 0x76, 0x17, - 0xcd, 0x1e, 0x71, 0x89, 0x8d, 0x58, 0x9b, 0x47, 0x40, 0xeb, 0xeb, 0x9b, 0x2c, 0x95, 0xfc, 0x26, - 0x97, 0x5b, 0xc4, 0x9a, 0x1b, 0x1f, 0xb5, 0x78, 0x8e, 0x0b, 0x68, 0x69, 0xa0, 0x34, 0x75, 0x65, - 0xab, 0x1b, 0xd8, 0x6c, 0x2e, 0xa7, 0xae, 0x6f, 0x96, 0xd6, 0x8d, 0x34, 0xeb, 0x4f, 0x99, 0x8f, - 0x66, 0xbf, 0xb1, 0x6f, 0x63, 0x90, 0x8b, 0xe6, 0x38, 0x0d, 0x72, 0x8f, 0x7a, 0x8b, 0xd3, 0xec, - 0x92, 0x8c, 0x8c, 0x43, 0x5c, 0x0c, 0xeb, 0x75, 0xb8, 0x6f, 0x6b, 0x46, 0x2d, 0xe5, 0xde, 0x41, - 0x74, 0xcb, 0x34, 0xba, 0x5a, 0xef, 0xa3, 0x71, 0xb7, 0x2e, 0xc3, 0x83, 0xee, 0xe9, 0xad, 0x4b, - 0x36, 0xdc, 0x8d, 0x15, 0xed, 0xe5, 0xe4, 0xfc, 0xfa, 0xe1, 0xee, 0x4f, 0x2c, 0x58, 0xb0, 0xb1, - 0xe6, 0xc2, 0x34, 0x4a, 0xdb, 0x64, 0x0b, 0x14, 0x69, 0x2d, 0x80, 0x41, 0xeb, 0x27, 0xfa, 0x2a, - 0xb7, 0x7d, 0xa0, 0x9b, 0xb8, 0x75, 0x2c, 0xdb, 0xfe, 0x5d, 0x11, 0x08, 0x2d, 0x42, 0xab, 0x9a, - 0x8e, 0x55, 0xb5, 0x60, 0xb8, 0xb4, 0x73, 0x89, 0x50, 0xd8, 0x6b, 0x74, 0x30, 0x37, 0x78, 0xc3, - 0x09, 0x8e, 0x87, 0xf6, 0x5e, 0x62, 0x34, 0x12, 0x5d, 0x32, 0x0b, 0xe9, 0x90, 0xf0, 0x80, 0xa3, - 0xf4, 0xa5, 0x08, 0x62, 0x59, 0xbb, 0xb6, 0x46, 0x81, 0xd2, 0x1b, 0x22, 0x20, 0x91, 0xb8, 0x90, - 0x02, 0x30, 0x71, 0xfa, 0x68, 0xd9, 0x06, 0xc7, 0x2e, 0x8c, 0xb8, 0xb1, 0x25, 0x4d, 0x4f, 0xba, - 0x7d, 0xcd, 0x81, 0x4c, 0x60, 0x5b, 0x0d, 0x2e, 0x57, 0x2c, 0xc2, 0x93, 0x66, 0x34, 0xb8, 0x2c, - 0x97, 0x08, 0x5f, 0xd4, 0x00, 0xfa, 0x83, 0x3e, 0x84, 0x5f, 0xd9, 0x5c, 0x85, 0x5b, 0xd9, 0x1f, - 0x8f, 0xc1, 0x2d, 0x56, 0xb9, 0xf7, 0xc5, 0x44, 0x57, 0x22, 0x52, 0x96, 0x09, 0x1d, 0x2c, 0xca, - 0x72, 0x91, 0x19, 0x45, 0x6b, 0x85, 0x66, 0xc1, 0xab, 0x19, 0x84, 0x7f, 0x2e, 0x73, 0x08, 0x4f, - 0xc1, 0xe5, 0xc2, 0xd3, 0x76, 0x35, 0x04, 0x8c, 0x22, 0xef, 0x0b, 0x38, 0x22, 0xd3, 0x24, 0x56, - 0xcd, 0x23, 0xb7, 0x4d, 0x4b, 0x27, 0xb0, 0xf8, 0x62, 0xfe, 0x10, 0x8a, 0xf5, 0x0a, 0x08, 0xde, - 0x58, 0xd1, 0x29, 0xda, 0x44, 0xab, 0xf3, 0x29, 0xe0, 0x1d, 0xaa, 0x7f, 0x51, 0x55, 0x87, 0x42, - 0xdf, 0x08, 0x20, 0xbc, 0x2a, 0xce, 0xd6, 0x78, 0x05, 0x8c, 0xd0, 0xf0, 0xa0, 0xc8, 0x82, 0x40, - 0xbe, 0x59, 0xad, 0x24, 0xf7, 0xb5, 0xdb, 0x15, 0xe1, 0x1f, 0xc7, 0x7f, 0x4b, 0x6c, 0xd0, 0xab, - 0x59, 0x1a, 0xdc, 0x35, 0x51, 0x03, 0x7e, 0xbd, 0xa4, 0x5d, 0xd9, 0x90, 0xb9, 0xbd, 0x02, 0xa1, - 0x14, 0xf2, 0x46, 0x1c, 0xb4, 0xe4, 0x81, 0xf6, 0x20, 0x5f, 0x78, 0xb3, 0xbf, 0x0e, 0xb8, 0x5f, - 0x63, 0x3b, 0x10, 0x2a, 0x1f, 0xf5, 0x5d, 0xa9, 0x44, 0x1a, 0x78, 0x24, 0x3a, 0xd8, 0x31, 0xd0, - 0x91, 0x77, 0x5a, 0xa0, 0x55, 0x3e, 0x3f, 0x04, 0x60, 0x32, 0xe1, 0x16, 0xee, 0x25, 0x7b, 0x90, - 0xb8, 0x47, 0x4b, 0xf1, 0xdd, 0x61, 0xd0, 0x5a, 0x8b, 0xb9, 0xfe, 0x68, 0x18, 0xf8, 0x2f, 0xdc, - 0x08, 0x83, 0xff, 0xde, 0x28, 0xba, 0xeb, 0x86, 0x90, 0xc0, 0x3d, 0x92, 0xa5, 0x71, 0x88, 0xa2, - 0x18, 0x9d, 0x8a, 0x5d, 0xd0, 0xa4, 0x5f, 0xde, 0x19, 0x42, 0x68, 0x1a, 0xbe, 0xcb, 0xf6, 0x67, - 0xa6, 0x42, 0x14, 0x23, 0x63, 0xb8, 0xd4, 0x8c, 0x97, 0x77, 0x87, 0x20, 0x76, 0xd7, 0xcf, 0xc2, - 0x72, 0xe7, 0x19, 0xec, 0x8d, 0xa0, 0xf7, 0x43, 0xf2, 0x6e, 0xe7, 0xbb, 0x9f, 0x9e, 0x61, 0x04, - 0xad, 0x54, 0x42, 0x1d, 0x6f, 0x4d, 0x25, 0xe3, 0x7d, 0xd8, 0x58, 0xfe, 0xb3, 0x24, 0x0a, 0xba, - 0x40, 0x37, 0x82, 0xf8, 0x03, 0x9b, 0x10, 0xe3, 0x3d, 0xc4, 0x78, 0x35, 0x3e, 0x87, 0x1b, 0xdb, - 0x50, 0x23, 0x4b, 0x17, 0x24, 0x90, 0x39, 0x58, 0x05, 0x7d, 0x29, 0xea, 0x08, 0xcc, 0x42, 0x2a, - 0x66, 0x30, 0xa4, 0x4b, 0x30, 0xe9, 0xc2, 0xc4, 0xc8, 0x23, 0x51, 0xe8, 0x61, 0x07, 0x69, 0x84, - 0x95, 0x60, 0x0d, 0x6d, 0x4b, 0x27, 0x6b, 0xc2, 0x15, 0xb6, 0xb2, 0xa8, 0xf2, 0x02, 0x91, 0x5f, - 0xaf, 0xe7, 0xb6, 0x94, 0xeb, 0xb1, 0x0b, 0x91, 0xe2, 0x7c, 0x29, 0x5e, 0x8c, 0x45, 0x2c, 0x70, - 0x81, 0x1c, 0x88, 0xf2, 0x2f, 0x2c, 0x31, 0xf2, 0x25, 0x67, 0x08, 0x23, 0x6b, 0xa4, 0xd7, 0xc6, - 0x42, 0x7c, 0xdd, 0x05, 0x2d, 0x83, 0x1e, 0x89, 0x29, 0x88, 0x41, 0x4f, 0x6e, 0x61, 0x78, 0xe2, - 0x1d, 0x8a, 0xb2, 0x88, 0x78, 0x63, 0xd7, 0x24, 0x89, 0xbe, 0x10, 0x03, 0x0b, 0x1c, 0x7a, 0x45, - 0xa5, 0x98, 0xb8, 0x46, 0x8a, 0x61, 0x09, 0xc7, 0x25, 0x56, 0x83, 0x93, 0x8c, 0xe9, 0xca, 0x1e, - 0xc6, 0xe5, 0xd9, 0x46, 0x68, 0x69, 0xc5, 0x31, 0xf1, 0xf2, 0x97, 0xc6, 0x79, 0xf2, 0xc1, 0x38, - 0x4f, 0xde, 0x19, 0xe7, 0x86, 0x3f, 0xd0, 0x6a, 0xd6, 0x97, 0xd7, 0x55, 0x71, 0xcd, 0x60, 0x4b, - 0x60, 0xb4, 0xbd, 0x3f, 0xc4, 0x8d, 0xf7, 0xe9, 0xc1, 0x8b, 0xb1, 0xf8, 0x94, 0xb0, 0xdb, 0xb8, - 0x3e, 0xd8, 0x4d, 0x60, 0x97, 0x0d, 0xa2, 0x3b, 0x51, 0x61, 0x6a, 0x47, 0x80, 0x30, 0xa4, 0xfc, - 0x11, 0xc2, 0xae, 0x57, 0x21, 0xcc, 0x47, 0x0f, 0x62, 0xec, 0xba, 0x27, 0x27, 0x97, 0x35, 0x19, - 0x24, 0x86, 0x0f, 0x54, 0x99, 0x4f, 0x69, 0x32, 0x71, 0xd6, 0x8a, 0x1d, 0xeb, 0xfd, 0xa5, 0x31, - 0x2d, 0x86, 0x74, 0xb0, 0x58, 0x3e, 0x7f, 0x3a, 0xa6, 0xb5, 0x43, 0xda, 0xf8, 0x4b, 0x63, 0x5a, - 0x58, 0x6a, 0x4b, 0x43, 0xda, 0xf8, 0xb3, 0x31, 0xed, 0x2e, 0x4f, 0xd3, 0xc6, 0xdf, 0x1d, 0xd3, - 0x9f, 0x68, 0x9c, 0xeb, 0xd7, 0xe9, 0x98, 0x0d, 0x6d, 0xe3, 0x13, 0x74, 0x4c, 0x05, 0xba, 0x4f, - 0xc8, 0x4b, 0x4a, 0x7d, 0x0c, 0x07, 0x1b, 0xcb, 0x48, 0xb8, 0x7f, 0x8f, 0x56, 0x97, 0x59, 0xd6, - 0x7f, 0x88, 0x5a, 0x43, 0x0a, 0x31, 0x06, 0x46, 0xbd, 0x37, 0x54, 0xc8, 0xc6, 0x4d, 0xf3, 0x8f, - 0x86, 0x0a, 0xb4, 0x1f, 0x1f, 0x6a, 0xf3, 0x83, 0xa1, 0xee, 0x32, 0xc8, 0xd4, 0xce, 0x48, 0xd3, - 0xd1, 0x44, 0x46, 0xbd, 0xf1, 0xc9, 0xc9, 0xff, 0xcc, 0xa8, 0xd7, 0xa9, 0xea, 0x1d, 0xdd, 0x74, - 0x9d, 0x4f, 0xf1, 0x2f, 0x3a, 0x2f, 0x60, 0x9e, 0x41, 0x79, 0x44, 0xc5, 0x46, 0xc8, 0xb9, 0xe2, - 0xe8, 0x71, 0x08, 0xbe, 0xce, 0x11, 0x76, 0xee, 0x84, 0x9c, 0x12, 0x5e, 0xe1, 0xc9, 0xc4, 0x49, - 0xc8, 0xae, 0x11, 0xf6, 0x0f, 0xb0, 0x6d, 0x15, 0xec, 0x15, 0x92, 0xc0, 0x76, 0x76, 0xd9, 0xdc, - 0xfd, 0x54, 0xdd, 0x2c, 0xd4, 0xcd, 0xfd, 0xc5, 0xba, 0x39, 0xa8, 0x9b, 0x5f, 0xb6, 0x7b, 0xe3, - 0x88, 0xf3, 0xe2, 0xf1, 0xde, 0x93, 0xf2, 0x5e, 0xd4, 0xdb, 0x12, 0x05, 0xfa, 0xf9, 0x5e, 0x08, - 0xe0, 0xe7, 0xd6, 0x9d, 0x57, 0x78, 0x89, 0x0c, 0xbb, 0xa0, 0x36, 0x2d, 0x64, 0x02, 0x23, 0x15, - 0x74, 0x13, 0x73, 0xe1, 0x02, 0x89, 0x90, 0xb7, 0x19, 0xfb, 0x8e, 0xfb, 0x11, 0x0b, 0xa1, 0xfa, - 0x8d, 0x6d, 0x50, 0x50, 0x3a, 0x14, 0x38, 0x8b, 0xf6, 0x19, 0x35, 0x31, 0xd3, 0xa0, 0xbe, 0x6f, - 0x1c, 0x48, 0x90, 0xcf, 0x33, 0xa3, 0x3d, 0x62, 0xb3, 0x2f, 0x36, 0x1a, 0x42, 0x26, 0x3b, 0x26, - 0x1a, 0x7e, 0x15, 0xea, 0x61, 0xc9, 0x7b, 0xbe, 0xa4, 0xa5, 0xfa, 0xa1, 0xfd, 0x11, 0xdf, 0x19, - 0x92, 0xf5, 0x4a, 0xc6, 0x15, 0x30, 0xda, 0xb7, 0x00, 0x5f, 0xb8, 0x7b, 0xb9, 0x16, 0xbb, 0xfb, - 0x60, 0xba, 0x28, 0x9f, 0x24, 0xee, 0x0d, 0x56, 0x78, 0x81, 0x5c, 0x4f, 0x09, 0x65, 0xc9, 0x09, - 0xc7, 0x22, 0x44, 0x5d, 0x31, 0xf0, 0xb0, 0xb3, 0x82, 0x76, 0x3c, 0x9f, 0x2b, 0xb2, 0x8e, 0x6f, - 0xfc, 0x91, 0x60, 0xe8, 0x50, 0xf8, 0x51, 0xe6, 0x40, 0xd3, 0xfe, 0xd4, 0x37, 0x21, 0xfe, 0xcf, - 0xf8, 0x26, 0x96, 0x31, 0x86, 0x9b, 0x46, 0xb8, 0x6b, 0x3c, 0xfd, 0x00, 0x6b, 0x61, 0xd7, 0x60, - 0x4f, 0x3f, 0xc5, 0xf9, 0x70, 0x7c, 0x27, 0x4f, 0x41, 0xac, 0x86, 0x9c, 0x3c, 0x9f, 0x56, 0x86, - 0x8e, 0x82, 0xa6, 0xa3, 0x08, 0x0d, 0xd2, 0x99, 0xf6, 0xb8, 0x1e, 0xa7, 0x1b, 0x7f, 0x8c, 0xd4, - 0xcf, 0xe8, 0xc7, 0x9f, 0x45, 0x6a, 0x44, 0x3e, 0x79, 0x6c, 0x34, 0x76, 0x7e, 0x0a, 0xf7, 0x03, - 0xfc, 0xa6, 0xc3, 0xe8, 0x6b, 0x4f, 0xf6, 0x6c, 0xd3, 0x52, 0xcd, 0xb1, 0x81, 0x43, 0xf4, 0xc9, - 0xde, 0x63, 0x75, 0x88, 0x20, 0x1a, 0x6c, 0xb9, 0xce, 0xed, 0x4a, 0x2a, 0x0c, 0xdb, 0xd4, 0x2b, - 0x13, 0xe9, 0x45, 0xb8, 0x8d, 0x4b, 0x49, 0x5f, 0xdf, 0x08, 0x5d, 0xa2, 0x34, 0x86, 0x73, 0x4d, - 0x23, 0xe8, 0x75, 0xdc, 0xc0, 0x56, 0xf6, 0x48, 0x57, 0x1a, 0xea, 0x6e, 0x7c, 0xcd, 0x76, 0x83, - 0x11, 0x04, 0xa0, 0x17, 0xfb, 0xb4, 0xdc, 0x2a, 0xc6, 0xe7, 0x4b, 0xdd, 0x3f, 0x62, 0x7c, 0x1b, - 0xab, 0x39, 0x5f, 0x77, 0x42, 0x19, 0x0a, 0xb0, 0xbe, 0x77, 0x38, 0xdf, 0xc6, 0x1f, 0xb2, 0xbe, - 0x38, 0xe7, 0xdb, 0xf8, 0x8b, 0xac, 0xcf, 0xeb, 0x5c, 0x22, 0xc2, 0xfa, 0xa2, 0x7c, 0x06, 0xb7, - 0xf4, 0xb9, 0x04, 0xde, 0x9f, 0xba, 0x85, 0x35, 0xc4, 0x50, 0x97, 0x80, 0xfe, 0xd9, 0xca, 0xa4, - 0x62, 0xf5, 0xbb, 0x94, 0x60, 0x6e, 0xe9, 0xaf, 0x62, 0x54, 0x08, 0x86, 0x0b, 0x79, 0x74, 0x20, - 0x6d, 0x7f, 0x60, 0x13, 0x2f, 0x08, 0x62, 0xc1, 0x98, 0x3f, 0x98, 0xb4, 0x0f, 0xe6, 0x6c, 0xe3, - 0x4f, 0xa4, 0x95, 0xa4, 0x7f, 0x3c, 0x69, 0x1b, 0x89, 0xff, 0xa1, 0x49, 0xf3, 0x7b, 0xf7, 0xd7, - 0x67, 0x0d, 0xd6, 0x1b, 0x71, 0x5d, 0xf2, 0xc1, 0xb4, 0x85, 0x4b, 0x05, 0x4b, 0x4b, 0xda, 0x8e, - 0x37, 0x83, 0xf1, 0x1e, 0x81, 0x2b, 0x6c, 0xb5, 0x7e, 0x18, 0xb6, 0x0e, 0xde, 0x9d, 0x77, 0xef, - 0xcc, 0x6d, 0x6c, 0xf3, 0x8a, 0x6d, 0x56, 0x49, 0x61, 0xb1, 0xec, 0x57, 0x08, 0x2e, 0x4e, 0x79, - 0x67, 0x67, 0x26, 0x0e, 0x0a, 0x37, 0x45, 0x03, 0xe4, 0xd1, 0xb3, 0xd3, 0x61, 0xfd, 0x0a, 0x4f, - 0xde, 0xd2, 0xf9, 0x1d, 0xf4, 0xfc, 0x32, 0x63, 0x8d, 0x4b, 0x48, 0x3a, 0xc8, 0x03, 0x7a, 0x39, - 0x73, 0xe8, 0x6a, 0x72, 0xcb, 0xe8, 0xf9, 0x77, 0x07, 0x6b, 0x77, 0xbb, 0x17, 0xd7, 0x63, 0xf1, - 0xe4, 0xa0, 0x67, 0xe2, 0x7d, 0x59, 0xe7, 0x9d, 0xdb, 0xfe, 0xfe, 0x2d, 0xde, 0x15, 0xbc, 0x4b, - 0xef, 0xcf, 0x6a, 0xb7, 0x9a, 0x8f, 0xf0, 0xd5, 0x2a, 0xb6, 0x87, 0xdd, 0x22, 0xbd, 0x2c, 0xf8, - 0xe1, 0xbc, 0x73, 0x2d, 0x1e, 0x35, 0x6d, 0xa7, 0xa0, 0x94, 0xe8, 0xed, 0xe4, 0xd7, 0xc6, 0xd5, - 0x6d, 0x76, 0x17, 0xca, 0x4c, 0x9e, 0xc7, 0xa3, 0xca, 0xe3, 0xd5, 0x2d, 0x26, 0x1e, 0x2b, 0xfb, - 0xfd, 0x27, 0x65, 0xdc, 0x6c, 0xee, 0x39, 0x67, 0xf0, 0xb3, 0xbc, 0xd7, 0x54, 0xd4, 0xd1, 0xeb, - 0x01, 0x56, 0xd8, 0x95, 0x3b, 0xb7, 0xd7, 0xbb, 0x77, 0xad, 0xfe, 0x8d, 0xfe, 0x58, 0x95, 0xf7, - 0xcc, 0xe6, 0x78, 0xef, 0xec, 0xfc, 0xbe, 0x6c, 0x54, 0x8d, 0x71, 0x4b, 0xb3, 0xa6, 0xee, 0xd5, - 0x79, 0xe1, 0xa9, 0xe2, 0xca, 0xf6, 0xcd, 0xe1, 0x60, 0x6f, 0xd0, 0x2e, 0x98, 0x97, 0x6f, 0x53, - 0x5d, 0x1d, 0x5f, 0xbf, 0x5a, 0xd9, 0x4e, 0x47, 0x35, 0xee, 0x32, 0xe7, 0xc3, 0xa7, 0xe1, 0xdb, - 0x2b, 0x18, 0x14, 0xbb, 0xd3, 0xc9, 0xc3, 0x9b, 0xb1, 0x3b, 0xce, 0x6b, 0xbd, 0x17, 0xd2, 0xde, - 0xef, 0x3e, 0x4c, 0x6f, 0x87, 0xfd, 0x93, 0xcc, 0xb4, 0x7d, 0x26, 0xb6, 0x26, 0xc7, 0xdd, 0xe9, - 0xeb, 0xc3, 0xd3, 0xfe, 0x85, 0x52, 0xca, 0x74, 0xec, 0x6a, 0x46, 0xee, 0x96, 0x87, 0x47, 0xad, - 0xe2, 0xf9, 0x58, 0x2d, 0x9b, 0xf6, 0xd9, 0xa8, 0x79, 0xb9, 0xf2, 0x3e, 0xf3, 0x15, 0x76, 0xee, - 0xcb, 0x28, 0xd8, 0x1c, 0x0d, 0x36, 0x45, 0x83, 0x12, 0x4b, 0xca, 0x74, 0x4c, 0x91, 0xb6, 0xc9, - 0xeb, 0x90, 0x38, 0xee, 0xb1, 0x83, 0x57, 0x43, 0x73, 0xdb, 0xd7, 0xa4, 0x0b, 0x7a, 0x6b, 0x7f, - 0xad, 0x2a, 0x1e, 0xab, 0x1d, 0xdd, 0x1e, 0x6c, 0xe9, 0xa6, 0x43, 0x12, 0xf8, 0xeb, 0xcf, 0xea, - 0x07, 0xf4, 0x74, 0x64, 0x38, 0x2e, 0x5a, 0x58, 0x09, 0xbc, 0x8c, 0xfb, 0x03, 0x18, 0xd4, 0x11, - 0x83, 0x2a, 0x36, 0xfd, 0xb9, 0x60, 0x0b, 0x46, 0xf7, 0x1a, 0x53, 0xd9, 0x60, 0x64, 0xd3, 0x74, - 0x13, 0xec, 0xf2, 0xf7, 0xb8, 0x7d, 0xe0, 0x58, 0x52, 0x00, 0x11, 0x35, 0xca, 0x33, 0x49, 0x25, - 0x89, 0xb1, 0xe6, 0xf6, 0xbd, 0x2c, 0x84, 0x4f, 0x8f, 0x3c, 0x23, 0xcb, 0xc8, 0x8a, 0x62, 0xa5, - 0x50, 0x07, 0xd6, 0xd1, 0xde, 0x17, 0xf7, 0x81, 0x75, 0x60, 0x89, 0xed, 0x84, 0x3c, 0x4d, 0x34, - 0x35, 0x5b, 0x31, 0x4d, 0xf3, 0x45, 0x23, 0x74, 0xcb, 0xdc, 0xed, 0x93, 0x04, 0xac, 0x7a, 0xef, - 0xa6, 0xfd, 0xbe, 0xeb, 0x5a, 0x4e, 0x2d, 0x93, 0x19, 0xeb, 0x44, 0x4d, 0x83, 0x9a, 0xa1, 0x98, - 0x43, 0xdb, 0x21, 0x69, 0xf4, 0x8a, 0x5a, 0x19, 0x50, 0x52, 0x24, 0xbb, 0x87, 0xef, 0x07, 0xf8, - 0x2f, 0x19, 0xcc, 0xca, 0x17, 0x8e, 0x5e, 0x52, 0x9f, 0x50, 0xcc, 0xc1, 0x60, 0x68, 0x80, 0xd6, - 0xc3, 0x38, 0x39, 0x6b, 0x68, 0x63, 0x69, 0x6d, 0xb2, 0x1d, 0xd3, 0x75, 0x0b, 0x0d, 0x0f, 0xf3, - 0x7b, 0xf0, 0x34, 0x0f, 0xa5, 0xce, 0xd2, 0x5a, 0x7d, 0x31, 0xfe, 0x98, 0x6c, 0x02, 0x2c, 0xe3, - 0x15, 0xe9, 0xc1, 0xac, 0x6d, 0x7c, 0x8a, 0x68, 0xd6, 0xcd, 0x39, 0x23, 0x1a, 0x3d, 0x3c, 0xe1, - 0x1b, 0x71, 0x1e, 0xa6, 0x31, 0xb7, 0x9b, 0x7f, 0x1d, 0x01, 0x17, 0x15, 0x0f, 0x78, 0x43, 0x50, - 0x94, 0x09, 0x9f, 0x32, 0x8f, 0x04, 0xd3, 0x4a, 0xb3, 0x22, 0x53, 0x61, 0xd8, 0xd8, 0xfc, 0xbb, - 0xff, 0xf1, 0x56, 0x79, 0xdd, 0x54, 0x34, 0x4b, 0x00, 0x53, 0x92, 0x39, 0x80, 0x05, 0x8b, 0x71, - 0x65, 0x67, 0x0f, 0xd8, 0x90, 0x30, 0x76, 0xd8, 0x4d, 0xf5, 0x02, 0xbb, 0x04, 0x5e, 0x70, 0xd9, - 0x4d, 0xea, 0x02, 0x54, 0x6a, 0x7c, 0xc9, 0xe2, 0x97, 0x65, 0x9b, 0xae, 0xc9, 0x66, 0xb9, 0xc6, - 0x09, 0x86, 0x79, 0x4e, 0xc6, 0x60, 0x65, 0x3a, 0x98, 0xab, 0x39, 0x17, 0x06, 0xfb, 0xc6, 0xd5, - 0xc0, 0x9e, 0xe8, 0x88, 0xd9, 0xe3, 0x75, 0x4f, 0x1e, 0xe3, 0x93, 0xa2, 0xb8, 0x0d, 0x7a, 0x25, - 0xbf, 0x06, 0xad, 0x36, 0x7e, 0xd0, 0x33, 0x46, 0x3f, 0x05, 0x0b, 0x77, 0xe9, 0x89, 0xda, 0xf8, - 0xf1, 0x05, 0x7e, 0xf8, 0x71, 0x8b, 0xed, 0x49, 0x43, 0x0c, 0x7e, 0x80, 0xf8, 0x80, 0x5f, 0x0a, - 0xfc, 0xc4, 0xaf, 0xa1, 0x8d, 0xa7, 0x40, 0x99, 0xbd, 0xd9, 0xd8, 0x82, 0xae, 0x01, 0x3b, 0xbf, - 0xa5, 0x6a, 0x32, 0xad, 0xd2, 0x6b, 0x99, 0x43, 0xc3, 0x85, 0x47, 0xa0, 0xc2, 0xe0, 0x11, 0x9a, - 0x80, 0x42, 0xc6, 0xd0, 0x81, 0x76, 0x44, 0x01, 0x14, 0x68, 0xe8, 0x39, 0xa6, 0xb3, 0x2f, 0xd7, - 0x6e, 0x94, 0x05, 0x35, 0xb8, 0xa8, 0x5e, 0xe8, 0x4e, 0x90, 0x33, 0x37, 0x7e, 0x40, 0xdf, 0x90, - 0x51, 0x34, 0x66, 0x73, 0x81, 0xf8, 0x0f, 0xba, 0xff, 0x60, 0x9d, 0x37, 0x38, 0x4e, 0xb0, 0x8e, - 0xa0, 0xbe, 0x75, 0x3e, 0x1c, 0xe0, 0xd7, 0xc0, 0x6d, 0x64, 0xf1, 0xf3, 0xb4, 0xc3, 0x7e, 0x9d, - 0x42, 0xcf, 0xb0, 0x15, 0xf8, 0x42, 0x49, 0x81, 0xb5, 0x94, 0x6e, 0xaf, 0x31, 0xa3, 0x6f, 0xc3, - 0xa8, 0xcd, 0x90, 0xdf, 0xd7, 0x40, 0x08, 0xd8, 0x2f, 0x9c, 0x20, 0xf7, 0x6a, 0xb3, 0xa1, 0xad, - 0xd7, 0x38, 0x6e, 0x2e, 0x48, 0xba, 0xd5, 0x97, 0x20, 0xbb, 0x57, 0x4b, 0x97, 0x04, 0x57, 0x92, - 0x6b, 0xe9, 0x0a, 0x54, 0xa4, 0x5b, 0x16, 0x98, 0x08, 0x45, 0xf0, 0xe7, 0xc0, 0xaa, 0xb1, 0x68, - 0x7a, 0xa7, 0x36, 0x63, 0x8e, 0xff, 0xda, 0x17, 0x51, 0xb0, 0x7b, 0x32, 0xbe, 0xf5, 0xe0, 0x15, - 0xf7, 0x45, 0xf1, 0x77, 0x9f, 0x4c, 0xe0, 0x37, 0x74, 0x9b, 0x9a, 0x2e, 0x98, 0x62, 0x29, 0x03, - 0xd0, 0xd3, 0xb1, 0x90, 0xa5, 0xa9, 0x98, 0x00, 0x28, 0xd3, 0x89, 0x81, 0xa5, 0xe6, 0x02, 0x28, - 0x35, 0x8d, 0x1f, 0x30, 0x31, 0xd9, 0xac, 0x90, 0x2b, 0x08, 0x05, 0x21, 0x58, 0xd3, 0x52, 0xb0, - 0xf0, 0xd3, 0x3d, 0x60, 0x1a, 0x43, 0x39, 0xad, 0x99, 0x99, 0xc9, 0x40, 0x72, 0xd2, 0x20, 0xb9, - 0xb8, 0x9f, 0x02, 0xd4, 0xc9, 0x09, 0xd9, 0xb2, 0x90, 0x5d, 0x54, 0xa1, 0x82, 0xcd, 0x49, 0xd3, - 0xd1, 0x28, 0x26, 0xbe, 0xdf, 0x20, 0x0d, 0xbd, 0xce, 0x14, 0xaa, 0x59, 0xfc, 0xcb, 0xe6, 0xf2, - 0xe9, 0x67, 0x8b, 0x56, 0xcd, 0x89, 0xb9, 0x9c, 0x90, 0xc7, 0xda, 0xb9, 0x0f, 0x1a, 0x24, 0x80, - 0x49, 0x62, 0xfb, 0x4d, 0x42, 0xbd, 0x3c, 0xd4, 0xab, 0xfe, 0x79, 0xb5, 0x02, 0x54, 0xc9, 0x67, - 0xff, 0xa8, 0xde, 0xcf, 0x7a, 0xf0, 0xfa, 0x0c, 0xb0, 0xd9, 0x54, 0x9d, 0xdc, 0x05, 0x61, 0x5c, - 0x2d, 0x6a, 0xc4, 0x25, 0xf9, 0xd9, 0x17, 0xd5, 0x3b, 0x14, 0xbd, 0xb9, 0x89, 0x6f, 0xac, 0x80, - 0x75, 0x85, 0xb7, 0x63, 0xf8, 0xd4, 0xb9, 0x9d, 0x27, 0xf9, 0xcd, 0xcd, 0x88, 0x00, 0x9a, 0x07, - 0x30, 0x1d, 0x58, 0x93, 0x49, 0x22, 0xb8, 0xfc, 0x0c, 0x58, 0xa7, 0x47, 0x87, 0xde, 0x4b, 0x1f, - 0xd2, 0xd4, 0xca, 0xc2, 0x57, 0x31, 0x5c, 0x82, 0x22, 0x4b, 0x6c, 0xb0, 0x10, 0xb1, 0xe0, 0xa2, - 0x6e, 0xef, 0x48, 0x4d, 0x12, 0x7e, 0x66, 0x13, 0x77, 0x68, 0x1b, 0x09, 0x35, 0xf4, 0x0e, 0x8f, - 0xdd, 0x29, 0xcd, 0x0a, 0x15, 0xdd, 0xdf, 0x6d, 0x9d, 0xaf, 0x29, 0xec, 0xec, 0x4e, 0x5b, 0xc8, - 0x67, 0xe8, 0x2b, 0x3f, 0xc2, 0x95, 0x34, 0x67, 0x7f, 0x60, 0x61, 0xab, 0x41, 0x35, 0xb1, 0xd1, - 0x68, 0x5c, 0xc8, 0xcf, 0xb0, 0x38, 0xf1, 0xd6, 0x31, 0x07, 0x72, 0xd2, 0x40, 0x42, 0x3d, 0xb7, - 0x1f, 0xae, 0x04, 0x05, 0x42, 0x55, 0xc8, 0xe6, 0x26, 0x67, 0xd2, 0x2a, 0x5c, 0xa3, 0x81, 0x9a, - 0xb5, 0xd9, 0xc5, 0xb4, 0x2f, 0x4d, 0xdb, 0x96, 0xa6, 0x69, 0xcd, 0xa1, 0xdf, 0x91, 0x66, 0xf1, - 0xcd, 0x16, 0xd3, 0x56, 0xb7, 0x07, 0x88, 0x55, 0x58, 0x74, 0x05, 0x47, 0xaf, 0x5a, 0xc4, 0x77, - 0x4a, 0xc0, 0x32, 0x4a, 0xd3, 0x55, 0x94, 0xc6, 0x45, 0xc4, 0x5e, 0x9a, 0x41, 0x42, 0xa9, 0x74, - 0x61, 0xa4, 0xe5, 0x5e, 0x1d, 0x9a, 0xa0, 0xa8, 0xe5, 0xe8, 0x31, 0x5b, 0x4e, 0x20, 0xfe, 0x0b, - 0x36, 0xb0, 0x2c, 0x2e, 0x22, 0x56, 0xd4, 0xa9, 0x23, 0x12, 0xbd, 0x7d, 0x7d, 0xde, 0xc3, 0xb8, - 0x67, 0x29, 0x37, 0xdc, 0x34, 0x5d, 0x4e, 0x3b, 0x1c, 0x8d, 0x16, 0xe5, 0x6a, 0x1c, 0x75, 0x17, - 0xd6, 0xbb, 0xc0, 0x75, 0x11, 0x96, 0xb9, 0x80, 0xc5, 0x56, 0x99, 0xe0, 0x34, 0x54, 0xa8, 0x42, - 0xec, 0x69, 0x87, 0x32, 0x30, 0xd3, 0x6e, 0xea, 0xd0, 0x83, 0xc5, 0x25, 0x4f, 0x1c, 0x2f, 0x18, - 0x0d, 0xb1, 0x6e, 0x7c, 0x77, 0x3c, 0xb4, 0xd5, 0x8d, 0x54, 0x8a, 0x77, 0x7e, 0x18, 0x3f, 0x63, - 0x2d, 0x9b, 0xf1, 0x36, 0xd7, 0x40, 0xf6, 0xa0, 0xd2, 0x2e, 0xfd, 0x45, 0xc8, 0xc9, 0x25, 0xd0, - 0x00, 0xb7, 0xaf, 0x72, 0x3c, 0xff, 0x41, 0x4d, 0xc1, 0xc7, 0xaf, 0x2c, 0x5b, 0x9c, 0x00, 0xb9, - 0xa1, 0x4b, 0x45, 0xa1, 0x8c, 0x77, 0xd3, 0x07, 0x0d, 0xb9, 0x83, 0x71, 0x07, 0x85, 0x01, 0xb4, - 0x10, 0x07, 0x15, 0xca, 0x1e, 0xb8, 0x34, 0x1b, 0x3d, 0x09, 0x35, 0xae, 0x08, 0x9f, 0x8b, 0x3c, - 0x77, 0x4b, 0xe6, 0x84, 0xc5, 0x54, 0x53, 0xfe, 0x82, 0xb8, 0x85, 0x12, 0xda, 0x1b, 0x2c, 0x43, - 0x94, 0x55, 0x92, 0xde, 0x81, 0x11, 0x00, 0xff, 0xc1, 0x65, 0x73, 0xe4, 0x92, 0x41, 0x92, 0x43, - 0xad, 0xe4, 0x56, 0x03, 0x7a, 0xe2, 0x84, 0xe3, 0xce, 0xc5, 0x39, 0x8c, 0x0a, 0x6f, 0x58, 0xd1, - 0xba, 0xd3, 0x24, 0xc0, 0xe2, 0x43, 0x74, 0xb7, 0x08, 0xe6, 0x99, 0x45, 0xc9, 0xac, 0xb1, 0x8e, - 0xfe, 0x76, 0x18, 0x13, 0xaf, 0x79, 0xf9, 0xc2, 0x82, 0x72, 0x23, 0x50, 0x7d, 0xf7, 0xd1, 0x2c, - 0x46, 0x2f, 0x8d, 0x2f, 0x71, 0x02, 0x5a, 0x05, 0xc0, 0x5b, 0x03, 0xb0, 0xa2, 0xc8, 0x4e, 0x32, - 0x42, 0xd3, 0x1c, 0x5e, 0x63, 0x1b, 0x42, 0x90, 0xb2, 0xd5, 0xc5, 0x44, 0x1a, 0x85, 0x10, 0x4a, - 0xcc, 0x61, 0xa2, 0xaa, 0xaa, 0x91, 0xc4, 0x3c, 0x26, 0xca, 0xb2, 0x1c, 0x49, 0x2c, 0x60, 0xa2, - 0x24, 0x49, 0x91, 0xc4, 0x22, 0x26, 0x56, 0xab, 0xd5, 0x48, 0x62, 0x69, 0x55, 0x62, 0x05, 0x13, - 0x2b, 0x95, 0x4a, 0x24, 0x51, 0xc6, 0xc4, 0x42, 0xa1, 0x10, 0x49, 0x54, 0x30, 0x31, 0x9f, 0xcf, - 0x47, 0x12, 0x09, 0x26, 0x66, 0xb3, 0xd9, 0x48, 0xa2, 0x8a, 0x89, 0xf8, 0xae, 0xa8, 0x70, 0xa2, - 0x8d, 0x89, 0x4a, 0x2e, 0x5a, 0xb2, 0x47, 0x4b, 0x2a, 0xd1, 0x44, 0x9d, 0x26, 0x96, 0x94, 0x48, - 0xa2, 0x09, 0x89, 0xf4, 0x5a, 0xdd, 0x9c, 0x58, 0x10, 0x12, 0x8b, 0x0f, 0xbc, 0xc3, 0x37, 0x52, - 0xd0, 0x91, 0x3d, 0x7c, 0xe6, 0x63, 0xc9, 0x7d, 0x2f, 0xbd, 0x14, 0x49, 0x77, 0xe5, 0x35, 0x80, - 0x43, 0x57, 0xf6, 0xc6, 0x2a, 0x48, 0x7e, 0x8d, 0x6c, 0x59, 0x14, 0x12, 0x8b, 0x8f, 0xf5, 0x35, - 0xfa, 0x9f, 0x6a, 0x83, 0x72, 0x35, 0x6a, 0x87, 0xfa, 0xcb, 0xb8, 0xab, 0xe9, 0x2e, 0xba, 0x2d, - 0x34, 0x03, 0x4f, 0x72, 0x24, 0xc5, 0x74, 0x05, 0xca, 0xd5, 0xe2, 0x04, 0x15, 0x47, 0x3f, 0x25, - 0x28, 0x1a, 0x39, 0x13, 0x27, 0xa8, 0xf8, 0x9c, 0xe4, 0x57, 0x4d, 0x69, 0x61, 0xd5, 0xe4, 0x53, - 0x82, 0x2a, 0x16, 0x8b, 0xcb, 0x04, 0x55, 0x2a, 0x95, 0x3e, 0x49, 0x50, 0x71, 0xca, 0xa5, 0x04, - 0xa5, 0x28, 0xca, 0x32, 0x41, 0xc5, 0x97, 0x88, 0xba, 0x6a, 0x35, 0x50, 0x82, 0x22, 0x85, 0xdc, - 0x32, 0x41, 0x15, 0x48, 0x6e, 0x99, 0xa0, 0x0a, 0x15, 0x69, 0x35, 0x41, 0xc5, 0x6f, 0x84, 0x5e, - 0x41, 0x4d, 0x80, 0xcc, 0x95, 0xd4, 0x04, 0xe9, 0xc5, 0x35, 0xd4, 0xb4, 0xe6, 0x2a, 0xe9, 0xb5, - 0xa4, 0xb4, 0xf6, 0x52, 0xe9, 0x75, 0xa4, 0xb4, 0xe6, 0x7a, 0xe9, 0x77, 0xe9, 0x68, 0x68, 0x00, - 0x87, 0xe5, 0x42, 0x7c, 0x0a, 0x6d, 0xa5, 0xdd, 0x1e, 0xf2, 0x29, 0xf6, 0x72, 0xa8, 0x15, 0xaf, - 0x16, 0xa3, 0x6a, 0x09, 0x46, 0x16, 0xf3, 0x82, 0xb9, 0xf6, 0x4d, 0x57, 0xd0, 0x1a, 0x48, 0x34, - 0x93, 0xbe, 0xc6, 0x8a, 0x08, 0xe6, 0xbb, 0x2f, 0xae, 0x42, 0x31, 0xec, 0x34, 0x2c, 0x7c, 0x11, - 0x53, 0x1b, 0x03, 0xaf, 0x93, 0x71, 0xf1, 0x20, 0xf7, 0xf8, 0x3a, 0x98, 0x24, 0xd2, 0x79, 0xd2, - 0xe1, 0x37, 0x37, 0x41, 0xd6, 0xa5, 0x4b, 0xbc, 0xe0, 0x6b, 0x56, 0x5e, 0xa4, 0x74, 0xc3, 0x09, - 0x52, 0x16, 0xc1, 0x3c, 0x47, 0xa8, 0xc4, 0x36, 0x7e, 0xe1, 0x8b, 0x9f, 0xfe, 0x31, 0xa3, 0x9d, - 0x99, 0xf3, 0xbf, 0xa0, 0xd7, 0xc6, 0x50, 0xd7, 0xe7, 0xb1, 0x51, 0x77, 0x5e, 0x34, 0xa3, 0xd5, - 0xe9, 0xe0, 0xd0, 0xb5, 0x6e, 0xf2, 0x0b, 0x53, 0xcb, 0xf8, 0x59, 0xec, 0x85, 0x5e, 0x1f, 0xbd, - 0x61, 0x6d, 0x3d, 0x46, 0xf0, 0x4d, 0x77, 0x14, 0x25, 0x60, 0x1d, 0x22, 0x46, 0xd8, 0x4b, 0xef, - 0xb0, 0xc3, 0x4e, 0x9f, 0x10, 0x14, 0x98, 0xe9, 0x85, 0xcb, 0x32, 0xa3, 0x38, 0x0e, 0xa6, 0x50, - 0xd3, 0x1c, 0xda, 0xbc, 0xbd, 0x3e, 0x4d, 0x72, 0x19, 0x07, 0xba, 0x98, 0xc6, 0x1c, 0xc0, 0x7c, - 0x9a, 0x86, 0xbf, 0x37, 0x38, 0x49, 0xd7, 0xe9, 0x8b, 0xc1, 0x42, 0x2f, 0xc9, 0x32, 0xf9, 0x79, - 0x48, 0x67, 0x64, 0x95, 0x03, 0x55, 0x2e, 0x09, 0xf2, 0x75, 0xc7, 0xb7, 0x07, 0x53, 0x5c, 0x26, - 0xc3, 0xa5, 0xa8, 0x65, 0x09, 0x86, 0x09, 0x9f, 0x22, 0x73, 0xc9, 0x99, 0x1a, 0x4a, 0x22, 0xa8, - 0xed, 0xbf, 0xd6, 0x8b, 0x52, 0x03, 0x69, 0xc4, 0xc2, 0x8f, 0xeb, 0x80, 0x28, 0x0e, 0x48, 0x09, - 0xec, 0xa0, 0x46, 0x83, 0xa4, 0x29, 0x48, 0x50, 0xc8, 0x78, 0x6a, 0x75, 0x8a, 0x42, 0x92, 0x02, - 0x6e, 0x44, 0x04, 0x7a, 0xcf, 0x17, 0xe8, 0x90, 0x7a, 0x64, 0x81, 0x7e, 0xf2, 0xfb, 0xb7, 0x57, - 0x0c, 0x6a, 0x83, 0x9e, 0x9a, 0xe4, 0xda, 0x00, 0x2f, 0x71, 0x06, 0x16, 0x47, 0x3a, 0x71, 0xa9, - 0xe3, 0xe5, 0x47, 0x09, 0xba, 0xb5, 0xc6, 0xc2, 0xdf, 0x8f, 0x2e, 0xbf, 0x70, 0xeb, 0x54, 0x04, - 0x06, 0x51, 0xa0, 0xd0, 0x78, 0xbe, 0x0e, 0x92, 0x98, 0x78, 0x44, 0x0c, 0x5d, 0x93, 0xdc, 0x3e, - 0xba, 0x08, 0x61, 0x7e, 0xe8, 0x79, 0x0e, 0x85, 0x24, 0xb3, 0x80, 0x35, 0x40, 0x99, 0x73, 0x0f, - 0x06, 0x03, 0xe0, 0x96, 0xe3, 0x77, 0xb6, 0xb2, 0xb5, 0x91, 0xa9, 0xa9, 0x09, 0x11, 0x56, 0x89, - 0x05, 0xa6, 0x01, 0x4d, 0xad, 0x7b, 0x7b, 0x29, 0x0e, 0x2a, 0x0e, 0x26, 0x4c, 0xf1, 0xe6, 0x26, - 0x10, 0x52, 0x5f, 0xeb, 0xba, 0x4c, 0x57, 0x61, 0x76, 0xf5, 0x62, 0xf0, 0xac, 0x7d, 0x48, 0xe8, - 0x9b, 0x8e, 0x8b, 0x4d, 0xa6, 0x92, 0x90, 0x69, 0xda, 0xee, 0x0e, 0x68, 0x18, 0x29, 0xf6, 0x88, - 0xb8, 0x86, 0x19, 0x64, 0x3a, 0xde, 0xb6, 0x08, 0xba, 0x35, 0xf7, 0x85, 0x01, 0xdf, 0x49, 0x7a, - 0xb8, 0xa3, 0x50, 0x52, 0x0d, 0xe8, 0x41, 0x0a, 0xd3, 0xf9, 0x9a, 0x67, 0xeb, 0x60, 0x2f, 0xfc, - 0x56, 0x61, 0x29, 0xb0, 0xd2, 0xfc, 0x9c, 0x51, 0xe9, 0x6a, 0x4c, 0x2f, 0x54, 0x27, 0x1e, 0x27, - 0xcc, 0xc5, 0xd7, 0xb7, 0x81, 0x1d, 0x3b, 0x20, 0x76, 0x8f, 0xec, 0x11, 0x62, 0xe1, 0x2f, 0xa6, - 0x54, 0xd1, 0x25, 0x98, 0x74, 0x79, 0x9e, 0x07, 0x23, 0xfb, 0x85, 0xdc, 0x77, 0x60, 0x88, 0x0b, - 0x65, 0x46, 0xe0, 0xb8, 0x88, 0xea, 0xd4, 0x4b, 0xc3, 0xba, 0xfa, 0xfd, 0x3b, 0x30, 0xc2, 0xc0, - 0x8c, 0x75, 0x86, 0x83, 0xb4, 0xd5, 0x87, 0xae, 0x39, 0x99, 0x6c, 0x35, 0x27, 0x66, 0xb2, 0x62, - 0x45, 0x8c, 0x29, 0x5c, 0xb4, 0x16, 0x5b, 0x56, 0xe6, 0x52, 0x7a, 0xbd, 0x4b, 0x5c, 0xa5, 0x9f, - 0x0c, 0x08, 0xbe, 0x8f, 0xbb, 0x04, 0xd2, 0xd4, 0x49, 0x3f, 0x83, 0xc1, 0x05, 0x38, 0x9b, 0x0d, - 0x88, 0xdb, 0x37, 0xd5, 0x1a, 0x07, 0x25, 0xb8, 0x39, 0x8f, 0x75, 0x8d, 0x24, 0xb0, 0x10, 0x42, - 0x0b, 0x24, 0xf9, 0x45, 0xca, 0x2c, 0x6e, 0x99, 0xc0, 0xa8, 0xd1, 0x3c, 0x06, 0x13, 0x85, 0x4f, - 0x03, 0xf5, 0x42, 0x2b, 0xf4, 0x05, 0x85, 0xa6, 0xe1, 0x98, 0xc0, 0x32, 0x74, 0xb3, 0x07, 0xab, - 0x38, 0xdc, 0x5a, 0x42, 0x35, 0x89, 0x43, 0x0f, 0x0b, 0x79, 0x21, 0xd0, 0x09, 0x09, 0x21, 0x25, - 0xc0, 0xf0, 0x09, 0xca, 0x25, 0x3c, 0x6f, 0xb8, 0x43, 0x19, 0x08, 0x51, 0xd3, 0x1c, 0x42, 0xef, - 0x6a, 0x06, 0x2c, 0xca, 0x29, 0x7b, 0x97, 0x9e, 0x6f, 0x66, 0x90, 0x86, 0x6f, 0x53, 0x0a, 0x2e, - 0xa8, 0xf8, 0xee, 0x77, 0x00, 0xe2, 0x2b, 0xf9, 0x2e, 0x28, 0xf9, 0x1e, 0x13, 0x04, 0xd3, 0x0c, - 0x32, 0x7e, 0xb8, 0x3f, 0x91, 0x16, 0xe8, 0x1c, 0xb6, 0x81, 0x55, 0x3d, 0x12, 0x60, 0xe7, 0x7c, - 0x2d, 0xc8, 0x01, 0xfb, 0xc3, 0x87, 0x96, 0x74, 0x04, 0x2f, 0x39, 0xfb, 0xd3, 0x7f, 0xca, 0xfd, - 0x04, 0xca, 0x5c, 0x94, 0x30, 0xf0, 0xa5, 0x8e, 0xb0, 0x4a, 0xe8, 0x0f, 0x1d, 0x61, 0xd2, 0x27, - 0x3e, 0xe5, 0x15, 0xcf, 0x43, 0x71, 0xb2, 0xdd, 0x00, 0xb3, 0x97, 0x7c, 0xd7, 0x01, 0x4d, 0xa6, - 0xdf, 0x85, 0xc2, 0x4f, 0x7e, 0xce, 0x28, 0x73, 0x73, 0xd3, 0x93, 0x0b, 0xc0, 0x5a, 0xf8, 0x39, - 0xae, 0x2c, 0x5f, 0x50, 0x2c, 0xcd, 0x6c, 0x3d, 0xcc, 0x4b, 0x39, 0xe4, 0x58, 0x2d, 0x64, 0x58, - 0x81, 0xbd, 0xe5, 0x34, 0xa8, 0x34, 0xc2, 0xb0, 0x0e, 0x98, 0x08, 0xe4, 0x57, 0x36, 0x31, 0x3e, - 0x30, 0xa8, 0x16, 0x0c, 0x9d, 0xfa, 0xbe, 0x68, 0x68, 0x5c, 0x12, 0xf4, 0x2b, 0xfc, 0x9f, 0x07, - 0xb3, 0x2a, 0x1c, 0xd6, 0xf1, 0xe9, 0x37, 0x3b, 0x32, 0x4f, 0xcf, 0xfa, 0x25, 0x73, 0x09, 0x46, - 0x0c, 0xae, 0x70, 0x49, 0xf5, 0xf6, 0x3f, 0x1c, 0x36, 0xa3, 0xe1, 0x14, 0xf4, 0xbd, 0x25, 0x6d, - 0xa2, 0xda, 0xd2, 0x18, 0x92, 0x2e, 0x6d, 0x32, 0x62, 0x35, 0xda, 0x0f, 0x8b, 0xb2, 0xed, 0x07, - 0x5a, 0xca, 0x03, 0xc5, 0xe2, 0x2c, 0x58, 0x6e, 0xd4, 0x99, 0x40, 0xff, 0x13, 0xd4, 0x15, 0x92, - 0x72, 0x71, 0xe4, 0xcc, 0x7f, 0xfb, 0xe4, 0x6a, 0x1f, 0x86, 0xf0, 0x25, 0x1b, 0x58, 0x51, 0x0c, - 0xc9, 0xa3, 0x40, 0xe0, 0xfb, 0x52, 0x52, 0xa4, 0x06, 0xb4, 0xbe, 0xca, 0x10, 0x5d, 0xf9, 0x9e, - 0xc8, 0xc5, 0xc4, 0x49, 0x48, 0xfa, 0x3a, 0x2f, 0xad, 0xe8, 0x20, 0x7d, 0x77, 0x03, 0xfa, 0x3a, - 0xf1, 0xcd, 0x95, 0xd4, 0x61, 0xba, 0x4b, 0x77, 0x9e, 0x81, 0x7b, 0xac, 0x2b, 0x4d, 0x67, 0x25, - 0x52, 0x36, 0xe4, 0x4d, 0xe9, 0x9b, 0xe3, 0x1b, 0xdc, 0xe6, 0x41, 0x4f, 0x49, 0x03, 0x06, 0x35, - 0x43, 0x9e, 0xc5, 0x46, 0xe4, 0xed, 0x0b, 0xf1, 0xeb, 0x28, 0xc3, 0x3f, 0xf1, 0x67, 0x83, 0xde, - 0x53, 0x67, 0x4c, 0x86, 0x56, 0x64, 0xdb, 0x46, 0x54, 0xfc, 0xe2, 0x8d, 0x27, 0x87, 0x37, 0x67, - 0xa7, 0x54, 0x0a, 0x2b, 0xbe, 0xcf, 0xa4, 0x01, 0x0c, 0x9a, 0xde, 0xbd, 0x0b, 0x6c, 0x1a, 0x3b, - 0x00, 0x46, 0x2a, 0x6e, 0xe4, 0xf9, 0xaf, 0xa4, 0xf4, 0x1c, 0xaa, 0xc8, 0xb6, 0x59, 0xcb, 0xc1, - 0x0d, 0xbc, 0x0d, 0xcf, 0x90, 0xf6, 0x4a, 0x34, 0xc2, 0xef, 0xb1, 0xc4, 0x59, 0xf6, 0xda, 0xc0, - 0xf1, 0x83, 0xcc, 0x1f, 0x98, 0x23, 0xd0, 0x17, 0x68, 0x03, 0xfc, 0x5c, 0xc8, 0x55, 0x45, 0xa0, - 0x58, 0x18, 0x5d, 0x98, 0x0f, 0xc5, 0x51, 0xb1, 0x8f, 0xbd, 0x62, 0xf8, 0xe0, 0x67, 0x63, 0x67, - 0x73, 0x73, 0xec, 0x84, 0x5e, 0xc6, 0x09, 0xdc, 0xf5, 0x9e, 0xc8, 0x1d, 0xb0, 0xc3, 0x89, 0x9b, - 0xbe, 0xb8, 0xdc, 0x3f, 0x07, 0x54, 0x41, 0x01, 0x05, 0x1d, 0xd5, 0x40, 0x07, 0x63, 0x87, 0x2a, - 0x3b, 0x81, 0x17, 0x33, 0x3d, 0x76, 0xb6, 0xb7, 0xb2, 0x9b, 0x9b, 0xa1, 0x5e, 0x32, 0x56, 0x2f, - 0x14, 0xa1, 0x2b, 0x40, 0x3e, 0x01, 0xee, 0xb9, 0x16, 0xe0, 0x9a, 0x78, 0xe6, 0xaf, 0x99, 0xa0, - 0xc6, 0x71, 0xa2, 0x2b, 0x81, 0x74, 0x56, 0xbf, 0x70, 0x02, 0x0a, 0x9d, 0x85, 0x71, 0x8b, 0x98, - 0x8a, 0x74, 0x33, 0x8c, 0xf3, 0x10, 0x8e, 0x57, 0x27, 0xc3, 0x68, 0xe8, 0x9e, 0x6c, 0xd2, 0x9b, - 0x00, 0x10, 0x34, 0x7c, 0x44, 0x81, 0xb9, 0x1e, 0x1a, 0x88, 0xdd, 0x8e, 0x6b, 0xa3, 0x1e, 0xc3, - 0x64, 0x1d, 0x95, 0x55, 0x47, 0xa0, 0x58, 0x11, 0x54, 0x43, 0xcf, 0x40, 0xbe, 0xa7, 0xbb, 0xba, - 0x09, 0xb4, 0xea, 0x66, 0x2a, 0xa5, 0x02, 0xa2, 0xd5, 0x09, 0xa7, 0x26, 0xdd, 0x2d, 0x9a, 0xfc, - 0x2f, 0x93, 0xcf, 0xe4, 0x4b, 0x98, 0x6d, 0xac, 0xce, 0xde, 0xc2, 0xdc, 0x7f, 0x39, 0x7c, 0xa6, - 0x24, 0x22, 0x17, 0x35, 0x77, 0x40, 0x49, 0x4a, 0x70, 0xa9, 0x64, 0xb6, 0x81, 0xbe, 0x13, 0x60, - 0xfb, 0x1c, 0x3a, 0x7d, 0xa7, 0xc0, 0xd2, 0x52, 0x9c, 0x90, 0xe0, 0xf0, 0xee, 0x0a, 0xcf, 0x47, - 0xa6, 0xa7, 0x1a, 0xce, 0xef, 0xdf, 0xe6, 0x8e, 0x13, 0x54, 0x70, 0x76, 0x40, 0xa6, 0x0c, 0x91, - 0xa2, 0xf0, 0x0b, 0xaa, 0x40, 0x69, 0xe1, 0x0b, 0x70, 0x53, 0x07, 0x45, 0x37, 0x48, 0x77, 0x00, - 0x00, 0xd3, 0xbf, 0x5d, 0xac, 0x6e, 0x6e, 0x7e, 0x31, 0x59, 0x9a, 0x91, 0xa2, 0x81, 0x21, 0x98, - 0xfe, 0x1d, 0xbb, 0xb2, 0xb9, 0xc9, 0xf2, 0x43, 0xe5, 0xbd, 0x74, 0x4c, 0x71, 0xb7, 0x4a, 0xe2, - 0xbf, 0xb0, 0x8a, 0x43, 0xd0, 0x6a, 0xd2, 0x43, 0x1e, 0x3c, 0x98, 0x6c, 0xdb, 0x1c, 0xe3, 0x12, - 0x02, 0xfc, 0x00, 0x46, 0x3d, 0xfd, 0xef, 0xd7, 0x77, 0xd7, 0xde, 0xfe, 0xee, 0xaa, 0xfe, 0xae, - 0x04, 0x7d, 0xef, 0x00, 0xb7, 0xfd, 0x8f, 0x19, 0x99, 0x7f, 0xcf, 0xb8, 0x6a, 0x38, 0x8b, 0xbe, - 0x3d, 0x00, 0xb3, 0xdc, 0x39, 0x68, 0xcf, 0x5e, 0x76, 0x06, 0xaa, 0xff, 0x5a, 0x34, 0x63, 0x79, - 0xfe, 0x46, 0x6f, 0x56, 0xbc, 0xa8, 0x33, 0x18, 0x3f, 0xf1, 0xd1, 0x42, 0x9d, 0xf0, 0x9b, 0x9b, - 0xf4, 0xeb, 0x07, 0xf9, 0xb9, 0x78, 0x4a, 0x43, 0x6a, 0x12, 0x26, 0x32, 0xf8, 0x09, 0x43, 0x0b, - 0x7b, 0x20, 0x2f, 0x75, 0x69, 0x8a, 0x3b, 0x2d, 0x21, 0x37, 0x64, 0x50, 0xd6, 0xf2, 0xf2, 0x42, - 0xd0, 0xfc, 0xa4, 0xb4, 0xe5, 0x84, 0xba, 0x27, 0x59, 0xda, 0x9d, 0xa4, 0xfb, 0x4a, 0x3d, 0x2d, - 0xfc, 0xfb, 0xf7, 0x17, 0xbf, 0x12, 0xcf, 0xe0, 0xc2, 0x1c, 0xb2, 0xee, 0x7b, 0x5e, 0x51, 0x18, - 0xbd, 0xd6, 0x33, 0x92, 0xb8, 0x4d, 0xe0, 0x17, 0xf4, 0x47, 0xe3, 0xa6, 0x41, 0x07, 0xde, 0xa1, - 0x9f, 0xb5, 0xa4, 0x4a, 0xf0, 0x2d, 0xb9, 0x90, 0x66, 0x08, 0xc1, 0xa3, 0xb5, 0x78, 0x7c, 0xd5, - 0xe3, 0xbe, 0x2a, 0x37, 0xec, 0xa9, 0x7a, 0xd5, 0x7d, 0xdc, 0x7d, 0x88, 0xa9, 0x57, 0x7d, 0x27, - 0xf4, 0x8c, 0x7b, 0x08, 0x8b, 0xb5, 0x67, 0xed, 0xd2, 0x57, 0x41, 0x33, 0x25, 0x83, 0x2e, 0x30, - 0x59, 0x41, 0x43, 0x83, 0x78, 0xb7, 0x48, 0x00, 0x13, 0xa0, 0x4a, 0x72, 0xc7, 0xbf, 0x6b, 0x8a, - 0xbe, 0x20, 0x18, 0xc4, 0x67, 0x95, 0xfe, 0x43, 0x91, 0x43, 0x26, 0x44, 0x69, 0x99, 0x83, 0x01, - 0x48, 0x15, 0x64, 0xb1, 0xd6, 0x94, 0x8b, 0x31, 0x02, 0x4b, 0x23, 0x2a, 0x32, 0x01, 0xbc, 0x34, - 0x4e, 0x36, 0x25, 0x1b, 0x38, 0x40, 0xcc, 0x7a, 0xf2, 0x05, 0x1b, 0xa1, 0xec, 0x86, 0x62, 0x9b, - 0xc0, 0x00, 0x06, 0x6e, 0xa3, 0x41, 0x05, 0x2d, 0x7d, 0xde, 0x16, 0xf9, 0xf0, 0x50, 0x1b, 0x21, - 0xa5, 0xf3, 0x1d, 0x39, 0x0c, 0x46, 0x82, 0x60, 0x99, 0xf4, 0xad, 0x45, 0xc4, 0x6f, 0x86, 0x0f, - 0x36, 0x68, 0xe0, 0x5b, 0xa0, 0x5a, 0x3b, 0x70, 0xbb, 0x7a, 0x92, 0xfc, 0xfe, 0x0d, 0x09, 0x5f, - 0x1a, 0x5e, 0x2e, 0x6a, 0x7d, 0xe1, 0x82, 0x31, 0xf5, 0xd2, 0x62, 0xd0, 0x3e, 0xd2, 0x2e, 0x41, - 0x81, 0x37, 0x5f, 0x7e, 0xff, 0x8e, 0xf3, 0x62, 0x21, 0xd0, 0x3a, 0x43, 0x6a, 0xe7, 0x12, 0x2b, - 0xf4, 0x36, 0xa1, 0xc8, 0xf2, 0x10, 0x02, 0x45, 0x74, 0xf1, 0xba, 0x63, 0xa0, 0x85, 0xb0, 0xf0, - 0xfb, 0x82, 0xea, 0x4c, 0x54, 0x32, 0xf0, 0x31, 0xfd, 0x92, 0x44, 0x58, 0x39, 0x81, 0x49, 0xc5, - 0x32, 0xb1, 0xb9, 0xf1, 0xf5, 0x17, 0x7f, 0x72, 0x62, 0x68, 0xc0, 0x51, 0x64, 0xfc, 0xed, 0xc4, - 0xff, 0x18, 0x1e, 0xd8, 0xd6, 0x9b, 0xb7, 0xc2, 0x40, 0x21, 0xb0, 0x35, 0xec, 0x51, 0x68, 0x6a, - 0xfd, 0x5e, 0x7e, 0x0e, 0x31, 0xab, 0x30, 0x41, 0xa8, 0x1a, 0x15, 0x19, 0x3b, 0x68, 0x62, 0xef, - 0x8d, 0x9a, 0x78, 0x61, 0x9c, 0xff, 0xa9, 0x41, 0x93, 0x0f, 0x06, 0xed, 0x85, 0x91, 0xfe, 0xbf, - 0x1e, 0x33, 0xd5, 0x38, 0xdf, 0x1b, 0x37, 0xdb, 0x23, 0xfd, 0x8f, 0x0d, 0x3b, 0xe9, 0xed, 0xc1, - 0xc2, 0x72, 0xfc, 0xf1, 0x93, 0x0f, 0xcc, 0x65, 0x96, 0x9a, 0x1e, 0x1a, 0x2c, 0x81, 0xfb, 0x77, - 0xfd, 0x4b, 0x9d, 0x5b, 0x33, 0xf4, 0xc5, 0x2e, 0xee, 0xe7, 0x90, 0x20, 0xb0, 0x58, 0xcb, 0xdb, - 0x23, 0x8a, 0x0f, 0xe4, 0x86, 0xd8, 0x51, 0x6f, 0x61, 0x08, 0xd6, 0xd5, 0x29, 0x80, 0x5a, 0x6c, - 0x02, 0xfa, 0xf8, 0xbf, 0x3a, 0x0d, 0x58, 0x27, 0x08, 0x01, 0x60, 0x5a, 0x50, 0x30, 0xb0, 0xcb, - 0x79, 0x5f, 0xf5, 0x75, 0x41, 0xf5, 0xa5, 0x39, 0x0e, 0x18, 0xef, 0x49, 0xba, 0x7f, 0x07, 0x36, - 0x27, 0x18, 0x62, 0xdb, 0x2e, 0xda, 0xe6, 0x08, 0x9d, 0x0e, 0x94, 0x27, 0xa9, 0xc6, 0xaf, 0xe5, - 0x70, 0x82, 0x04, 0xbb, 0x01, 0x33, 0x81, 0x17, 0xb1, 0x79, 0x61, 0x8c, 0x20, 0x53, 0xa1, 0xe6, - 0xfc, 0x55, 0x97, 0x39, 0x3f, 0xb6, 0x15, 0x93, 0x72, 0x3f, 0x77, 0xf0, 0x03, 0x19, 0x7c, 0x2c, - 0x50, 0x8b, 0x32, 0x8d, 0xa4, 0x57, 0x8d, 0xaf, 0x53, 0xa9, 0x0c, 0x26, 0xdf, 0x3c, 0x08, 0x43, - 0xf8, 0xc5, 0xf6, 0xc0, 0xf0, 0xe8, 0x2c, 0x1f, 0xd6, 0x71, 0xe7, 0x4b, 0x63, 0x0e, 0x18, 0x10, - 0x32, 0x69, 0xca, 0x9d, 0xf8, 0x99, 0x27, 0xb3, 0x98, 0x90, 0x11, 0x7f, 0xd6, 0x7d, 0x94, 0x08, - 0x6e, 0x9c, 0x78, 0x59, 0x85, 0xba, 0xcb, 0x70, 0xa1, 0x0c, 0xac, 0x4b, 0xde, 0xc7, 0x2e, 0x53, - 0xb7, 0x11, 0xcd, 0xbe, 0xad, 0x47, 0xf1, 0xc6, 0xb6, 0xd7, 0x5d, 0x86, 0x21, 0x2a, 0x86, 0xd9, - 0xee, 0xa2, 0x03, 0xfd, 0xe7, 0x79, 0xb4, 0xae, 0x35, 0x63, 0x48, 0xbc, 0x97, 0xd1, 0x07, 0x6a, - 0x9d, 0x83, 0x98, 0xa5, 0x20, 0x8d, 0x06, 0x96, 0x04, 0xb9, 0x57, 0x47, 0xe1, 0x08, 0xb3, 0x60, - 0x0d, 0x9d, 0x7e, 0xf2, 0x87, 0x2b, 0x18, 0x02, 0xd3, 0x3e, 0x5c, 0xfe, 0x27, 0xea, 0xe5, 0x34, - 0x19, 0x34, 0x74, 0x3a, 0x09, 0xb1, 0xd8, 0xb4, 0x84, 0x92, 0x40, 0x66, 0xbf, 0xc0, 0xfe, 0xdc, - 0x5c, 0x87, 0xe0, 0x39, 0xcf, 0x6d, 0xff, 0xa2, 0x40, 0xfe, 0x31, 0x0b, 0x29, 0x21, 0x2e, 0xbf, - 0xc3, 0x05, 0x51, 0xa7, 0xdf, 0x58, 0x2c, 0x87, 0x7f, 0x17, 0xe8, 0x37, 0x1a, 0xbb, 0x91, 0xcd, - 0xb3, 0x88, 0x62, 0xd4, 0x09, 0xe7, 0x91, 0x88, 0x1d, 0xff, 0xe6, 0x24, 0x9c, 0x35, 0xbf, 0xcb, - 0x73, 0x2f, 0x5c, 0x86, 0x45, 0x8d, 0xfc, 0xa2, 0x51, 0x08, 0xa9, 0xd4, 0x9c, 0x4d, 0x22, 0x0b, - 0x92, 0x8f, 0x98, 0x2a, 0x8c, 0xbc, 0x2f, 0x9b, 0xc9, 0x05, 0xf3, 0x40, 0xe2, 0x65, 0xc6, 0xb8, - 0x1f, 0xe8, 0x10, 0x56, 0x7c, 0x28, 0x1e, 0x31, 0xd4, 0xc9, 0xa3, 0x6f, 0xdf, 0x02, 0x10, 0xd0, - 0x1f, 0x86, 0xbd, 0x61, 0x04, 0xb3, 0x08, 0x9c, 0x0b, 0xb7, 0xe7, 0xc2, 0x42, 0xd7, 0xb5, 0x11, - 0xa1, 0x1a, 0x1a, 0x97, 0x3c, 0x85, 0x47, 0x1e, 0x94, 0x3a, 0x97, 0xba, 0xbc, 0xfc, 0x44, 0x2f, - 0x45, 0x4d, 0x33, 0x0a, 0x76, 0xfd, 0x58, 0x11, 0xa8, 0x4a, 0x54, 0x27, 0x3d, 0x1e, 0x2d, 0x82, - 0x38, 0xbc, 0x24, 0x05, 0x7f, 0x08, 0xe8, 0x62, 0xbc, 0xe9, 0xe9, 0xd7, 0x44, 0x19, 0x41, 0x06, - 0x68, 0x47, 0x7e, 0x48, 0x87, 0x57, 0x0a, 0x7e, 0x39, 0xa4, 0x47, 0x03, 0x32, 0x48, 0xba, 0xeb, - 0xa4, 0x51, 0x72, 0x63, 0xf0, 0x89, 0x0f, 0x44, 0x71, 0x97, 0x89, 0x9a, 0x0e, 0x75, 0xa1, 0x86, - 0x72, 0x02, 0xfa, 0xe4, 0xba, 0x36, 0x21, 0x7d, 0x22, 0x59, 0x99, 0x2c, 0xc9, 0xd7, 0xcd, 0x86, - 0x99, 0x76, 0xcd, 0x36, 0xbe, 0xe7, 0x22, 0x99, 0x65, 0x94, 0xe5, 0xf8, 0x20, 0xad, 0xb1, 0x0d, - 0xf6, 0x00, 0x77, 0x8e, 0xde, 0x1e, 0x49, 0x57, 0x28, 0x44, 0x95, 0xab, 0x3b, 0xdb, 0x50, 0x71, - 0xc7, 0x68, 0x24, 0x1d, 0xf8, 0x3f, 0xd3, 0x80, 0x1f, 0x7c, 0x00, 0x02, 0xf2, 0xc4, 0x1d, 0xb1, - 0x96, 0xe5, 0xc1, 0x0e, 0x48, 0x34, 0xb9, 0x9a, 0x83, 0x7e, 0xbc, 0x24, 0x2d, 0x5b, 0x14, 0xff, - 0x45, 0x4d, 0x0b, 0x6a, 0x97, 0x42, 0xc5, 0xa2, 0x48, 0x0b, 0x0d, 0x9a, 0x9e, 0x49, 0xaa, 0x7b, - 0xbc, 0x86, 0xa4, 0x87, 0x94, 0xc5, 0x20, 0x2d, 0x81, 0xdd, 0x2d, 0x98, 0x3f, 0xc1, 0xc2, 0x8e, - 0xcb, 0x0a, 0x28, 0xc3, 0x9b, 0x40, 0xff, 0x3b, 0xa0, 0xed, 0xfb, 0x3a, 0x3d, 0x14, 0xa5, 0xbe, - 0x66, 0x5c, 0x40, 0xb5, 0x68, 0x3a, 0x6b, 0x41, 0x6a, 0x70, 0x27, 0xc3, 0x61, 0x5f, 0x7a, 0x19, - 0x72, 0xa0, 0x07, 0x8e, 0x88, 0x9d, 0xa6, 0xd6, 0xb9, 0xe7, 0xeb, 0x14, 0xd3, 0xd9, 0x42, 0x9a, - 0x43, 0xdd, 0x08, 0xca, 0x1d, 0x9a, 0xc0, 0x8c, 0x39, 0x64, 0xec, 0x58, 0x4c, 0x83, 0x25, 0x31, - 0xc4, 0x58, 0x27, 0x6e, 0x4b, 0xd6, 0xfd, 0x22, 0x9d, 0xa1, 0xf5, 0x7f, 0xfe, 0x37, 0x80, 0xc2, - 0x42, 0x8a, 0x41, 0xd3, 0xf0, 0x01, 0xd4, 0x75, 0x58, 0x24, 0x23, 0xb0, 0x1c, 0xb0, 0xea, 0x3c, - 0x01, 0x1c, 0x4c, 0x9a, 0x73, 0x18, 0xb8, 0x44, 0xff, 0xe8, 0xcb, 0x3e, 0xb6, 0xff, 0x97, 0xf1, - 0x8f, 0x99, 0x3e, 0xc7, 0x4f, 0xbf, 0x93, 0xdc, 0xee, 0x50, 0xd3, 0xd1, 0xf3, 0x9f, 0x1e, 0x69, - 0x2a, 0x1f, 0xcd, 0xea, 0x80, 0xda, 0x2d, 0xe9, 0x09, 0x20, 0x09, 0xca, 0x82, 0xb1, 0xd0, 0x58, - 0xeb, 0x6a, 0x69, 0x87, 0xa6, 0xa7, 0xb8, 0x7f, 0x26, 0x92, 0xe8, 0x43, 0xa5, 0x69, 0x36, 0x28, - 0xe9, 0x02, 0x97, 0x50, 0x77, 0x07, 0x60, 0xea, 0x47, 0xc1, 0xdc, 0x5a, 0x68, 0x2e, 0x72, 0x42, - 0xcc, 0x74, 0x4c, 0x0f, 0x69, 0x3a, 0x1f, 0x2b, 0xdd, 0x06, 0x2a, 0x49, 0x20, 0x99, 0x00, 0xd1, - 0x00, 0xc0, 0x97, 0x5d, 0x0f, 0x1c, 0x01, 0x4b, 0xc2, 0x96, 0x06, 0x3b, 0xd1, 0x82, 0x97, 0x9d, - 0xeb, 0xe6, 0x19, 0x27, 0x24, 0xbd, 0xdc, 0x4c, 0x56, 0xcc, 0x15, 0xf8, 0x10, 0x61, 0x79, 0x10, - 0x90, 0x07, 0x44, 0x5a, 0xd9, 0x87, 0xd5, 0x37, 0x40, 0xb2, 0x4a, 0x78, 0x21, 0x50, 0x9c, 0x60, - 0xc4, 0x3a, 0xd2, 0x04, 0x34, 0x82, 0xfa, 0x9b, 0x68, 0x5f, 0x76, 0x70, 0xe4, 0x94, 0x32, 0xbb, - 0x96, 0x13, 0x2b, 0x75, 0xd6, 0x6c, 0x25, 0x24, 0x55, 0x05, 0x7e, 0xe5, 0x60, 0xa9, 0x81, 0xa4, - 0xc4, 0xc7, 0x03, 0x26, 0xba, 0x33, 0x75, 0x40, 0x81, 0xc6, 0x7c, 0x58, 0x3f, 0xc3, 0x14, 0xba, - 0x91, 0xe9, 0xa3, 0x9b, 0xc2, 0xee, 0x21, 0x16, 0x43, 0x14, 0x9a, 0x05, 0x83, 0x97, 0x15, 0xcc, - 0xb0, 0x42, 0x40, 0xad, 0xff, 0x5c, 0x42, 0xea, 0xbe, 0x31, 0xd2, 0x6c, 0xd3, 0x18, 0xd0, 0xae, - 0x93, 0x34, 0x06, 0x29, 0x53, 0x43, 0x17, 0xc3, 0x35, 0x6c, 0x02, 0x8f, 0x74, 0x6a, 0xf4, 0xb1, - 0x66, 0xa5, 0x38, 0x56, 0x19, 0x6c, 0x45, 0x4a, 0x03, 0xbf, 0x98, 0x37, 0xea, 0x65, 0x14, 0x65, - 0x31, 0xcb, 0x8b, 0xd8, 0x3f, 0xf6, 0x14, 0x5e, 0xc8, 0xb8, 0x50, 0x82, 0xb0, 0xb0, 0x24, 0x5a, - 0x32, 0x3d, 0xa6, 0x54, 0x30, 0x29, 0x1d, 0x0f, 0x0e, 0xf3, 0x62, 0xc2, 0xfc, 0x1a, 0xdb, 0x59, - 0x7e, 0x11, 0xe8, 0x21, 0xd6, 0xcd, 0xef, 0x7e, 0xc6, 0xe6, 0xa6, 0xf9, 0xbd, 0x50, 0x37, 0x17, - 0x9e, 0x57, 0x0a, 0xf9, 0x87, 0xf9, 0x93, 0xca, 0x21, 0x23, 0x24, 0x87, 0xd2, 0x40, 0xa5, 0x75, - 0x2f, 0xca, 0xed, 0x87, 0xf1, 0xb3, 0xe1, 0xa4, 0x4d, 0xf4, 0x57, 0x36, 0xc2, 0x0d, 0x53, 0x4f, - 0x7c, 0xa8, 0x1f, 0x46, 0x0a, 0x08, 0xc1, 0xd8, 0xc6, 0xce, 0x60, 0x16, 0xf6, 0xc9, 0x5b, 0x2e, - 0x11, 0xc1, 0xe4, 0x1f, 0x10, 0xfa, 0xc7, 0xcc, 0x41, 0x63, 0x98, 0xfa, 0x5a, 0xe1, 0x69, 0x07, - 0xfe, 0x6a, 0xfe, 0x19, 0x30, 0xc0, 0x30, 0x9a, 0xde, 0x28, 0x24, 0x00, 0xa3, 0xec, 0x2b, 0xf1, - 0x9d, 0x55, 0xf5, 0xcf, 0x47, 0xd0, 0x1b, 0x2c, 0xe9, 0x9d, 0xa9, 0x1c, 0xe6, 0x26, 0x36, 0x0d, - 0xd9, 0xb1, 0xea, 0xf8, 0x14, 0x89, 0x85, 0xa7, 0xe5, 0x64, 0x73, 0xc2, 0xf9, 0xe7, 0xc7, 0xfe, - 0x31, 0x33, 0xe6, 0x8e, 0x17, 0x32, 0x1d, 0x1c, 0x65, 0xc1, 0xde, 0x26, 0x31, 0x87, 0xe7, 0x12, - 0xd8, 0x31, 0x48, 0xd9, 0xe1, 0xbc, 0xcb, 0x34, 0xa9, 0x68, 0xa3, 0x4d, 0x44, 0xe4, 0x5b, 0x70, - 0x77, 0x26, 0xed, 0x04, 0xe7, 0x47, 0x82, 0x62, 0x47, 0x33, 0xb4, 0xa7, 0xf4, 0x31, 0x76, 0x3b, - 0x0b, 0xeb, 0xde, 0xda, 0xc3, 0x3b, 0x09, 0xe0, 0xc9, 0xd0, 0xfe, 0x02, 0xf1, 0x3b, 0x9c, 0xa4, - 0xb8, 0x1c, 0x53, 0x8d, 0x42, 0xfd, 0x87, 0x62, 0x51, 0x49, 0x0e, 0xdd, 0xbf, 0x1c, 0xdb, 0xfe, - 0x08, 0x02, 0xe5, 0x0a, 0x70, 0x3a, 0x8f, 0xde, 0x3a, 0x44, 0x3b, 0x10, 0x9c, 0xa6, 0x63, 0x47, - 0xa5, 0x18, 0x4c, 0x7a, 0x93, 0xcb, 0xea, 0x23, 0x41, 0x58, 0x29, 0x72, 0xc4, 0x8a, 0xd5, 0x90, - 0x97, 0xee, 0x7e, 0x01, 0x50, 0x78, 0xfd, 0x8b, 0xd7, 0x8d, 0xbf, 0x7f, 0x03, 0x0c, 0x8e, 0x00, - 0x5a, 0x81, 0xc1, 0x67, 0xbc, 0x4e, 0x7c, 0x74, 0x36, 0x88, 0x8e, 0x6f, 0xf1, 0xf4, 0xa9, 0x03, - 0x42, 0x74, 0xca, 0x3c, 0x5a, 0x63, 0x8a, 0x09, 0xd3, 0x48, 0xfc, 0xc3, 0x86, 0x91, 0x05, 0x1c, - 0xe8, 0x79, 0x9e, 0xf7, 0x3e, 0x58, 0x5a, 0x06, 0x2c, 0x2d, 0x74, 0xe1, 0x87, 0x07, 0x8b, 0x60, - 0x7e, 0x2d, 0xb0, 0xf5, 0x2b, 0x6c, 0xa4, 0xca, 0x38, 0x60, 0x6a, 0xef, 0x8c, 0x35, 0xba, 0x33, - 0xc3, 0xcf, 0x14, 0xdc, 0xf8, 0xcb, 0xd5, 0xe8, 0x57, 0x3e, 0x57, 0xf3, 0xfc, 0x34, 0xfb, 0x9d, - 0xcb, 0x7c, 0x8e, 0xab, 0xd3, 0xd4, 0x2c, 0xcb, 0xac, 0x84, 0x33, 0x2b, 0xb9, 0x52, 0x89, 0x9b, - 0x7b, 0xbf, 0x77, 0x42, 0x5e, 0x12, 0xd9, 0x88, 0xb8, 0x5a, 0x38, 0xdc, 0x4c, 0xa4, 0x7b, 0x96, - 0x98, 0xbe, 0x43, 0xd2, 0x9a, 0x55, 0x63, 0xcf, 0xcb, 0x4c, 0x89, 0xc5, 0xfe, 0xd2, 0xe0, 0x3e, - 0xc6, 0x46, 0x40, 0xb9, 0x70, 0xf0, 0x03, 0x47, 0x8d, 0xfb, 0x69, 0x69, 0x1a, 0xdf, 0xcc, 0xcf, - 0xbc, 0x87, 0xa8, 0x91, 0x40, 0x81, 0xd2, 0x0d, 0x53, 0x9d, 0xb4, 0xcc, 0x01, 0xbe, 0x03, 0x05, - 0x6b, 0x48, 0x28, 0x86, 0x02, 0xfc, 0xe9, 0x00, 0x49, 0xff, 0xee, 0xd7, 0xf7, 0xf6, 0x40, 0x74, - 0x9f, 0x37, 0x49, 0x0d, 0x2f, 0xe7, 0x87, 0xfe, 0x13, 0x1b, 0x94, 0x58, 0x75, 0x67, 0x21, 0xf7, - 0x57, 0xd9, 0x1c, 0xc0, 0x7a, 0x43, 0xd4, 0x2f, 0xc1, 0x08, 0xe7, 0x91, 0x90, 0x68, 0xef, 0x02, - 0x29, 0xcf, 0xd5, 0xf5, 0x8d, 0xc6, 0x05, 0x67, 0x32, 0x5e, 0xc9, 0x6f, 0xcc, 0xc2, 0x60, 0x58, - 0x93, 0xf8, 0x90, 0x95, 0x21, 0x80, 0x56, 0xcc, 0xa6, 0x4b, 0xa2, 0xdb, 0xd5, 0x90, 0x87, 0xc2, - 0x5e, 0x83, 0xd2, 0x62, 0xa3, 0x21, 0xa1, 0x4c, 0xdf, 0xe1, 0xce, 0x33, 0xa0, 0x10, 0xd1, 0xe7, - 0x39, 0x2e, 0xb4, 0x5f, 0xc0, 0x0b, 0x41, 0xb5, 0x9d, 0x03, 0x32, 0x54, 0xe5, 0xbb, 0xb8, 0x63, - 0xa6, 0x1a, 0x5c, 0x24, 0x78, 0x3e, 0xa1, 0xe1, 0x8d, 0x74, 0x0e, 0x0a, 0x0b, 0x35, 0xcd, 0xd5, - 0x00, 0x10, 0x6a, 0x19, 0x58, 0xec, 0xdc, 0x4c, 0x98, 0x60, 0x67, 0xda, 0x8b, 0xc8, 0xf0, 0x44, - 0x17, 0x65, 0x56, 0x1a, 0x37, 0x50, 0x91, 0x9d, 0xb2, 0x57, 0x8a, 0xf9, 0x4c, 0x04, 0x5f, 0xb4, - 0x4a, 0xd7, 0x28, 0xac, 0x96, 0x39, 0xfd, 0x0a, 0xc4, 0x57, 0x8b, 0x49, 0xdd, 0x00, 0x50, 0x0d, - 0x85, 0x18, 0x45, 0xe4, 0x9c, 0x12, 0x7d, 0x54, 0x54, 0x19, 0x11, 0x4a, 0x37, 0xa3, 0xf6, 0xb5, - 0x17, 0x0d, 0xbe, 0xd2, 0xb0, 0x66, 0xb1, 0xee, 0x9f, 0xb2, 0xab, 0x03, 0xef, 0xda, 0x50, 0x57, - 0xe9, 0x46, 0x23, 0xc2, 0x4e, 0x20, 0x70, 0x1a, 0x60, 0xce, 0x9c, 0xec, 0x9f, 0x75, 0x32, 0x45, - 0x88, 0x35, 0x50, 0xf5, 0xc9, 0x5f, 0x75, 0x32, 0x2d, 0x2f, 0x83, 0xc0, 0x53, 0xe1, 0x99, 0x13, - 0xd4, 0xb3, 0x21, 0x50, 0x09, 0x4d, 0x7c, 0x03, 0x9f, 0x12, 0x34, 0xb3, 0xe3, 0x70, 0x8b, 0x93, - 0x84, 0x37, 0x38, 0xc9, 0x0f, 0xf7, 0x67, 0x63, 0xa6, 0xa9, 0x35, 0xe2, 0xef, 0x61, 0x02, 0xee, - 0xd9, 0x0f, 0x30, 0x63, 0x11, 0xc6, 0x67, 0x97, 0x0d, 0xa0, 0xc4, 0xf7, 0x20, 0x20, 0x3c, 0x91, - 0x41, 0xe2, 0xe8, 0x89, 0x32, 0xf4, 0x28, 0x88, 0x80, 0xef, 0xa0, 0x27, 0x8c, 0x35, 0x91, 0xf0, - 0xc6, 0x22, 0x6a, 0xde, 0xb8, 0xb7, 0x48, 0x9b, 0xa0, 0xf7, 0x8c, 0x5e, 0x74, 0x93, 0xdc, 0x75, - 0xe7, 0x6e, 0x8f, 0xe3, 0xbf, 0x8b, 0xfe, 0x2a, 0x5f, 0x51, 0xe4, 0xdf, 0xe8, 0x16, 0xc5, 0x01, - 0x9b, 0xdb, 0xe2, 0x8e, 0x13, 0x2a, 0xe1, 0x0c, 0x65, 0x50, 0x59, 0x93, 0x26, 0x5f, 0x33, 0x1b, - 0xd5, 0x6a, 0x15, 0x05, 0x7d, 0x0f, 0xf7, 0xba, 0x00, 0x6d, 0x48, 0xde, 0xe8, 0xcb, 0x3c, 0x74, - 0x07, 0x7a, 0x92, 0xeb, 0x4e, 0x80, 0xea, 0xb0, 0x9a, 0xa6, 0x0a, 0x4b, 0xd5, 0x45, 0xd0, 0xde, - 0x85, 0xc5, 0x31, 0x39, 0xdc, 0x06, 0xc1, 0xff, 0x41, 0xff, 0xa3, 0x34, 0xe9, 0x9f, 0x1f, 0x7c, - 0x5f, 0x85, 0x5a, 0x78, 0xd1, 0x7c, 0xb3, 0x0f, 0xe7, 0xe9, 0xff, 0x93, 0x29, 0xf2, 0xb6, 0xcb, - 0x71, 0x7e, 0x02, 0xf5, 0xce, 0xef, 0x0f, 0x53, 0xcf, 0x82, 0xfe, 0xa0, 0x66, 0xb6, 0x16, 0x8d, - 0x9e, 0xaf, 0x12, 0x71, 0x69, 0x7a, 0xb8, 0x34, 0x19, 0x2e, 0x85, 0xd0, 0x79, 0x35, 0x4e, 0xf8, - 0xf6, 0xde, 0x11, 0x35, 0xe0, 0x71, 0xcc, 0xd8, 0xf6, 0xcf, 0xf8, 0xad, 0x46, 0x6c, 0x64, 0x77, - 0x37, 0x08, 0x84, 0x59, 0x15, 0xc7, 0xfb, 0xd5, 0x83, 0x94, 0xa0, 0xb7, 0x1f, 0x73, 0xef, 0xa2, - 0x7a, 0xc6, 0x86, 0x8c, 0xb8, 0x4d, 0xa3, 0x9f, 0x0b, 0x7a, 0x8d, 0xe3, 0x70, 0x58, 0x4a, 0x3c, - 0x90, 0x37, 0xe8, 0x3a, 0x5f, 0xc7, 0x9d, 0x23, 0x87, 0x6d, 0x41, 0x22, 0x72, 0xbc, 0x7e, 0xb5, - 0x1c, 0x07, 0xa8, 0x2f, 0x1a, 0xf6, 0x13, 0xce, 0x63, 0xdb, 0x1f, 0xe1, 0x13, 0x23, 0x8b, 0x6d, - 0xb4, 0x45, 0xda, 0x0f, 0x42, 0xe5, 0xcb, 0x17, 0xd7, 0xdf, 0x16, 0xf1, 0x2f, 0x58, 0x48, 0xb0, - 0x20, 0xe3, 0x6c, 0x03, 0x24, 0x11, 0x1b, 0x04, 0xba, 0x00, 0x80, 0x28, 0x1a, 0xe8, 0x8e, 0x12, - 0xa2, 0xa1, 0x16, 0x98, 0xce, 0x7b, 0xf9, 0x90, 0xdb, 0x00, 0xcd, 0x86, 0xe7, 0xa3, 0xbe, 0x21, - 0x86, 0x43, 0xb1, 0x4e, 0xbe, 0xfb, 0xf0, 0xea, 0x04, 0x91, 0x42, 0x0d, 0x61, 0xd0, 0xc5, 0x5d, - 0xec, 0x09, 0x5d, 0xbd, 0x82, 0x2e, 0x48, 0x82, 0xdd, 0xf8, 0x92, 0xc5, 0x8e, 0x45, 0xdb, 0x71, - 0x78, 0xde, 0x6e, 0xa0, 0x97, 0x28, 0x03, 0x2d, 0xfc, 0x0b, 0x6c, 0x18, 0x81, 0x39, 0x8a, 0x04, - 0x1d, 0xbe, 0x72, 0x3f, 0x05, 0x09, 0xbe, 0xf2, 0x3f, 0x69, 0x18, 0x50, 0x02, 0xe3, 0x94, 0x6c, - 0x90, 0xf7, 0x0e, 0x6f, 0x60, 0x7f, 0x3c, 0xf3, 0x9c, 0xde, 0x01, 0x85, 0x9e, 0xe9, 0x15, 0x69, - 0xd2, 0x72, 0x5a, 0x00, 0x2a, 0x38, 0x83, 0xe3, 0x53, 0x03, 0x36, 0xbb, 0x95, 0xad, 0x43, 0xfb, - 0x7e, 0x0e, 0x0c, 0x00, 0x31, 0xa3, 0x47, 0x53, 0xb2, 0xb4, 0x57, 0xe1, 0x94, 0xdc, 0xcf, 0xf9, - 0x17, 0x40, 0x6b, 0xc3, 0x06, 0x84, 0xd9, 0x0d, 0x92, 0xf1, 0xf1, 0x81, 0xe3, 0x09, 0x7c, 0x5a, - 0xbf, 0x30, 0xdc, 0x01, 0xf5, 0x26, 0x01, 0x6d, 0x69, 0x01, 0xcd, 0x6c, 0x1e, 0x44, 0x9b, 0x3d, - 0xff, 0xe7, 0x2f, 0xde, 0x53, 0x76, 0x7e, 0x85, 0x2e, 0xb0, 0x4a, 0xac, 0xbd, 0xc1, 0x0a, 0x63, - 0xe0, 0x9e, 0x4d, 0x8d, 0x46, 0x1b, 0xd4, 0x7f, 0x45, 0xa9, 0x85, 0x2e, 0xb3, 0x0b, 0xfa, 0xb6, - 0x97, 0x60, 0xa1, 0x51, 0xa5, 0xc7, 0xdf, 0x36, 0x64, 0x6f, 0x82, 0x59, 0xa8, 0xa3, 0x64, 0xce, - 0xb6, 0x06, 0x41, 0x77, 0xa4, 0x39, 0xe1, 0x5d, 0xc1, 0x95, 0xcb, 0x96, 0xee, 0x44, 0x0a, 0x0e, - 0x3a, 0x5a, 0x38, 0x01, 0x7d, 0x20, 0x80, 0x8c, 0xf0, 0xbe, 0x64, 0xdc, 0x65, 0x87, 0x83, 0x0d, - 0x1d, 0x5d, 0xc5, 0xb6, 0xbc, 0x9f, 0xd0, 0x60, 0x83, 0x79, 0x1b, 0x40, 0xa3, 0x69, 0x31, 0x8d, - 0x06, 0x25, 0xbe, 0xef, 0xbe, 0x8b, 0x59, 0x1b, 0xa1, 0xbb, 0xd0, 0xb9, 0x65, 0xe3, 0x65, 0xe1, - 0x9c, 0xa3, 0x6a, 0x35, 0xee, 0x74, 0x32, 0xcd, 0x79, 0x61, 0xc3, 0x78, 0x3a, 0x34, 0x4e, 0xc1, - 0x42, 0x2f, 0x0e, 0x06, 0x1b, 0xd6, 0x72, 0xd9, 0x42, 0x43, 0xbf, 0xfb, 0x97, 0x46, 0x60, 0xc4, - 0x92, 0x74, 0x5f, 0x72, 0x9a, 0xae, 0x6b, 0x6b, 0xa0, 0x45, 0x91, 0x24, 0x07, 0x0a, 0x3f, 0xc7, - 0x83, 0xd2, 0x29, 0xf9, 0x49, 0xd4, 0xe5, 0xc5, 0xee, 0x68, 0xa9, 0x01, 0xd9, 0x09, 0x66, 0x83, - 0x99, 0xe4, 0x34, 0x25, 0xe3, 0xd6, 0x93, 0xe6, 0xc2, 0x1e, 0x85, 0x65, 0xfe, 0xbd, 0x28, 0x32, - 0xf5, 0x28, 0xe7, 0xbb, 0xb1, 0x7e, 0xad, 0x7e, 0x55, 0x62, 0xe8, 0x85, 0x04, 0x74, 0x5c, 0xff, - 0x14, 0x42, 0xf7, 0x51, 0xb3, 0x14, 0xfe, 0x57, 0x1d, 0xa3, 0xe3, 0x50, 0x35, 0x42, 0xdd, 0x61, - 0xdd, 0x81, 0x92, 0x98, 0x85, 0x81, 0xa1, 0x8e, 0x4b, 0x11, 0x18, 0x0d, 0xc7, 0x73, 0xd7, 0x46, - 0x00, 0xae, 0x83, 0x1d, 0xc4, 0x4e, 0x32, 0xcb, 0x83, 0x82, 0x44, 0x07, 0x6f, 0xd2, 0x08, 0xbb, - 0x3d, 0xbd, 0x8b, 0x6b, 0x42, 0xa4, 0x1a, 0x8e, 0x19, 0xa1, 0xe1, 0xf4, 0x69, 0x76, 0x32, 0xf1, - 0xaf, 0xb6, 0x19, 0x8a, 0xce, 0x60, 0xa0, 0x93, 0x5c, 0xfc, 0x4d, 0x8a, 0xe1, 0xbd, 0xce, 0x85, - 0x1b, 0xd6, 0xdf, 0x71, 0xa5, 0x67, 0x72, 0x38, 0xea, 0x5d, 0xfe, 0x50, 0xba, 0xae, 0x0a, 0x05, - 0xf1, 0x4e, 0xc9, 0xe1, 0x8e, 0x6d, 0x00, 0x0c, 0x37, 0x0a, 0xfe, 0x26, 0x30, 0x20, 0xc3, 0xc8, - 0x59, 0xbb, 0x6d, 0xd1, 0x27, 0x47, 0x6a, 0x89, 0x59, 0xff, 0x98, 0x45, 0xb2, 0xe7, 0xe6, 0x2f, - 0xbe, 0x0e, 0xa6, 0x9b, 0x1b, 0x82, 0x2a, 0xa9, 0x6a, 0x18, 0xa4, 0x90, 0x5c, 0x57, 0xf7, 0x55, - 0x97, 0xc1, 0x9e, 0x7b, 0xb7, 0xf2, 0x3c, 0x8e, 0x42, 0xdc, 0xa8, 0x61, 0x61, 0x22, 0xe1, 0xfb, - 0x83, 0xc3, 0xc1, 0x22, 0x78, 0x2c, 0x91, 0x1a, 0xfd, 0xda, 0x88, 0xd0, 0x38, 0x0b, 0x86, 0x70, - 0x6a, 0x74, 0xe9, 0x6c, 0xab, 0x9c, 0x7e, 0x79, 0x78, 0xe1, 0x83, 0x58, 0x3b, 0x86, 0xaf, 0x70, - 0x1e, 0xc5, 0x99, 0x5f, 0x0d, 0x51, 0x07, 0x0c, 0xa5, 0x11, 0x3a, 0x9f, 0x08, 0x64, 0x04, 0xe6, - 0xac, 0x6c, 0x13, 0xe9, 0x65, 0xee, 0x2b, 0x05, 0x78, 0xcf, 0x44, 0x58, 0x27, 0xf8, 0xb6, 0xf6, - 0xce, 0x09, 0x7a, 0x38, 0xff, 0x5b, 0x4a, 0x0f, 0x02, 0x19, 0xd0, 0x8e, 0x44, 0x2d, 0xb3, 0x21, - 0xb2, 0x0d, 0xc0, 0xcd, 0x4d, 0xb2, 0xd4, 0x51, 0x6f, 0x52, 0x57, 0x74, 0x92, 0xac, 0xea, 0x64, - 0x7b, 0x12, 0xee, 0xa3, 0xa7, 0xa2, 0x86, 0x1b, 0x8c, 0xa8, 0xa9, 0xa0, 0x49, 0x35, 0x28, 0x8f, - 0x68, 0xd0, 0x1d, 0x7e, 0x4f, 0x7f, 0xfc, 0xdc, 0x88, 0x82, 0xab, 0x3a, 0xbe, 0xa5, 0xa2, 0x0d, - 0x84, 0xd4, 0xd4, 0x79, 0xdc, 0xb2, 0x0f, 0x5d, 0x81, 0xcb, 0xfb, 0x5b, 0x71, 0x4b, 0xb9, 0xec, - 0x22, 0x9a, 0xf5, 0xf9, 0x8b, 0xbb, 0x55, 0x78, 0xaf, 0xcf, 0xec, 0xe6, 0xb0, 0xf8, 0x19, 0x26, - 0xb6, 0xcd, 0x10, 0x3f, 0xc8, 0xc4, 0x2a, 0xe0, 0x75, 0x5b, 0xf1, 0xf2, 0x8a, 0xe2, 0xae, 0x2c, - 0xfc, 0xb2, 0x12, 0x3a, 0x2d, 0x4d, 0x4b, 0xd5, 0xbc, 0x4a, 0xe1, 0xbd, 0x97, 0x98, 0x3a, 0xe8, - 0x67, 0x75, 0x58, 0x8c, 0x70, 0xd2, 0x67, 0xc8, 0xf1, 0x23, 0x41, 0xc6, 0xc7, 0x27, 0xbf, 0x18, - 0x41, 0x44, 0x88, 0x81, 0x52, 0x41, 0xb4, 0x77, 0x4e, 0x6c, 0x24, 0xa1, 0x40, 0x90, 0x81, 0x75, - 0x19, 0x96, 0xd8, 0x09, 0x82, 0xbb, 0x66, 0xc6, 0x0e, 0x28, 0xec, 0xf8, 0xe0, 0x87, 0xc7, 0xec, - 0x70, 0xff, 0x0d, 0x75, 0x13, 0x18, 0xec, 0x4d, 0xf3, 0xf9, 0x98, 0x0a, 0x4f, 0xf5, 0xb6, 0x15, - 0xa5, 0x69, 0xb2, 0xc1, 0x42, 0x2d, 0x44, 0x61, 0x66, 0x0c, 0x07, 0xc4, 0xd6, 0x94, 0xda, 0x17, - 0x71, 0xce, 0xd7, 0x82, 0xad, 0xd0, 0x45, 0x6f, 0xfc, 0xf8, 0x61, 0x14, 0x87, 0x63, 0xc7, 0x53, - 0x28, 0xeb, 0x4c, 0x5d, 0xc2, 0x08, 0xf4, 0xc0, 0x6a, 0x1e, 0x03, 0xa7, 0x5b, 0x04, 0x80, 0xa1, - 0x1b, 0x02, 0xac, 0x9e, 0x31, 0x8d, 0x95, 0x1a, 0x63, 0x54, 0x31, 0x97, 0x5a, 0xba, 0xf3, 0xda, - 0x0f, 0xac, 0xa6, 0x95, 0xeb, 0x49, 0x0c, 0x71, 0x23, 0xe3, 0x44, 0x10, 0x05, 0x87, 0x61, 0xfb, - 0x69, 0x74, 0x54, 0x3b, 0x0e, 0x46, 0xff, 0xfb, 0x27, 0x0c, 0xdc, 0x70, 0xb8, 0x09, 0xa1, 0x5a, - 0x37, 0xcf, 0xd4, 0x5d, 0xea, 0x69, 0xe7, 0x67, 0x91, 0x78, 0xbf, 0xd0, 0xe6, 0x31, 0x2f, 0x84, - 0x7e, 0x2c, 0xa2, 0xe9, 0xbc, 0x43, 0xcb, 0x41, 0x58, 0xef, 0xb2, 0x51, 0xfe, 0x67, 0x11, 0x8b, - 0x3a, 0xcf, 0x79, 0x5a, 0x32, 0x98, 0x02, 0x60, 0xbc, 0xd7, 0xcd, 0x9d, 0xc0, 0x90, 0x6f, 0x98, - 0x42, 0x68, 0x43, 0xcf, 0x3b, 0xa8, 0xbd, 0xb9, 0x19, 0xd9, 0xfc, 0x02, 0xc5, 0x00, 0xcc, 0xcf, - 0xc0, 0xf4, 0xc7, 0x08, 0x41, 0x1a, 0x20, 0x98, 0xc4, 0x63, 0x11, 0xf0, 0xbd, 0xe3, 0x7d, 0xd7, - 0x5c, 0x60, 0xc6, 0xc2, 0x18, 0xdd, 0xd8, 0x34, 0x48, 0x90, 0x22, 0xe8, 0x8f, 0x83, 0x2b, 0xff, - 0x30, 0xb0, 0xd0, 0x6b, 0xd0, 0xb4, 0x88, 0x41, 0xdb, 0x1b, 0xa3, 0x5f, 0x19, 0xa3, 0x8d, 0x66, - 0xdf, 0x46, 0xdf, 0x6a, 0xae, 0x3d, 0x04, 0x6d, 0x12, 0x17, 0xd7, 0xab, 0x73, 0x4a, 0x7a, 0x92, - 0x8e, 0x11, 0xf0, 0x4b, 0xf8, 0x9c, 0x87, 0x8d, 0x32, 0x7f, 0x70, 0x7e, 0x84, 0x28, 0x4e, 0x24, - 0xf1, 0xc8, 0x0c, 0xad, 0x05, 0x3c, 0xd2, 0x4e, 0xd0, 0x53, 0x1f, 0xe7, 0x4e, 0x4c, 0xa3, 0x80, - 0x3c, 0xd9, 0xd6, 0x04, 0x43, 0x6f, 0xa2, 0x0f, 0x50, 0xa7, 0x2e, 0x7d, 0x7d, 0x6f, 0x68, 0xb3, - 0x5f, 0xea, 0xd0, 0x86, 0x9f, 0x37, 0x92, 0xf7, 0xd3, 0x65, 0x45, 0xdb, 0x92, 0x4a, 0x58, 0x02, - 0xbe, 0xb4, 0x9d, 0xee, 0x62, 0x76, 0x60, 0x0c, 0x90, 0x34, 0x54, 0x2d, 0x83, 0x8e, 0x27, 0x76, - 0xbc, 0x1d, 0x34, 0x11, 0xfd, 0xbb, 0xb8, 0x83, 0x5b, 0x45, 0x35, 0x7c, 0xc6, 0xa3, 0xea, 0xa0, - 0xaf, 0x04, 0xaf, 0x3c, 0xca, 0x64, 0x45, 0x6f, 0xca, 0x45, 0x30, 0xfd, 0xc4, 0xfa, 0x8a, 0x7d, - 0x90, 0x98, 0x12, 0xb0, 0xbc, 0x01, 0xc2, 0xcc, 0x49, 0xba, 0x9b, 0x88, 0x1b, 0x18, 0xc8, 0x30, - 0x08, 0xc8, 0x33, 0x13, 0xb4, 0x31, 0x26, 0x2b, 0x9c, 0x54, 0x6a, 0xee, 0xeb, 0x65, 0xde, 0x16, - 0x07, 0x22, 0xcb, 0xf0, 0x43, 0xb1, 0x42, 0xae, 0xa8, 0x73, 0x33, 0xe1, 0x37, 0xed, 0x79, 0x9f, - 0xe8, 0x72, 0x5f, 0x08, 0xec, 0x7a, 0x60, 0xbc, 0x34, 0x0c, 0x3c, 0x7a, 0xeb, 0x6d, 0x67, 0xae, - 0x88, 0xe8, 0x0e, 0xd9, 0x79, 0x7e, 0x9c, 0x3b, 0x58, 0x48, 0x64, 0x1b, 0xad, 0xbe, 0xad, 0x2d, - 0xcf, 0xb1, 0x29, 0xd8, 0x82, 0x26, 0x28, 0x75, 0x89, 0x01, 0xf3, 0x6c, 0x26, 0x7b, 0xf1, 0x0b, - 0xec, 0x25, 0x6d, 0xf1, 0x0b, 0x6c, 0x3a, 0xc6, 0xf9, 0xf1, 0x00, 0xc3, 0x22, 0x19, 0xc3, 0xd7, - 0xf1, 0xe1, 0xbd, 0x58, 0x71, 0x2e, 0x25, 0xa5, 0x80, 0xad, 0xa4, 0x6c, 0xfa, 0xa9, 0xe1, 0x06, - 0xd5, 0x02, 0x16, 0xbb, 0xd0, 0x00, 0x20, 0x2c, 0x94, 0x6c, 0x05, 0x23, 0x61, 0x17, 0x51, 0xe5, - 0x78, 0x77, 0x01, 0x8f, 0x12, 0x3d, 0x44, 0x4c, 0xf7, 0x01, 0x29, 0x79, 0xf5, 0xb1, 0xd0, 0x4f, - 0xc1, 0xc0, 0xed, 0xe9, 0xcd, 0x4d, 0xfa, 0xb5, 0x4d, 0x65, 0x70, 0xa8, 0x4e, 0x33, 0xa8, 0x43, - 0xf3, 0x79, 0x61, 0x59, 0x38, 0x06, 0xf9, 0xce, 0x44, 0x58, 0x2d, 0x1a, 0x83, 0x12, 0xda, 0x44, - 0x20, 0x69, 0x1a, 0x31, 0xbb, 0xb9, 0x29, 0x82, 0xb9, 0xc1, 0x9e, 0x19, 0x6a, 0x55, 0x74, 0xad, - 0xf8, 0xde, 0x74, 0x3f, 0x83, 0xb9, 0xcd, 0xc5, 0x1a, 0xbd, 0x44, 0xd8, 0x77, 0x3a, 0x0e, 0xd0, - 0x65, 0x9f, 0xe8, 0x06, 0x7b, 0x86, 0x5f, 0x38, 0x46, 0x37, 0x9e, 0x93, 0x3d, 0x8b, 0xa5, 0x71, - 0x5f, 0x9c, 0x18, 0xe6, 0xb0, 0xd7, 0x4f, 0xd0, 0xb7, 0x3e, 0x61, 0x28, 0xa0, 0x23, 0x8d, 0x48, - 0x82, 0x05, 0xd0, 0xc5, 0xaa, 0xe4, 0x6a, 0xc1, 0xed, 0x83, 0xb4, 0x05, 0xcf, 0x61, 0x1b, 0x29, - 0x93, 0xc7, 0x32, 0x67, 0x9a, 0xe3, 0xe0, 0x3b, 0x32, 0x8e, 0xae, 0xa9, 0x8f, 0x33, 0x56, 0xa4, - 0x8a, 0x45, 0x9a, 0xa1, 0x9e, 0x25, 0xe8, 0x30, 0x12, 0x60, 0x4b, 0x25, 0x4c, 0x05, 0x16, 0x1a, - 0xfa, 0x8a, 0xe7, 0x21, 0xea, 0xa5, 0xbc, 0x82, 0x6e, 0x48, 0xd2, 0x82, 0x29, 0xae, 0x06, 0x3f, - 0x54, 0x1a, 0x32, 0x14, 0xbe, 0x8a, 0xc2, 0x00, 0x11, 0xa0, 0x87, 0x6f, 0xaa, 0x30, 0xd2, 0xdd, - 0x49, 0x38, 0x7a, 0x08, 0xf1, 0x17, 0xe2, 0x44, 0xd9, 0x7a, 0x88, 0xed, 0x2c, 0x02, 0xf6, 0x43, - 0x81, 0x8e, 0x7f, 0xce, 0x3c, 0xbf, 0x90, 0xdf, 0xbf, 0x83, 0x26, 0xf8, 0x59, 0x48, 0xbe, 0xfc, - 0xfe, 0x1d, 0x16, 0x3d, 0xe1, 0x60, 0xf2, 0x68, 0x28, 0x96, 0x90, 0x27, 0x79, 0xde, 0x77, 0xa3, - 0x51, 0x46, 0x6c, 0x36, 0x3e, 0x8e, 0x0d, 0x47, 0x07, 0xd3, 0x0e, 0x67, 0x81, 0x00, 0xe5, 0x98, - 0x67, 0x1a, 0x4f, 0xd8, 0x27, 0x31, 0xf4, 0x18, 0x79, 0x14, 0xb4, 0x0d, 0x06, 0x57, 0x83, 0x79, - 0x9d, 0x71, 0xa7, 0x3c, 0x1c, 0x21, 0x8d, 0x32, 0x2e, 0x6d, 0x98, 0xe3, 0x24, 0x8f, 0xd1, 0x14, - 0xd4, 0x18, 0x88, 0x05, 0xb7, 0xa2, 0xd8, 0xf5, 0x42, 0xa7, 0xb2, 0x78, 0x57, 0x42, 0x12, 0xaf, - 0x12, 0x81, 0x85, 0x64, 0xee, 0xf8, 0xdc, 0x1e, 0x46, 0xf7, 0x6d, 0xc6, 0x8d, 0x38, 0xc6, 0xf0, - 0xbf, 0xf1, 0x35, 0x8c, 0x11, 0xc5, 0x96, 0x23, 0x62, 0x23, 0x84, 0x65, 0x21, 0x87, 0x6e, 0x90, - 0x55, 0x7e, 0x76, 0x47, 0x0b, 0x39, 0xd9, 0x1d, 0x01, 0x0f, 0xe0, 0x11, 0xbc, 0x4b, 0x03, 0xa3, - 0xd6, 0xd1, 0xd0, 0xdf, 0xc2, 0xcd, 0x09, 0x18, 0x24, 0x1e, 0x5f, 0xd2, 0x98, 0xe2, 0x40, 0x2b, - 0xd6, 0xf1, 0x72, 0x59, 0x1b, 0x99, 0xf3, 0xed, 0x4d, 0x7b, 0xab, 0xc2, 0xcd, 0x05, 0x7c, 0x99, - 0x4b, 0xcd, 0xfd, 0x8b, 0xa1, 0x6f, 0xc9, 0xff, 0x61, 0xa5, 0xa1, 0xc7, 0xe3, 0xa5, 0x08, 0x3b, - 0xa8, 0x9c, 0x2b, 0x0a, 0x28, 0x3c, 0x74, 0x0a, 0x35, 0xaa, 0x1c, 0x2c, 0x94, 0x07, 0x96, 0xf2, - 0xb1, 0x06, 0xe1, 0x57, 0xe0, 0xf9, 0x90, 0xf6, 0x40, 0x3c, 0xed, 0xc1, 0xfb, 0xae, 0x91, 0xa8, - 0x98, 0xe6, 0x6b, 0xe1, 0x15, 0x88, 0x17, 0x4d, 0xc0, 0x2a, 0x71, 0x2c, 0xb0, 0x26, 0x08, 0x3b, - 0x24, 0xf0, 0xd7, 0xf6, 0x1f, 0x96, 0x2d, 0x7e, 0xef, 0x4d, 0x32, 0x91, 0x43, 0x33, 0x33, 0xd3, - 0xa8, 0xb1, 0xcb, 0x6b, 0xf0, 0x33, 0x1c, 0x06, 0x19, 0xbe, 0xea, 0x69, 0xe6, 0xdd, 0x66, 0x03, - 0xf6, 0x69, 0xf8, 0x32, 0x1f, 0x21, 0xe9, 0xdf, 0x77, 0xc3, 0xbe, 0xf9, 0xd8, 0xed, 0x1e, 0xde, - 0xa9, 0x59, 0xbc, 0x23, 0xcc, 0x9f, 0x86, 0xe0, 0x7a, 0xf7, 0x06, 0xab, 0xb2, 0xc3, 0x85, 0xae, - 0x79, 0xc7, 0xb7, 0x24, 0x01, 0xc1, 0x85, 0x52, 0xf0, 0x95, 0x64, 0xbc, 0x67, 0x6b, 0xf8, 0x6f, - 0xab, 0x89, 0x1a, 0xb8, 0x0c, 0xc8, 0xc2, 0xc4, 0x8d, 0x0f, 0xc0, 0xdf, 0x69, 0xf2, 0xa7, 0x2b, - 0x3c, 0x2c, 0xec, 0xbf, 0x77, 0x4b, 0x8f, 0xf7, 0xc0, 0xb3, 0x63, 0x5a, 0xfe, 0xf8, 0x58, 0x78, - 0x17, 0xdb, 0x8f, 0x5a, 0x31, 0x00, 0x5a, 0xec, 0x8f, 0x47, 0x70, 0xee, 0xc1, 0x0b, 0x8f, 0xc2, - 0x83, 0xb4, 0x72, 0x18, 0xec, 0x3d, 0x31, 0x7e, 0x88, 0xa5, 0x57, 0x04, 0xf8, 0x52, 0x08, 0x64, - 0xeb, 0x32, 0x0c, 0xaf, 0xbe, 0x36, 0x07, 0x59, 0x17, 0xae, 0x68, 0x06, 0x83, 0x75, 0xca, 0xbb, - 0x33, 0x3f, 0x6e, 0xc3, 0x91, 0xb8, 0x05, 0x47, 0x0b, 0x8f, 0x56, 0xda, 0x7b, 0xab, 0xcb, 0xfa, - 0x97, 0xaf, 0x7f, 0x54, 0xda, 0xdf, 0xc8, 0x60, 0xbf, 0xfc, 0x81, 0xb1, 0x8b, 0x8f, 0x63, 0x75, - 0xeb, 0xeb, 0xb3, 0x1a, 0x71, 0x93, 0x33, 0x8a, 0xc1, 0x50, 0x40, 0x8c, 0xef, 0x80, 0x21, 0x73, - 0xc5, 0x81, 0xac, 0x5f, 0x7c, 0xda, 0x0b, 0xcd, 0xa8, 0x2f, 0x72, 0xcc, 0xec, 0xaf, 0x15, 0xf0, - 0x97, 0x0d, 0x60, 0xaf, 0x74, 0xee, 0xd7, 0xe7, 0x7b, 0xe3, 0x85, 0x87, 0x90, 0xd8, 0x3a, 0x04, - 0xbd, 0xb2, 0x46, 0x37, 0x8e, 0x50, 0xae, 0xd6, 0x16, 0x5b, 0xfd, 0x04, 0x25, 0xef, 0xa2, 0x8f, - 0xf3, 0x79, 0xf4, 0x4a, 0x8d, 0xc8, 0x75, 0x9f, 0xe1, 0x13, 0x0c, 0xe1, 0x6b, 0x1f, 0xbd, 0xce, - 0xd5, 0x17, 0xdd, 0x5b, 0x20, 0x3b, 0x48, 0x5b, 0x39, 0x87, 0xa1, 0xfb, 0x3e, 0xe3, 0x23, 0xf4, - 0xb0, 0xb0, 0x02, 0xd2, 0xe6, 0xe6, 0xaa, 0x1e, 0xd0, 0x17, 0xcd, 0x81, 0x12, 0x66, 0xde, 0x69, - 0x64, 0x9c, 0x9c, 0xc9, 0xa4, 0x2f, 0x8d, 0x34, 0xd3, 0xae, 0x71, 0xce, 0xc0, 0x34, 0x31, 0x50, - 0x8d, 0x02, 0xaa, 0xf9, 0xd7, 0x00, 0xc7, 0xc6, 0x19, 0xbe, 0x3a, 0x35, 0x3c, 0xcc, 0xe5, 0x0e, - 0xfe, 0x85, 0x51, 0xae, 0xc0, 0xd5, 0xe7, 0x87, 0x19, 0xed, 0xc1, 0xdf, 0x18, 0xe5, 0x22, 0xf0, - 0x66, 0x3d, 0x6d, 0x00, 0xb7, 0xfe, 0xe2, 0xc7, 0xf3, 0x90, 0x9f, 0xf3, 0xe5, 0xea, 0x18, 0x30, - 0xb3, 0xbe, 0x3a, 0x58, 0x61, 0xb5, 0x40, 0x43, 0x0f, 0xd3, 0x18, 0x0d, 0x27, 0x09, 0x3c, 0xc5, - 0x51, 0xa8, 0xde, 0x95, 0xa3, 0xa4, 0x21, 0xf2, 0xb3, 0xd8, 0x4c, 0x08, 0xcb, 0xed, 0x74, 0x27, - 0xb5, 0xf0, 0xb9, 0xb2, 0xee, 0x44, 0x25, 0x5d, 0x74, 0x71, 0xc4, 0x80, 0xfa, 0x17, 0x62, 0xfa, - 0x3a, 0x60, 0x9c, 0x94, 0x57, 0x40, 0x86, 0x59, 0xaa, 0x91, 0x38, 0x1c, 0xfa, 0x7e, 0xa8, 0xe8, - 0x70, 0x97, 0x06, 0xb9, 0x6c, 0xbb, 0xf2, 0x71, 0xc4, 0xb1, 0xbb, 0x9c, 0x57, 0xa0, 0xcd, 0x99, - 0xac, 0x84, 0x15, 0x31, 0x35, 0x96, 0x30, 0x16, 0xba, 0xc9, 0x78, 0xd5, 0x4c, 0xac, 0x06, 0xb9, - 0x64, 0x9f, 0x2c, 0x81, 0xc5, 0x5b, 0xee, 0xe2, 0x73, 0x8b, 0x77, 0xa2, 0x91, 0x38, 0x6e, 0x59, - 0x20, 0x76, 0xc0, 0xf0, 0x66, 0x68, 0x3b, 0xcf, 0xeb, 0x91, 0xe3, 0x60, 0xb8, 0xbb, 0x08, 0x26, - 0x3b, 0xd5, 0x54, 0x43, 0xea, 0x87, 0xff, 0xce, 0x3d, 0xcb, 0x3f, 0x83, 0xe6, 0x1f, 0x4e, 0xf3, - 0x82, 0x13, 0x69, 0x5c, 0x62, 0x64, 0x6e, 0xdc, 0x48, 0xdb, 0x81, 0xbd, 0x87, 0xf1, 0x47, 0x78, - 0x5d, 0x1d, 0xa9, 0x2f, 0x98, 0xee, 0x7a, 0xfb, 0x76, 0x69, 0x1f, 0x13, 0xb7, 0x2f, 0x57, 0x38, - 0xe7, 0xe9, 0x3b, 0xe4, 0x39, 0xbe, 0x1e, 0xcb, 0xa6, 0x8e, 0x72, 0x2f, 0x4f, 0x40, 0x04, 0x50, - 0x91, 0x96, 0x74, 0xd7, 0x9a, 0xb4, 0x11, 0xb3, 0x71, 0xc9, 0x0c, 0x25, 0x3f, 0x3f, 0xf4, 0x51, - 0x52, 0x0b, 0x07, 0x95, 0xbd, 0x3e, 0xf4, 0x7d, 0x11, 0x41, 0xd0, 0xf2, 0x76, 0xaf, 0xe8, 0xbb, - 0x72, 0x1a, 0xb8, 0x7d, 0x05, 0x04, 0x3e, 0xeb, 0xd7, 0x44, 0xc1, 0x81, 0xbf, 0x11, 0xbe, 0x61, - 0x15, 0xb4, 0xb9, 0xc8, 0xa9, 0xca, 0x20, 0xd2, 0xd9, 0xdb, 0x22, 0x4d, 0x15, 0x45, 0xbe, 0xae, - 0x9a, 0x33, 0x92, 0xee, 0x87, 0x8b, 0xe5, 0x4b, 0xb1, 0x72, 0xfc, 0x1c, 0x7a, 0xab, 0x93, 0x24, - 0x4d, 0x94, 0x64, 0x0c, 0x73, 0xee, 0xd3, 0xbb, 0xd6, 0xfa, 0xb8, 0xb9, 0xc5, 0xd7, 0x59, 0xe7, - 0x20, 0x71, 0xbe, 0x40, 0x08, 0xa1, 0xd8, 0xf1, 0x5f, 0xe0, 0xb0, 0xb4, 0x23, 0x13, 0x8c, 0xce, - 0x63, 0xb0, 0xec, 0x18, 0x38, 0xbb, 0x49, 0x0c, 0x84, 0x79, 0x3d, 0x84, 0xb3, 0xeb, 0x90, 0x17, - 0xc8, 0x0e, 0x23, 0xf3, 0x20, 0x94, 0xd1, 0x8b, 0x78, 0x8e, 0xc2, 0x7e, 0xa3, 0x7a, 0x18, 0x74, - 0x9f, 0x4c, 0x3a, 0xd4, 0x02, 0xf2, 0xdc, 0xe3, 0xf0, 0xe4, 0x47, 0x97, 0xbb, 0x11, 0xcf, 0x40, - 0xdd, 0xc5, 0x00, 0x71, 0xdc, 0x64, 0xea, 0x78, 0xa5, 0x4a, 0x91, 0x03, 0xca, 0xfe, 0x4b, 0x78, - 0xf0, 0x88, 0x32, 0x6b, 0x2a, 0xdc, 0x0c, 0x4d, 0xf1, 0x7c, 0xcb, 0x30, 0x25, 0x91, 0x1e, 0x0c, - 0x41, 0xea, 0x46, 0x52, 0x1c, 0xc9, 0x1d, 0xda, 0xd4, 0xe4, 0xf1, 0x66, 0x4d, 0x30, 0x1a, 0x9a, - 0x6d, 0xa6, 0x5b, 0xac, 0xbc, 0x33, 0xba, 0x31, 0xf1, 0x55, 0x20, 0x0e, 0xee, 0x7c, 0x7b, 0xee, - 0x11, 0x23, 0xcd, 0x5c, 0x23, 0x46, 0xba, 0xe7, 0x7d, 0xcb, 0xb8, 0x5a, 0xa0, 0x2f, 0x06, 0x99, - 0xf8, 0x3b, 0x68, 0x1d, 0x4d, 0xd6, 0xe9, 0x48, 0x57, 0xdf, 0xb2, 0xb2, 0x66, 0x0f, 0x12, 0x6f, - 0x58, 0x4a, 0x88, 0xff, 0x14, 0xe8, 0x7e, 0x2e, 0xff, 0x2b, 0x8c, 0xd6, 0x93, 0x00, 0xad, 0xe1, - 0xee, 0xbf, 0x10, 0x7d, 0xa4, 0x19, 0x51, 0xa6, 0xe0, 0x93, 0x80, 0xc7, 0x14, 0xd0, 0x7e, 0x0a, - 0x46, 0x84, 0x5e, 0x32, 0x97, 0xc1, 0xd9, 0x16, 0x77, 0x22, 0x88, 0x20, 0x78, 0x6e, 0xa3, 0x16, - 0x4b, 0x6a, 0xb1, 0xb7, 0x8b, 0x24, 0x39, 0xc0, 0x04, 0x8c, 0x15, 0xfe, 0xc2, 0xe4, 0xe4, 0xbd, - 0xea, 0x68, 0xf6, 0x61, 0xa5, 0xa5, 0x9b, 0xfa, 0x16, 0x53, 0xe8, 0xb3, 0xc0, 0x08, 0xd0, 0x93, - 0x65, 0xa0, 0xc9, 0x19, 0x1b, 0x6b, 0x6d, 0x1d, 0xac, 0x00, 0x41, 0xf3, 0x18, 0x30, 0xfa, 0x2a, - 0x97, 0xd9, 0x02, 0x33, 0x5e, 0x88, 0xc0, 0x2a, 0x22, 0xc7, 0x80, 0x81, 0x55, 0x34, 0x1e, 0x4b, - 0xdf, 0x5d, 0x34, 0xf5, 0x6b, 0xcd, 0x4a, 0x0b, 0x12, 0x23, 0xda, 0x68, 0x9c, 0x31, 0x66, 0x81, - 0x75, 0x6c, 0x6e, 0x46, 0xaf, 0x68, 0x68, 0x34, 0x5c, 0xb6, 0x0a, 0x56, 0x73, 0xb4, 0xcd, 0xcd, - 0x0f, 0xb1, 0x4d, 0xe3, 0x21, 0xde, 0x05, 0x12, 0x5f, 0xf1, 0x6c, 0x99, 0x09, 0xb9, 0x2f, 0xd8, - 0x9d, 0x64, 0x78, 0x29, 0x36, 0x56, 0x49, 0xb0, 0x80, 0x91, 0x06, 0xc1, 0x2a, 0x31, 0x78, 0x02, - 0xac, 0x3c, 0x2a, 0x02, 0x21, 0xa5, 0xf6, 0xe3, 0x87, 0x09, 0xac, 0xc3, 0x04, 0x2e, 0x61, 0xa6, - 0x65, 0x21, 0x0c, 0xfc, 0xa7, 0xf0, 0x03, 0xff, 0x07, 0xf5, 0xa6, 0x9e, 0xa5, 0x4d, 0xc7, 0x4c, - 0x83, 0xd5, 0x16, 0x0b, 0xd8, 0xed, 0xe8, 0x23, 0xe9, 0xa5, 0xbb, 0x13, 0xd0, 0x54, 0x04, 0xc0, - 0x21, 0x02, 0xdb, 0x89, 0x36, 0x09, 0x70, 0xdf, 0x6b, 0x15, 0x9a, 0xac, 0xe5, 0x58, 0x45, 0x7a, - 0x49, 0x52, 0xac, 0xea, 0x7b, 0xb5, 0x51, 0x19, 0x8b, 0x08, 0x46, 0x27, 0xa6, 0xa8, 0x78, 0xef, - 0x92, 0x59, 0xa9, 0x9c, 0x29, 0x8a, 0x1b, 0xd6, 0x9a, 0xe6, 0xde, 0xf1, 0xbb, 0xbe, 0x12, 0x96, - 0x2e, 0xe8, 0xf9, 0x3f, 0x38, 0xc4, 0x0b, 0x0c, 0xd8, 0x6e, 0x0e, 0xfe, 0x4e, 0x06, 0x57, 0xc7, - 0x78, 0x97, 0x76, 0xe2, 0x05, 0xa3, 0x8b, 0x3b, 0x8a, 0x33, 0x18, 0xa4, 0x9b, 0x19, 0x6b, 0x2f, - 0xa0, 0xf9, 0xcc, 0x3d, 0xc5, 0xc4, 0x86, 0x29, 0x62, 0xa7, 0xfe, 0x7c, 0x93, 0x38, 0x99, 0xec, - 0x2b, 0xa9, 0x46, 0xb6, 0xc2, 0x6f, 0xe7, 0xe9, 0xa1, 0x78, 0x6c, 0x96, 0x17, 0xfa, 0xca, 0x76, - 0xce, 0xff, 0x99, 0x17, 0x4b, 0x80, 0xd1, 0x42, 0xa1, 0xd1, 0xe8, 0x2b, 0x34, 0x25, 0xd5, 0xc8, - 0x63, 0x8a, 0x58, 0x09, 0xa5, 0x00, 0x00, 0xc6, 0x99, 0xd8, 0x2d, 0xca, 0xfe, 0xf4, 0xd0, 0xd9, - 0x6f, 0xfc, 0xea, 0x3b, 0x78, 0x81, 0x54, 0x5f, 0x99, 0xe3, 0x6d, 0x5c, 0xc8, 0xcb, 0x8a, 0x60, - 0x17, 0xff, 0xe2, 0xe7, 0x42, 0x35, 0x2b, 0x32, 0x72, 0x51, 0x8c, 0xae, 0x1d, 0xf1, 0x15, 0x2e, - 0xae, 0x76, 0xa6, 0x7b, 0x13, 0x98, 0x1f, 0xd1, 0xfd, 0x83, 0xdb, 0xa0, 0x83, 0xa3, 0xe5, 0x24, - 0xd2, 0x26, 0xf7, 0x15, 0x5f, 0x6e, 0x27, 0x90, 0xd0, 0x7e, 0x2d, 0x47, 0x5f, 0xd4, 0x6a, 0x0f, - 0x12, 0xec, 0xaa, 0x68, 0x8e, 0x7a, 0xe7, 0x93, 0xac, 0x65, 0x58, 0xa7, 0x6b, 0xde, 0x0d, 0x4b, - 0x1b, 0xe2, 0x56, 0x9f, 0x08, 0x8e, 0x9c, 0x13, 0x8d, 0x47, 0x88, 0x79, 0x7b, 0x76, 0x1f, 0x5d, - 0x2d, 0x04, 0xb0, 0x26, 0xde, 0xcd, 0x42, 0xbc, 0x6b, 0x4f, 0x11, 0x4c, 0x32, 0xb2, 0xd7, 0xe6, - 0xb2, 0xd0, 0x80, 0x11, 0x6e, 0x67, 0x07, 0xbb, 0x45, 0x78, 0xf6, 0xc7, 0x3f, 0x0b, 0x1e, 0x6a, - 0xb4, 0x81, 0x07, 0xe8, 0xe9, 0xb0, 0xd8, 0xa9, 0x4e, 0x7e, 0xee, 0xdd, 0xd5, 0xc3, 0xcf, 0xe6, - 0x91, 0x72, 0xb3, 0x39, 0x9e, 0xee, 0x89, 0x8c, 0x43, 0x14, 0xbc, 0x3b, 0x57, 0xd6, 0xdd, 0x1f, - 0x49, 0x7b, 0x1a, 0x3f, 0x92, 0x3f, 0xb3, 0x6a, 0x91, 0x9b, 0x94, 0xa1, 0x63, 0xb5, 0x70, 0x2f, - 0xe7, 0x18, 0xcd, 0xb8, 0xea, 0x90, 0x75, 0xe4, 0x86, 0x8a, 0x28, 0x42, 0x71, 0x13, 0x76, 0xcd, - 0x19, 0xeb, 0xc9, 0x8e, 0x85, 0xc2, 0x12, 0xb4, 0xd1, 0x58, 0x8c, 0xf0, 0xdf, 0x70, 0x61, 0xfe, - 0x05, 0xdf, 0xa5, 0x09, 0x88, 0x8a, 0xe0, 0x73, 0xf9, 0xe6, 0x83, 0x30, 0x52, 0xcc, 0xb4, 0x05, - 0x30, 0xbe, 0x9b, 0xe9, 0xc1, 0x4e, 0xfc, 0x7a, 0x93, 0xa5, 0xc1, 0xa7, 0xb2, 0x78, 0xbd, 0xad, - 0x00, 0x6a, 0x5c, 0xcd, 0x4d, 0x46, 0x6f, 0x5b, 0x5a, 0x3a, 0xc9, 0x1b, 0x66, 0x32, 0xf4, 0xad, - 0x0a, 0xb8, 0x9d, 0xb7, 0xb8, 0x40, 0x60, 0xbd, 0xf2, 0x11, 0x18, 0xb8, 0x78, 0x64, 0xc6, 0x8b, - 0x12, 0x8a, 0xbb, 0x38, 0x82, 0x80, 0x7d, 0x5c, 0x6f, 0x2e, 0xbf, 0x72, 0xff, 0x7d, 0x11, 0xa8, - 0xa9, 0x61, 0x60, 0xc9, 0x77, 0xff, 0x52, 0xae, 0xba, 0xb6, 0x38, 0x19, 0x64, 0xfe, 0xd0, 0xf0, - 0xc6, 0x25, 0x67, 0x65, 0x58, 0x26, 0x8d, 0x1c, 0xf3, 0x82, 0x2a, 0x6e, 0xa0, 0xb7, 0xa0, 0xdf, - 0xdd, 0xe2, 0x9b, 0xb5, 0x5b, 0x12, 0x5e, 0xbf, 0x52, 0x77, 0x62, 0xfd, 0x35, 0x82, 0x30, 0x0d, - 0xaf, 0xd3, 0xd1, 0xf2, 0xfc, 0xf6, 0x56, 0x96, 0x3a, 0xb9, 0xd8, 0xde, 0xfe, 0x3c, 0x7a, 0xc5, - 0x8a, 0xc1, 0xe2, 0x9d, 0x56, 0x99, 0xf8, 0x75, 0x3f, 0xd2, 0x0c, 0xc3, 0x44, 0x35, 0x73, 0xe8, - 0x44, 0xb1, 0xe6, 0xeb, 0x47, 0xf4, 0x44, 0x6f, 0x9a, 0xbe, 0xc8, 0x22, 0x89, 0x37, 0xe8, 0x21, - 0x10, 0x9c, 0x1d, 0x7a, 0x43, 0x4f, 0x12, 0xb5, 0x2a, 0xf6, 0xc4, 0xae, 0x4e, 0xe2, 0xc2, 0x71, - 0xe0, 0x43, 0xf6, 0xfe, 0x8b, 0x85, 0x9a, 0xbd, 0x64, 0x9c, 0xca, 0xfa, 0xd0, 0x4e, 0xae, 0xdc, - 0xd3, 0x5a, 0xce, 0x09, 0xdb, 0x8b, 0x2c, 0x77, 0xce, 0x82, 0x3f, 0xff, 0xab, 0xb5, 0xe2, 0x22, - 0xdb, 0xc5, 0x4b, 0x88, 0x79, 0xe1, 0xbc, 0x91, 0xa5, 0x61, 0x04, 0x63, 0x41, 0xa3, 0x7d, 0x69, - 0x88, 0xc2, 0x44, 0x64, 0x0e, 0x76, 0xe6, 0xbf, 0xe8, 0xd0, 0x1b, 0xc3, 0xd1, 0xdd, 0x14, 0xe1, - 0xc7, 0x43, 0x83, 0xed, 0x51, 0x04, 0xd1, 0x11, 0x69, 0x76, 0x58, 0x47, 0xbd, 0xa1, 0xd7, 0x11, - 0x39, 0x3b, 0xf1, 0x84, 0x1f, 0xe2, 0xcf, 0x5a, 0xe8, 0x38, 0x48, 0x5f, 0x72, 0x8e, 0x6c, 0x93, - 0x46, 0xc4, 0xd1, 0xe3, 0xe9, 0x91, 0x58, 0x23, 0xb2, 0xb4, 0x19, 0xcb, 0x22, 0x37, 0x16, 0x67, - 0x2e, 0xa1, 0x2e, 0xa0, 0xd3, 0xdb, 0x9f, 0x16, 0xe7, 0xfe, 0x46, 0x75, 0x98, 0x2d, 0x2b, 0x2f, - 0xc9, 0x50, 0xc8, 0xa0, 0x17, 0xd5, 0x16, 0xd8, 0x89, 0xf4, 0x40, 0x6b, 0x24, 0xd4, 0xcd, 0xbf, - 0x60, 0x3a, 0x28, 0x02, 0xb3, 0xec, 0x61, 0xca, 0x49, 0x06, 0x2f, 0x85, 0xe3, 0x7f, 0xff, 0x0e, - 0x77, 0xdd, 0x8d, 0xfd, 0x36, 0xf1, 0x02, 0x3e, 0x40, 0xa0, 0x8f, 0x1e, 0x80, 0x86, 0xca, 0xfb, - 0x43, 0x80, 0x4c, 0x2f, 0x24, 0x2d, 0xf4, 0xbe, 0x67, 0xfe, 0x07, 0xc3, 0xfc, 0x4f, 0xcf, 0x61, - 0x74, 0x63, 0x5a, 0xc2, 0x7f, 0xb5, 0x56, 0xc5, 0xd1, 0x79, 0x5e, 0xa3, 0x2f, 0x49, 0x7f, 0x3e, - 0x44, 0x3e, 0x4c, 0x52, 0xd4, 0x2c, 0x66, 0x36, 0x27, 0x2b, 0xe0, 0x8f, 0x7e, 0xa9, 0x33, 0x66, - 0xc3, 0xdd, 0x9a, 0x88, 0xfe, 0x8d, 0x3e, 0x94, 0x45, 0x99, 0x78, 0x83, 0x4f, 0x2a, 0xe9, 0xfc, - 0xcb, 0xcc, 0x8c, 0x17, 0xe7, 0x2f, 0x73, 0x7c, 0x5d, 0xfc, 0xd2, 0xc0, 0xeb, 0xa2, 0x58, 0x1f, - 0xb7, 0x45, 0x60, 0x86, 0xdf, 0x45, 0x3e, 0x48, 0xf8, 0x8e, 0x09, 0xdb, 0x98, 0x60, 0x6c, 0xa7, - 0xb3, 0xb9, 0xcd, 0xcd, 0x4f, 0x8d, 0xaf, 0xd1, 0xf0, 0xd0, 0x01, 0x70, 0x60, 0xa8, 0xcb, 0x57, - 0x7a, 0x73, 0x5b, 0x5b, 0x1a, 0xe7, 0x51, 0xe4, 0x56, 0xc3, 0xc1, 0xbe, 0x65, 0xb7, 0x0c, 0x3f, - 0xd0, 0x49, 0xc2, 0x45, 0xf8, 0xe2, 0x78, 0x5d, 0x00, 0x81, 0xb2, 0x0e, 0x46, 0x17, 0x0f, 0x85, - 0x7e, 0x16, 0x99, 0xb8, 0xb7, 0xe6, 0x91, 0x7e, 0x88, 0x51, 0xb0, 0xfb, 0xbf, 0xc2, 0x9a, 0x86, - 0x6b, 0x5a, 0x9c, 0x8f, 0xca, 0x43, 0x82, 0x81, 0xc0, 0xf5, 0xe0, 0x32, 0x66, 0x3c, 0x62, 0x9b, - 0xe2, 0xa2, 0x17, 0x34, 0x5b, 0x90, 0xb6, 0x95, 0x8c, 0xa9, 0xad, 0xfe, 0xfb, 0xd8, 0x63, 0x7a, - 0xeb, 0x8e, 0x58, 0x8b, 0x65, 0xb3, 0x76, 0x00, 0x67, 0x7c, 0x0c, 0x2e, 0xbd, 0xa8, 0x14, 0x6f, - 0x84, 0x0e, 0x53, 0x40, 0x70, 0x07, 0x21, 0x11, 0xd2, 0xe9, 0xb4, 0xcb, 0x74, 0x25, 0xdf, 0x99, - 0xe2, 0x2b, 0x08, 0xa4, 0xce, 0x78, 0x03, 0xbd, 0xbb, 0xd1, 0x3b, 0xc6, 0x00, 0xe5, 0xfc, 0x3b, - 0xca, 0x37, 0x37, 0xd9, 0x93, 0xc9, 0x2f, 0x4e, 0x53, 0x27, 0xf0, 0xa0, 0x4f, 0xc2, 0xe4, 0xbd, - 0x1c, 0x58, 0x8d, 0xfc, 0x0e, 0x5d, 0x94, 0xbf, 0x7f, 0x47, 0x25, 0x1d, 0x11, 0x66, 0x90, 0x5a, - 0x9b, 0xa1, 0x02, 0x1c, 0xea, 0x0d, 0xa4, 0x09, 0xb4, 0x16, 0x5f, 0x5b, 0x59, 0x1e, 0xf3, 0xe6, - 0x81, 0xe6, 0xb6, 0x34, 0x8c, 0xb9, 0x77, 0x0b, 0x9b, 0xa7, 0x92, 0x2d, 0xdf, 0x81, 0x06, 0x4a, - 0x19, 0x94, 0xe0, 0xe8, 0x6d, 0x6d, 0xf4, 0xda, 0x36, 0x98, 0xf3, 0xe5, 0x52, 0x03, 0x13, 0x4f, - 0x93, 0xa2, 0x73, 0x96, 0x72, 0xb4, 0xf5, 0x05, 0xc3, 0x17, 0xb0, 0xbd, 0x5f, 0x92, 0x82, 0x04, - 0xe1, 0xcd, 0x09, 0xb8, 0xfa, 0x3e, 0x28, 0x37, 0xb4, 0x3e, 0x2a, 0xb6, 0xb8, 0xcb, 0xcd, 0x2f, - 0xb7, 0xf1, 0x3d, 0xe3, 0xbd, 0xb5, 0x22, 0xf1, 0x3d, 0x83, 0x7b, 0xab, 0xf8, 0xdd, 0x77, 0x07, - 0xfa, 0x76, 0xe2, 0xff, 0x02, 0x56, 0xec, 0xce, 0xa9, 0xe8, 0xc4, 0x00, 0x00 -}; diff --git a/wled00/html_ui.h b/wled00/html_ui.h deleted file mode 100644 index 84a71595f..000000000 --- a/wled00/html_ui.h +++ /dev/null @@ -1,2012 +0,0 @@ -/* - * Binary array for the Web UI. - * gzip is used for smaller size and improved speeds. - * - * Please see https://kno.wled.ge/advanced/custom-features/#changing-web-ui - * to find out how to easily modify the web UI source! - */ - -// Autogenerated from wled00/data/index.htm, do not edit!! -const uint16_t PAGE_index_L = 32000; -const uint8_t PAGE_index[] PROGMEM = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0xcc, 0xbd, 0xe9, 0x76, 0xe2, 0xc8, - 0xb2, 0x30, 0xfa, 0xdf, 0x4f, 0xa1, 0x52, 0xf5, 0x76, 0x41, 0x23, 0x83, 0x18, 0xcd, 0x50, 0xd8, - 0x1f, 0xc6, 0xf3, 0x6c, 0xe3, 0xb9, 0x4e, 0xad, 0x53, 0x02, 0x12, 0x90, 0x2d, 0x24, 0x59, 0x12, - 0x83, 0x4d, 0x73, 0x1e, 0xe3, 0x5b, 0xeb, 0xbe, 0xc0, 0xfd, 0x71, 0xef, 0x5b, 0xdd, 0x27, 0xb9, - 0x11, 0x99, 0x1a, 0x52, 0x42, 0x60, 0x57, 0xef, 0x3e, 0x67, 0x7d, 0xbd, 0x77, 0x19, 0x29, 0x87, - 0xc8, 0xcc, 0xc8, 0xc8, 0xc8, 0x88, 0xc8, 0xc8, 0xd0, 0xf7, 0x2f, 0xbb, 0x17, 0xcd, 0x9b, 0xc7, - 0xcb, 0x3d, 0x61, 0xe0, 0x0c, 0xb5, 0x2d, 0xe1, 0x3b, 0xfe, 0x08, 0x9a, 0xa2, 0xf7, 0xeb, 0x22, - 0xd1, 0x45, 0x4c, 0x20, 0x4a, 0x17, 0x7e, 0x86, 0xc4, 0x51, 0x04, 0x5d, 0x19, 0x92, 0xba, 0x38, - 0x56, 0xc9, 0xc4, 0x34, 0x2c, 0x47, 0x14, 0xd6, 0x3a, 0x86, 0xee, 0x10, 0xdd, 0xa9, 0x8b, 0x13, - 0xb5, 0xeb, 0x0c, 0xea, 0x5d, 0x32, 0x56, 0x3b, 0x64, 0x83, 0xbe, 0x48, 0xaa, 0xae, 0x3a, 0xaa, - 0xa2, 0x6d, 0xd8, 0x1d, 0x45, 0x23, 0xf5, 0xac, 0x34, 0x84, 0x84, 0xe1, 0x68, 0xe8, 0xbd, 0x8b, - 0x1e, 0xd0, 0xb5, 0xce, 0x40, 0xb1, 0x6c, 0x02, 0x40, 0x46, 0x4e, 0x6f, 0xa3, 0x2c, 0x86, 0x1b, - 0x73, 0x06, 0x64, 0x48, 0x36, 0x3a, 0x86, 0x66, 0x58, 0xa2, 0xe0, 0x37, 0xf7, 0x35, 0x47, 0xff, - 0xe3, 0x60, 0x78, 0x39, 0x6f, 0xc4, 0x16, 0xdd, 0xaa, 0x8a, 0x69, 0x6a, 0x64, 0x63, 0x68, 0xb4, - 0x55, 0xf8, 0x99, 0x90, 0xf6, 0x06, 0x24, 0x6c, 0x74, 0x14, 0x53, 0x69, 0x6b, 0x04, 0x6b, 0x6a, - 0xaa, 0xfe, 0x22, 0x58, 0x44, 0xab, 0x8b, 0xf6, 0x00, 0x86, 0xd3, 0x19, 0x39, 0x82, 0x0a, 0x70, - 0x60, 0x58, 0x03, 0x8b, 0xf4, 0xea, 0x62, 0x57, 0x71, 0x94, 0xaa, 0x3a, 0x54, 0xfa, 0x24, 0x33, - 0xdd, 0xc0, 0x9c, 0x5a, 0x5b, 0xb1, 0x49, 0xa9, 0x20, 0x35, 0x1a, 0x8d, 0x9d, 0x46, 0x63, 0xaf, - 0xb1, 0x07, 0x7f, 0xf1, 0xf7, 0xa0, 0xd1, 0x3c, 0xc0, 0xa7, 0xfd, 0x3e, 0xfc, 0x39, 0xd2, 0xae, - 0x6e, 0x5e, 0x3a, 0xe7, 0xcd, 0x81, 0x71, 0x82, 0x69, 0xbb, 0xb7, 0xda, 0xd1, 0xf5, 0xfe, 0x11, - 0x3e, 0x5e, 0xb1, 0xd2, 0x7d, 0x5a, 0xf6, 0x30, 0x73, 0x99, 0x79, 0xc4, 0x94, 0xbd, 0xec, 0xf1, - 0xf5, 0xde, 0xfe, 0xed, 0xc5, 0x51, 0xf6, 0x19, 0x92, 0x32, 0x97, 0x93, 0x8b, 0x69, 0xff, 0xfc, - 0x80, 0x34, 0x6e, 0xcf, 0xa6, 0x7b, 0x95, 0x83, 0x52, 0xe7, 0xaa, 0x79, 0xb2, 0x7b, 0xdf, 0x18, - 0x98, 0x8d, 0xdd, 0xa7, 0x5c, 0xaf, 0x7c, 0x79, 0xf6, 0xbc, 0xd3, 0xca, 0x5f, 0xdd, 0xcb, 0xe5, - 0xab, 0x93, 0x9c, 0x7c, 0xa2, 0x3c, 0x35, 0x73, 0xfd, 0x5e, 0xb3, 0x32, 0x68, 0xea, 0xaf, 0xc6, - 0xc8, 0x38, 0xef, 0x37, 0xae, 0xfb, 0x8f, 0x9b, 0xef, 0x67, 0xd3, 0xc6, 0xdb, 0xb9, 0x76, 0xdb, - 0xbd, 0x3a, 0xd4, 0x1e, 0xd4, 0x86, 0x76, 0x91, 0x3b, 0xdb, 0x6d, 0xec, 0x96, 0xf2, 0x7b, 0x77, - 0xaf, 0xe7, 0x87, 0x0d, 0x22, 0x37, 0x68, 0x47, 0xb4, 0xfd, 0x9b, 0x97, 0xd6, 0xe8, 0x6a, 0xd8, - 0x6c, 0x8a, 0x5b, 0x6b, 0xc2, 0x77, 0x47, 0x75, 0x34, 0xb2, 0x75, 0x7f, 0xba, 0xb7, 0xfb, 0x3d, - 0xc3, 0x9e, 0x85, 0xef, 0x76, 0xc7, 0x52, 0x4d, 0x67, 0x6b, 0xad, 0x37, 0xd2, 0x3b, 0x8e, 0x6a, - 0xe8, 0x42, 0x8f, 0x90, 0x6e, 0x5b, 0xe9, 0xbc, 0x24, 0x92, 0xb3, 0xf9, 0x58, 0xb1, 0x04, 0x98, - 0x72, 0xa3, 0x33, 0x1a, 0x02, 0xe6, 0xd3, 0x7d, 0xe2, 0xec, 0x69, 0x04, 0x1f, 0xed, 0x9d, 0xb7, - 0x1b, 0xa5, 0x7f, 0x0e, 0x73, 0x90, 0x10, 0x91, 0x7a, 0xc4, 0xe4, 0x0f, 0xf9, 0xa7, 0xa4, 0x05, - 0x45, 0x3b, 0x16, 0x51, 0x1c, 0xe2, 0x96, 0x4e, 0x88, 0xac, 0x15, 0x31, 0x59, 0xd3, 0xd2, 0xce, - 0x9b, 0xe9, 0x4e, 0x9c, 0xda, 0x51, 0xb0, 0xc5, 0xcc, 0xb3, 0x32, 0x56, 0xdc, 0x02, 0x92, 0x96, - 0xb6, 0xad, 0x4e, 0x5d, 0x54, 0x2d, 0x23, 0xfd, 0x6c, 0xe3, 0xab, 0xd2, 0xed, 0xee, 0x8d, 0x01, - 0xc6, 0xa9, 0x6a, 0xc3, 0xec, 0x13, 0x2b, 0x21, 0x6a, 0x06, 0xb4, 0x27, 0x91, 0xfa, 0xd6, 0xac, - 0x63, 0xaa, 0x9d, 0x97, 0xba, 0x4e, 0x26, 0x02, 0x96, 0x6f, 0x22, 0x01, 0x5d, 0x42, 0x0a, 0x16, - 0xfa, 0x6a, 0xd2, 0x07, 0x51, 0x9a, 0x51, 0x4a, 0xad, 0xe6, 0x4a, 0xb2, 0x34, 0x19, 0x10, 0xa2, - 0x9d, 0xaa, 0xfd, 0x81, 0xa3, 0x13, 0xdb, 0xae, 0x7e, 0xc9, 0xb2, 0x94, 0x86, 0xde, 0xd7, 0x48, - 0x35, 0xb7, 0xe9, 0x16, 0xd8, 0x55, 0x2d, 0x42, 0x31, 0x51, 0x15, 0x3b, 0x9a, 0xd1, 0x79, 0x99, - 0xa8, 0x36, 0x81, 0x8e, 0x28, 0x6f, 0xc6, 0xc8, 0xa9, 0xfe, 0x98, 0x75, 0x8c, 0xa1, 0x69, 0xe8, - 0xd0, 0xa1, 0x2a, 0xb6, 0x39, 0x52, 0xd3, 0xf7, 0x58, 0x49, 0x32, 0x4c, 0xac, 0x62, 0x57, 0x67, - 0xf3, 0xf9, 0xcf, 0x79, 0x52, 0xa2, 0x3d, 0x4b, 0x1b, 0x7a, 0x42, 0x54, 0x75, 0x13, 0xea, 0x11, - 0x1d, 0xba, 0x9c, 0x48, 0x42, 0x9f, 0x61, 0x15, 0xd0, 0x8e, 0x26, 0xb2, 0xc9, 0x50, 0x39, 0x4a, - 0xfe, 0x55, 0x58, 0x27, 0x7a, 0x9f, 0xb8, 0x45, 0x47, 0x26, 0x90, 0x27, 0xb9, 0x6c, 0x69, 0x6a, - 0x97, 0x58, 0x76, 0x02, 0xca, 0xd7, 0x70, 0x42, 0x9c, 0x8f, 0xb1, 0xec, 0x7c, 0x80, 0x65, 0x87, - 0x61, 0xd9, 0xc2, 0xc6, 0x1c, 0x63, 0xd4, 0x19, 0x50, 0x64, 0x3b, 0x2b, 0x91, 0x4d, 0x0b, 0xdb, - 0xf5, 0x6b, 0xfc, 0xb9, 0xa1, 0x75, 0x60, 0x28, 0x23, 0x33, 0xf1, 0x8d, 0x8e, 0xf0, 0x07, 0x6b, - 0x90, 0x16, 0x12, 0x7f, 0x7e, 0x93, 0x66, 0xd0, 0x59, 0x8d, 0x38, 0xd0, 0x59, 0x28, 0x75, 0x04, - 0x0b, 0xd7, 0x1a, 0x2b, 0x5a, 0x82, 0x0e, 0x4b, 0x44, 0x14, 0x42, 0x1e, 0x11, 0xeb, 0xf5, 0x60, - 0x28, 0x30, 0x92, 0xee, 0x5b, 0xcb, 0x81, 0xe1, 0xac, 0xaf, 0x27, 0x3a, 0x1a, 0x51, 0x2c, 0xbf, - 0x96, 0x93, 0x94, 0x0c, 0xfd, 0x14, 0x3a, 0x92, 0x48, 0x26, 0xe7, 0x52, 0x56, 0x96, 0x11, 0x73, - 0x00, 0xf6, 0x46, 0x1d, 0x12, 0x98, 0x14, 0x06, 0x75, 0x90, 0x86, 0xc1, 0x02, 0x9a, 0x9b, 0x03, - 0x55, 0xeb, 0x42, 0x95, 0x4f, 0x16, 0xd4, 0xdc, 0x82, 0x6b, 0xdf, 0x33, 0xee, 0x4a, 0x80, 0x25, - 0xe1, 0xbc, 0xc1, 0xd2, 0x58, 0xfb, 0x5f, 0x3d, 0x60, 0x38, 0x1b, 0x3d, 0xa5, 0x43, 0x66, 0xee, - 0xd3, 0x50, 0xd5, 0xde, 0xaa, 0xf7, 0x47, 0xc0, 0x26, 0xec, 0x1a, 0x20, 0xb0, 0x3a, 0xb2, 0xb4, - 0x04, 0xe5, 0x20, 0x98, 0x9f, 0x99, 0x18, 0xbd, 0x5e, 0xae, 0xe6, 0x71, 0x3a, 0xca, 0xe8, 0x3c, - 0x6e, 0xd2, 0x95, 0x2b, 0x07, 0x67, 0xfd, 0x06, 0xe5, 0x25, 0x8d, 0x86, 0x7e, 0xdb, 0x68, 0xd8, - 0x6c, 0x81, 0x66, 0xf1, 0xef, 0x70, 0xbf, 0xd1, 0x38, 0x78, 0x1a, 0xf6, 0x1b, 0x4b, 0xff, 0xdb, - 0x19, 0x36, 0x1a, 0xfd, 0x87, 0xc9, 0x75, 0xb3, 0xf1, 0xda, 0x79, 0x3c, 0x7e, 0x3a, 0x6a, 0xdc, - 0x3c, 0x36, 0x8f, 0x1b, 0xe7, 0x93, 0xe6, 0xbb, 0xd1, 0xd8, 0x69, 0x02, 0x53, 0x9a, 0x3c, 0x1e, - 0x1e, 0xed, 0xd8, 0x9b, 0xbb, 0x65, 0xf5, 0x62, 0xf2, 0xde, 0x1f, 0xe6, 0xcf, 0x1e, 0xce, 0xf4, - 0xf7, 0xa7, 0xe6, 0x8b, 0xa3, 0x3f, 0x77, 0xda, 0xe7, 0xa9, 0x2b, 0xed, 0xf8, 0x54, 0x39, 0xce, - 0x8f, 0xb4, 0xdb, 0x53, 0x53, 0x33, 0xef, 0x4b, 0xb7, 0xaf, 0xf7, 0xaa, 0x41, 0x5a, 0x95, 0xec, - 0xf1, 0x1b, 0x91, 0x9f, 0x6f, 0xb5, 0xe3, 0xc9, 0x93, 0x55, 0xd4, 0x6f, 0xba, 0x7b, 0xf9, 0x53, - 0xdd, 0xe9, 0x5e, 0x8e, 0x1b, 0xfd, 0x54, 0xcf, 0xc9, 0xf4, 0xda, 0xf6, 0xa9, 0x7d, 0xa0, 0x9d, - 0x9f, 0x8e, 0x06, 0xda, 0xf0, 0xea, 0xf9, 0x44, 0xdd, 0x3c, 0xbf, 0xdc, 0xdd, 0x3b, 0xea, 0x4f, - 0x6e, 0x86, 0xc0, 0xc5, 0x94, 0xd2, 0xb0, 0xab, 0xa5, 0x5a, 0x87, 0xb7, 0x3b, 0x83, 0xbd, 0xa3, - 0xee, 0xe1, 0xfe, 0x54, 0x79, 0xd9, 0xb4, 0x0b, 0x7b, 0x99, 0xb7, 0xf7, 0xc1, 0x71, 0xeb, 0xb9, - 0xb9, 0xb9, 0x73, 0x75, 0x75, 0xda, 0xdb, 0x9d, 0x18, 0xe6, 0x7e, 0x46, 0x2d, 0x29, 0xaf, 0xad, - 0x3d, 0x6d, 0x6f, 0x7f, 0xf7, 0x61, 0x5a, 0x7e, 0xba, 0xbb, 0x7f, 0x7e, 0xcb, 0x5b, 0x6f, 0xc3, - 0xc2, 0x79, 0x69, 0x5f, 0x7b, 0xba, 0x2a, 0x0c, 0x46, 0x29, 0xfd, 0xc1, 0x3e, 0x38, 0xda, 0x3d, - 0xbb, 0xda, 0xcf, 0xf7, 0x1b, 0x53, 0x25, 0x5b, 0x68, 0xf4, 0x1b, 0x96, 0x73, 0x77, 0x36, 0xe8, - 0xbd, 0xf4, 0x9f, 0x7b, 0x7b, 0x8d, 0xb6, 0xda, 0x1c, 0x4c, 0x46, 0xad, 0xa3, 0xc9, 0xde, 0x6d, - 0x73, 0x38, 0xea, 0x5e, 0x0e, 0xd4, 0xab, 0xee, 0x4d, 0xc9, 0x1a, 0x1f, 0x3d, 0x9f, 0xb6, 0xae, - 0x9f, 0xf6, 0x26, 0xbb, 0x83, 0xfd, 0xca, 0xce, 0x91, 0x6d, 0x18, 0x47, 0xc5, 0xfc, 0xcd, 0xd1, - 0xf5, 0x91, 0x71, 0x74, 0xbb, 0x5b, 0x7e, 0x79, 0x3b, 0x7f, 0x3a, 0xda, 0xbc, 0x7d, 0x6e, 0xbc, - 0x9d, 0x59, 0xd7, 0x19, 0xe5, 0x2c, 0xb3, 0x3b, 0x51, 0x2e, 0x4c, 0xe3, 0x5d, 0x19, 0x54, 0x4e, - 0x0f, 0x9a, 0xf6, 0x63, 0xee, 0xfd, 0x3c, 0xf7, 0x78, 0xf1, 0x6e, 0xe7, 0x4e, 0xf3, 0xd3, 0x57, - 0x72, 0x6e, 0x16, 0xde, 0x1f, 0x9e, 0x5f, 0xcb, 0xed, 0x87, 0x9b, 0xcc, 0xe0, 0x6c, 0xe7, 0xf4, - 0x39, 0x53, 0xcc, 0x3f, 0xee, 0x36, 0x8e, 0x5a, 0xa9, 0xcd, 0x51, 0xa9, 0x54, 0xd6, 0xf3, 0x87, - 0xa9, 0xc3, 0xeb, 0xcb, 0xee, 0x53, 0x37, 0x3b, 0xca, 0xdf, 0xbc, 0x77, 0xaf, 0x9f, 0xba, 0x77, - 0x67, 0x37, 0xbd, 0x23, 0xad, 0x78, 0xd8, 0x3b, 0xe9, 0x77, 0xb3, 0xed, 0xcd, 0xd6, 0xf8, 0xb5, - 0x5b, 0xb9, 0xaf, 0x8c, 0x4c, 0xab, 0x7b, 0x59, 0xbe, 0xba, 0xb9, 0x18, 0x12, 0xe5, 0xbd, 0x78, - 0x73, 0x79, 0x71, 0x7d, 0xac, 0xed, 0xee, 0x3e, 0x1f, 0xde, 0x3d, 0x1f, 0xc8, 0x8d, 0xf3, 0xb3, - 0xab, 0x47, 0x7b, 0x78, 0x6d, 0x9d, 0x68, 0x43, 0xf3, 0xed, 0xf5, 0x6e, 0xf3, 0x65, 0xd4, 0x3e, - 0xba, 0x6a, 0xe6, 0x0e, 0x5a, 0x47, 0x2f, 0xfb, 0xad, 0xd4, 0x99, 0x4e, 0x9a, 0xc7, 0x85, 0xf2, - 0xf1, 0xf1, 0xfe, 0x5d, 0x73, 0x70, 0xd5, 0x1b, 0x4d, 0x4e, 0xce, 0xcc, 0xdc, 0xdb, 0x6d, 0xc5, - 0x1c, 0xbe, 0x66, 0xef, 0x4e, 0x6e, 0xaf, 0x4b, 0x16, 0x71, 0xe4, 0x03, 0x53, 0x6e, 0x3d, 0xdf, - 0x3d, 0x5e, 0x5f, 0xef, 0xa7, 0x1e, 0x9e, 0x37, 0x53, 0x17, 0xea, 0x6d, 0xeb, 0x25, 0x73, 0x70, - 0xf4, 0x3e, 0xca, 0x0e, 0xd5, 0xc3, 0xa7, 0xfb, 0x69, 0xaa, 0x5f, 0x7e, 0xcc, 0x5e, 0xdf, 0xbe, - 0x38, 0x97, 0xc3, 0xd7, 0x23, 0xd5, 0xb9, 0xbe, 0x79, 0xb8, 0x3b, 0x7f, 0x7f, 0x6f, 0x3a, 0xa3, - 0xfd, 0xcb, 0x93, 0xce, 0xa1, 0xfc, 0x7e, 0xbd, 0x73, 0x90, 0x7a, 0xac, 0x64, 0x9a, 0xfa, 0x60, - 0x47, 0xc9, 0xc9, 0xe3, 0xa2, 0x71, 0xd8, 0xb3, 0xf7, 0x6e, 0xcf, 0xfa, 0x0f, 0x67, 0x97, 0x7b, - 0xbd, 0x8b, 0xe2, 0x53, 0xe7, 0x78, 0x2a, 0xef, 0x1f, 0x5d, 0xaa, 0x77, 0x6f, 0x93, 0xfe, 0x73, - 0xbb, 0x74, 0x76, 0x34, 0xba, 0x4b, 0x19, 0x4f, 0x85, 0x71, 0xee, 0xe5, 0xa5, 0x94, 0x79, 0xd7, - 0x8f, 0xa6, 0xbb, 0x27, 0x56, 0x7f, 0x74, 0x96, 0xcb, 0xbd, 0xa5, 0xda, 0xf7, 0xe5, 0xc9, 0xed, - 0xc1, 0xab, 0xba, 0xa9, 0x9c, 0x96, 0x7b, 0x57, 0xc7, 0xef, 0x13, 0xbd, 0xf9, 0x5c, 0x76, 0x8e, - 0x4c, 0xb3, 0x7b, 0x54, 0x69, 0x3f, 0xee, 0xb6, 0xee, 0x8e, 0xef, 0x9a, 0x57, 0x47, 0xba, 0x6a, - 0xde, 0xcb, 0x87, 0x6d, 0xa7, 0xa3, 0x75, 0x6e, 0x36, 0xc7, 0xcd, 0xb7, 0xd3, 0xe1, 0x83, 0xd2, - 0xba, 0xb3, 0xae, 0x5a, 0xe7, 0x67, 0x6f, 0x6d, 0xe5, 0xf8, 0x78, 0x67, 0x90, 0xbb, 0x54, 0x1f, - 0xac, 0x87, 0x76, 0xbf, 0x5b, 0x6a, 0xb4, 0x5f, 0x49, 0xa7, 0xbb, 0x7b, 0x73, 0x51, 0xd9, 0xbb, - 0xda, 0x3b, 0x22, 0xf7, 0xf2, 0xdd, 0xe5, 0xfd, 0x55, 0xa7, 0x7b, 0x55, 0xd6, 0x9c, 0xcb, 0x8b, - 0xbd, 0x51, 0x6a, 0xb3, 0xf4, 0x9a, 0x3b, 0x9a, 0xde, 0xde, 0x18, 0xc7, 0xe4, 0xde, 0xec, 0x3d, - 0x5f, 0xa9, 0x87, 0x87, 0x87, 0x45, 0x58, 0x4a, 0xbb, 0xa7, 0xcf, 0xd9, 0xf6, 0x61, 0xff, 0x6a, - 0xfa, 0x60, 0xdf, 0xc2, 0x80, 0x4e, 0x1e, 0xdb, 0xfd, 0x54, 0x73, 0x0a, 0xff, 0x2b, 0x55, 0xc8, - 0x61, 0xe7, 0x62, 0x0c, 0x2c, 0xfa, 0x38, 0xab, 0x95, 0xda, 0xb2, 0xbe, 0xbb, 0xf9, 0x7c, 0x90, - 0x6a, 0xb7, 0x1a, 0xd9, 0x6e, 0xf3, 0xe9, 0x6e, 0x3a, 0x9c, 0x94, 0x9f, 0x8e, 0x33, 0x47, 0x8f, - 0xce, 0xf4, 0xd2, 0x69, 0x1f, 0x4f, 0x35, 0xf3, 0x2a, 0x73, 0x7a, 0xf0, 0xdc, 0x7a, 0x95, 0xe5, - 0x9b, 0x61, 0xf7, 0xfc, 0xe8, 0x69, 0x6a, 0x1d, 0x10, 0x2d, 0xf5, 0x96, 0xb2, 0x9e, 0x8e, 0x2d, - 0x23, 0xa5, 0xdf, 0x0e, 0xf2, 0x97, 0xd6, 0xf9, 0xd1, 0xc1, 0xe4, 0xa4, 0x74, 0x6f, 0x3d, 0x9c, - 0x9f, 0xdd, 0xe5, 0xa6, 0x37, 0xe4, 0xfa, 0xfe, 0xb0, 0xf5, 0xdc, 0xea, 0xbc, 0x38, 0xa7, 0xc7, - 0x3d, 0x92, 0xb5, 0x3a, 0x9b, 0xb6, 0xf9, 0x36, 0x7e, 0xc9, 0xb7, 0x4b, 0x77, 0x85, 0x97, 0x42, - 0xb9, 0x65, 0xe5, 0x1b, 0xc3, 0xec, 0xe5, 0x38, 0x73, 0xa5, 0xf6, 0x06, 0xf6, 0x51, 0x6e, 0x74, - 0x36, 0xee, 0x94, 0x4b, 0xf9, 0x0b, 0xf5, 0xea, 0xea, 0xfa, 0xdc, 0x20, 0x5d, 0xf3, 0xb2, 0x77, - 0xa8, 0xb7, 0x26, 0x1d, 0xe0, 0x86, 0x29, 0x65, 0x77, 0x6f, 0xaf, 0xb4, 0xd9, 0x39, 0x79, 0xbf, - 0xe9, 0xef, 0x68, 0x57, 0xfd, 0x67, 0xf3, 0xb9, 0x7f, 0xb3, 0xab, 0x1f, 0x3b, 0x07, 0xfa, 0x43, - 0xee, 0xb5, 0x3d, 0x7c, 0x38, 0x2e, 0xed, 0x5f, 0xec, 0x9c, 0x3e, 0x6d, 0x4e, 0x6c, 0x2b, 0x75, - 0xfc, 0xf4, 0xfe, 0xa8, 0xb7, 0x9f, 0xbb, 0xed, 0x97, 0xe6, 0x68, 0xaf, 0x77, 0x2b, 0x1f, 0x8e, - 0xb5, 0xc9, 0x6b, 0xdb, 0xb9, 0xed, 0x1f, 0x6f, 0xbe, 0x5f, 0x3f, 0xec, 0x9f, 0x1f, 0xdb, 0xe3, - 0xd6, 0x54, 0x9b, 0xbc, 0xe7, 0xee, 0x1f, 0x1d, 0xa5, 0x30, 0x7d, 0xb6, 0xd4, 0x4c, 0xcf, 0x1e, - 0x69, 0xba, 0xbe, 0x7f, 0x77, 0xf9, 0x66, 0xe8, 0xe6, 0xa5, 0x7c, 0x7d, 0x5a, 0x34, 0xee, 0xce, - 0x4f, 0x5e, 0x5e, 0x7a, 0x7b, 0xda, 0x41, 0xa1, 0x63, 0xdf, 0xec, 0x9e, 0x37, 0xec, 0xfe, 0x7b, - 0x33, 0x5f, 0x3e, 0xd8, 0xec, 0xb7, 0x4e, 0xee, 0xfa, 0xad, 0xa7, 0xcd, 0x61, 0xa6, 0xb3, 0x37, - 0x3e, 0x69, 0x9c, 0x0e, 0xa7, 0x27, 0xef, 0x99, 0xcc, 0x68, 0x73, 0x50, 0x22, 0xfd, 0xc3, 0xfd, - 0xcd, 0x33, 0xeb, 0xb0, 0xf0, 0x7c, 0x6c, 0x66, 0x9e, 0xa6, 0x85, 0xd7, 0x7c, 0x4e, 0x29, 0xdf, - 0x6c, 0x66, 0xa7, 0xfa, 0xe1, 0xdd, 0x75, 0xf3, 0x40, 0xeb, 0xed, 0x3f, 0x9d, 0x3b, 0x4e, 0x37, - 0xb7, 0xdf, 0xb9, 0x55, 0x94, 0xb7, 0x12, 0xa9, 0x5c, 0xbe, 0x0c, 0x46, 0x9d, 0xb7, 0x6b, 0xd9, - 0xb8, 0x1c, 0x65, 0xdf, 0xb3, 0xef, 0x99, 0xdd, 0x9d, 0x54, 0x79, 0xa2, 0x4e, 0x1b, 0xfb, 0xdd, - 0xb3, 0xdb, 0x6c, 0x5f, 0x1f, 0xee, 0x14, 0xa6, 0x8d, 0x49, 0xa9, 0x6c, 0x4e, 0x0e, 0x3b, 0xf7, - 0xcf, 0xda, 0xbe, 0xb5, 0xa3, 0x3f, 0x4c, 0x4f, 0x9f, 0x9f, 0x4b, 0xf9, 0xdb, 0x83, 0xfe, 0xf8, - 0xfc, 0xe0, 0xee, 0xa0, 0x71, 0xbc, 0xff, 0x3e, 0xdd, 0x9f, 0xa4, 0xee, 0x8d, 0xa1, 0xbe, 0x79, - 0xd6, 0x50, 0xdb, 0x77, 0xed, 0x51, 0x49, 0x23, 0x87, 0xd7, 0x3b, 0x45, 0xbb, 0x93, 0x95, 0x7b, - 0xa7, 0x4e, 0xdb, 0xea, 0x5a, 0x99, 0xe3, 0xd7, 0xbb, 0xd2, 0xa3, 0x95, 0x32, 0xc6, 0x93, 0x7d, - 0xe7, 0xfa, 0x70, 0x6f, 0xf3, 0xac, 0xf0, 0x7e, 0x50, 0x91, 0x5f, 0xcf, 0x77, 0x4a, 0x8f, 0xd7, - 0x7b, 0x86, 0x51, 0xcc, 0xbe, 0xec, 0x1f, 0x2b, 0xed, 0xd7, 0xfc, 0x39, 0x39, 0xbc, 0x3b, 0xe9, - 0x92, 0x5e, 0x66, 0x60, 0x9f, 0xed, 0xef, 0xb7, 0x4c, 0xa7, 0x38, 0x2c, 0x3f, 0x0c, 0x8f, 0x5f, - 0x77, 0x77, 0x1b, 0xfa, 0xb5, 0xdc, 0x29, 0x64, 0xcb, 0xc3, 0xe9, 0x70, 0x6a, 0x5d, 0xbd, 0x5f, - 0x8d, 0xde, 0x2e, 0x75, 0xdb, 0xbc, 0x9e, 0xf4, 0x1a, 0x8f, 0x2f, 0xa6, 0x33, 0x78, 0xb7, 0x00, - 0x2d, 0x37, 0xd9, 0xe9, 0x79, 0xab, 0x57, 0xb8, 0x77, 0x76, 0xce, 0xce, 0x2a, 0xbb, 0x57, 0x37, - 0xd9, 0xca, 0xe8, 0x34, 0xd5, 0x6f, 0x17, 0x36, 0xfb, 0xfb, 0xa7, 0x97, 0xf9, 0xce, 0x8d, 0x5c, - 0xde, 0x2f, 0x1f, 0x15, 0xba, 0x4f, 0xd3, 0x63, 0xad, 0x90, 0x3d, 0xb0, 0xa7, 0x95, 0xfb, 0xc3, - 0xf7, 0xd3, 0x9d, 0x8b, 0xc3, 0xf7, 0xfb, 0xe7, 0xeb, 0x56, 0xe5, 0xfc, 0xb4, 0x79, 0x71, 0xbb, - 0xd3, 0xdc, 0xbf, 0x4a, 0x8d, 0x0e, 0x06, 0x3b, 0x99, 0xbb, 0xcd, 0xa7, 0xf7, 0xdb, 0xc9, 0xc9, - 0x5e, 0xeb, 0x66, 0xb8, 0x6b, 0xa9, 0xc7, 0xa9, 0x5b, 0xa4, 0xfd, 0x4c, 0x7b, 0xff, 0x61, 0xff, - 0xec, 0xf4, 0xd4, 0x7e, 0xee, 0xab, 0x0d, 0xa7, 0x60, 0x9a, 0x9b, 0x23, 0xcd, 0x9c, 0xb6, 0x73, - 0xce, 0xfb, 0x5e, 0xf9, 0xa8, 0x3c, 0x1d, 0xbc, 0x1d, 0x5e, 0xec, 0xee, 0x9c, 0xe4, 0x5b, 0x07, - 0xfd, 0xd2, 0xd5, 0x65, 0x36, 0xb7, 0xa3, 0x5e, 0xe6, 0x1f, 0xcf, 0x26, 0x39, 0x6b, 0x77, 0xdf, - 0xb9, 0xbf, 0xdd, 0x7d, 0x38, 0x4d, 0x11, 0x5b, 0x1f, 0xe7, 0x0f, 0x2b, 0x57, 0xd3, 0xd7, 0xde, - 0xb0, 0xbd, 0xab, 0xb7, 0xcf, 0x4e, 0x9f, 0x0f, 0x6e, 0xf7, 0xcd, 0xd7, 0xd7, 0xa7, 0xb6, 0x7e, - 0xdf, 0xea, 0xcb, 0xda, 0xe0, 0x7e, 0x5c, 0x99, 0xdc, 0xe6, 0x8b, 0xaf, 0x37, 0x87, 0xaf, 0x97, - 0x95, 0xf7, 0xd7, 0x5b, 0xeb, 0x74, 0xf3, 0xe5, 0xf5, 0xe4, 0xb9, 0xfc, 0xf8, 0xfc, 0xf4, 0xde, - 0x97, 0xb3, 0x66, 0xbb, 0x92, 0x7a, 0xbb, 0x2a, 0xdb, 0x0f, 0x4f, 0xe6, 0xe3, 0xf4, 0xe4, 0x40, - 0xdd, 0x3f, 0xbe, 0x39, 0xb7, 0x8f, 0x26, 0x13, 0xf3, 0xed, 0xba, 0x50, 0xe8, 0xef, 0x5d, 0xe8, - 0x77, 0x99, 0x14, 0x01, 0x42, 0xea, 0x1e, 0xee, 0x66, 0x72, 0xda, 0x55, 0x7e, 0xd4, 0x2a, 0xbe, - 0x65, 0x5f, 0xdf, 0x8f, 0xde, 0x9d, 0x87, 0xdb, 0xf3, 0xcb, 0xbd, 0x92, 0xd1, 0x7d, 0x3c, 0x96, - 0x2f, 0x5f, 0x6f, 0xd5, 0xfb, 0x63, 0xa7, 0x7f, 0x72, 0x70, 0x72, 0x76, 0x74, 0xfa, 0x58, 0x92, - 0xbb, 0x53, 0xf2, 0xf8, 0xa6, 0xb7, 0xdb, 0x29, 0x7b, 0xff, 0xe4, 0xe4, 0xf5, 0x5c, 0x97, 0xef, - 0xdf, 0x73, 0xd6, 0xa9, 0x73, 0xd6, 0xde, 0xb9, 0xba, 0xbf, 0xd4, 0x1f, 0x9d, 0xe1, 0xb1, 0x52, - 0xb8, 0x7f, 0xdd, 0xbf, 0x36, 0xda, 0x99, 0xca, 0x70, 0x38, 0x7a, 0xeb, 0x5c, 0xdd, 0x8d, 0x37, - 0xd5, 0x5e, 0xf3, 0x7c, 0xfc, 0x60, 0x69, 0x83, 0xf7, 0xfe, 0xee, 0xe9, 0xee, 0x18, 0x84, 0xf0, - 0x54, 0xf9, 0xb0, 0x38, 0x7d, 0x3e, 0xa9, 0x14, 0xca, 0x9d, 0x5d, 0xe2, 0xa4, 0xf6, 0x95, 0x87, - 0x5e, 0x2b, 0x75, 0xfa, 0x62, 0x64, 0xee, 0x9d, 0xd4, 0xb8, 0xd5, 0x79, 0x55, 0xac, 0xd7, 0xd2, - 0xcb, 0xd3, 0x4d, 0xfb, 0xa5, 0x70, 0xae, 0x9c, 0xbc, 0x9a, 0x17, 0xed, 0x97, 0xbd, 0x3d, 0xd3, - 0x56, 0x3a, 0x95, 0xd3, 0xac, 0x75, 0x7d, 0xfe, 0x70, 0xdc, 0xbf, 0x6c, 0x5b, 0xf7, 0x6f, 0xbb, - 0xdd, 0xc7, 0x67, 0x52, 0x72, 0x76, 0xae, 0x1a, 0xef, 0xce, 0x4b, 0xfb, 0xb1, 0x29, 0x4f, 0x76, - 0x49, 0xe1, 0x56, 0x3f, 0x57, 0xcd, 0xa1, 0xfe, 0x04, 0xd2, 0xca, 0x28, 0x33, 0x7a, 0xee, 0x95, - 0x4e, 0x7a, 0x9b, 0x63, 0x92, 0xcd, 0xe6, 0x0e, 0x47, 0xbd, 0x4a, 0x6e, 0x6f, 0x9c, 0xd9, 0x24, - 0xfa, 0x4e, 0x26, 0xa5, 0x5f, 0x6e, 0x9a, 0x6d, 0x10, 0x33, 0xaf, 0x8e, 0x9f, 0xda, 0xaa, 0xfc, - 0xdc, 0x6c, 0x99, 0xc6, 0x79, 0x05, 0x06, 0x7e, 0xf3, 0xf2, 0xbc, 0x79, 0x7c, 0x36, 0x31, 0xdb, - 0xf7, 0x7d, 0xc3, 0x6c, 0xb4, 0x07, 0x4e, 0xfb, 0xe2, 0xfe, 0xe5, 0xcd, 0x69, 0xec, 0xe7, 0x4f, - 0x52, 0x99, 0x57, 0x43, 0x6e, 0x35, 0x5a, 0xe7, 0xf7, 0xb9, 0x83, 0x5c, 0xfb, 0xb4, 0xa7, 0xdb, - 0x03, 0x73, 0xa7, 0xa0, 0x54, 0xba, 0xc3, 0xf7, 0xcd, 0xcc, 0xe1, 0x34, 0x93, 0xe9, 0x76, 0xf2, - 0x17, 0x0f, 0xe7, 0x4f, 0x05, 0xa0, 0xd5, 0xb7, 0x87, 0xdb, 0xbb, 0x5c, 0xf7, 0xf1, 0xda, 0xde, - 0xad, 0x6c, 0xbe, 0x9e, 0x9c, 0x6e, 0x56, 0x5e, 0x95, 0xf7, 0x11, 0x0c, 0xed, 0x28, 0x3b, 0xbe, - 0x7c, 0xb8, 0xd9, 0xcc, 0x6f, 0x16, 0xdb, 0xf7, 0xad, 0x03, 0xa3, 0xb3, 0x63, 0xf4, 0x76, 0x73, - 0xe4, 0xe8, 0xfa, 0xfd, 0x58, 0xee, 0x9c, 0x35, 0x65, 0x90, 0xd6, 0x26, 0x57, 0x72, 0xbf, 0x37, - 0x1e, 0xb5, 0xba, 0xe3, 0x6e, 0xb6, 0xd0, 0xcb, 0x8e, 0x80, 0xea, 0x4f, 0x2f, 0xf7, 0xf2, 0xc7, - 0xc7, 0x87, 0xa7, 0xa5, 0x51, 0xb3, 0x9b, 0xd1, 0x8b, 0x7a, 0xb9, 0x9b, 0x2f, 0xde, 0x5e, 0x9c, - 0x5c, 0xea, 0x25, 0x7d, 0x60, 0xc1, 0x06, 0x69, 0xdd, 0xe5, 0x95, 0x6e, 0x5e, 0x7f, 0xcf, 0xa9, - 0x37, 0xea, 0xf9, 0x69, 0x21, 0x5b, 0xd8, 0xd3, 0x49, 0xef, 0x34, 0x73, 0x7c, 0x70, 0xaa, 0xdd, - 0x3f, 0x39, 0x4f, 0xf7, 0xca, 0xab, 0xb1, 0x37, 0x28, 0x4c, 0x5b, 0xcf, 0x63, 0xfb, 0xa0, 0x9d, - 0x29, 0x0d, 0x2b, 0x96, 0xb2, 0xaf, 0xd9, 0xa7, 0xc3, 0xc2, 0xe8, 0xf0, 0xe5, 0xea, 0x5e, 0x1b, - 0x6f, 0xde, 0x64, 0x26, 0xe4, 0xe9, 0xfd, 0xf9, 0xf0, 0x90, 0x6c, 0x4e, 0x9f, 0xd4, 0xdb, 0x77, - 0xf3, 0xb8, 0x78, 0xdf, 0xb8, 0xdf, 0x39, 0xdd, 0x3d, 0x9f, 0x5c, 0x9f, 0x4c, 0x27, 0xd7, 0x8f, - 0xfa, 0xbe, 0xf1, 0x70, 0x30, 0xed, 0x28, 0x27, 0xd3, 0xf3, 0xd2, 0xee, 0x75, 0x79, 0xe7, 0x5c, - 0xcf, 0x19, 0x95, 0xf3, 0x57, 0x98, 0x61, 0x67, 0x6c, 0x29, 0xc5, 0x1b, 0xfd, 0xe8, 0xf9, 0xe1, - 0x6c, 0x47, 0x1b, 0x1e, 0xed, 0x3f, 0xe5, 0xdf, 0x2e, 0x1f, 0x1f, 0xf2, 0x67, 0x4e, 0x65, 0x5c, - 0x1c, 0x0e, 0x0f, 0x47, 0x93, 0xc7, 0xf1, 0x78, 0x7a, 0x39, 0x26, 0xd6, 0x69, 0x85, 0xb4, 0xc6, - 0xf6, 0xfb, 0xc3, 0xf9, 0xf3, 0xed, 0x83, 0xf5, 0xd2, 0x7e, 0xed, 0x1c, 0x5c, 0xdc, 0xdd, 0xe7, - 0xda, 0x7b, 0xed, 0xdd, 0x83, 0x13, 0x35, 0x7f, 0x76, 0x7a, 0x77, 0x73, 0xff, 0xfe, 0x7e, 0x7f, - 0xb8, 0x5f, 0x2c, 0xec, 0x8c, 0x32, 0x39, 0xab, 0x91, 0x7d, 0x7d, 0x31, 0x4a, 0x5a, 0xa5, 0xb7, - 0xdf, 0xbf, 0x6b, 0xef, 0x8c, 0xac, 0xde, 0xdd, 0xce, 0xfd, 0xfe, 0xbe, 0x76, 0x77, 0x9f, 0x1d, - 0xf5, 0xa7, 0x17, 0x93, 0x8e, 0x9d, 0x2a, 0xdf, 0x67, 0x32, 0xc0, 0x9f, 0x9e, 0x8e, 0x55, 0x72, - 0xaa, 0x55, 0xee, 0x1f, 0x1a, 0x65, 0x72, 0x70, 0x5a, 0xec, 0x58, 0x3b, 0x9b, 0xbd, 0xc1, 0xc5, - 0xd9, 0xdb, 0x54, 0x2b, 0xb7, 0x9f, 0xaf, 0xee, 0x0f, 0x9e, 0x77, 0xb2, 0xed, 0xfb, 0x8c, 0xf1, - 0x52, 0xba, 0xed, 0xbc, 0x12, 0xdd, 0xb6, 0x36, 0xf7, 0xcb, 0x87, 0x9b, 0x23, 0xc7, 0x1e, 0x76, - 0x5f, 0x8d, 0xc3, 0xe1, 0x7b, 0xa5, 0x62, 0x8d, 0xdf, 0xc8, 0x5e, 0xe6, 0xf2, 0x1d, 0x04, 0x84, - 0xc2, 0x70, 0x7c, 0xf7, 0x70, 0xfa, 0xfc, 0xf6, 0x58, 0x1e, 0x97, 0x9f, 0x8b, 0x0f, 0x83, 0x27, - 0x72, 0x98, 0x57, 0x2e, 0x1f, 0x36, 0x8b, 0x5d, 0x53, 0xbd, 0x28, 0x92, 0xf3, 0xcc, 0xc5, 0xfb, - 0xa4, 0x73, 0xb0, 0xf9, 0xfe, 0xd2, 0xd3, 0x9c, 0x8c, 0xdd, 0x2d, 0x92, 0xcd, 0xc7, 0xce, 0x6b, - 0xfb, 0xc2, 0x98, 0xf4, 0xae, 0xfb, 0xb9, 0xdc, 0x75, 0xb1, 0x58, 0x2e, 0x2a, 0x4e, 0x6e, 0xfc, - 0xf0, 0x50, 0xde, 0xbc, 0xcf, 0x3e, 0xca, 0xfd, 0x2b, 0x79, 0xb3, 0x52, 0xa8, 0x6c, 0x92, 0xc7, - 0x9b, 0xec, 0xde, 0xcb, 0x9b, 0xb1, 0xf7, 0x7a, 0xf6, 0x08, 0x32, 0xe0, 0x61, 0xb7, 0x7c, 0x35, - 0x3e, 0x39, 0xb0, 0xae, 0x0f, 0x4a, 0xed, 0xe3, 0xc7, 0x9b, 0xdd, 0x66, 0xf3, 0xe9, 0xf1, 0x60, - 0xef, 0xbe, 0x33, 0x2c, 0x1e, 0x64, 0x01, 0x8d, 0x39, 0xb5, 0x58, 0x78, 0xac, 0xdc, 0x3b, 0xea, - 0xce, 0xe8, 0x45, 0xbb, 0x2c, 0x6e, 0x3e, 0x3a, 0x3b, 0x4f, 0x67, 0x8d, 0x7b, 0x6d, 0x94, 0xeb, - 0x3d, 0xbe, 0xef, 0x9e, 0x6d, 0x5e, 0xa5, 0x8a, 0xfb, 0xc0, 0xc9, 0x5b, 0xf9, 0x8b, 0xf7, 0xe2, - 0x33, 0xec, 0x61, 0x47, 0x4a, 0xc7, 0x69, 0xdf, 0x5f, 0x1a, 0x93, 0xd1, 0x55, 0xff, 0xfc, 0xed, - 0x50, 0x1b, 0x9d, 0x68, 0xca, 0xa4, 0x32, 0xd1, 0xdb, 0x17, 0x43, 0x67, 0xa4, 0x3c, 0x1b, 0x99, - 0xbb, 0xd6, 0xa4, 0x02, 0x1c, 0xb9, 0x75, 0x3d, 0x39, 0xeb, 0x8c, 0x80, 0x2c, 0x9f, 0x26, 0xfb, - 0x83, 0x41, 0xc9, 0xde, 0x1c, 0xd8, 0xaf, 0x96, 0x7a, 0xdf, 0xb4, 0xfb, 0x8d, 0x9c, 0x9d, 0xd7, - 0xf7, 0x41, 0x6c, 0x2e, 0x1c, 0x6d, 0x5e, 0xa4, 0x14, 0x7b, 0x3a, 0x99, 0x3e, 0xb5, 0x9d, 0xd3, - 0x53, 0x39, 0xbf, 0x57, 0x69, 0x0f, 0x3a, 0xd7, 0xa5, 0xc7, 0xf7, 0xca, 0xf0, 0xa8, 0xbd, 0x2f, - 0xdf, 0x56, 0x4a, 0x27, 0xf2, 0xf4, 0xa0, 0xb1, 0xd9, 0x9e, 0x56, 0xde, 0x52, 0x5a, 0x2e, 0x93, - 0xd9, 0xcc, 0x3f, 0xa7, 0x0e, 0x73, 0xaa, 0xbc, 0x77, 0xd0, 0xcd, 0x6d, 0x8e, 0x1a, 0x77, 0xe7, - 0x47, 0x99, 0xfb, 0x41, 0xf3, 0x71, 0x74, 0xff, 0x7a, 0xb4, 0xab, 0x3c, 0x4e, 0x95, 0xae, 0x2d, - 0x6b, 0x9d, 0xbb, 0xfd, 0xbb, 0x54, 0xf7, 0x42, 0x3b, 0x1c, 0xee, 0x4c, 0x33, 0xaf, 0x17, 0x9b, - 0x9d, 0x52, 0x66, 0xf4, 0xf4, 0x20, 0x3b, 0xd7, 0xe4, 0xd6, 0x39, 0xbe, 0x1a, 0x97, 0x0a, 0x6f, - 0x40, 0xbe, 0x8d, 0xf1, 0x43, 0x69, 0xba, 0x4b, 0xde, 0x1b, 0x0f, 0x99, 0xf2, 0xfd, 0xb0, 0xdc, - 0xec, 0x0f, 0x32, 0x95, 0xe2, 0x45, 0xe5, 0x62, 0x6a, 0x9f, 0x37, 0x1f, 0x75, 0xfb, 0xe1, 0xfe, - 0x2a, 0xb5, 0x69, 0x36, 0xdf, 0xcb, 0x99, 0xf3, 0xb3, 0xa7, 0xe2, 0xe6, 0x53, 0xe3, 0xe8, 0x60, - 0xaf, 0x7b, 0x33, 0x49, 0x29, 0x66, 0xf9, 0x2e, 0x75, 0x94, 0x3f, 0xbf, 0xbd, 0x23, 0xb0, 0xa6, - 0x26, 0xea, 0x38, 0xa5, 0x75, 0x3a, 0xaf, 0xcf, 0xd9, 0xcd, 0xdc, 0xc3, 0xe6, 0xe3, 0xa4, 0xd8, - 0x3f, 0x6e, 0xdc, 0x5e, 0x1d, 0x3c, 0x5e, 0x5e, 0x95, 0xae, 0xde, 0xa6, 0xd7, 0xbd, 0x3e, 0x69, - 0xa6, 0xae, 0x3a, 0xc5, 0x7b, 0xbd, 0x71, 0xd6, 0x6c, 0x1c, 0xee, 0x8f, 0x4b, 0x37, 0xc7, 0x0e, - 0x71, 0xf2, 0xa6, 0x9e, 0x29, 0xe7, 0xdb, 0x85, 0xc7, 0x66, 0xe3, 0x68, 0x67, 0x9c, 0x2f, 0x1a, - 0x3d, 0xf3, 0xe6, 0xfa, 0xcd, 0x29, 0x5e, 0x3e, 0x83, 0x4c, 0x7a, 0x53, 0x3e, 0x79, 0x6c, 0xec, - 0x5d, 0x9d, 0x94, 0xf5, 0xfd, 0xfe, 0x4e, 0x07, 0xc4, 0xe2, 0xdb, 0x09, 0xd0, 0xfe, 0xeb, 0x61, - 0x6b, 0xe7, 0xc4, 0xd8, 0x3b, 0xd8, 0x3c, 0x79, 0xba, 0x3a, 0x3d, 0x33, 0x9f, 0x8d, 0xe2, 0x68, - 0xa0, 0x64, 0x2e, 0x8f, 0x72, 0x6f, 0xa3, 0x9d, 0xfb, 0x8b, 0xe6, 0x4d, 0x6b, 0xf7, 0x49, 0x79, - 0x36, 0x5f, 0xaf, 0x4a, 0xe5, 0xd4, 0x93, 0x92, 0x2d, 0x3f, 0xf7, 0x0f, 0xfa, 0x8f, 0x67, 0x37, - 0x65, 0x7d, 0x67, 0xf0, 0x7c, 0xd2, 0xd9, 0xb7, 0x4e, 0x9a, 0x8f, 0xfb, 0xa5, 0xb7, 0x93, 0xd6, - 0xd3, 0xf5, 0xe9, 0x7e, 0xd1, 0xb9, 0x2e, 0x3e, 0x9e, 0x0c, 0x6e, 0xdf, 0xdf, 0xcf, 0xef, 0xcf, - 0x8a, 0xb9, 0xe1, 0xce, 0x78, 0x74, 0x79, 0xa6, 0x9e, 0x6e, 0x4e, 0x2f, 0xa7, 0x85, 0x5b, 0xe5, - 0xba, 0xbf, 0xaf, 0x1e, 0x3f, 0x35, 0xee, 0xf6, 0xed, 0xce, 0x53, 0xee, 0xf0, 0xf6, 0x68, 0x70, - 0x7b, 0xd9, 0xd9, 0x53, 0x0e, 0x8b, 0xf7, 0xf7, 0xbb, 0xe3, 0xf1, 0x70, 0xdc, 0xbd, 0xec, 0x69, - 0xc5, 0x13, 0xa5, 0x39, 0xbe, 0x28, 0x1b, 0xd9, 0x54, 0x6f, 0xbf, 0xb9, 0xd3, 0x2e, 0x0d, 0xc6, - 0xa3, 0xd3, 0xf7, 0xb2, 0x76, 0x76, 0x7d, 0x31, 0xe9, 0x3d, 0x5f, 0x9e, 0x97, 0x55, 0xc5, 0xaa, - 0xc8, 0xd7, 0xcd, 0xa6, 0x7a, 0xdd, 0x3c, 0xb6, 0xf2, 0xa3, 0xfe, 0xeb, 0x61, 0xaf, 0x74, 0xfa, - 0xda, 0xbf, 0x7d, 0x7c, 0xb4, 0x8b, 0x83, 0xf7, 0xf1, 0xa8, 0xe2, 0x9c, 0x1d, 0x5d, 0xdc, 0x5a, - 0x99, 0xa9, 0x39, 0xbe, 0xb6, 0xcf, 0xef, 0xc6, 0xdd, 0xa7, 0x8c, 0x99, 0x1a, 0xee, 0x94, 0xf5, - 0xcd, 0xbb, 0x1c, 0x70, 0x45, 0xf9, 0x26, 0xa5, 0x5c, 0x0f, 0x2e, 0xcd, 0xf3, 0x81, 0x7d, 0xbe, - 0x7f, 0xf1, 0x3a, 0x35, 0xf6, 0x72, 0x23, 0xd9, 0x1e, 0xbd, 0xde, 0xa8, 0x66, 0x7f, 0x5a, 0x2c, - 0x1f, 0x1d, 0x37, 0xa8, 0x91, 0xa2, 0x9e, 0x14, 0x7a, 0x86, 0x35, 0x54, 0x9c, 0xc4, 0x37, 0x54, - 0xa0, 0xbe, 0x25, 0xe7, 0x55, 0xcb, 0x30, 0x9c, 0xd9, 0xc6, 0x46, 0x67, 0x23, 0x5b, 0xfd, 0x9a, - 0xcd, 0x66, 0x6b, 0xf8, 0xd8, 0xab, 0x7e, 0xed, 0xf5, 0x7a, 0xf4, 0x31, 0x57, 0x45, 0xd3, 0x10, - 0x7d, 0xcc, 0x57, 0xbf, 0xe6, 0xf3, 0x79, 0xfa, 0x58, 0xa8, 0x7e, 0x2d, 0x14, 0x0a, 0xf4, 0xb1, - 0x58, 0xfd, 0x5a, 0x2c, 0x16, 0xe9, 0x63, 0xa9, 0xfa, 0xb5, 0x54, 0x2a, 0xd1, 0xc7, 0x72, 0xf5, - 0x6b, 0xb9, 0x5c, 0xa6, 0x8f, 0xed, 0xea, 0xd7, 0x76, 0xbb, 0x4d, 0x1f, 0x3b, 0xd5, 0xaf, 0x9d, - 0x4e, 0x87, 0x3e, 0x92, 0xea, 0x57, 0x42, 0x08, 0x7d, 0xec, 0x56, 0xbf, 0x76, 0xbb, 0x5d, 0xfa, - 0x68, 0x41, 0x81, 0x3c, 0x6b, 0xad, 0x0f, 0x0d, 0x77, 0x58, 0x77, 0x34, 0x68, 0xad, 0xac, 0xd0, - 0xc7, 0xb7, 0xea, 0x57, 0xa5, 0x22, 0xc3, 0xa3, 0x03, 0x70, 0xe5, 0x34, 0x6b, 0xd7, 0xa8, 0x5a, - 0xfd, 0xb6, 0x92, 0xc8, 0x17, 0x24, 0xc1, 0xfb, 0x27, 0xa7, 0x2b, 0x49, 0x9a, 0xe7, 0xb4, 0x17, - 0x33, 0x41, 0xaf, 0x4f, 0x50, 0x08, 0x49, 0xaf, 0x8c, 0xc2, 0x0a, 0x65, 0xe5, 0x9c, 0x24, 0x04, - 0x7f, 0x16, 0xcb, 0x0d, 0x58, 0xb9, 0x62, 0x56, 0x12, 0xbc, 0x7f, 0xe1, 0x42, 0xce, 0xa0, 0xba, - 0x29, 0x9b, 0x53, 0x7c, 0x32, 0xbd, 0x27, 0xa8, 0x55, 0xca, 0xb3, 0xb4, 0xb6, 0x59, 0xcd, 0x16, - 0xcc, 0xa9, 0xc0, 0xfe, 0xc8, 0xee, 0x13, 0x96, 0x81, 0x9c, 0x0a, 0xbc, 0xca, 0xc2, 0x26, 0xfe, - 0xa5, 0xb5, 0xba, 0x55, 0xdd, 0xd0, 0x11, 0x45, 0x76, 0xdf, 0xac, 0x8a, 0x6d, 0x34, 0x8f, 0x88, - 0x98, 0x31, 0x74, 0xaa, 0x50, 0x73, 0x8e, 0x86, 0xc5, 0x19, 0xb5, 0x27, 0x6c, 0x28, 0xcc, 0x84, - 0x32, 0x54, 0x40, 0xfe, 0x1f, 0x69, 0xd4, 0x02, 0x31, 0x6f, 0x1b, 0xdd, 0xb7, 0xd9, 0x50, 0xb1, - 0xfa, 0xaa, 0x5e, 0x95, 0x6b, 0x68, 0x63, 0xea, 0x5b, 0xc6, 0x48, 0xef, 0x32, 0xd3, 0x5f, 0x95, - 0x75, 0x1b, 0x66, 0x3d, 0x59, 0xe3, 0xf5, 0xed, 0x43, 0xa2, 0x8d, 0x89, 0xa3, 0x76, 0x14, 0xe9, - 0x8e, 0x58, 0x5d, 0x45, 0x57, 0x24, 0x5b, 0xd1, 0xed, 0x0d, 0x9b, 0x58, 0x6a, 0x8f, 0x15, 0xb4, - 0xd5, 0x77, 0x52, 0xcd, 0x42, 0x2f, 0x6b, 0x61, 0x40, 0xbd, 0x64, 0xcd, 0x21, 0x53, 0x67, 0x43, - 0xd1, 0xd4, 0xbe, 0x5e, 0xed, 0x10, 0xb4, 0x27, 0xd4, 0xd0, 0x4a, 0xf8, 0xa2, 0x3a, 0x1b, 0xac, - 0x9b, 0x1d, 0x45, 0xd3, 0xd0, 0xae, 0xc3, 0x86, 0xe5, 0x66, 0x8d, 0x00, 0x36, 0xc0, 0xd7, 0x48, - 0xc7, 0xcb, 0x18, 0x1a, 0xef, 0x71, 0xa9, 0xf6, 0x62, 0xe2, 0x62, 0x29, 0xaf, 0x3d, 0xc5, 0xdc, - 0x18, 0xa8, 0xfd, 0x81, 0x86, 0xf6, 0x27, 0x77, 0xc4, 0x8e, 0x05, 0x23, 0x31, 0x15, 0x0b, 0x7a, - 0x56, 0xb3, 0x3b, 0x96, 0xa1, 0x69, 0x6d, 0xc5, 0x62, 0xa6, 0xd5, 0x6a, 0x09, 0x86, 0x13, 0xa4, - 0x85, 0x07, 0x66, 0xb7, 0x93, 0x02, 0x57, 0x97, 0x22, 0x56, 0xa2, 0xc8, 0x1f, 0x10, 0x04, 0x5f, - 0xcd, 0xca, 0xf2, 0xbf, 0x6a, 0x0c, 0x0e, 0x7d, 0x34, 0x0d, 0x5b, 0xa5, 0xf3, 0xd1, 0x53, 0xa7, - 0xa4, 0x5b, 0x33, 0x60, 0x5b, 0x65, 0xb0, 0x37, 0xda, 0x64, 0xa0, 0x8c, 0x55, 0x80, 0x8d, 0x9d, - 0x9d, 0x7f, 0x6d, 0xf7, 0x39, 0x10, 0xe3, 0x41, 0x00, 0x63, 0x3c, 0x89, 0x02, 0x79, 0xdf, 0x50, - 0xf5, 0x2e, 0x99, 0x56, 0x37, 0xb2, 0xa1, 0xb9, 0xf4, 0x4b, 0xb9, 0xf8, 0xe6, 0xb2, 0x2c, 0x62, - 0x12, 0x05, 0xd1, 0xe2, 0x3e, 0xf1, 0x79, 0x74, 0x0e, 0x3b, 0xd8, 0xb1, 0x9a, 0x61, 0x2a, 0x1d, - 0xd5, 0x79, 0x03, 0x12, 0xa1, 0x63, 0x64, 0xd0, 0xdc, 0x44, 0x21, 0x67, 0xcf, 0x4d, 0x8f, 0x86, - 0x28, 0xb5, 0xca, 0x42, 0x0e, 0xff, 0xce, 0x15, 0x49, 0xa9, 0x8e, 0x55, 0x28, 0x4d, 0xba, 0x92, - 0x39, 0x0b, 0xe3, 0xab, 0x9b, 0xe4, 0xb3, 0x67, 0x94, 0x28, 0xba, 0xa4, 0x63, 0x58, 0x94, 0x2e, - 0xd9, 0xd0, 0xdb, 0x23, 0xc7, 0x31, 0xf4, 0x19, 0x10, 0x83, 0xa6, 0xea, 0x04, 0x1a, 0xef, 0x8c, - 0x2c, 0x1b, 0x60, 0x98, 0x86, 0x8a, 0xe3, 0x98, 0xa7, 0x35, 0xa5, 0x4d, 0x34, 0x3b, 0xa0, 0x5f, - 0x53, 0xe9, 0x76, 0x55, 0xbd, 0x5f, 0x2d, 0x73, 0x9d, 0xf8, 0x8a, 0x56, 0x69, 0x5a, 0x70, 0x16, - 0xc1, 0x56, 0xdb, 0x00, 0xf0, 0xc3, 0x2a, 0xd0, 0x5b, 0x27, 0xc1, 0xba, 0xd5, 0x1e, 0x24, 0x85, - 0x94, 0x00, 0xd3, 0x9c, 0xac, 0x59, 0x14, 0xe3, 0xa5, 0x05, 0x02, 0x2e, 0x27, 0x23, 0xbd, 0xa8, - 0x4d, 0x2c, 0x00, 0xaa, 0xf7, 0x81, 0x20, 0xbb, 0xa4, 0x0a, 0xc8, 0xc2, 0x75, 0xa1, 0x6d, 0x58, - 0xda, 0x3c, 0xdd, 0xb6, 0xd4, 0x99, 0xd7, 0x25, 0x58, 0xc0, 0xf3, 0xf4, 0xc4, 0x42, 0x3b, 0x97, - 0x15, 0xed, 0x88, 0x63, 0x98, 0xd0, 0x79, 0x8d, 0xf4, 0x60, 0xc9, 0xba, 0x0d, 0xf3, 0xf3, 0xe7, - 0xb7, 0xed, 0xb4, 0x93, 0xfe, 0x14, 0x67, 0xe7, 0x69, 0xb4, 0x8d, 0xdb, 0x71, 0x76, 0x30, 0xb6, - 0x02, 0xd1, 0x62, 0x06, 0x78, 0x04, 0x3e, 0xae, 0x71, 0x6b, 0x32, 0x07, 0x1d, 0xf9, 0xa2, 0x0e, - 0xf1, 0x20, 0x41, 0x01, 0x12, 0x47, 0xc4, 0x6e, 0x78, 0xe4, 0xc5, 0xa5, 0x77, 0x55, 0xdb, 0xd4, - 0x94, 0xb7, 0xaa, 0xaa, 0xd3, 0x12, 0x94, 0xad, 0xcc, 0xd3, 0x30, 0x19, 0x61, 0x6c, 0xf4, 0x93, - 0x41, 0x1d, 0xc8, 0xee, 0xf5, 0x22, 0xf9, 0xa5, 0x50, 0x3e, 0x20, 0x5c, 0x60, 0xbd, 0x96, 0xd2, - 0x30, 0x66, 0xf7, 0xd9, 0x9b, 0xbe, 0x0d, 0x3a, 0x5f, 0x42, 0x81, 0xce, 0x5a, 0x7a, 0x30, 0xea, - 0xbb, 0x36, 0x3e, 0xda, 0xed, 0x42, 0x0e, 0xf1, 0x67, 0x6a, 0x40, 0xc0, 0xd6, 0x9b, 0x70, 0xd3, - 0xd8, 0x39, 0xdd, 0x93, 0xd2, 0x36, 0xe9, 0x3b, 0x33, 0x07, 0xcf, 0x15, 0x36, 0x5c, 0x5b, 0x30, - 0xc3, 0x67, 0xb0, 0xca, 0xe6, 0xb4, 0x8c, 0x70, 0xb3, 0xeb, 0xcf, 0x03, 0x6d, 0x84, 0x1b, 0xe8, - 0x02, 0x37, 0xe2, 0x5a, 0xd9, 0x95, 0xfc, 0xea, 0x1c, 0x53, 0x43, 0x26, 0xed, 0x41, 0x93, 0x6b, - 0xfe, 0x84, 0x33, 0x18, 0x43, 0xb5, 0xdb, 0xd5, 0xc8, 0x3c, 0xfd, 0x42, 0xde, 0x1c, 0x97, 0xaa, - 0x59, 0x06, 0xce, 0xee, 0x3c, 0x3d, 0x56, 0xb4, 0x70, 0x32, 0x9d, 0x6d, 0x37, 0x5d, 0x50, 0xb9, - 0x66, 0x6c, 0x98, 0x36, 0x20, 0x21, 0x9b, 0x1a, 0x9a, 0xe9, 0x31, 0x48, 0x40, 0x35, 0x4a, 0xdb, - 0x36, 0xb4, 0x91, 0x43, 0x18, 0xc9, 0x00, 0xb1, 0x7b, 0xa4, 0x5c, 0x44, 0x24, 0x01, 0xa7, 0x63, - 0xe5, 0xe9, 0x52, 0xc5, 0x8d, 0x9c, 0x31, 0x35, 0xe0, 0xf8, 0xe4, 0x21, 0x01, 0xbd, 0x4f, 0xce, - 0xd3, 0x84, 0x96, 0x90, 0xd2, 0x7d, 0xf7, 0xd7, 0xab, 0x23, 0x85, 0x1a, 0x8c, 0x10, 0xfa, 0xc2, - 0x02, 0x76, 0xab, 0xcf, 0x16, 0xe9, 0x6d, 0xb1, 0xab, 0x48, 0xe3, 0xd8, 0x53, 0x46, 0xde, 0x65, - 0x3a, 0x9b, 0x86, 0x19, 0x33, 0xa6, 0x38, 0xca, 0x73, 0x57, 0x88, 0xbb, 0x34, 0x68, 0xcd, 0x8d, - 0x4e, 0x4c, 0xdd, 0xa5, 0xfb, 0x57, 0x2e, 0x09, 0x28, 0xb2, 0x60, 0x60, 0xd5, 0x2c, 0xcc, 0x3f, - 0x94, 0x56, 0xbb, 0x02, 0xb7, 0xa2, 0x59, 0xde, 0x86, 0xa5, 0x74, 0xd5, 0x91, 0x5d, 0xcd, 0xe1, - 0x86, 0xec, 0xaf, 0x33, 0xda, 0x76, 0xde, 0xef, 0x79, 0xbe, 0xc8, 0x4d, 0x3f, 0x24, 0x0b, 0xc8, - 0x6b, 0x00, 0x68, 0x64, 0x89, 0x85, 0x16, 0x56, 0xae, 0xe0, 0x0e, 0x77, 0xa3, 0x23, 0xc0, 0xfe, - 0xa0, 0x87, 0x88, 0xb1, 0xc4, 0xe6, 0x4c, 0xb1, 0x60, 0xeb, 0x5b, 0x32, 0xcd, 0x1e, 0xee, 0xe8, - 0x74, 0x67, 0xa1, 0x92, 0x4b, 0xe1, 0xb4, 0xa1, 0x50, 0x1b, 0xd4, 0x48, 0xff, 0x11, 0x18, 0x36, - 0x90, 0x0a, 0xb2, 0xb6, 0x08, 0x3f, 0xed, 0x69, 0xd6, 0x6c, 0x71, 0xbf, 0xf6, 0xc9, 0xc8, 0x32, - 0xf0, 0x2c, 0x20, 0x21, 0x27, 0xf9, 0x5d, 0xc0, 0xcf, 0x16, 0xd2, 0x79, 0x7b, 0xc9, 0xc4, 0x07, - 0x5c, 0x8d, 0xe3, 0xd0, 0x40, 0x85, 0x53, 0x53, 0xc2, 0x3f, 0x0a, 0x60, 0xba, 0x2b, 0xd0, 0xd6, - 0x17, 0x1a, 0xcb, 0x96, 0xe5, 0x2e, 0xe9, 0x03, 0xad, 0xa9, 0xda, 0x2c, 0x96, 0x34, 0xe2, 0x17, - 0xe0, 0x57, 0x4d, 0x1d, 0x13, 0x3c, 0x31, 0xf5, 0xf6, 0xce, 0x82, 0x8f, 0x35, 0xba, 0xfb, 0xba, - 0xd4, 0x20, 0x07, 0x05, 0x73, 0xbb, 0x5e, 0xd1, 0x8a, 0xbf, 0x51, 0x57, 0xb8, 0x92, 0x4b, 0x86, - 0x56, 0x84, 0x22, 0x74, 0x5e, 0xf0, 0x21, 0x66, 0xc5, 0x25, 0x36, 0x20, 0x43, 0xc2, 0x3f, 0x30, - 0x06, 0xe0, 0x55, 0xb3, 0x05, 0x1a, 0xe5, 0x25, 0x8e, 0xc5, 0x25, 0x06, 0x2b, 0x7b, 0xc9, 0xbe, - 0xe5, 0xef, 0x18, 0xfc, 0xb0, 0x96, 0x2d, 0x00, 0xd8, 0x3a, 0x68, 0xf3, 0x82, 0xbb, 0xa7, 0xae, - 0xec, 0x45, 0x4f, 0x33, 0x40, 0x26, 0x40, 0xe8, 0xde, 0xe8, 0xa9, 0xd8, 0xc4, 0x4d, 0x3a, 0xad, - 0x83, 0x13, 0x2e, 0x45, 0x01, 0x51, 0x2a, 0x58, 0x29, 0x02, 0x76, 0x92, 0xb5, 0xa1, 0xaa, 0xbb, - 0x22, 0x55, 0x81, 0x92, 0x2d, 0x6e, 0x06, 0x6e, 0xc7, 0x3c, 0x02, 0x71, 0x05, 0xe6, 0xb6, 0x09, - 0xa5, 0xdd, 0xed, 0x9d, 0x6d, 0x20, 0xb1, 0xe5, 0xda, 0x58, 0xce, 0x5d, 0x14, 0xc5, 0x7f, 0x71, - 0x35, 0x82, 0x21, 0x57, 0x07, 0x28, 0xc9, 0xcc, 0x56, 0x60, 0x68, 0x90, 0x8c, 0xf4, 0x94, 0x84, - 0x70, 0x96, 0x46, 0xf9, 0x79, 0x4c, 0x56, 0x41, 0x50, 0xb8, 0xed, 0x6e, 0x41, 0xf0, 0x9d, 0x7f, - 0x08, 0xa0, 0xb4, 0xba, 0x3a, 0x1e, 0xb6, 0x2b, 0x40, 0xf8, 0x16, 0x28, 0x62, 0x20, 0x69, 0xf1, - 0xf3, 0xce, 0x1e, 0x39, 0x49, 0x46, 0x4f, 0xfe, 0x89, 0x19, 0x49, 0x8f, 0x3d, 0xd0, 0x2c, 0x4c, - 0x11, 0x36, 0x3c, 0x5d, 0xc4, 0x4c, 0xfa, 0xcf, 0x30, 0x74, 0x0f, 0xcd, 0x1b, 0x48, 0xd4, 0x7e, - 0x89, 0x58, 0x8a, 0xe6, 0x9a, 0x51, 0x25, 0x39, 0x99, 0x11, 0xfc, 0x26, 0x37, 0x68, 0x9b, 0xc9, - 0xe5, 0xc2, 0x2c, 0xa2, 0xd3, 0xf5, 0x19, 0x98, 0x71, 0x54, 0xe6, 0x13, 0xb8, 0x45, 0x50, 0x2f, - 0x19, 0x93, 0x25, 0x63, 0xc3, 0xf7, 0x8c, 0xd7, 0x1a, 0xb2, 0xed, 0x29, 0x52, 0x19, 0x92, 0x81, - 0xcb, 0xc1, 0x21, 0x25, 0x58, 0xb0, 0xd8, 0x0b, 0x68, 0x64, 0x52, 0x55, 0x46, 0x8e, 0x51, 0xe3, - 0xc5, 0xf0, 0x65, 0xfd, 0x0b, 0xf6, 0x75, 0x81, 0x2a, 0x5c, 0xae, 0x9e, 0xe0, 0x01, 0xda, 0x60, - 0x75, 0xb0, 0x00, 0x55, 0x55, 0xe6, 0x5f, 0x7b, 0x53, 0xe9, 0xab, 0xa9, 0x68, 0x13, 0xf8, 0x8b, - 0xc3, 0x82, 0x9f, 0x57, 0x0d, 0xfe, 0x8c, 0x1c, 0x15, 0x7e, 0x40, 0x76, 0x60, 0x89, 0xf0, 0xe0, - 0xa7, 0xe0, 0x43, 0x4e, 0x4a, 0xf7, 0xf4, 0x2e, 0xc8, 0x3d, 0x53, 0x77, 0x15, 0xe4, 0xca, 0x72, - 0x68, 0x07, 0xc9, 0x02, 0x73, 0x9e, 0x73, 0x60, 0xc2, 0xb5, 0x67, 0xb8, 0x7c, 0x3c, 0xb6, 0x86, - 0xbb, 0x81, 0x27, 0x7b, 0xe3, 0x76, 0x84, 0x63, 0x45, 0xa9, 0xd7, 0x2d, 0x2c, 0xa0, 0x04, 0xa3, - 0xfa, 0xcb, 0x85, 0xce, 0x2e, 0xee, 0x20, 0xac, 0xeb, 0x03, 0x32, 0x85, 0xae, 0x6b, 0xa4, 0x3b, - 0x54, 0x4c, 0x3a, 0x10, 0x2d, 0x18, 0x08, 0x3d, 0xab, 0x77, 0x07, 0xf4, 0xda, 0xb1, 0x37, 0x26, - 0xfc, 0x80, 0xd8, 0xf1, 0x37, 0x0c, 0x43, 0xd5, 0x60, 0xe3, 0xa0, 0xc3, 0x91, 0xd2, 0xec, 0xbc, - 0x5d, 0x4a, 0x9b, 0x28, 0x71, 0x53, 0xd1, 0xc9, 0x7d, 0xa0, 0xa5, 0x7d, 0x29, 0x9d, 0x76, 0xd1, - 0x1d, 0x9d, 0xbf, 0x8c, 0x8b, 0x54, 0xf6, 0x83, 0x05, 0x6b, 0x0f, 0x0d, 0xc3, 0x19, 0xcc, 0x62, - 0x37, 0x18, 0x8e, 0xf0, 0x7a, 0x52, 0x36, 0xf9, 0x67, 0xba, 0x68, 0x27, 0x05, 0xa2, 0xd8, 0x64, - 0x03, 0x64, 0x3f, 0x4a, 0x5b, 0x1b, 0x4c, 0xd0, 0xf7, 0x9b, 0x92, 0x85, 0x0d, 0x0a, 0xd9, 0x9b, - 0xd8, 0x0d, 0x97, 0x77, 0xe2, 0xec, 0x7a, 0xbb, 0x89, 0xb7, 0x04, 0x90, 0xdb, 0xe2, 0x4c, 0x43, - 0x5a, 0x94, 0xe3, 0x2e, 0x51, 0xe1, 0x42, 0x72, 0xfb, 0xd2, 0x55, 0x9d, 0x4f, 0x46, 0x65, 0x03, - 0xaf, 0xe5, 0x9e, 0x46, 0xa6, 0x35, 0xba, 0x6d, 0x6d, 0x80, 0x12, 0x34, 0xb4, 0x3d, 0xfd, 0xec, - 0x79, 0x64, 0x3b, 0x6a, 0xef, 0x6d, 0xc3, 0x5d, 0x29, 0x5e, 0xb2, 0x2f, 0x92, 0x64, 0x7d, 0x7d, - 0x2c, 0x5d, 0x29, 0xf2, 0x6c, 0x39, 0xbd, 0x89, 0x3b, 0x30, 0xdd, 0xcc, 0x37, 0x08, 0x3a, 0x0d, - 0xd8, 0xee, 0xb2, 0xb3, 0x1d, 0xe5, 0x0d, 0x86, 0x2e, 0xd1, 0x07, 0xe8, 0xb6, 0xbf, 0x95, 0xb2, - 0x3d, 0xd4, 0x1f, 0xae, 0x47, 0xf1, 0xd0, 0x7e, 0xe7, 0xe5, 0x2d, 0x48, 0x67, 0xef, 0xbc, 0xd8, - 0x4c, 0x87, 0xee, 0xf5, 0x28, 0x57, 0x0b, 0x4d, 0x2e, 0x9b, 0x61, 0xaf, 0xd1, 0x19, 0x27, 0x9c, - 0x7a, 0x94, 0x33, 0xfb, 0x64, 0x8b, 0xc1, 0x5e, 0x17, 0x2c, 0x96, 0xbc, 0x2c, 0x73, 0x90, 0x04, - 0x4f, 0x09, 0xe4, 0x29, 0x3c, 0x1f, 0x5a, 0x4d, 0x21, 0x51, 0x7a, 0x16, 0x91, 0xf5, 0x70, 0x3e, - 0x16, 0xd9, 0x4f, 0x84, 0x5c, 0xa8, 0xf2, 0xc1, 0xea, 0xa3, 0x0a, 0xe7, 0x09, 0x0a, 0x79, 0x39, - 0x10, 0xc5, 0xe8, 0x33, 0xb7, 0xa2, 0xe9, 0xfb, 0x22, 0x60, 0x0f, 0x63, 0x32, 0x37, 0x00, 0xb7, - 0x63, 0x5e, 0x9b, 0xae, 0xe6, 0x89, 0x1b, 0xe3, 0x57, 0x55, 0xef, 0x19, 0x5e, 0x01, 0x69, 0xa1, - 0xc6, 0x0a, 0x71, 0x77, 0x01, 0x3c, 0xf6, 0x1b, 0xa6, 0xbf, 0x1d, 0x4a, 0x98, 0x51, 0xda, 0xcd, - 0xd3, 0xe1, 0x79, 0x4b, 0x99, 0xad, 0xe2, 0xe5, 0xb0, 0x0b, 0x0b, 0xe2, 0x72, 0x89, 0x93, 0x42, - 0x4b, 0x21, 0x2c, 0xd0, 0xa9, 0xaa, 0x71, 0x2a, 0x30, 0xea, 0xe4, 0x31, 0x58, 0xf1, 0xc8, 0x39, - 0x1b, 0x67, 0x5e, 0x80, 0x55, 0x2e, 0xa0, 0xbc, 0xa7, 0x58, 0x12, 0x6b, 0x05, 0x53, 0x24, 0x4e, - 0xec, 0x2c, 0xda, 0x5e, 0xef, 0x67, 0x81, 0xd4, 0xee, 0x33, 0xff, 0x01, 0x08, 0x84, 0x44, 0x9f, - 0xbb, 0xe3, 0x12, 0x40, 0xd6, 0x30, 0x34, 0x47, 0x35, 0x51, 0x07, 0xf3, 0x58, 0x53, 0x28, 0x71, - 0x86, 0x26, 0x89, 0xb6, 0xaa, 0x61, 0x7f, 0x58, 0xdd, 0xe5, 0x4b, 0xbb, 0xe8, 0xee, 0x41, 0x03, - 0xa5, 0x0b, 0x2d, 0xe1, 0xf8, 0x7c, 0x8b, 0x1d, 0x3e, 0x70, 0xd6, 0xb3, 0x4f, 0x58, 0xc1, 0x78, - 0x34, 0x31, 0x9d, 0x8e, 0xc7, 0x72, 0x29, 0x90, 0x5f, 0x4b, 0x21, 0xd2, 0xf2, 0xa5, 0xd1, 0x60, - 0xec, 0x2e, 0xd5, 0x96, 0x79, 0xd1, 0xd4, 0xdd, 0xdd, 0xe9, 0xfb, 0x46, 0x85, 0x4d, 0xc3, 0x02, - 0xa3, 0x58, 0x6d, 0xe7, 0x49, 0x6f, 0x22, 0xa6, 0x63, 0xf0, 0xe8, 0xad, 0xf0, 0x6c, 0x0e, 0x35, - 0xee, 0x98, 0x02, 0xd5, 0xaa, 0xd2, 0xa3, 0xc4, 0x15, 0x83, 0x6f, 0x37, 0x6f, 0xe6, 0x31, 0x3b, - 0x51, 0x5c, 0x22, 0x69, 0x53, 0x96, 0x1b, 0x3f, 0x9e, 0x62, 0x80, 0x2e, 0x86, 0x23, 0x2e, 0x81, - 0xe9, 0xa5, 0x54, 0xe5, 0xf3, 0x92, 0xa2, 0x93, 0xc8, 0x1b, 0xee, 0x96, 0x3d, 0x07, 0xe3, 0xea, - 0x0c, 0x48, 0xe7, 0x85, 0x49, 0x93, 0xb1, 0xd4, 0x14, 0x93, 0xc5, 0xd3, 0x14, 0x7d, 0xd4, 0x38, - 0x9a, 0x07, 0xe2, 0x55, 0xba, 0x24, 0x86, 0xec, 0x22, 0x93, 0x41, 0xa5, 0x30, 0xea, 0xc5, 0xf9, - 0x88, 0x2a, 0x98, 0xbb, 0xe2, 0x02, 0x95, 0x4a, 0xc6, 0x55, 0x60, 0xd9, 0xce, 0x8c, 0x13, 0xe4, - 0xb2, 0x94, 0x55, 0x3a, 0x86, 0x02, 0xc9, 0x01, 0xb8, 0xd5, 0xf4, 0xbc, 0x44, 0x4d, 0xce, 0x25, - 0xb9, 0x85, 0x8d, 0x8a, 0xd1, 0x27, 0x48, 0x3a, 0x4c, 0xc2, 0xbc, 0xe6, 0x9c, 0x0b, 0x31, 0x82, - 0xb0, 0xf5, 0xb2, 0xb8, 0x52, 0xa1, 0x7a, 0xa0, 0x1a, 0x55, 0x72, 0xa9, 0xf5, 0x0e, 0x21, 0x27, - 0xa3, 0x1a, 0x48, 0xdc, 0xa6, 0xc8, 0xd0, 0x92, 0xb6, 0x07, 0xc6, 0x64, 0x16, 0x30, 0x20, 0x45, - 0x57, 0x87, 0xcc, 0x04, 0x89, 0xb3, 0xa2, 0xea, 0x94, 0xd9, 0x04, 0x8f, 0x42, 0x0e, 0xff, 0x58, - 0x04, 0x05, 0x48, 0x1f, 0x04, 0xb1, 0x2c, 0xc3, 0xe2, 0x60, 0x2c, 0xe0, 0xf7, 0x6b, 0x3b, 0x17, - 0x0f, 0x79, 0x9e, 0x1e, 0x1a, 0x5d, 0x65, 0xc1, 0x32, 0xe9, 0x89, 0x14, 0xde, 0xe6, 0xe7, 0x69, - 0xcf, 0x38, 0xa5, 0xdc, 0x80, 0x9d, 0x01, 0x8a, 0xf0, 0x59, 0x1c, 0xef, 0xd2, 0x29, 0x35, 0x62, - 0x65, 0xf8, 0xc7, 0x04, 0xd3, 0x0e, 0xe2, 0xf5, 0xf8, 0x82, 0xcd, 0xeb, 0xe9, 0xbc, 0xf4, 0x82, - 0x9c, 0x27, 0x24, 0x56, 0xa3, 0xc9, 0xc1, 0xb0, 0xc9, 0xa7, 0xf7, 0x73, 0x26, 0x37, 0x30, 0xd1, - 0x9f, 0xd9, 0xbe, 0xe8, 0x1e, 0x27, 0x7d, 0xd5, 0x8d, 0x2e, 0xb1, 0x7d, 0xfe, 0x5d, 0x98, 0x7f, - 0xb5, 0xa8, 0xba, 0xe6, 0x25, 0xe4, 0xe7, 0x5f, 0xf5, 0xae, 0xe6, 0xf8, 0x66, 0x66, 0xd7, 0xb6, - 0x4b, 0x0b, 0x81, 0x9c, 0x11, 0x6b, 0x52, 0x8d, 0x60, 0x2a, 0x25, 0x14, 0x11, 0x53, 0xcc, 0x88, - 0xb2, 0x68, 0xfc, 0xf8, 0x0a, 0x0c, 0x48, 0x87, 0xc6, 0x3e, 0x6b, 0x25, 0x0e, 0x80, 0x15, 0x38, - 0xba, 0x2e, 0x2e, 0x30, 0x6e, 0x9a, 0xb2, 0x40, 0x10, 0x78, 0x3c, 0xe5, 0x5b, 0xeb, 0x73, 0xe1, - 0x8d, 0x9e, 0x57, 0x0c, 0xe8, 0x06, 0x1a, 0xa8, 0xcb, 0xd9, 0x02, 0x82, 0xe3, 0xd0, 0x17, 0xa8, - 0xba, 0x21, 0x10, 0x74, 0x73, 0xe7, 0x40, 0xb8, 0xb9, 0xd4, 0x56, 0xea, 0xe2, 0x9a, 0xbd, 0x7c, - 0x60, 0x3e, 0x75, 0xab, 0x75, 0xfd, 0x3a, 0xdd, 0x59, 0x44, 0x34, 0x2a, 0x07, 0x62, 0x4a, 0xdb, - 0xd1, 0xbd, 0xf9, 0x29, 0x86, 0x9b, 0xa4, 0x79, 0xa1, 0x76, 0x43, 0xa5, 0xbd, 0xce, 0x77, 0xd5, - 0xb1, 0x57, 0x08, 0x1e, 0x39, 0x34, 0x14, 0x2a, 0x72, 0xa0, 0xe6, 0x78, 0x0a, 0x04, 0xad, 0xf2, - 0x55, 0x1d, 0xf6, 0x27, 0x1e, 0x9c, 0xb2, 0xab, 0xff, 0xcc, 0xbf, 0x6a, 0x7c, 0xed, 0x12, 0x45, - 0x62, 0xac, 0x45, 0x1b, 0x34, 0x20, 0xc5, 0x72, 0x66, 0x8b, 0x96, 0x8d, 0x4a, 0xc8, 0x88, 0x11, - 0x1c, 0x03, 0x58, 0xa4, 0x3b, 0x87, 0x26, 0x39, 0xe8, 0x74, 0x5b, 0xc2, 0x57, 0x4e, 0x49, 0x98, - 0xa7, 0x27, 0xea, 0x8c, 0xba, 0xb0, 0x6f, 0xc0, 0xde, 0x01, 0xf3, 0x81, 0xa4, 0x61, 0x02, 0x72, - 0x71, 0xed, 0x75, 0x6b, 0xd1, 0x9c, 0x8e, 0x05, 0x7d, 0xdb, 0x20, 0xdd, 0x3e, 0xb1, 0x3d, 0x71, - 0x92, 0x32, 0xee, 0xff, 0xf5, 0x42, 0xde, 0x7a, 0x16, 0xe8, 0x50, 0xb6, 0xc0, 0x58, 0xc6, 0xac, - 0x67, 0x19, 0xc3, 0x99, 0xcf, 0x16, 0x7c, 0x8e, 0x3e, 0x77, 0x8c, 0xd9, 0x6a, 0x7e, 0x18, 0xec, - 0x36, 0x9e, 0x20, 0xeb, 0xe2, 0xc3, 0xdf, 0x77, 0xbf, 0x7d, 0x5b, 0xb6, 0xef, 0xe6, 0x3c, 0xd3, - 0x63, 0xc8, 0x7e, 0xeb, 0x6d, 0x40, 0x61, 0xfa, 0x5e, 0x2e, 0x26, 0x52, 0x24, 0xc6, 0xc9, 0x1c, - 0xc1, 0xa1, 0x15, 0x1e, 0x5b, 0xf6, 0x79, 0x93, 0xc7, 0x57, 0x4a, 0xc8, 0x42, 0xa4, 0xc7, 0xb4, - 0x14, 0xad, 0xca, 0xb5, 0xcb, 0x24, 0xc4, 0x8d, 0x3e, 0xb6, 0x86, 0x8e, 0xd7, 0x15, 0x34, 0x1b, - 0x4a, 0x5f, 0x65, 0x19, 0x54, 0xc0, 0x6c, 0xf1, 0x5f, 0x12, 0x4c, 0x1c, 0xc0, 0xeb, 0xff, 0x63, - 0xf0, 0xbe, 0xca, 0x3d, 0x19, 0x00, 0xb6, 0xff, 0x41, 0x80, 0x32, 0x8e, 0x78, 0xf2, 0xcf, 0x01, - 0xec, 0xf5, 0x10, 0xe0, 0x4b, 0x0c, 0x40, 0xe9, 0xeb, 0xa4, 0xad, 0x68, 0xd1, 0x56, 0x3e, 0x86, - 0xdd, 0xeb, 0x95, 0x7b, 0xd9, 0x9e, 0x20, 0x53, 0xd8, 0x02, 0x1a, 0x36, 0xbf, 0x76, 0xda, 0xdd, - 0x36, 0x6d, 0x87, 0xd9, 0x12, 0x06, 0x54, 0xcf, 0x60, 0x8d, 0x4a, 0xbe, 0x6d, 0x55, 0xe2, 0xac, - 0xac, 0xd4, 0xa4, 0x20, 0x7c, 0xb5, 0xfa, 0x6d, 0x56, 0xc6, 0xb5, 0x2d, 0xf8, 0x9c, 0x1c, 0xd4, - 0x1c, 0x96, 0x81, 0x5d, 0x94, 0x18, 0x3e, 0x24, 0xce, 0xb0, 0x2d, 0xa5, 0x49, 0x17, 0xf6, 0x17, - 0xf6, 0x68, 0x3a, 0x20, 0x5c, 0x79, 0x2b, 0xdb, 0x55, 0x75, 0xe9, 0x98, 0xda, 0xa3, 0x36, 0x72, - 0x37, 0xce, 0x4e, 0xfe, 0xc9, 0x93, 0x86, 0x18, 0xa2, 0x8d, 0xa1, 0xee, 0x7c, 0x8c, 0x44, 0xcf, - 0xc9, 0xef, 0x3c, 0xef, 0x28, 0xf8, 0x8b, 0x06, 0x61, 0x71, 0x9c, 0x26, 0x10, 0xf8, 0x84, 0x74, - 0x0e, 0x84, 0x0a, 0x34, 0x64, 0x48, 0xbe, 0xac, 0xed, 0xa5, 0x70, 0x52, 0xe0, 0xa2, 0x84, 0x88, - 0xcb, 0x13, 0xf5, 0x44, 0xe0, 0xdd, 0xe6, 0xc8, 0x09, 0x0d, 0x9d, 0x8a, 0x35, 0x2b, 0xc5, 0x4e, - 0xee, 0x8e, 0x00, 0xbd, 0x22, 0xf0, 0x73, 0xe6, 0xed, 0xdd, 0x78, 0x48, 0xa9, 0x40, 0x5a, 0x87, - 0x30, 0xa2, 0xe3, 0x4f, 0xad, 0xfd, 0x83, 0xaf, 0xe5, 0x4e, 0x03, 0x21, 0x83, 0x76, 0x78, 0x93, - 0x5d, 0x68, 0xb3, 0xda, 0x33, 0x3a, 0x23, 0x3b, 0x38, 0xe2, 0x8d, 0x29, 0x11, 0x88, 0x14, 0xec, - 0x68, 0xca, 0x1a, 0xe9, 0x3a, 0xdd, 0xb4, 0xa0, 0x9d, 0xce, 0xcb, 0x8c, 0xeb, 0x1c, 0xaf, 0x96, - 0x47, 0xce, 0xae, 0xb8, 0x39, 0x44, 0x33, 0xd3, 0xc7, 0xad, 0x38, 0x83, 0xd1, 0xb0, 0xed, 0x1f, - 0xbc, 0xf3, 0xda, 0xd7, 0xe2, 0x0e, 0x1f, 0x32, 0xbc, 0xf3, 0x24, 0x11, 0xe9, 0xc4, 0x32, 0xfc, - 0x72, 0x02, 0x3b, 0x08, 0xab, 0xb1, 0x9d, 0x43, 0x6f, 0x07, 0xfa, 0xb2, 0x7a, 0xd4, 0x0b, 0x73, - 0x41, 0x1d, 0x51, 0x64, 0x89, 0xfe, 0x2f, 0xf9, 0x11, 0x64, 0x3a, 0x64, 0xcf, 0x7c, 0xea, 0x8a, - 0xff, 0xfc, 0x64, 0xfe, 0x9b, 0xd8, 0x88, 0x95, 0x43, 0x51, 0x8c, 0x9a, 0x7f, 0xa5, 0xd7, 0x6f, - 0x6c, 0xe1, 0x77, 0xa7, 0xa5, 0x1c, 0x74, 0x24, 0xd0, 0x98, 0xe9, 0xa9, 0x5a, 0x58, 0x77, 0xc9, - 0x86, 0xac, 0xdb, 0x54, 0x38, 0x59, 0xd1, 0xe2, 0x12, 0x8c, 0xc4, 0x81, 0xf5, 0xe1, 0xf0, 0x72, - 0x97, 0xbb, 0x32, 0x0a, 0x9e, 0x49, 0x73, 0xd0, 0x9d, 0xc5, 0xd8, 0x1a, 0xbf, 0xb6, 0x2d, 0x95, - 0x15, 0xf7, 0xa5, 0xbb, 0x5c, 0x69, 0x33, 0x56, 0xba, 0xe3, 0x6c, 0xf2, 0xed, 0xa1, 0x03, 0x55, - 0x99, 0x71, 0x96, 0x57, 0xf4, 0xca, 0xa1, 0x53, 0x7d, 0x4e, 0x80, 0x44, 0x63, 0xc1, 0x9c, 0x0a, - 0x5b, 0xbc, 0x48, 0xcf, 0x7b, 0x6b, 0x14, 0x22, 0x46, 0xac, 0xb0, 0x19, 0x7a, 0xe1, 0x48, 0x6a, - 0x61, 0x65, 0x85, 0x8d, 0x41, 0xc5, 0x10, 0x93, 0xdb, 0xe8, 0x8e, 0x5c, 0x87, 0x0e, 0x3c, 0x16, - 0xf2, 0xe6, 0x12, 0xc9, 0x03, 0xef, 0xf0, 0x6c, 0x2c, 0x72, 0x34, 0xdf, 0x35, 0x67, 0x91, 0x56, - 0xf2, 0x5d, 0x46, 0xc8, 0x4c, 0xd9, 0x59, 0x52, 0x7f, 0x65, 0xbd, 0x88, 0x4d, 0x88, 0x29, 0xac, - 0x7e, 0x22, 0xd1, 0x34, 0xd5, 0xb4, 0x55, 0x7b, 0xb9, 0x0a, 0x9c, 0x4f, 0xae, 0xb2, 0xf2, 0xba, - 0x26, 0x6d, 0x2a, 0xd9, 0x6e, 0xd8, 0xcc, 0x0a, 0x20, 0x05, 0x76, 0xf8, 0xb8, 0xd4, 0x5c, 0x38, - 0x19, 0x5f, 0xbc, 0x63, 0xaa, 0x65, 0x7d, 0x28, 0x26, 0x57, 0xa9, 0xef, 0x73, 0x06, 0x6f, 0x16, - 0x12, 0x4d, 0xfd, 0xd3, 0x33, 0xc8, 0xa2, 0x47, 0xc3, 0x9e, 0xc3, 0x85, 0x67, 0xb0, 0xda, 0xc8, - 0x52, 0x1b, 0x79, 0xec, 0x49, 0xea, 0x12, 0x4f, 0x10, 0x84, 0xa5, 0xcf, 0xc2, 0xb6, 0x4f, 0x57, - 0x3a, 0x2f, 0x7b, 0x74, 0x8f, 0x65, 0x3c, 0x2d, 0x24, 0x9b, 0xe3, 0xca, 0x14, 0x99, 0x8b, 0x07, - 0xcd, 0x87, 0xd6, 0xba, 0x5d, 0xc9, 0x7b, 0xee, 0x12, 0x8d, 0x3d, 0x4f, 0xbd, 0x31, 0xe0, 0x01, - 0x07, 0x47, 0xd9, 0xdc, 0xb1, 0x47, 0xd4, 0x89, 0xc3, 0x9f, 0xc8, 0x0e, 0xcc, 0xe3, 0xdc, 0x83, - 0xe2, 0x36, 0xc9, 0x7c, 0x4b, 0xb0, 0x5b, 0xfc, 0x2c, 0x05, 0xf9, 0x32, 0xa7, 0xc4, 0x60, 0xf2, - 0x52, 0xfc, 0x17, 0x22, 0xf3, 0xec, 0x8d, 0x2f, 0x4f, 0xb9, 0x0a, 0x53, 0x5e, 0xd2, 0x08, 0x2a, - 0xac, 0xdf, 0xf0, 0x55, 0xa2, 0x44, 0xb1, 0x40, 0x0e, 0xb3, 0x55, 0x67, 0x09, 0x2b, 0xa8, 0x73, - 0x19, 0x4a, 0x03, 0x07, 0xa9, 0xc9, 0x40, 0x75, 0xc8, 0x06, 0xf0, 0x73, 0xba, 0xf5, 0x20, 0xfb, - 0x99, 0x33, 0x01, 0x6c, 0xc1, 0x68, 0x94, 0x86, 0x64, 0x0e, 0x79, 0x51, 0xb9, 0xa8, 0xb0, 0x44, - 0xa3, 0xf2, 0x38, 0x09, 0xa7, 0x20, 0xd0, 0xe7, 0x90, 0x3b, 0x44, 0xd9, 0x85, 0xdf, 0xf6, 0x2f, - 0x82, 0x46, 0x2c, 0xc8, 0xa1, 0xd2, 0xc1, 0x16, 0xc3, 0x0d, 0x1a, 0x05, 0x50, 0x26, 0x73, 0xce, - 0x22, 0x9c, 0x9d, 0x39, 0xfa, 0xcd, 0xa2, 0xd6, 0x54, 0x1f, 0x05, 0x11, 0xf6, 0xb6, 0x0a, 0xd5, - 0x9f, 0x63, 0x7d, 0xfe, 0x56, 0xb9, 0xe0, 0x6c, 0x12, 0x72, 0x28, 0x89, 0x65, 0x8a, 0xc5, 0x7f, - 0x8e, 0x29, 0x2e, 0x13, 0x2e, 0xe8, 0x76, 0x16, 0x4d, 0xfc, 0xbb, 0x1c, 0x34, 0x9e, 0x63, 0xce, - 0xbf, 0x3a, 0xce, 0x2c, 0xc6, 0x91, 0xaa, 0xa3, 0x2d, 0x52, 0x32, 0xea, 0x27, 0xee, 0x1c, 0x51, - 0xaf, 0x23, 0x53, 0xe2, 0x5f, 0xb4, 0xf0, 0x1b, 0x99, 0xf1, 0x1c, 0xa3, 0xb6, 0x28, 0xf4, 0x14, - 0x90, 0x54, 0xbb, 0xea, 0x98, 0x95, 0x9f, 0x2d, 0x9c, 0x2c, 0x04, 0x79, 0x9f, 0xb1, 0x32, 0x5b, - 0xae, 0x02, 0x8f, 0xb3, 0x05, 0xd4, 0x94, 0x0b, 0x3c, 0x6d, 0xe4, 0xc0, 0xdc, 0xea, 0x4e, 0xad, - 0xa7, 0x10, 0xc7, 0x88, 0x49, 0xde, 0xe4, 0x7b, 0x9a, 0xf2, 0xf2, 0x22, 0xee, 0xce, 0x1d, 0xa1, - 0x1f, 0xd0, 0xa6, 0x22, 0x58, 0x58, 0xc4, 0x2d, 0x57, 0xc0, 0xee, 0x87, 0xb1, 0xc4, 0xa3, 0xe6, - 0xa3, 0xc3, 0x9c, 0x18, 0x3d, 0x86, 0x17, 0x12, 0x75, 0x10, 0x7f, 0x88, 0xf5, 0x53, 0xe2, 0x92, - 0xb0, 0x2b, 0x3f, 0x67, 0x9f, 0x54, 0x89, 0x3e, 0xbb, 0x40, 0xb2, 0xfc, 0x31, 0x51, 0x79, 0x51, - 0x06, 0xe1, 0xb4, 0xa6, 0x45, 0x7f, 0x93, 0x9c, 0x5d, 0x0b, 0x3c, 0x44, 0x63, 0x56, 0x01, 0xf6, - 0xb8, 0xa7, 0x12, 0xad, 0xbb, 0xb0, 0x14, 0x82, 0x9c, 0xb8, 0xc4, 0x18, 0x44, 0x2c, 0x78, 0xee, - 0xb9, 0xe4, 0x51, 0x94, 0xc3, 0x62, 0x3b, 0x43, 0xd2, 0xe2, 0xac, 0x2d, 0x42, 0x64, 0xfa, 0xcf, - 0x02, 0x82, 0x5d, 0xb5, 0x28, 0x06, 0xcd, 0xa5, 0xb8, 0x09, 0x0a, 0xc4, 0x64, 0x55, 0xd7, 0xf1, - 0xcc, 0xc3, 0x04, 0x86, 0xc8, 0xbc, 0x56, 0xa4, 0x55, 0xa5, 0x01, 0x6f, 0xe1, 0xd2, 0xcb, 0x54, - 0x40, 0xc6, 0x6a, 0x85, 0x85, 0x21, 0xba, 0x06, 0x36, 0x32, 0x5c, 0x18, 0x3d, 0x53, 0xcd, 0x23, - 0xbe, 0x1b, 0xc2, 0x86, 0x80, 0xba, 0x78, 0x72, 0x8e, 0x45, 0x60, 0x25, 0x28, 0x71, 0x23, 0xcc, - 0xc5, 0x10, 0xd2, 0x22, 0x1c, 0xdc, 0x81, 0xfc, 0x43, 0x10, 0x6a, 0x1e, 0x8c, 0x31, 0xbb, 0x2e, - 0x13, 0xdc, 0x41, 0x88, 0x0a, 0x48, 0xc6, 0x22, 0x94, 0xd0, 0x28, 0x5f, 0x8c, 0xd0, 0x1d, 0x67, - 0xd5, 0x9d, 0xa7, 0x15, 0x53, 0xc5, 0x21, 0xb9, 0x4d, 0x6e, 0xc2, 0x98, 0xab, 0x55, 0xb6, 0x0c, - 0xc3, 0x4b, 0xcc, 0xef, 0x37, 0xba, 0x5c, 0x51, 0x2c, 0x78, 0xf2, 0x56, 0xd6, 0x95, 0xb7, 0x42, - 0xc2, 0x3a, 0x9e, 0x93, 0xfb, 0x98, 0x42, 0x42, 0x0a, 0x79, 0xcc, 0x32, 0x0f, 0x8a, 0xb0, 0x47, - 0xc5, 0x6c, 0x71, 0x17, 0x8f, 0x39, 0x7b, 0xf9, 0xa4, 0xb0, 0x1b, 0xf5, 0x53, 0x0c, 0xf9, 0x50, - 0xd3, 0x04, 0xce, 0xd4, 0xb9, 0x19, 0x7b, 0xa8, 0xed, 0x76, 0x73, 0x16, 0x38, 0xcf, 0xb8, 0x0e, - 0x8f, 0x98, 0x4a, 0xdd, 0xfa, 0xfc, 0xae, 0x2f, 0x71, 0xf2, 0x93, 0x3d, 0x7f, 0xeb, 0x0d, 0xe6, - 0x0d, 0xd9, 0xb6, 0x23, 0x1a, 0x93, 0xdd, 0xf7, 0xfd, 0xbb, 0x98, 0x7d, 0x95, 0xc2, 0x9e, 0x51, - 0x69, 0x85, 0x39, 0x06, 0xfb, 0xef, 0xe8, 0x1e, 0xaa, 0x76, 0x3f, 0xe5, 0x45, 0x19, 0xb1, 0xf0, - 0x2e, 0xe2, 0x30, 0x4c, 0x87, 0x38, 0x9f, 0x3a, 0x99, 0xc0, 0x50, 0x3c, 0xcf, 0xd8, 0x2e, 0xe9, - 0x29, 0x23, 0xcd, 0x41, 0x57, 0x6c, 0x7f, 0xf4, 0x25, 0x5f, 0xd2, 0x4c, 0x4f, 0x03, 0x29, 0x96, - 0xf3, 0xd4, 0x2c, 0x14, 0x42, 0x92, 0x30, 0x2d, 0xe6, 0x0b, 0x60, 0xd5, 0x60, 0xcf, 0x41, 0x5a, - 0xf0, 0x8d, 0xac, 0xd4, 0x86, 0xdf, 0xb1, 0x41, 0x64, 0x9c, 0x06, 0xd2, 0xe9, 0x22, 0x61, 0x77, - 0x79, 0x7f, 0x6b, 0xbf, 0x3c, 0x40, 0x8f, 0x9e, 0x8e, 0xf2, 0xc5, 0x7c, 0x07, 0x79, 0x89, 0x0a, - 0x7d, 0x14, 0x0d, 0xee, 0x91, 0x36, 0x25, 0x59, 0xa6, 0x1e, 0x70, 0x5a, 0xaf, 0x14, 0x9f, 0x4a, - 0x53, 0x62, 0xcb, 0x46, 0x13, 0x61, 0x8a, 0x6c, 0xc7, 0x5e, 0x74, 0x35, 0x0d, 0x34, 0x67, 0x28, - 0x31, 0xb1, 0x16, 0x9c, 0xc9, 0x17, 0x1c, 0x56, 0x15, 0x90, 0xf4, 0x16, 0x1d, 0xe5, 0xba, 0xbc, - 0xaf, 0x7f, 0xe0, 0x1c, 0xec, 0x1f, 0x58, 0xf0, 0x4e, 0xc8, 0x3d, 0xeb, 0x9d, 0x79, 0x41, 0x64, - 0xe3, 0x4f, 0xd5, 0x3d, 0xaa, 0x89, 0x88, 0x7e, 0x9c, 0x1b, 0x3e, 0x3d, 0x0f, 0x96, 0xd2, 0xc8, - 0x77, 0x8c, 0x65, 0x7e, 0x35, 0xbe, 0xa7, 0x43, 0x74, 0x00, 0x16, 0x19, 0x77, 0x06, 0x2f, 0x5a, - 0x48, 0x5c, 0x45, 0xea, 0xa1, 0x6e, 0xc6, 0xae, 0x64, 0xcb, 0xf9, 0xc0, 0xf0, 0xfa, 0xfe, 0xfc, - 0x66, 0x57, 0x58, 0xa8, 0x2f, 0xb3, 0xda, 0x81, 0x57, 0xd8, 0x86, 0xbb, 0x26, 0x68, 0x2f, 0x19, - 0x03, 0x77, 0xfb, 0xca, 0x5e, 0x62, 0x10, 0x15, 0x58, 0x1c, 0x23, 0x83, 0xf6, 0x65, 0x20, 0x57, - 0x28, 0x72, 0xa1, 0x42, 0x43, 0xde, 0xf8, 0xf1, 0x31, 0x06, 0x22, 0xcf, 0x5f, 0x38, 0x93, 0x2c, - 0x3b, 0x0c, 0x8c, 0xba, 0xb3, 0xfe, 0x2d, 0xe5, 0x27, 0x07, 0xd3, 0x1e, 0xf4, 0x20, 0xb4, 0xd4, - 0x79, 0x55, 0x84, 0xf3, 0x9d, 0xce, 0x7d, 0x60, 0xb9, 0x5a, 0x34, 0x66, 0x72, 0xc3, 0x9d, 0x2d, - 0xca, 0x2f, 0xf3, 0x90, 0x63, 0x00, 0xc5, 0xed, 0x7f, 0x2d, 0xe0, 0x27, 0x9c, 0x1b, 0x74, 0x78, - 0xa5, 0x4a, 0xef, 0x03, 0xf1, 0xbc, 0x28, 0xfc, 0x7a, 0x9f, 0x11, 0x6a, 0xc3, 0xd6, 0x71, 0x46, - 0x06, 0x51, 0x90, 0x6c, 0x05, 0x54, 0xdc, 0x29, 0x09, 0x66, 0xa9, 0x18, 0xa0, 0x2e, 0x1b, 0x6c, - 0xb1, 0xd5, 0xa8, 0xb8, 0x1a, 0xf6, 0xbd, 0x00, 0xf2, 0x83, 0xe9, 0xc9, 0x33, 0x1d, 0x3f, 0xbe, - 0x3d, 0x18, 0x82, 0xe1, 0x14, 0x8a, 0xb3, 0x45, 0xc5, 0xc6, 0xdd, 0x10, 0x0a, 0x45, 0x74, 0xfa, - 0xa6, 0xd7, 0xb9, 0x96, 0xe5, 0x2d, 0x49, 0x77, 0xc9, 0x40, 0x58, 0x40, 0x92, 0x77, 0x80, 0xca, - 0x0d, 0xc9, 0xa3, 0xc1, 0xe2, 0xa2, 0x63, 0x49, 0x75, 0x63, 0xf3, 0xf3, 0x96, 0x4d, 0xba, 0x12, - 0x83, 0xa9, 0xa6, 0xeb, 0x32, 0x44, 0x8b, 0x6c, 0x5b, 0x1b, 0x44, 0x6f, 0x91, 0x7c, 0x66, 0xc3, - 0x69, 0x7b, 0xf6, 0x44, 0xfe, 0xc0, 0x35, 0x6d, 0x82, 0xd0, 0x42, 0x37, 0xd5, 0xd9, 0x27, 0xae, - 0x3c, 0xc8, 0x0b, 0xfa, 0x45, 0x2d, 0x72, 0x31, 0x65, 0xb5, 0x80, 0x5d, 0xb4, 0xa3, 0xfa, 0x6c, - 0x96, 0xdd, 0x59, 0xe8, 0xd3, 0xc1, 0xe1, 0x89, 0x2b, 0x67, 0x8b, 0x71, 0xbb, 0x19, 0x4e, 0xa5, - 0xa5, 0x85, 0xb4, 0xcd, 0x78, 0x55, 0x2c, 0x93, 0xdd, 0xf4, 0xd6, 0x6b, 0x25, 0xf0, 0x46, 0x03, - 0x71, 0x01, 0x6b, 0x48, 0xbe, 0xef, 0x8d, 0x41, 0x01, 0xc4, 0x1a, 0x1e, 0x02, 0x33, 0x6a, 0x1a, - 0x64, 0x33, 0x5f, 0x8c, 0xf1, 0x64, 0x2e, 0xfc, 0x47, 0xd9, 0x62, 0x74, 0xe8, 0x0b, 0x02, 0x50, - 0xbc, 0x19, 0xcc, 0x23, 0x55, 0xd6, 0xb1, 0x6a, 0xdf, 0x52, 0xde, 0xa8, 0x2f, 0x8e, 0xeb, 0x48, - 0x11, 0x9f, 0x3c, 0x4f, 0x6b, 0x6d, 0x6d, 0x43, 0xfb, 0x78, 0xde, 0x43, 0xec, 0x9f, 0xd5, 0xb2, - 0x97, 0x0c, 0x33, 0xe0, 0xea, 0xa5, 0xb0, 0x08, 0x93, 0xf7, 0x97, 0x6d, 0xa1, 0xfc, 0xaf, 0xb8, - 0x7b, 0x4d, 0x9a, 0x6a, 0x3b, 0x8b, 0x2a, 0xf2, 0x87, 0x73, 0xef, 0x2e, 0x08, 0xdf, 0xb1, 0x93, - 0xfa, 0xb7, 0xc5, 0xdc, 0x6f, 0xd1, 0x6c, 0xe7, 0x68, 0x16, 0xe3, 0xcd, 0xba, 0xf4, 0x24, 0x66, - 0x91, 0x60, 0xa3, 0x32, 0xeb, 0xe7, 0xbd, 0x44, 0xa3, 0xe4, 0x19, 0xe3, 0x13, 0x5d, 0xe3, 0xdd, - 0xa6, 0xe5, 0x38, 0xa3, 0x52, 0xc8, 0x7d, 0xd2, 0x33, 0xd1, 0xd1, 0x61, 0x85, 0xf7, 0x52, 0x26, - 0xf5, 0x93, 0xee, 0x2c, 0xf6, 0xdc, 0x7b, 0xee, 0xf9, 0x49, 0x53, 0xdf, 0x6b, 0xc6, 0xf1, 0x81, - 0xfb, 0x3a, 0x89, 0x1f, 0x1d, 0x4d, 0xb1, 0xed, 0x3f, 0xeb, 0xde, 0x8d, 0x97, 0x9f, 0x49, 0x89, - 0x42, 0x5f, 0x59, 0x24, 0xae, 0x0d, 0xdc, 0x14, 0xbc, 0x3e, 0xf0, 0x8c, 0x87, 0x4b, 0xf4, 0xf9, - 0x0f, 0x97, 0x18, 0xa3, 0xd8, 0xc7, 0x66, 0x46, 0x55, 0xfc, 0x45, 0x4b, 0x37, 0xed, 0x76, 0x80, - 0x86, 0xc8, 0x3e, 0xbe, 0xca, 0x76, 0x1a, 0xae, 0x29, 0xb9, 0xaf, 0x74, 0x16, 0x67, 0xbc, 0x03, - 0xa3, 0xef, 0x54, 0x89, 0xe2, 0x4c, 0x8c, 0x43, 0xe5, 0x9c, 0xf9, 0xa9, 0x0b, 0x3e, 0xa8, 0xa5, - 0xe8, 0x73, 0x9d, 0x8f, 0x73, 0xde, 0xe6, 0xe6, 0x3a, 0xbf, 0xe3, 0x62, 0x10, 0x62, 0xc6, 0x51, - 0x2e, 0x2c, 0xe6, 0xb3, 0xee, 0x05, 0xb5, 0xd1, 0x51, 0x7e, 0x65, 0xf5, 0x48, 0x81, 0x48, 0x7d, - 0x9a, 0xea, 0xdd, 0x82, 0xf0, 0x56, 0xbe, 0x7f, 0xad, 0x3b, 0x4e, 0xbf, 0xc2, 0x0a, 0x2b, 0x35, - 0xbf, 0x45, 0xbd, 0xee, 0xef, 0xf2, 0x2b, 0x68, 0x09, 0x36, 0x97, 0x71, 0xcc, 0x01, 0x63, 0x29, - 0x56, 0x3e, 0x8e, 0x4a, 0x6f, 0x81, 0x37, 0xc7, 0x9c, 0x5e, 0x72, 0x88, 0x19, 0x0d, 0x24, 0x2f, - 0x92, 0x5b, 0x58, 0x70, 0x0e, 0xdd, 0xd4, 0x8a, 0xbb, 0xe4, 0xc1, 0x6b, 0xa9, 0xb8, 0x98, 0xe9, - 0xa9, 0x43, 0x44, 0xb3, 0xf2, 0xd6, 0x7d, 0x94, 0xe3, 0xc7, 0x70, 0x8b, 0x78, 0x33, 0xc4, 0xaa, - 0x83, 0xa0, 0xbf, 0x89, 0xdf, 0xb8, 0xb1, 0x2f, 0x18, 0x7b, 0x16, 0x3c, 0xae, 0x97, 0xd4, 0x73, - 0x4f, 0x8d, 0x62, 0xf3, 0x70, 0x39, 0x54, 0x01, 0xa3, 0x1d, 0x32, 0x30, 0x34, 0xea, 0x07, 0x3b, - 0x30, 0x26, 0x7a, 0x72, 0xf5, 0xb2, 0x46, 0xb1, 0x42, 0xa5, 0xd7, 0x41, 0xb9, 0x3b, 0x23, 0x54, - 0x80, 0x8e, 0x53, 0xfa, 0xf1, 0x08, 0x48, 0xf2, 0x4e, 0x2c, 0x56, 0xb8, 0x8d, 0xae, 0x72, 0x53, - 0x67, 0xfe, 0x8f, 0x42, 0x70, 0xf2, 0xe5, 0x36, 0x2e, 0xfc, 0x13, 0x67, 0x61, 0x38, 0x1c, 0x81, - 0x5f, 0x6d, 0xde, 0xc8, 0xe2, 0x64, 0x62, 0x16, 0x14, 0x92, 0x3e, 0x93, 0xee, 0x7f, 0x2d, 0x4a, - 0xac, 0x1e, 0x4f, 0xe1, 0x6f, 0x2c, 0x72, 0x9e, 0x28, 0x41, 0xa2, 0x87, 0xc4, 0x20, 0xc5, 0x6e, - 0xdb, 0xa1, 0x57, 0xec, 0x43, 0x48, 0x09, 0x0b, 0x9a, 0x8d, 0x48, 0xad, 0x12, 0x73, 0x4f, 0x8d, - 0x93, 0x04, 0x78, 0xe1, 0x8a, 0xbb, 0x43, 0x69, 0xbd, 0xf3, 0x4d, 0xf5, 0x97, 0xf4, 0x2e, 0x0d, - 0x1b, 0x2c, 0x89, 0x74, 0x71, 0x31, 0x0d, 0xfb, 0xe9, 0xa6, 0xe2, 0xdf, 0x10, 0xda, 0xf8, 0xe6, - 0x87, 0x25, 0xcf, 0x7a, 0x51, 0x72, 0xa5, 0xfe, 0xb8, 0xd3, 0x00, 0xd3, 0xc8, 0x85, 0x20, 0x44, - 0xd5, 0x59, 0xd0, 0xf8, 0x15, 0xcb, 0xbb, 0x60, 0x8e, 0x7e, 0x76, 0xe9, 0x01, 0xe8, 0xe6, 0x8c, - 0x13, 0xf0, 0x37, 0xb8, 0x72, 0xab, 0x4e, 0x6d, 0xda, 0xbe, 0x11, 0x81, 0x29, 0x20, 0x9c, 0x03, - 0x81, 0x17, 0xb8, 0x61, 0xe6, 0x07, 0x73, 0x88, 0xcb, 0x75, 0xfd, 0x2b, 0x22, 0xfe, 0x22, 0xb1, - 0x05, 0x99, 0x73, 0xc0, 0x22, 0xe7, 0xb0, 0xdb, 0x81, 0xbf, 0x5d, 0x3a, 0xb7, 0x68, 0x97, 0x5c, - 0x0e, 0x6d, 0xe1, 0x8e, 0x22, 0x07, 0x73, 0x90, 0x9c, 0xff, 0xaf, 0x21, 0x10, 0x9c, 0x22, 0xc0, - 0xd2, 0x16, 0x60, 0x83, 0x11, 0x60, 0x9a, 0x84, 0x84, 0x27, 0x3b, 0xe8, 0x24, 0x39, 0xe3, 0x9c, - 0x10, 0x18, 0xa4, 0x54, 0x8c, 0x63, 0xd0, 0x6a, 0xa7, 0x20, 0xaf, 0x0d, 0x1f, 0x3e, 0xef, 0xe8, - 0x98, 0xc3, 0xcb, 0xe3, 0x33, 0xfe, 0xb6, 0x26, 0xcb, 0x29, 0x07, 0x7e, 0x41, 0x6e, 0xfc, 0x87, - 0x32, 0x73, 0xcf, 0x65, 0xa5, 0x2e, 0x3b, 0xc3, 0xf0, 0x8a, 0x5b, 0xd1, 0x48, 0x1e, 0x0d, 0x1f, - 0xfe, 0x48, 0xdc, 0x1e, 0x7f, 0xb6, 0x72, 0x11, 0xcd, 0x64, 0x49, 0x37, 0xd5, 0x57, 0x07, 0xf2, - 0x9b, 0x68, 0x2a, 0x9e, 0x7d, 0xc2, 0x1d, 0x75, 0xd1, 0x61, 0xd6, 0x3b, 0xc9, 0x95, 0xa2, 0x27, - 0xbb, 0x9c, 0x3b, 0xee, 0x47, 0xce, 0xab, 0x79, 0x3c, 0xfe, 0x5b, 0xd5, 0xed, 0x02, 0x16, 0x80, - 0x0e, 0x32, 0x6c, 0x9d, 0x53, 0x47, 0xe8, 0xcf, 0x0e, 0xb9, 0x94, 0xaf, 0xc4, 0xcf, 0x49, 0xb6, - 0x94, 0x2e, 0xfd, 0x2b, 0x12, 0x10, 0xa3, 0xe0, 0xce, 0x8a, 0xe7, 0x78, 0xc2, 0xfb, 0xd3, 0x72, - 0x1a, 0x1c, 0x73, 0x40, 0xa1, 0x4b, 0x34, 0xfe, 0xf0, 0x9f, 0x73, 0x68, 0x89, 0xb0, 0x82, 0xc5, - 0x9e, 0x06, 0x37, 0x7d, 0x73, 0xdc, 0xe4, 0x7c, 0xa2, 0xff, 0x85, 0x74, 0xae, 0x1c, 0x3f, 0x80, - 0x15, 0x8d, 0x94, 0x0a, 0x71, 0x8d, 0x6c, 0xa2, 0x5f, 0xcd, 0xef, 0x21, 0x38, 0xf0, 0xb8, 0x96, - 0xe9, 0x89, 0xc5, 0xc2, 0x62, 0xc8, 0x15, 0x68, 0xc7, 0x97, 0xdd, 0x00, 0xb5, 0xf7, 0x41, 0x0c, - 0xfa, 0xcc, 0x4d, 0x50, 0xff, 0x46, 0x5c, 0xc4, 0x9b, 0x78, 0xc9, 0xc5, 0x50, 0xea, 0x6e, 0xed, - 0xba, 0xff, 0x70, 0xde, 0x17, 0xf1, 0x3e, 0x09, 0xd9, 0x42, 0xe8, 0xa2, 0xdc, 0xf2, 0x35, 0xf5, - 0xb9, 0xcb, 0x62, 0x8b, 0x87, 0x30, 0x28, 0xce, 0x26, 0x3f, 0xba, 0xc9, 0x26, 0xc7, 0x82, 0x9f, - 0xf9, 0x66, 0xf8, 0xb9, 0x7f, 0xae, 0x11, 0x8c, 0x3b, 0x74, 0xd2, 0x83, 0x3c, 0x25, 0xb9, 0x18, - 0xc9, 0x83, 0x8b, 0xe2, 0xf1, 0x99, 0x33, 0x4b, 0xf7, 0x64, 0x59, 0xf2, 0x8f, 0x9e, 0x22, 0x58, - 0x8d, 0x39, 0xed, 0xf3, 0xd6, 0xef, 0x12, 0x99, 0xdd, 0x3f, 0x03, 0x0e, 0xcc, 0xb8, 0x1c, 0x81, - 0x94, 0x7d, 0x4d, 0x7f, 0x51, 0x38, 0xf7, 0x2f, 0x14, 0x4f, 0x99, 0xb3, 0xca, 0x1c, 0x43, 0x1d, - 0xd3, 0x08, 0xc7, 0xc2, 0xf7, 0x8c, 0x1b, 0xf9, 0x1d, 0x03, 0x08, 0xc1, 0x0f, 0xf0, 0x12, 0x41, - 0xed, 0xd6, 0xc5, 0xce, 0x58, 0x14, 0xa8, 0x76, 0x53, 0x17, 0xdd, 0x4b, 0xaa, 0xe2, 0x16, 0xc6, - 0x5f, 0x86, 0x7e, 0x08, 0x18, 0x3d, 0x5c, 0xb8, 0x3d, 0x4a, 0xa7, 0xd3, 0xdf, 0x33, 0x50, 0x7e, - 0x4b, 0x58, 0xfb, 0xae, 0x1b, 0x6e, 0xe8, 0x64, 0x0a, 0x20, 0x52, 0x51, 0xa0, 0x6d, 0xc1, 0xbb, - 0xc7, 0xf6, 0xc5, 0xad, 0xb5, 0x96, 0x61, 0x59, 0x6f, 0x92, 0x07, 0x4a, 0xd0, 0x09, 0xe9, 0xda, - 0xc2, 0xb1, 0x32, 0x56, 0x5a, 0x14, 0xce, 0x17, 0x06, 0xf9, 0x7b, 0xc6, 0x07, 0x1c, 0x74, 0xad, - 0xdd, 0x17, 0xb7, 0xdc, 0x86, 0x69, 0xda, 0x9a, 0xdb, 0x9c, 0x1b, 0xed, 0x46, 0xa4, 0x85, 0x60, - 0x81, 0x8b, 0x6e, 0xbe, 0x9b, 0x8d, 0x37, 0xeb, 0x17, 0x53, 0x81, 0x80, 0xb1, 0x1e, 0xa6, 0xb2, - 0xe5, 0x2a, 0xac, 0xd1, 0x36, 0xd8, 0x4e, 0x62, 0x4c, 0x10, 0x9e, 0xa1, 0x03, 0xd6, 0x3a, 0x2f, - 0x08, 0xb4, 0xdf, 0xd7, 0x08, 0x4d, 0x4d, 0x24, 0x7d, 0xfc, 0x38, 0x7d, 0x0d, 0x3a, 0xa4, 0x7a, - 0xaf, 0x34, 0xc8, 0x8c, 0xb8, 0xb5, 0xfe, 0x75, 0x4a, 0xe4, 0x72, 0xaf, 0x06, 0xa8, 0x56, 0xb7, - 0xbe, 0x9b, 0x5c, 0x2f, 0xd8, 0xa5, 0x61, 0x71, 0x8b, 0xc2, 0xf9, 0x9e, 0x31, 0x61, 0x30, 0xac, - 0xb9, 0xa0, 0x0f, 0x41, 0x17, 0xce, 0x35, 0x51, 0x58, 0x8b, 0x74, 0xe0, 0x5c, 0x83, 0xd6, 0xe3, - 0x5b, 0xcc, 0x29, 0xb9, 0xda, 0xd2, 0x06, 0x31, 0x06, 0x36, 0x6d, 0x70, 0x6d, 0x55, 0x8b, 0xad, - 0x37, 0xbd, 0xb3, 0x30, 0x66, 0x4c, 0x8c, 0x6d, 0x74, 0x0d, 0x5b, 0xcd, 0x66, 0x4b, 0xcb, 0x5b, - 0xc5, 0xaa, 0x1f, 0x8d, 0xb2, 0x65, 0x2d, 0x8e, 0xf2, 0xd4, 0x75, 0xe1, 0x5e, 0x3a, 0xd6, 0x42, - 0x56, 0x5e, 0xde, 0xea, 0xda, 0x25, 0x21, 0x2f, 0x1f, 0x35, 0x7b, 0xb4, 0x30, 0xce, 0x23, 0xd8, - 0x5a, 0x97, 0x8f, 0x53, 0x2e, 0xad, 0x18, 0x27, 0x56, 0xfd, 0x70, 0x36, 0x71, 0x2f, 0x88, 0x99, - 0x50, 0x4c, 0x5e, 0x3e, 0xa7, 0xb9, 0xee, 0xf2, 0x56, 0x69, 0xd5, 0xb5, 0xf8, 0x76, 0xbd, 0x56, - 0xbe, 0x4d, 0x60, 0x73, 0x30, 0x26, 0x69, 0xd8, 0x4d, 0xa9, 0x1f, 0x50, 0x9a, 0x7e, 0xf8, 0xa0, - 0x4f, 0x9c, 0xdb, 0xeb, 0xd3, 0x84, 0x98, 0xb1, 0x89, 0x83, 0x01, 0xa5, 0x6c, 0x31, 0xf9, 0x0d, - 0x3b, 0xb0, 0x16, 0x43, 0xc7, 0xab, 0xa8, 0xaa, 0x69, 0xe8, 0x3d, 0xb5, 0x1f, 0xdf, 0x03, 0x7e, - 0x2d, 0x75, 0x86, 0x8b, 0x2b, 0xa9, 0x73, 0x06, 0xdd, 0x4f, 0x7c, 0x91, 0x97, 0x0e, 0x3d, 0xef, - 0x0f, 0x7d, 0x2d, 0x66, 0x01, 0x35, 0x05, 0xac, 0x1f, 0x69, 0x9a, 0xe3, 0x0c, 0xb4, 0x75, 0x26, - 0x7d, 0xe0, 0x02, 0xf7, 0x7b, 0x3f, 0xe8, 0xc2, 0x84, 0xee, 0x58, 0xde, 0x67, 0x00, 0x10, 0x40, - 0x88, 0x29, 0xb0, 0x6d, 0xc3, 0xe7, 0x5b, 0xe1, 0xfd, 0x05, 0xf9, 0x33, 0x42, 0x8b, 0x60, 0x4a, - 0xe0, 0x22, 0x19, 0xf1, 0x03, 0xed, 0x6b, 0x37, 0xf8, 0x6d, 0x0b, 0xe4, 0x17, 0x6b, 0x2e, 0xbc, - 0xd8, 0xb0, 0x2d, 0x08, 0x56, 0x42, 0x61, 0xd4, 0x5b, 0xc8, 0x8c, 0xd4, 0x62, 0xfa, 0x45, 0x2f, - 0x58, 0xa8, 0x30, 0x7e, 0xe0, 0xbb, 0x74, 0x17, 0xa1, 0xe3, 0x64, 0x79, 0x30, 0x28, 0xda, 0x38, - 0xfd, 0x86, 0x00, 0x24, 0x12, 0x07, 0x52, 0xb0, 0x6d, 0x43, 0xa7, 0x45, 0xeb, 0x22, 0xfb, 0xa2, - 0xc0, 0x8d, 0xa5, 0xa8, 0x5a, 0xc2, 0x19, 0xa8, 0x36, 0xe4, 0xc1, 0x2e, 0x52, 0x17, 0x73, 0xc5, - 0x22, 0xf4, 0x10, 0x04, 0x91, 0xba, 0x98, 0x15, 0x05, 0x3e, 0x94, 0x3f, 0xe8, 0xbf, 0xda, 0x08, - 0xde, 0xb2, 0xb9, 0xb2, 0x18, 0xd7, 0x1f, 0x77, 0x6b, 0x0f, 0x98, 0xb2, 0xb7, 0x29, 0x30, 0x6d, - 0x20, 0x5c, 0x98, 0x89, 0x03, 0x58, 0x96, 0xe5, 0x06, 0x13, 0xe6, 0xfe, 0xa8, 0xf4, 0x06, 0x12, - 0x1d, 0x92, 0x77, 0x89, 0x03, 0x31, 0x87, 0xdf, 0x2a, 0x50, 0xda, 0x78, 0x69, 0xac, 0xad, 0x29, - 0xfa, 0x0b, 0x02, 0x60, 0x25, 0x17, 0x00, 0x70, 0xfd, 0xf3, 0x23, 0x98, 0x78, 0xfd, 0xa6, 0xf4, - 0xc8, 0x5c, 0xa8, 0x45, 0x8e, 0x94, 0xdd, 0x8d, 0x56, 0xe4, 0xc8, 0xc6, 0xfd, 0x76, 0x84, 0x57, - 0x08, 0xb6, 0x21, 0xec, 0x7e, 0x64, 0xe3, 0xc1, 0x82, 0xf4, 0x06, 0x8a, 0xb8, 0x84, 0x72, 0x38, - 0x95, 0x13, 0xc5, 0x51, 0xf1, 0x77, 0xa7, 0xf3, 0x70, 0xa1, 0x03, 0xc1, 0x44, 0xe2, 0xdd, 0xac, - 0x43, 0x36, 0xb5, 0xdc, 0x74, 0xb3, 0x0f, 0x4b, 0xc8, 0x48, 0x6d, 0x74, 0x5a, 0xf3, 0xc5, 0x0a, - 0x4c, 0x30, 0xce, 0xaa, 0x1c, 0x3f, 0xab, 0x32, 0x76, 0x96, 0x98, 0x80, 0x5d, 0xfd, 0x6d, 0xe5, - 0xf4, 0xfa, 0xe4, 0xfb, 0xe1, 0xbd, 0x1d, 0x50, 0xa6, 0x85, 0x1c, 0xbd, 0x10, 0x24, 0x0b, 0xd9, - 0x0a, 0xbb, 0xbb, 0x24, 0xe4, 0xd9, 0x25, 0xa6, 0x9e, 0x50, 0xcc, 0xb1, 0xcb, 0x47, 0x42, 0xa9, - 0x8c, 0x65, 0xe0, 0xa1, 0xec, 0xde, 0x97, 0x12, 0x71, 0x63, 0x0a, 0xcd, 0x25, 0x46, 0xaf, 0xf2, - 0xe7, 0x29, 0xb8, 0xdf, 0x2c, 0x6e, 0x1d, 0x8e, 0x60, 0xd9, 0x63, 0xee, 0xe2, 0x82, 0xb7, 0xd9, - 0x84, 0xac, 0x85, 0x67, 0x64, 0x35, 0xe6, 0x17, 0x10, 0xdf, 0x5a, 0x44, 0xfc, 0x5a, 0x08, 0xf3, - 0xad, 0x15, 0x98, 0xa7, 0x88, 0x07, 0x69, 0x72, 0x09, 0xe2, 0xd7, 0xbc, 0xf5, 0x24, 0xff, 0x37, - 0xe0, 0xfe, 0xab, 0xa2, 0x28, 0x82, 0xec, 0xa2, 0x33, 0x0e, 0x9b, 0x6b, 0x71, 0xe8, 0x6c, 0x29, - 0x8e, 0xeb, 0x23, 0xba, 0x0c, 0xab, 0xe3, 0x38, 0x32, 0x47, 0x92, 0xfd, 0x1d, 0xac, 0xde, 0x7d, - 0x84, 0xd5, 0xbb, 0xff, 0x51, 0xac, 0x7e, 0x1e, 0x3f, 0x77, 0x08, 0x3b, 0xc3, 0xef, 0x18, 0xf1, - 0x58, 0x7a, 0xf9, 0x27, 0x68, 0xef, 0xe4, 0x23, 0x2c, 0x9d, 0x7c, 0x02, 0x4b, 0x95, 0xac, 0x8b, - 0xa7, 0x6c, 0x45, 0x5e, 0x86, 0xaa, 0x52, 0xb1, 0x28, 0xff, 0x43, 0x08, 0x3a, 0x21, 0xda, 0x58, - 0xd5, 0x33, 0x37, 0x64, 0x08, 0x12, 0x38, 0x12, 0xd3, 0xd2, 0xe5, 0xe9, 0x5e, 0xc4, 0x0b, 0x71, - 0x64, 0x2b, 0x9e, 0xb8, 0x7e, 0x0b, 0x6b, 0xd7, 0x01, 0xda, 0xe3, 0x79, 0xe5, 0x75, 0xbf, 0xfd, - 0x11, 0xde, 0xe8, 0x1e, 0xe8, 0x51, 0xd7, 0xda, 0x3f, 0xb0, 0x07, 0xae, 0xc0, 0xd8, 0x35, 0x30, - 0x49, 0xec, 0x89, 0x4e, 0xb4, 0x65, 0xa8, 0xea, 0xff, 0x13, 0x6b, 0xee, 0xe0, 0x23, 0x6a, 0xfa, - 0x5d, 0xbc, 0xc4, 0xaf, 0xba, 0xbf, 0x83, 0x97, 0x38, 0xb4, 0xac, 0x1d, 0x58, 0x84, 0xe8, 0x1f, - 0x61, 0xa6, 0xbd, 0x82, 0x60, 0xd6, 0x3e, 0x8b, 0x99, 0x9d, 0x0f, 0x36, 0x57, 0x17, 0x31, 0x6b, - 0x7f, 0x0f, 0x33, 0x8b, 0x88, 0x59, 0xfb, 0xf7, 0x30, 0xb3, 0x03, 0xf0, 0x3c, 0xbc, 0xac, 0x45, - 0x11, 0x13, 0xc1, 0xcf, 0x64, 0x05, 0x7e, 0x68, 0xfe, 0x40, 0x6d, 0xa3, 0xa4, 0xf8, 0x69, 0x5c, - 0xdd, 0x7f, 0x80, 0xab, 0xfb, 0xff, 0x93, 0x30, 0x75, 0x8f, 0xa7, 0x96, 0x4b, 0x51, 0xe5, 0xe3, - 0xa0, 0xad, 0x68, 0x7f, 0x87, 0xe7, 0xac, 0x71, 0x68, 0x69, 0xc4, 0xa1, 0x85, 0x17, 0xbe, 0x15, - 0x0d, 0x7d, 0x9a, 0xa9, 0xa0, 0x9d, 0xa6, 0xe3, 0x8c, 0x11, 0xb7, 0xe5, 0x7f, 0x44, 0xdc, 0xa6, - 0xe8, 0x58, 0x5b, 0x81, 0x8f, 0x36, 0xeb, 0xcb, 0x32, 0x74, 0xd0, 0x6b, 0x39, 0xd1, 0x09, 0x80, - 0xc4, 0x40, 0x97, 0xf9, 0x66, 0x36, 0x13, 0x22, 0x0a, 0x75, 0xf0, 0x1f, 0xe8, 0x8a, 0x02, 0xfd, - 0x7c, 0x5c, 0x5d, 0x04, 0x46, 0xe6, 0xcb, 0xbb, 0x8b, 0xf7, 0x41, 0x49, 0x97, 0x93, 0xea, 0xb8, - 0xb1, 0xc4, 0x42, 0x56, 0xc2, 0x90, 0x2f, 0x3c, 0x26, 0xb3, 0x0c, 0xba, 0x57, 0x65, 0x6b, 0x59, - 0x03, 0x6b, 0xd1, 0x16, 0x3a, 0xe5, 0x50, 0x0b, 0x8f, 0x44, 0xd3, 0x8c, 0xc9, 0xf2, 0xee, 0x7b, - 0x35, 0xb6, 0x7c, 0x9d, 0xe6, 0xa3, 0x21, 0x80, 0xae, 0xcc, 0x37, 0x70, 0xaf, 0x58, 0x43, 0x81, - 0xe2, 0x7f, 0xf5, 0x30, 0x68, 0xb5, 0xcf, 0x0f, 0x03, 0xff, 0xe3, 0x5b, 0x61, 0x0d, 0xac, 0x80, - 0xdf, 0x8b, 0x37, 0x99, 0x01, 0x74, 0x01, 0x2f, 0x46, 0x45, 0xc7, 0x21, 0xcb, 0x91, 0x49, 0xde, - 0xd1, 0x00, 0xe8, 0xaa, 0x21, 0x70, 0xd3, 0xf0, 0xbd, 0x6d, 0x7d, 0x66, 0x0c, 0xa0, 0x02, 0xf0, - 0x63, 0xb8, 0x54, 0x41, 0xab, 0x5b, 0x31, 0x04, 0x79, 0xf9, 0x10, 0xe2, 0x7a, 0x1f, 0x82, 0x8d, - 0xac, 0x73, 0x05, 0x6c, 0x19, 0x61, 0x7f, 0x92, 0x48, 0x11, 0x72, 0xa7, 0xcc, 0xc1, 0x6e, 0xbe, - 0x29, 0xfa, 0x6a, 0xc4, 0xd0, 0x0a, 0x9f, 0x9d, 0x5b, 0xb9, 0x8c, 0x98, 0xe1, 0xe0, 0xd3, 0xfd, - 0x70, 0x55, 0xe7, 0x59, 0x85, 0x4f, 0x52, 0xa8, 0xa5, 0x77, 0xf9, 0xa5, 0xab, 0xe8, 0x5d, 0x63, - 0xf8, 0x29, 0xed, 0xc2, 0x31, 0x04, 0x2a, 0xfd, 0xa2, 0x66, 0x21, 0x19, 0x74, 0x61, 0x52, 0x05, - 0x4f, 0xea, 0x63, 0xff, 0xa8, 0x42, 0x27, 0x99, 0x23, 0xcb, 0xd4, 0xc8, 0x92, 0x8b, 0xd7, 0x1b, - 0xd9, 0x2c, 0x35, 0x6e, 0xac, 0x5d, 0x2f, 0xd9, 0xb3, 0x3a, 0xb6, 0x26, 0x86, 0x6d, 0x66, 0x90, - 0x22, 0x8b, 0x9c, 0xa1, 0x56, 0x98, 0x4e, 0x6d, 0x78, 0xe5, 0xed, 0x67, 0xcc, 0xc8, 0xde, 0xd2, - 0x0c, 0x87, 0xee, 0x34, 0xf8, 0x25, 0xbe, 0x0d, 0x8b, 0xb2, 0x54, 0xfa, 0xd8, 0x0f, 0x1e, 0xdb, - 0xc1, 0xe3, 0x04, 0x1f, 0xb7, 0xb2, 0x81, 0xcd, 0x68, 0x2d, 0xd2, 0x6a, 0x36, 0xb6, 0xd5, 0xb8, - 0x46, 0xb3, 0xe1, 0x46, 0xd7, 0x3e, 0x6c, 0x35, 0x17, 0x6f, 0x1e, 0x84, 0x46, 0x73, 0xc1, 0x76, - 0xfc, 0x51, 0xab, 0xb9, 0xcf, 0x0c, 0x75, 0x8d, 0x6b, 0x35, 0xbf, 0x68, 0x1f, 0xf3, 0x8d, 0x61, - 0x2c, 0x9e, 0xa1, 0x30, 0x10, 0xbd, 0x8e, 0x9c, 0x32, 0xeb, 0x5a, 0x60, 0x15, 0x63, 0x76, 0x0e, - 0x32, 0x9d, 0x30, 0xb3, 0x57, 0xd8, 0xea, 0xe5, 0x46, 0xf2, 0x0e, 0x9b, 0xbc, 0x98, 0xe8, 0x14, - 0xb2, 0x5e, 0x7a, 0x32, 0x85, 0x07, 0xac, 0xe3, 0xed, 0x7a, 0x74, 0x8f, 0x8a, 0xd9, 0x46, 0x5f, - 0xc8, 0x5b, 0xd7, 0x98, 0xe8, 0xb4, 0xf0, 0x1e, 0x1e, 0xe9, 0xa3, 0x88, 0x81, 0x47, 0x87, 0xde, - 0xb7, 0x23, 0xeb, 0xa2, 0x01, 0xab, 0x9c, 0xda, 0x39, 0x34, 0xa2, 0xf7, 0x9d, 0x41, 0x5d, 0x2c, - 0x47, 0x28, 0x08, 0xdb, 0xd1, 0x7b, 0xa1, 0xd9, 0x64, 0x17, 0x6e, 0xb9, 0xee, 0x52, 0x3b, 0x0a, - 0x99, 0xba, 0xe6, 0xd7, 0xb0, 0x4d, 0xcf, 0xbb, 0xc2, 0xcc, 0x86, 0x92, 0xaf, 0xb8, 0x06, 0xe7, - 0x8f, 0x90, 0xc9, 0x50, 0x89, 0x5e, 0x59, 0xc8, 0x57, 0x3e, 0x85, 0x31, 0xb7, 0x07, 0x14, 0x63, - 0xed, 0x3c, 0xc3, 0x18, 0x95, 0xa0, 0x04, 0x00, 0x43, 0x1c, 0x87, 0xf8, 0xd3, 0xb1, 0xe6, 0x01, - 0x9f, 0xf8, 0xe3, 0x62, 0xd2, 0x09, 0x2f, 0x29, 0xb0, 0xb0, 0x9b, 0x42, 0x0f, 0x96, 0xbb, 0x8f, - 0x79, 0x1e, 0xdd, 0x6b, 0x9c, 0xab, 0x4e, 0x5d, 0x6c, 0xd1, 0x70, 0xe0, 0x81, 0x48, 0xf7, 0x8d, - 0xc5, 0x07, 0xa7, 0x62, 0x8b, 0x24, 0xba, 0xde, 0x65, 0xc8, 0x37, 0x60, 0xe1, 0x51, 0xe7, 0xa1, - 0xa5, 0x25, 0x16, 0x09, 0x24, 0x88, 0xa4, 0xc2, 0xaf, 0x5b, 0x4c, 0xd5, 0x5d, 0xfb, 0x23, 0xc3, - 0x6d, 0xb9, 0xe7, 0x91, 0x49, 0x14, 0x5d, 0x7e, 0xa8, 0x72, 0xcf, 0x18, 0x9d, 0x65, 0x25, 0xd7, - 0xa2, 0x1c, 0xc4, 0xeb, 0x86, 0x3f, 0x19, 0xf8, 0x12, 0x46, 0x0c, 0x1e, 0xab, 0xd1, 0x8f, 0x02, - 0xe3, 0x3c, 0xf9, 0x93, 0xcd, 0x5c, 0x63, 0xa8, 0xb7, 0x30, 0x37, 0x2b, 0xf8, 0xdd, 0xd3, 0x4b, - 0x86, 0x7c, 0x6a, 0x9c, 0x5f, 0x00, 0xc4, 0x99, 0x0d, 0x43, 0x7a, 0x9e, 0xe7, 0x3e, 0x07, 0x19, - 0xee, 0x91, 0x59, 0x3a, 0x9d, 0x16, 0x16, 0x44, 0x76, 0xda, 0x87, 0x58, 0x11, 0x7e, 0x2d, 0x62, - 0x78, 0xf6, 0xe2, 0x1d, 0xba, 0x26, 0x44, 0x97, 0xc0, 0x63, 0x88, 0x9a, 0x4d, 0x31, 0xcb, 0xe7, - 0xb7, 0x96, 0xd5, 0x07, 0x00, 0x1d, 0x40, 0x5c, 0x7a, 0xe0, 0x0c, 0xdd, 0x03, 0x80, 0x25, 0x2b, - 0x80, 0x9d, 0xf4, 0x94, 0x95, 0xe8, 0x12, 0xf8, 0xfd, 0xde, 0xb8, 0x14, 0x6d, 0xef, 0x02, 0x83, - 0xaa, 0xeb, 0x23, 0x4d, 0x93, 0xb0, 0x63, 0x5a, 0xcb, 0x81, 0x7d, 0xa5, 0x4f, 0xd2, 0x16, 0x19, - 0x1a, 0x63, 0x72, 0xe4, 0x90, 0x61, 0x42, 0x9c, 0x68, 0x04, 0xe7, 0x60, 0x2a, 0x26, 0x61, 0xe3, - 0x79, 0x1d, 0x11, 0xdb, 0x39, 0xb6, 0x0d, 0x3d, 0x31, 0xb3, 0x86, 0xd8, 0xe9, 0xea, 0x17, 0x39, - 0xfc, 0x75, 0x57, 0x7e, 0xca, 0xa4, 0x5c, 0x51, 0x96, 0xf8, 0x04, 0x6c, 0x0e, 0x46, 0xb8, 0xb6, - 0x7c, 0x88, 0x94, 0xbc, 0xf2, 0x9b, 0x4b, 0x16, 0x79, 0xcc, 0x3c, 0x21, 0xd5, 0xed, 0x81, 0xf4, - 0xd6, 0x71, 0x3e, 0xb2, 0x27, 0xf7, 0xa6, 0x62, 0x1c, 0xd3, 0x05, 0xd1, 0x99, 0x02, 0xc1, 0x8f, - 0x79, 0xb8, 0x7c, 0x97, 0xc1, 0x13, 0x86, 0xee, 0xc9, 0xc6, 0xd2, 0x75, 0xed, 0x82, 0xc5, 0x83, - 0xff, 0x60, 0x8d, 0xaf, 0xf1, 0x8b, 0xfc, 0x37, 0xd6, 0x38, 0x73, 0x40, 0x5d, 0xb1, 0xc4, 0xbd, - 0x02, 0x52, 0xff, 0xa8, 0x9b, 0x10, 0x99, 0xbb, 0xa1, 0x2d, 0x26, 0xd3, 0xb4, 0x63, 0xf8, 0xad, - 0x60, 0xfc, 0x70, 0x30, 0x64, 0x28, 0xc0, 0xbc, 0x19, 0x94, 0xb6, 0x36, 0xb2, 0xea, 0xdf, 0x96, - 0x16, 0x67, 0xb3, 0xec, 0xd7, 0xf8, 0xef, 0x65, 0x1c, 0x1c, 0xf1, 0x2d, 0xed, 0x10, 0x3b, 0x92, - 0x4a, 0x88, 0xe8, 0x7a, 0x86, 0x43, 0x70, 0xd7, 0x60, 0xd8, 0x9d, 0xdc, 0x3b, 0x08, 0xf4, 0x78, - 0x50, 0x94, 0x05, 0xb9, 0x68, 0xfa, 0x07, 0x39, 0xd0, 0xfe, 0xc3, 0xff, 0x1c, 0xef, 0x89, 0x92, - 0xb6, 0xeb, 0x47, 0x11, 0xa2, 0x63, 0x17, 0x73, 0x5e, 0x5f, 0xd8, 0x7b, 0x30, 0xa0, 0xa0, 0xcc, - 0x25, 0xaa, 0xd7, 0x5e, 0xb7, 0x98, 0xcf, 0x23, 0xbd, 0x5d, 0x41, 0xa7, 0x2d, 0xbb, 0x9f, 0x6f, - 0x94, 0x6b, 0xe1, 0x9d, 0x89, 0x96, 0x69, 0x1b, 0x53, 0x57, 0x8a, 0xe9, 0x69, 0x4e, 0x5d, 0xf4, - 0x8b, 0x86, 0xac, 0x0b, 0xac, 0x81, 0xfd, 0xa9, 0x47, 0x07, 0x61, 0x5b, 0x80, 0xef, 0x4a, 0x89, - 0x32, 0x8c, 0x37, 0x6e, 0x6f, 0xc0, 0x2e, 0xda, 0x83, 0x6e, 0xca, 0xbb, 0xa2, 0xb0, 0xd8, 0x49, - 0x81, 0x52, 0x01, 0xf4, 0xb4, 0x9c, 0xcb, 0x95, 0x96, 0xf6, 0x73, 0x8d, 0xef, 0x28, 0x2d, 0xc9, - 0xeb, 0xff, 0xbf, 0xdd, 0xcb, 0xb5, 0x68, 0x37, 0x83, 0x5e, 0x66, 0x63, 0x7b, 0x49, 0x3b, 0x58, - 0x29, 0xe4, 0x6a, 0x91, 0xe5, 0x1f, 0x8f, 0x49, 0x5a, 0xf2, 0x13, 0x1d, 0x5c, 0xfb, 0x3c, 0x1e, - 0x83, 0x0e, 0xe6, 0x96, 0x74, 0x10, 0x96, 0x4b, 0xa5, 0x94, 0xff, 0xdc, 0x54, 0xd3, 0x82, 0x2b, - 0x3b, 0xb8, 0xf6, 0xbb, 0x13, 0x1d, 0x74, 0xf0, 0xce, 0x58, 0x4e, 0x8e, 0x95, 0x72, 0xbe, 0xf0, - 0xb9, 0x1e, 0x62, 0xc1, 0xff, 0x36, 0x52, 0xdc, 0x87, 0x2d, 0x6e, 0xd9, 0x34, 0x43, 0xcb, 0xc5, - 0xcf, 0xd1, 0x21, 0x2d, 0xf9, 0x4f, 0xd1, 0x61, 0xf4, 0x6c, 0x8d, 0x32, 0x04, 0x39, 0xc6, 0x6c, - 0x16, 0x65, 0xbe, 0xfc, 0x61, 0xf8, 0x1a, 0x2f, 0xe8, 0xc2, 0x20, 0xc9, 0x3b, 0xf1, 0x64, 0xdd, - 0x7c, 0xae, 0xf8, 0xf1, 0x31, 0x37, 0xaf, 0x39, 0xb8, 0xc7, 0x73, 0x26, 0x41, 0xab, 0xd3, 0x4a, - 0xdb, 0x1b, 0x2d, 0xe3, 0x9a, 0x25, 0x3f, 0x73, 0xf6, 0xfd, 0x8f, 0xda, 0x26, 0x3f, 0x79, 0xf4, - 0xcd, 0x6c, 0x76, 0xc1, 0xb8, 0xa8, 0x08, 0x10, 0xa0, 0x37, 0x64, 0xc5, 0x73, 0xe5, 0x02, 0x1b, - 0x87, 0x15, 0x67, 0xc4, 0xe3, 0xd0, 0x93, 0xfd, 0xcd, 0x09, 0xe2, 0xe7, 0x87, 0x76, 0x81, 0xca, - 0xbb, 0x74, 0xa7, 0x2b, 0xc8, 0x95, 0x4f, 0x4f, 0x50, 0xd0, 0x81, 0x23, 0xdc, 0x9c, 0x6c, 0xd5, - 0x79, 0x8b, 0x3d, 0x94, 0xe1, 0x26, 0xc9, 0x2f, 0xf8, 0xbb, 0x3e, 0x0a, 0xf2, 0xff, 0xac, 0x8f, - 0xc2, 0x32, 0x5b, 0x33, 0x8f, 0x75, 0x8a, 0xb9, 0xac, 0x3f, 0x51, 0xaa, 0x37, 0xb4, 0xa5, 0x07, - 0xd5, 0xb4, 0x56, 0x2e, 0x6a, 0x85, 0x77, 0xb7, 0x9e, 0x95, 0x33, 0x16, 0xf2, 0x7f, 0xfa, 0xcd, - 0x63, 0x8f, 0x66, 0x36, 0xf6, 0x44, 0x88, 0xb7, 0xdc, 0x8f, 0x6c, 0x50, 0x37, 0xa8, 0x6d, 0xe3, - 0xf7, 0x96, 0xce, 0x5a, 0xbc, 0x83, 0xc1, 0xef, 0x58, 0xb1, 0xdd, 0xf9, 0x58, 0xfb, 0xdb, 0x13, - 0x12, 0x99, 0x8f, 0x1c, 0xd0, 0x31, 0x1b, 0x8f, 0x90, 0x5d, 0x3d, 0x11, 0xf9, 0xc8, 0xa2, 0xe1, - 0xe6, 0x61, 0x6d, 0xf5, 0x44, 0x78, 0xee, 0x51, 0xbf, 0xc9, 0xc4, 0x9a, 0xb9, 0x0f, 0x38, 0x98, - 0x3b, 0x0f, 0xb9, 0x7f, 0x86, 0x87, 0xc9, 0xff, 0x8d, 0x1c, 0xec, 0x13, 0x13, 0x91, 0x17, 0xb7, - 0xdc, 0x79, 0xc8, 0xad, 0x9e, 0x87, 0xc2, 0xdf, 0x5e, 0x10, 0x32, 0x29, 0xff, 0xad, 0x05, 0x91, - 0xff, 0xe4, 0x82, 0xc8, 0x7f, 0x66, 0x41, 0xe4, 0xb3, 0xff, 0x47, 0xaf, 0x87, 0x42, 0xb0, 0x1e, - 0xf2, 0xcb, 0xe6, 0xa1, 0x37, 0x35, 0xcc, 0x40, 0x87, 0x71, 0xef, 0x42, 0x53, 0x3d, 0x2d, 0x24, - 0x57, 0x41, 0x86, 0x1c, 0x15, 0xa9, 0x0c, 0x4e, 0x78, 0x8e, 0xf7, 0xe8, 0x73, 0x8d, 0x5b, 0x1f, - 0x70, 0x54, 0x80, 0xed, 0xee, 0x85, 0x5b, 0x4d, 0x0a, 0x38, 0x58, 0xbc, 0xc1, 0xf4, 0xd1, 0x26, - 0x2f, 0x7c, 0x6f, 0x35, 0x4e, 0x1e, 0x0a, 0xcd, 0xde, 0x05, 0x1d, 0x40, 0x22, 0x2b, 0xd1, 0x53, - 0x38, 0xf7, 0xea, 0xd3, 0x6f, 0x89, 0x6a, 0x6b, 0xe1, 0x51, 0x67, 0x23, 0x42, 0xda, 0x87, 0x83, - 0xce, 0x17, 0xda, 0xdc, 0xa0, 0xd7, 0x96, 0x4d, 0x93, 0x37, 0xe8, 0xac, 0x37, 0xe8, 0xdc, 0xd2, - 0x41, 0xe7, 0xc4, 0x45, 0x59, 0x3f, 0x6e, 0xd0, 0xb9, 0x4f, 0x0f, 0x7a, 0x6d, 0x95, 0x08, 0x0d, - 0x3d, 0xcb, 0xfd, 0xce, 0xa0, 0x99, 0x92, 0x5c, 0xe8, 0x7c, 0x30, 0xd5, 0xfc, 0xa0, 0x73, 0xde, - 0xa0, 0xf3, 0x91, 0x41, 0xaf, 0x05, 0xa3, 0xce, 0x2f, 0x4e, 0x75, 0xdc, 0xa0, 0xf3, 0x4b, 0x06, - 0xfd, 0x29, 0xc5, 0x66, 0xa9, 0x46, 0x8c, 0xdd, 0x68, 0x91, 0xfe, 0x10, 0x23, 0x89, 0x8b, 0xbc, - 0x3b, 0x6a, 0x8c, 0xb5, 0xc7, 0xbd, 0x80, 0x11, 0x55, 0xc2, 0x23, 0xec, 0x8e, 0xdd, 0xc9, 0xe0, - 0xd8, 0x1d, 0xfb, 0x80, 0x91, 0xb8, 0xb5, 0xac, 0x68, 0x6e, 0xb9, 0xf5, 0xcf, 0x76, 0x17, 0x8e, - 0x65, 0xc3, 0x1b, 0x27, 0xd1, 0x59, 0xd0, 0x65, 0x2a, 0xcd, 0x5d, 0x13, 0x40, 0x90, 0x60, 0xbb, - 0x03, 0x88, 0x31, 0x61, 0x6f, 0xdd, 0x04, 0x17, 0xf3, 0x43, 0xae, 0x88, 0x8e, 0xe3, 0xa1, 0x9d, - 0x5d, 0x54, 0x08, 0xf8, 0x1b, 0x65, 0x78, 0xa5, 0x62, 0xba, 0xe8, 0x79, 0x5c, 0xc9, 0xe9, 0x6c, - 0xc0, 0xe7, 0xd2, 0x9b, 0x40, 0xfd, 0x7a, 0xdb, 0x36, 0x6b, 0xcc, 0x41, 0x19, 0xcd, 0x5f, 0xd4, - 0xad, 0x93, 0x7e, 0xff, 0xcb, 0x27, 0x27, 0x97, 0x84, 0x68, 0x81, 0xc8, 0xb0, 0x2f, 0x2d, 0xec, - 0xf4, 0x87, 0xd8, 0x36, 0x5f, 0x35, 0x71, 0xc5, 0xc1, 0x46, 0x57, 0xdc, 0x72, 0x01, 0x71, 0x47, - 0x1a, 0xcb, 0x0c, 0x6a, 0xec, 0x26, 0x4d, 0xbc, 0xd1, 0x3c, 0xd6, 0x9e, 0xb6, 0xb6, 0xc4, 0x68, - 0x4e, 0xe7, 0x3f, 0xf9, 0x4d, 0x58, 0x62, 0x31, 0x77, 0xb3, 0x63, 0xc4, 0x0b, 0xde, 0xee, 0xf5, - 0x39, 0xb3, 0xd7, 0xda, 0x27, 0x0d, 0xe6, 0x0b, 0xf6, 0x72, 0xda, 0x89, 0x88, 0xad, 0xca, 0x55, - 0xb1, 0xc3, 0x56, 0x70, 0x86, 0x3e, 0x24, 0xa3, 0x80, 0x9e, 0x97, 0xed, 0x1e, 0xe6, 0x47, 0x44, - 0xbd, 0xd4, 0x5d, 0x97, 0x7e, 0xfb, 0xd0, 0x70, 0xf9, 0x82, 0x5b, 0xc7, 0x73, 0x24, 0x0f, 0x8a, - 0x68, 0xaa, 0xfe, 0xc2, 0x9f, 0xdf, 0x18, 0x26, 0xd1, 0x6f, 0x94, 0x76, 0x62, 0xb9, 0x13, 0xb9, - 0xb7, 0xe5, 0xc4, 0x3a, 0x91, 0x33, 0x6f, 0xe0, 0x78, 0xf7, 0xf5, 0x85, 0x46, 0xd7, 0x16, 0x5a, - 0xcd, 0x7e, 0xc2, 0x75, 0x7d, 0xb1, 0x51, 0xd7, 0x66, 0xbc, 0xf6, 0xc9, 0x66, 0x17, 0x5a, 0xcd, - 0x2d, 0xbd, 0xa2, 0xe0, 0x6f, 0x35, 0xb1, 0x57, 0x31, 0xfc, 0xd5, 0xff, 0x37, 0x47, 0x9b, 0x5f, - 0x36, 0x5a, 0x9f, 0xd7, 0xc7, 0x5e, 0x74, 0x61, 0xe4, 0xb3, 0xb6, 0xda, 0x51, 0xdf, 0xfd, 0x1e, - 0x4a, 0xf8, 0xa4, 0x9c, 0x5d, 0xe5, 0x51, 0xd0, 0xa4, 0x1a, 0xb6, 0x01, 0x5b, 0x7b, 0xf8, 0x11, - 0x9c, 0x1b, 0xcc, 0xc2, 0x8b, 0x5b, 0xc9, 0xc5, 0x6a, 0x7e, 0x98, 0xb1, 0x55, 0xf7, 0x2d, 0x22, - 0x75, 0xf0, 0x66, 0xa5, 0xbf, 0x20, 0xe8, 0x55, 0xf1, 0x18, 0x1a, 0x0c, 0x8e, 0x38, 0x04, 0xfa, - 0x31, 0x9a, 0xcf, 0x5e, 0x22, 0x11, 0x68, 0x10, 0x22, 0x86, 0x2f, 0x3c, 0x47, 0x59, 0x8b, 0x1c, - 0x33, 0xf8, 0x9d, 0x18, 0xf6, 0xd9, 0x49, 0xeb, 0xb0, 0xef, 0xd5, 0x9f, 0xa8, 0xa2, 0xa0, 0x68, - 0x8e, 0xeb, 0x07, 0x8f, 0xd6, 0x9e, 0x2a, 0xfd, 0xa8, 0x47, 0xc6, 0xd4, 0xfb, 0xb5, 0xb6, 0x62, - 0x93, 0x52, 0x41, 0x52, 0xef, 0x76, 0x2e, 0xae, 0x27, 0xf2, 0xc9, 0x41, 0xdf, 0x68, 0xc0, 0x7f, - 0xe7, 0xad, 0xdb, 0xc1, 0xde, 0x6d, 0x1f, 0x9e, 0x76, 0x64, 0x7c, 0xdf, 0x6f, 0x36, 0x1e, 0xe1, - 0xa7, 0x59, 0xdc, 0x1f, 0xf5, 0x8a, 0x98, 0xd0, 0x78, 0x38, 0x6f, 0x5d, 0xcb, 0x47, 0x0d, 0xcb, - 0x2e, 0x74, 0x4a, 0x57, 0x98, 0x70, 0xad, 0x5f, 0xdd, 0x66, 0x77, 0xa0, 0xcc, 0xf4, 0x79, 0x32, - 0x2e, 0x3f, 0x5e, 0xdd, 0x62, 0xe2, 0x71, 0x67, 0x6f, 0xf0, 0xd4, 0x99, 0x34, 0x1a, 0xbb, 0xf6, - 0x19, 0xbc, 0x6e, 0xee, 0x36, 0x3a, 0xdd, 0xf1, 0xeb, 0x01, 0x56, 0xd8, 0x69, 0xb7, 0x6e, 0xaf, - 0x77, 0xee, 0x9a, 0x83, 0x1b, 0xed, 0xb1, 0xd2, 0xde, 0x35, 0x1a, 0x93, 0xdd, 0xb3, 0xf3, 0xfb, - 0x4d, 0xbd, 0xa2, 0x4f, 0x9a, 0xaa, 0xf9, 0xe6, 0x5c, 0x9d, 0x17, 0x9e, 0xca, 0x4e, 0xdb, 0xba, - 0x39, 0x1c, 0xee, 0x0e, 0xf7, 0x0b, 0xc6, 0xe5, 0xfb, 0x9b, 0xd6, 0x9d, 0x5c, 0xbf, 0x9a, 0xd9, - 0x56, 0xab, 0xab, 0xdf, 0x65, 0xce, 0x47, 0x4f, 0xa3, 0xf7, 0x57, 0x62, 0x35, 0x76, 0xde, 0xa6, - 0x0f, 0xef, 0xfa, 0xce, 0x24, 0xaf, 0xf6, 0x5f, 0xc8, 0xfe, 0x5e, 0xef, 0xe1, 0xed, 0x76, 0x34, - 0x38, 0xc9, 0xbc, 0xed, 0x9f, 0xc9, 0xcd, 0xe9, 0x71, 0xef, 0xed, 0xf5, 0xe1, 0x69, 0xef, 0xa2, - 0x53, 0xca, 0xb4, 0xac, 0x4a, 0xa6, 0xdd, 0xdb, 0x1c, 0x1d, 0x35, 0x8b, 0xe7, 0x93, 0xee, 0xa6, - 0x61, 0x9d, 0x8d, 0x1b, 0x97, 0x74, 0x2c, 0x7b, 0xda, 0xfe, 0xcd, 0x4b, 0x6b, 0x74, 0x35, 0x6c, - 0x36, 0x61, 0x21, 0x2c, 0xfa, 0xe5, 0x8e, 0xc3, 0x9c, 0x2b, 0xe4, 0xa6, 0x12, 0xbb, 0xa7, 0xba, - 0x17, 0x6f, 0x79, 0xda, 0xe1, 0x0f, 0xa0, 0xe8, 0x86, 0xda, 0x03, 0xba, 0x1e, 0xac, 0x3c, 0x09, - 0x8b, 0x81, 0x12, 0xa1, 0xc0, 0x23, 0x1d, 0x18, 0xa4, 0xde, 0x21, 0x02, 0x9e, 0x41, 0xfc, 0x26, - 0x2c, 0xef, 0x58, 0x0f, 0x57, 0x67, 0xc2, 0x3f, 0xcd, 0x63, 0x8a, 0x89, 0x98, 0x94, 0xc4, 0xff, - 0xb4, 0x89, 0x86, 0x6e, 0x30, 0x5b, 0xb7, 0x34, 0x89, 0x5e, 0xb6, 0x8b, 0xb9, 0xa3, 0x13, 0xd7, - 0x06, 0x15, 0x25, 0x70, 0xd5, 0x86, 0xa5, 0x89, 0x8e, 0xde, 0xa3, 0x72, 0x04, 0x1b, 0x7f, 0xdb, - 0x30, 0x9c, 0x08, 0x50, 0xff, 0x4c, 0x96, 0x22, 0x97, 0x17, 0xfc, 0x06, 0xe2, 0xd6, 0x19, 0xa8, - 0x10, 0xc2, 0x44, 0x75, 0x06, 0x6e, 0x0e, 0x3b, 0xa1, 0x57, 0x2c, 0x07, 0xd7, 0x04, 0x2c, 0xe2, - 0x72, 0xa1, 0x06, 0x6b, 0x63, 0x7f, 0x4f, 0xde, 0xab, 0xb9, 0x9b, 0xcb, 0x9a, 0xd0, 0x7e, 0x13, - 0x1a, 0xaa, 0xd5, 0x31, 0x0c, 0xe3, 0x45, 0x25, 0xf4, 0x56, 0xac, 0x33, 0x20, 0xc2, 0x77, 0x45, - 0xa0, 0x47, 0x98, 0xe2, 0xc0, 0x71, 0x4c, 0xbb, 0x9a, 0xc9, 0xe0, 0x39, 0x61, 0x1a, 0x74, 0xa8, - 0x8e, 0x31, 0xb2, 0x6c, 0x92, 0x46, 0x27, 0x16, 0x33, 0x03, 0x62, 0x8b, 0x62, 0x01, 0x5e, 0xea, - 0xe2, 0x7f, 0xba, 0x97, 0x46, 0xd6, 0xe8, 0x7d, 0xc3, 0x8e, 0x31, 0x1c, 0x8e, 0x74, 0x6a, 0x99, - 0x51, 0xb6, 0x96, 0x6d, 0x63, 0x3a, 0xbb, 0xaa, 0xf5, 0xef, 0xf2, 0x82, 0x65, 0x57, 0xbb, 0x3e, - 0xcb, 0x0c, 0xf0, 0x2b, 0x54, 0xe2, 0x16, 0xed, 0xb6, 0xea, 0x92, 0x8a, 0xbd, 0x40, 0xdd, 0xfa, - 0x22, 0x75, 0xbb, 0x8e, 0x40, 0xde, 0x41, 0xf2, 0x92, 0xcf, 0x5c, 0x8a, 0x9f, 0xa5, 0x5a, 0x94, - 0x02, 0xfc, 0xa1, 0x2c, 0x52, 0x7e, 0xbc, 0xb4, 0x3c, 0xd4, 0xc6, 0x78, 0x2c, 0xb0, 0x16, 0xc5, - 0xa1, 0xdf, 0x6f, 0x96, 0xef, 0xf6, 0x71, 0x31, 0x02, 0x0c, 0x3e, 0xc7, 0x8e, 0x2c, 0xea, 0x52, - 0x8e, 0x17, 0x4d, 0x17, 0xa7, 0x2a, 0x82, 0xf0, 0xc1, 0xa8, 0x4f, 0x22, 0x17, 0x07, 0x91, 0x48, - 0xd7, 0x7c, 0x30, 0x1a, 0x30, 0x89, 0xed, 0x80, 0x37, 0xe0, 0xbf, 0x35, 0xe1, 0xc6, 0x10, 0x46, - 0x36, 0x11, 0xda, 0x23, 0x55, 0xc3, 0x68, 0xb7, 0x02, 0x61, 0x3b, 0xb7, 0x44, 0x53, 0x51, 0x4e, - 0x82, 0xa6, 0x2d, 0x90, 0x60, 0xdd, 0xdb, 0xe4, 0x02, 0xec, 0x37, 0xb0, 0x22, 0x59, 0xdd, 0x47, - 0x63, 0x24, 0x74, 0xa0, 0x8c, 0x45, 0x9c, 0x91, 0xa5, 0x0b, 0xe8, 0x42, 0x45, 0x80, 0x8b, 0xab, - 0x43, 0x42, 0x4f, 0x77, 0x91, 0xb6, 0x31, 0x3c, 0x86, 0x8d, 0x77, 0x6a, 0x91, 0xaa, 0xf1, 0x73, - 0x34, 0x80, 0x7c, 0xfa, 0x8c, 0x42, 0x29, 0xde, 0xf7, 0x05, 0x62, 0xb5, 0x74, 0x62, 0xa5, 0xd7, - 0xd8, 0x8a, 0x5a, 0x98, 0xac, 0x90, 0x83, 0x90, 0x73, 0x6a, 0x58, 0x54, 0x22, 0xb9, 0xf0, 0x7a, - 0x65, 0x50, 0x8f, 0xcf, 0x15, 0x4b, 0x7e, 0xb1, 0x7e, 0x8e, 0xaf, 0x3f, 0xd2, 0xf1, 0x9a, 0xb7, - 0x45, 0x97, 0xba, 0x0f, 0x87, 0x5b, 0xdc, 0x6b, 0xc1, 0xea, 0x5e, 0xdb, 0x37, 0x2c, 0x18, 0xbe, - 0xed, 0x08, 0x26, 0xb1, 0xd0, 0xfb, 0x0b, 0x69, 0x55, 0x12, 0x54, 0x50, 0x22, 0xf0, 0x0b, 0x76, - 0xb8, 0xe8, 0x08, 0x0d, 0xf4, 0x01, 0x78, 0xa0, 0xf8, 0x30, 0x7a, 0x3d, 0x77, 0xd8, 0x80, 0x96, - 0x21, 0x22, 0xc1, 0x86, 0xd5, 0x0b, 0xac, 0x70, 0x32, 0x20, 0x3a, 0x8d, 0x3a, 0x01, 0xb8, 0x00, - 0x34, 0xa7, 0x17, 0x5c, 0x78, 0xd5, 0x60, 0xda, 0x11, 0x67, 0x62, 0xcc, 0x44, 0x2f, 0x0c, 0x4b, - 0x4e, 0x06, 0x93, 0xbf, 0xe6, 0xcf, 0xfe, 0x77, 0xf7, 0x76, 0xf1, 0xda, 0x18, 0x50, 0xaf, 0x19, - 0x1d, 0xd5, 0x94, 0x26, 0xf7, 0x12, 0xef, 0xa0, 0x20, 0x4d, 0x6c, 0xa9, 0x83, 0xb7, 0xc1, 0x24, - 0x6a, 0xc6, 0xb1, 0x25, 0x87, 0xf9, 0x1a, 0xa0, 0xcf, 0x42, 0xfd, 0x4b, 0x16, 0x7f, 0x4c, 0x58, - 0xcb, 0x06, 0xe3, 0x45, 0x55, 0x51, 0x52, 0xed, 0x0b, 0x1d, 0x33, 0x74, 0xad, 0x81, 0x3f, 0xaa, - 0x7d, 0x3a, 0x66, 0xbf, 0x28, 0x16, 0xb0, 0x27, 0xba, 0x92, 0xf0, 0xd1, 0x7e, 0xd3, 0x3b, 0x2d, - 0xc0, 0x8a, 0xf7, 0x7c, 0xd3, 0xd7, 0xae, 0x49, 0x07, 0xca, 0xcb, 0xd2, 0x40, 0xb1, 0xa9, 0x5b, - 0x27, 0x66, 0xc1, 0xf3, 0xf5, 0xc1, 0x8e, 0xfb, 0xd4, 0x6c, 0xde, 0x30, 0xf0, 0xbb, 0x23, 0xab, - 0x5e, 0x92, 0xe1, 0xe1, 0x46, 0xb1, 0xea, 0xf8, 0x8b, 0x97, 0x21, 0x29, 0x24, 0xd2, 0x3f, 0x45, - 0xd5, 0x4c, 0x96, 0xbc, 0x58, 0x51, 0xfb, 0xfc, 0xcb, 0xa5, 0xa2, 0xc1, 0x5b, 0x07, 0x5e, 0xf1, - 0x67, 0x64, 0x61, 0xac, 0x49, 0x26, 0xa2, 0xd5, 0x37, 0x60, 0x3c, 0x20, 0x51, 0xb1, 0xfd, 0x82, - 0x56, 0xe9, 0x37, 0x0d, 0xa0, 0x01, 0x78, 0x04, 0x06, 0xeb, 0x3f, 0x1a, 0x13, 0x98, 0xe6, 0x5b, - 0x1d, 0xe6, 0xa6, 0x0b, 0xaf, 0xd0, 0x14, 0x08, 0x96, 0x98, 0xce, 0x7e, 0xcc, 0x8e, 0xd7, 0x11, - 0xf6, 0x44, 0xd1, 0x80, 0x60, 0x27, 0x90, 0xe9, 0x58, 0xf5, 0x4d, 0xa9, 0x5b, 0xef, 0x82, 0x4e, - 0x84, 0xa2, 0xa8, 0xd4, 0x9b, 0xa2, 0x34, 0x53, 0xff, 0xf1, 0x53, 0x32, 0x71, 0x63, 0xad, 0xcf, - 0xe6, 0x12, 0xf1, 0x1e, 0x34, 0xef, 0xc1, 0x0c, 0x9e, 0xce, 0xeb, 0xa2, 0x28, 0x99, 0x47, 0xd8, - 0xcc, 0xf9, 0x68, 0x88, 0x3f, 0x43, 0xa7, 0x9e, 0xc5, 0xbf, 0xa7, 0x2d, 0xf6, 0x76, 0x0a, 0x2d, - 0x61, 0x67, 0xe0, 0x07, 0x19, 0x19, 0xd6, 0x52, 0xed, 0x33, 0xec, 0xc3, 0x10, 0x3b, 0x30, 0x1c, - 0xc0, 0x9f, 0x89, 0x7d, 0x6d, 0x62, 0xa1, 0x4e, 0xaf, 0x5f, 0x9f, 0x39, 0x78, 0x3f, 0xb3, 0x3a, - 0x43, 0x31, 0xaa, 0x0a, 0xb2, 0x95, 0xf5, 0x22, 0x4a, 0xed, 0x7e, 0x75, 0x36, 0xb2, 0xb4, 0xaa, - 0x28, 0xce, 0x25, 0x45, 0x33, 0x07, 0x0a, 0x64, 0xf7, 0xab, 0xe9, 0x92, 0x04, 0x52, 0x6d, 0x35, - 0x5d, 0x9e, 0x4b, 0xcc, 0xf9, 0x12, 0x13, 0xa1, 0x08, 0xbe, 0x0e, 0xcd, 0x2a, 0x0b, 0x25, 0x63, - 0x57, 0x67, 0xec, 0xee, 0x60, 0x15, 0x26, 0xd1, 0xea, 0xb7, 0xab, 0xd0, 0xf0, 0xeb, 0x08, 0x52, - 0xf0, 0x7d, 0x40, 0xa6, 0xf0, 0x0e, 0x23, 0xa3, 0xaa, 0x29, 0xa6, 0x98, 0x9d, 0x21, 0x30, 0x63, - 0x2c, 0x64, 0xaa, 0x5d, 0x4c, 0x00, 0x94, 0x6b, 0x44, 0xaf, 0xb2, 0x69, 0x34, 0x27, 0x96, 0xfb, - 0x44, 0xa6, 0x26, 0x3e, 0x75, 0x6c, 0x5a, 0x6b, 0xd0, 0x55, 0xde, 0x6c, 0x7c, 0x07, 0xf4, 0x91, - 0x1e, 0xba, 0xc1, 0xcc, 0x25, 0x50, 0x4c, 0xeb, 0x3f, 0x7e, 0xc8, 0x52, 0x36, 0x2b, 0xe5, 0x0a, - 0x52, 0x41, 0xf2, 0xf7, 0x46, 0xc5, 0xdf, 0x3f, 0xd3, 0x7d, 0xd8, 0x7c, 0x47, 0xed, 0xb4, 0x6a, - 0x64, 0xa6, 0x43, 0xc5, 0x4e, 0x83, 0xf4, 0x28, 0xfe, 0x94, 0xa0, 0x4e, 0x4e, 0xca, 0x6e, 0x4a, - 0xd9, 0xa0, 0x0a, 0x15, 0x2e, 0xed, 0x34, 0x1d, 0x7a, 0xc7, 0x40, 0x1f, 0x80, 0x34, 0x0c, 0x31, - 0x53, 0xa8, 0x64, 0xf1, 0x5f, 0x36, 0x97, 0x4f, 0x3f, 0x9b, 0xb4, 0x6a, 0x4e, 0xce, 0x15, 0xa5, - 0xbc, 0x94, 0x43, 0x10, 0xab, 0x1b, 0x24, 0x30, 0x1f, 0xc0, 0xc7, 0xdc, 0x26, 0xa1, 0x5e, 0x1e, - 0xea, 0x55, 0x7e, 0xbf, 0x5a, 0x01, 0xaa, 0xe4, 0xb3, 0xbf, 0x59, 0x4f, 0x96, 0x4a, 0x80, 0x11, - 0x7e, 0x80, 0xb0, 0xfd, 0xab, 0x40, 0xe3, 0x0b, 0x43, 0x44, 0x97, 0x43, 0xdc, 0xec, 0x32, 0x13, - 0x45, 0xd3, 0x4c, 0x05, 0x58, 0x59, 0xa6, 0x98, 0x2d, 0x6d, 0x56, 0x72, 0x2e, 0x4e, 0x32, 0x30, - 0x70, 0x48, 0x91, 0x2b, 0xb9, 0x6c, 0xbe, 0x94, 0xcf, 0x55, 0x72, 0xc5, 0x7c, 0x89, 0xb5, 0x00, - 0x98, 0xff, 0xbb, 0x2d, 0x64, 0xb3, 0x95, 0x72, 0x59, 0x96, 0xf9, 0x26, 0x72, 0xc5, 0x5c, 0xae, - 0x2c, 0x6f, 0x16, 0xca, 0xd9, 0x62, 0xb9, 0x58, 0x92, 0x65, 0xf1, 0xe7, 0xcf, 0x5a, 0x6f, 0xa4, - 0xd3, 0xe0, 0xdf, 0xc2, 0x00, 0xe4, 0x20, 0x8d, 0xdc, 0xf9, 0x81, 0x75, 0x9a, 0xd4, 0x04, 0x96, - 0x48, 0xce, 0xbe, 0x74, 0xd3, 0x2c, 0x94, 0xe1, 0xfa, 0xba, 0x4e, 0x26, 0x02, 0xf0, 0x2f, 0xfc, - 0xd6, 0xa2, 0xb7, 0xa0, 0xb7, 0xf2, 0x24, 0xbf, 0xbe, 0x1e, 0x12, 0x63, 0xe7, 0x3e, 0x4c, 0x1b, - 0x14, 0xe1, 0x04, 0x91, 0x9c, 0xe4, 0x0c, 0x04, 0x29, 0x77, 0x75, 0xee, 0x69, 0x04, 0x7f, 0xd2, - 0x74, 0x87, 0x4e, 0x03, 0x83, 0xb8, 0xb4, 0x40, 0xd6, 0xb4, 0x9c, 0x37, 0x5a, 0x30, 0xa8, 0x8b, - 0x3e, 0x35, 0x24, 0x39, 0x73, 0xf7, 0xb9, 0x6e, 0x1a, 0x64, 0x2e, 0xb7, 0xea, 0xce, 0x1b, 0xcd, - 0xe2, 0x8a, 0xee, 0xed, 0x34, 0xcf, 0x97, 0x14, 0xb6, 0x77, 0xde, 0x9a, 0xc8, 0xc8, 0xcf, 0x41, - 0x73, 0x0b, 0x55, 0x52, 0xed, 0xbd, 0xa1, 0x89, 0xad, 0xfa, 0xd5, 0xe4, 0x7a, 0xbd, 0x7e, 0xd1, - 0x7e, 0xc6, 0x6f, 0x12, 0xbc, 0x90, 0x37, 0x1b, 0x72, 0xd2, 0xcc, 0x07, 0x94, 0xaf, 0x04, 0x05, - 0xb8, 0x2a, 0x64, 0x7d, 0x5d, 0x34, 0x68, 0x15, 0xb1, 0x5e, 0x47, 0xb3, 0x8e, 0xd1, 0xc3, 0xb4, - 0x2f, 0x0d, 0xcb, 0x52, 0xde, 0xd2, 0xaa, 0x4d, 0x7f, 0x23, 0xcd, 0x02, 0x8b, 0x21, 0x96, 0xda, - 0x09, 0xa0, 0x7c, 0x81, 0x34, 0xe5, 0x3c, 0x61, 0x2a, 0x20, 0x65, 0xee, 0x63, 0xdc, 0x1a, 0xc8, - 0x4a, 0xae, 0xaf, 0xab, 0x68, 0x35, 0x02, 0x66, 0x1d, 0xa9, 0x7e, 0xdd, 0x6f, 0x53, 0xc7, 0xf9, - 0x70, 0xc7, 0x69, 0xe5, 0x23, 0x1d, 0xaa, 0xa6, 0x2d, 0xa8, 0x1b, 0x4e, 0xe9, 0x2f, 0xa4, 0xb4, - 0x39, 0x90, 0xc0, 0x4f, 0x5a, 0x8e, 0x15, 0x80, 0xc3, 0xdb, 0x74, 0x09, 0x31, 0x05, 0x80, 0x52, - 0xa2, 0x84, 0xbf, 0x7d, 0xf7, 0xb7, 0x9d, 0x12, 0x93, 0x62, 0xa8, 0x1e, 0xde, 0x03, 0xf7, 0xeb, - 0xa5, 0x73, 0xd9, 0x5c, 0xe9, 0xcf, 0x50, 0x47, 0x52, 0xe9, 0xcd, 0x6c, 0x31, 0xf7, 0x67, 0xa8, - 0x2b, 0xa9, 0xb4, 0xbc, 0x99, 0x0b, 0xa5, 0xf1, 0x9d, 0xc1, 0x83, 0x91, 0xd6, 0x29, 0x02, 0x85, - 0xdd, 0x52, 0x70, 0xea, 0x24, 0x8d, 0xac, 0x1c, 0x52, 0xd3, 0x93, 0x6d, 0xae, 0x8a, 0x9f, 0x98, - 0xac, 0x02, 0x77, 0x43, 0xc1, 0x5a, 0x27, 0xe2, 0x97, 0x3a, 0xba, 0x1f, 0x36, 0x81, 0x6d, 0x8e, - 0x60, 0x47, 0x6a, 0x21, 0x7d, 0xe1, 0x1c, 0xa2, 0x9d, 0xad, 0x45, 0x03, 0x31, 0xd6, 0xd8, 0x9e, - 0x07, 0xf3, 0xc3, 0xa3, 0xd1, 0x03, 0x96, 0xdc, 0x4e, 0xd8, 0x7f, 0xfd, 0x05, 0xef, 0x8c, 0x32, - 0x29, 0xe3, 0xad, 0x7b, 0x83, 0xf4, 0x0b, 0x6d, 0x65, 0x73, 0x9b, 0xdb, 0xf4, 0x3a, 0x80, 0x58, - 0xa5, 0xb7, 0x26, 0x40, 0x29, 0xf2, 0xaa, 0x04, 0xae, 0xee, 0x75, 0x6f, 0xa7, 0x5d, 0x5f, 0x77, - 0xb6, 0xe4, 0xed, 0x5f, 0x51, 0xcf, 0xf7, 0x6c, 0x99, 0x5e, 0xac, 0x15, 0xfe, 0x98, 0x79, 0xd8, - 0xf7, 0x1b, 0x98, 0x0b, 0x79, 0xf9, 0x5f, 0x12, 0x62, 0x37, 0xf1, 0xc7, 0xcc, 0x99, 0x4b, 0xfe, - 0x9f, 0x64, 0xf2, 0x57, 0x75, 0xa1, 0x74, 0xb2, 0x9a, 0xf0, 0x07, 0x15, 0xb4, 0x99, 0x80, 0x7d, - 0x28, 0xb6, 0x5b, 0xbf, 0x62, 0xc0, 0xfe, 0x92, 0x16, 0x87, 0xed, 0xc4, 0x0c, 0x93, 0x9b, 0x25, - 0xc5, 0x34, 0xb5, 0xb7, 0x66, 0xaf, 0x0f, 0xdc, 0xa1, 0xc3, 0x22, 0x11, 0x88, 0x1a, 0x4a, 0xd7, - 0xb0, 0x08, 0xea, 0xb0, 0xfd, 0xa5, 0xe9, 0xee, 0x97, 0xc6, 0xcd, 0x2f, 0x59, 0x43, 0x21, 0x88, - 0x70, 0xa9, 0xb4, 0x81, 0x74, 0xbb, 0x5f, 0x83, 0x7e, 0x52, 0xfe, 0x20, 0xd2, 0x68, 0x98, 0xa2, - 0xe4, 0x96, 0x75, 0x68, 0x59, 0xdc, 0xfc, 0xd2, 0x6c, 0x47, 0xab, 0x79, 0xa5, 0x9c, 0xb6, 0x29, - 0x4a, 0xce, 0xb6, 0x98, 0xa5, 0x1f, 0x28, 0xf7, 0xbf, 0x52, 0x8e, 0x4f, 0xd0, 0x49, 0xfa, 0x8c, - 0x11, 0xb1, 0x69, 0x84, 0x25, 0x7c, 0x80, 0x99, 0xf1, 0xaa, 0xb6, 0xdd, 0xaa, 0x7e, 0x84, 0x4a, - 0x41, 0xf6, 0xaa, 0xb8, 0x11, 0x99, 0xf8, 0xc2, 0x83, 0x2e, 0x2d, 0x4c, 0x23, 0x45, 0x41, 0x31, - 0x4a, 0x5c, 0x5c, 0xf6, 0xd0, 0xa1, 0xd9, 0x32, 0x6d, 0xb6, 0x18, 0x6a, 0xc7, 0xd9, 0x68, 0x8b, - 0x52, 0x30, 0x56, 0xca, 0xa6, 0xd3, 0xb0, 0xbf, 0x07, 0x25, 0xec, 0xbe, 0xc9, 0x4a, 0xd0, 0x11, - 0xb2, 0xed, 0x78, 0x9b, 0x35, 0x51, 0x75, 0x5b, 0x84, 0xc2, 0x2a, 0x7a, 0xb3, 0x84, 0x3d, 0x58, - 0xd1, 0xb1, 0xc1, 0x77, 0x5f, 0xbd, 0x55, 0x01, 0xfb, 0xa2, 0x74, 0xdc, 0xba, 0x38, 0x87, 0x79, - 0xc3, 0x0f, 0xb0, 0xaa, 0xbd, 0xb7, 0x04, 0x80, 0x4d, 0x26, 0x7d, 0x21, 0x05, 0x98, 0x57, 0xd7, - 0x5e, 0x5f, 0x67, 0xaa, 0xfb, 0xed, 0x11, 0xcf, 0x97, 0x3d, 0xdf, 0xf0, 0x99, 0xdf, 0x11, 0x26, - 0x66, 0xa4, 0x41, 0x96, 0xa8, 0x7f, 0x89, 0x49, 0x94, 0x82, 0x19, 0x0f, 0x41, 0x71, 0xc3, 0x50, - 0xcc, 0xc2, 0x93, 0x5e, 0x5f, 0x46, 0x0d, 0xdb, 0x4c, 0x14, 0xaa, 0xba, 0xf9, 0xcb, 0xa0, 0x7a, - 0xee, 0x22, 0xb3, 0x08, 0x25, 0x70, 0x5d, 0x63, 0x09, 0xcb, 0x00, 0xd0, 0xab, 0x02, 0x0b, 0x83, - 0x03, 0xda, 0x5f, 0x1c, 0x1c, 0x24, 0xc6, 0x42, 0x71, 0xe9, 0x1a, 0x18, 0x11, 0x01, 0xbe, 0xc0, - 0xd3, 0xa9, 0xf8, 0x95, 0x10, 0x9e, 0x1e, 0x3a, 0x1b, 0x3d, 0x4c, 0xa4, 0x77, 0x9b, 0xb8, 0xc4, - 0x1c, 0x26, 0x76, 0xbb, 0xdd, 0x50, 0x62, 0x1e, 0x13, 0xdb, 0xed, 0x76, 0x28, 0xb1, 0x80, 0x89, - 0x8a, 0xa2, 0x84, 0x12, 0x8b, 0x98, 0x58, 0xa9, 0x54, 0x42, 0x89, 0xa5, 0xb8, 0xc4, 0x32, 0x26, - 0x96, 0xcb, 0xe5, 0x50, 0x62, 0x1b, 0x13, 0x0b, 0x85, 0x42, 0x28, 0xb1, 0x83, 0x89, 0xf9, 0x7c, - 0x3e, 0x94, 0x48, 0x30, 0x31, 0x9b, 0xcd, 0x86, 0x12, 0xbb, 0x98, 0x98, 0xcb, 0xe5, 0x42, 0x89, - 0x16, 0xed, 0x67, 0x2e, 0x5c, 0xb2, 0x4f, 0x4b, 0x2a, 0xe1, 0x44, 0x8d, 0x26, 0x96, 0x3a, 0xa1, - 0x44, 0x03, 0x12, 0xe9, 0xa7, 0x1c, 0x73, 0x72, 0x41, 0x12, 0x82, 0x3f, 0x72, 0xba, 0x92, 0x0c, - 0x15, 0xb4, 0xdb, 0x2e, 0x3e, 0xf3, 0x91, 0xe4, 0x81, 0x9b, 0x5e, 0x0a, 0xa5, 0x3b, 0xed, 0x25, - 0x80, 0xdd, 0xcf, 0x66, 0x6f, 0xb4, 0x93, 0xc9, 0x48, 0x05, 0xc5, 0xab, 0x91, 0xdd, 0x94, 0x25, - 0x21, 0xf8, 0xb3, 0xbc, 0xc6, 0xe0, 0x53, 0x6d, 0x50, 0x3f, 0x60, 0x6a, 0x6a, 0x4d, 0xba, 0xec, - 0x94, 0xf9, 0xc9, 0xa1, 0x11, 0x18, 0x43, 0x72, 0x27, 0xe4, 0x74, 0x19, 0xca, 0x55, 0xa3, 0x04, - 0x15, 0x45, 0x3f, 0x25, 0x28, 0xb6, 0xb7, 0x44, 0x08, 0x2a, 0x3a, 0x27, 0xf9, 0xb8, 0x29, 0x2d, - 0xc4, 0x4d, 0x3e, 0x25, 0xa8, 0x62, 0xb1, 0xb8, 0x48, 0x50, 0xa5, 0x52, 0xe9, 0x93, 0x04, 0x15, - 0xa5, 0x5c, 0x4a, 0x50, 0x9d, 0x4e, 0x67, 0x91, 0xa0, 0xa2, 0x4b, 0xa4, 0x1b, 0xb7, 0x1a, 0x28, - 0x41, 0x91, 0x42, 0x6e, 0x91, 0xa0, 0x0a, 0x24, 0xb7, 0x48, 0x50, 0x85, 0xb2, 0x12, 0x4f, 0x50, - 0x79, 0x98, 0x08, 0xef, 0xdf, 0x12, 0x6a, 0x02, 0x64, 0xc6, 0x52, 0x13, 0xa4, 0x17, 0x97, 0x50, - 0x13, 0x0f, 0xf5, 0x33, 0xa4, 0x24, 0xe7, 0x80, 0x8a, 0xfc, 0x3f, 0x9f, 0x20, 0xa5, 0x62, 0x56, - 0x12, 0xbc, 0x7f, 0x9f, 0xa5, 0xa3, 0x91, 0x0e, 0xfb, 0x80, 0xc8, 0xf1, 0x29, 0x94, 0xfa, 0x77, - 0xfa, 0x81, 0xc0, 0x44, 0xab, 0xb6, 0xfb, 0xd8, 0x66, 0xbd, 0x9b, 0xee, 0x58, 0x04, 0x98, 0xbf, - 0x2b, 0x0a, 0x53, 0x90, 0x62, 0xb2, 0xa6, 0xf6, 0x12, 0x76, 0x1a, 0x8d, 0xfe, 0x44, 0x12, 0x81, - 0x47, 0x93, 0xbf, 0xfe, 0xf2, 0x15, 0x0c, 0xd0, 0x32, 0xed, 0xd1, 0x30, 0x6d, 0x0e, 0x0c, 0xc7, - 0xb0, 0x33, 0xd9, 0x4a, 0x4e, 0xce, 0x64, 0xe5, 0xb2, 0x8c, 0x9c, 0x1c, 0x5a, 0xc0, 0xed, 0x59, - 0xaf, 0x7b, 0x4a, 0x40, 0xad, 0x67, 0x58, 0x09, 0x6a, 0xe2, 0x10, 0x40, 0xea, 0x05, 0x4d, 0xf1, - 0xaf, 0xbf, 0x7e, 0xfc, 0x64, 0x85, 0x94, 0x3a, 0x88, 0x9b, 0xda, 0x0f, 0xf9, 0xe7, 0xb6, 0x8e, - 0xa2, 0xf8, 0xfe, 0x48, 0xd3, 0x1e, 0x41, 0xfe, 0x49, 0x24, 0xab, 0x98, 0x28, 0xa9, 0x3e, 0x8c, - 0x84, 0x22, 0x69, 0x3f, 0xb2, 0x3f, 0xe1, 0x4f, 0xee, 0x67, 0x52, 0x32, 0x82, 0x74, 0x35, 0x59, - 0x33, 0x70, 0xcb, 0xa3, 0x2f, 0x06, 0x02, 0xa1, 0x4f, 0xc9, 0x94, 0xf6, 0x23, 0x0f, 0x25, 0xf5, - 0xad, 0xba, 0x0a, 0xea, 0xc8, 0xf7, 0xba, 0x01, 0xc2, 0x0e, 0x1b, 0x8c, 0xf6, 0xa3, 0xf0, 0x33, - 0x39, 0x9f, 0xdb, 0x78, 0x67, 0x60, 0x0f, 0x3f, 0xcd, 0x8d, 0xc6, 0x6f, 0xa2, 0x13, 0x2b, 0x41, - 0x0d, 0x8d, 0x20, 0x5f, 0xd4, 0xb7, 0xdc, 0x11, 0x70, 0x92, 0x76, 0x74, 0xaf, 0x6e, 0xf7, 0x01, - 0x3f, 0x54, 0x1c, 0xd7, 0x41, 0x68, 0x4e, 0xe8, 0xf5, 0x74, 0x29, 0x29, 0x79, 0xca, 0x8a, 0x1b, - 0x6b, 0xae, 0xae, 0xfb, 0x29, 0x81, 0x68, 0x75, 0x84, 0x6a, 0x56, 0xfd, 0x17, 0x28, 0xf8, 0x20, - 0x5f, 0xd1, 0x1e, 0x51, 0xc9, 0x8a, 0x5d, 0x45, 0xa1, 0x93, 0x12, 0x9c, 0x1d, 0x25, 0x43, 0xb2, - 0x96, 0xe8, 0xc5, 0x47, 0xed, 0x80, 0x74, 0x1d, 0x99, 0xd9, 0xd6, 0x8b, 0xaa, 0x37, 0x5b, 0x2d, - 0x9c, 0x5e, 0x98, 0xb5, 0x2f, 0x4c, 0x27, 0x62, 0x38, 0x76, 0xea, 0x11, 0x35, 0xe7, 0x46, 0xe9, - 0x53, 0x25, 0x07, 0xcd, 0xdf, 0xb0, 0xce, 0x10, 0xd1, 0x31, 0x24, 0x80, 0xc7, 0x70, 0x40, 0x03, - 0x76, 0x5a, 0xed, 0xc2, 0xfc, 0xc3, 0xfe, 0x47, 0x34, 0x3c, 0x4f, 0x7d, 0xc3, 0xaf, 0x2d, 0x13, - 0x20, 0x2d, 0x48, 0x0a, 0x8e, 0xa7, 0x33, 0x1d, 0xdb, 0xc6, 0x94, 0x48, 0x6c, 0x2f, 0xe8, 0x54, - 0x1a, 0x73, 0x80, 0xc6, 0xd2, 0x34, 0xe8, 0x64, 0x5d, 0xc4, 0x6b, 0x69, 0x80, 0x15, 0x0c, 0x96, - 0xa7, 0x77, 0x9b, 0x03, 0x55, 0xeb, 0x26, 0x6c, 0x98, 0x8d, 0x40, 0x45, 0x63, 0x95, 0x7d, 0x65, - 0x21, 0x01, 0xb2, 0xcd, 0xb6, 0x67, 0xe6, 0x4a, 0x89, 0x99, 0x8c, 0x98, 0xa2, 0x96, 0xb2, 0xaa, - 0x28, 0x26, 0x53, 0x24, 0xa8, 0x67, 0xe8, 0x68, 0xaa, 0x4d, 0x30, 0xea, 0x26, 0xf5, 0xc8, 0x9d, - 0x23, 0x24, 0x65, 0x74, 0x45, 0x26, 0x55, 0xa4, 0xe3, 0x34, 0x05, 0x06, 0x48, 0x4d, 0x52, 0x33, - 0x9a, 0x2c, 0x25, 0x28, 0xc8, 0x7a, 0x48, 0x8c, 0xea, 0x7b, 0x62, 0x14, 0xa4, 0x1e, 0x99, 0x20, - 0xd5, 0x82, 0xec, 0xcb, 0x8a, 0x41, 0x6d, 0x50, 0x08, 0x13, 0xe2, 0x3e, 0xc0, 0xa3, 0x31, 0xc0, - 0xd2, 0xc2, 0xa5, 0x86, 0x9f, 0xaf, 0x16, 0x68, 0xf0, 0x5f, 0x16, 0x56, 0xf0, 0xe8, 0xf2, 0x8b, - 0xb8, 0x4c, 0x30, 0x63, 0x10, 0x25, 0x0a, 0x2d, 0x99, 0xac, 0x81, 0x7c, 0x42, 0x7c, 0x2d, 0xc6, - 0x54, 0x9c, 0x01, 0xfd, 0x00, 0x96, 0x5d, 0xa7, 0xa1, 0x6c, 0x3b, 0x04, 0x7d, 0x87, 0xd2, 0x80, - 0x2c, 0xfb, 0x5e, 0x75, 0x06, 0x80, 0x55, 0x31, 0xb9, 0xbd, 0x91, 0xad, 0x8e, 0x0d, 0xb5, 0x2b, - 0xc8, 0x40, 0x20, 0x26, 0xe8, 0xe0, 0x34, 0xb5, 0xe6, 0x1b, 0x03, 0x83, 0x01, 0xb2, 0x36, 0x20, - 0x61, 0x60, 0xd8, 0x0e, 0x82, 0x4d, 0x81, 0xfc, 0x8e, 0x71, 0x24, 0xb7, 0x41, 0xb6, 0x4a, 0xb1, - 0x47, 0xc4, 0x24, 0xcc, 0x0f, 0xd3, 0x60, 0xb7, 0x64, 0x50, 0x54, 0x51, 0x41, 0xb2, 0x71, 0x51, - 0x26, 0x5c, 0xfc, 0x50, 0x28, 0xa9, 0x3a, 0xb4, 0x92, 0xc2, 0xf4, 0x64, 0xd5, 0xe5, 0x03, 0xb8, - 0xdc, 0xbd, 0x56, 0x61, 0x11, 0xb0, 0xd2, 0xc9, 0x39, 0xa3, 0xba, 0x78, 0x6c, 0x06, 0x42, 0x69, - 0xb2, 0xe6, 0x40, 0x1d, 0x34, 0x82, 0x81, 0x9a, 0xdb, 0x27, 0xbb, 0x84, 0x98, 0xf8, 0xc6, 0x64, - 0x55, 0xba, 0xf2, 0x12, 0xa0, 0xb6, 0xe0, 0xd5, 0x2b, 0xd4, 0xfd, 0x6f, 0x1d, 0x55, 0x03, 0x49, - 0x37, 0x21, 0x3a, 0xd6, 0x88, 0x88, 0xf5, 0x25, 0xd0, 0xcd, 0xce, 0x50, 0x84, 0x89, 0xfa, 0x92, - 0x39, 0x33, 0xda, 0x6a, 0x06, 0x34, 0x3a, 0xdb, 0x49, 0xe8, 0xca, 0x58, 0xed, 0x2b, 0x50, 0x32, - 0x3d, 0xb2, 0x89, 0xd5, 0xe8, 0xc3, 0x24, 0xc1, 0x8a, 0xc5, 0xe5, 0xb6, 0x12, 0x0a, 0x94, 0x89, - 0xc6, 0x89, 0xe3, 0xe4, 0xbf, 0x40, 0x32, 0xa7, 0xd6, 0xb0, 0xed, 0x1e, 0x71, 0x3a, 0x83, 0xe0, - 0x18, 0x6c, 0x80, 0xa1, 0xbb, 0x21, 0x3d, 0xfd, 0x6c, 0x1b, 0x3a, 0xa0, 0x77, 0x36, 0x24, 0xce, - 0xc0, 0xe8, 0x56, 0x45, 0x28, 0x01, 0x6b, 0x17, 0x39, 0x89, 0x9e, 0x00, 0x3e, 0x43, 0x68, 0x81, - 0x44, 0x32, 0x48, 0x99, 0x45, 0x2d, 0x02, 0x80, 0x23, 0x34, 0xae, 0x81, 0x6e, 0x9f, 0x4c, 0x03, - 0x31, 0x43, 0x2b, 0x58, 0x0a, 0x6d, 0xcd, 0x06, 0x70, 0x06, 0xcd, 0xe8, 0x27, 0xc4, 0x73, 0x43, - 0x50, 0xb0, 0xb4, 0xcb, 0x5e, 0x69, 0xcb, 0x68, 0xbe, 0x0e, 0xf5, 0x22, 0x2d, 0xec, 0xb2, 0x0f, - 0x78, 0xd9, 0x94, 0x61, 0x90, 0x6e, 0x5a, 0x44, 0x90, 0x3d, 0x55, 0x87, 0x25, 0xf9, 0x96, 0x48, - 0x24, 0x01, 0xaa, 0xbb, 0x47, 0x70, 0xb2, 0x78, 0x3f, 0x0d, 0x8c, 0x0a, 0xca, 0x55, 0x97, 0x65, - 0x05, 0x88, 0x80, 0x85, 0xbe, 0xbe, 0xce, 0xf3, 0x22, 0x11, 0xd7, 0x7f, 0x93, 0x2d, 0x7f, 0xfe, - 0xa6, 0xb4, 0xe4, 0x7a, 0x2f, 0xba, 0x47, 0xfd, 0x98, 0xc2, 0x2c, 0xa8, 0xcb, 0x29, 0xe6, 0x72, - 0xe8, 0xd0, 0xd5, 0xc4, 0xdd, 0x89, 0xf4, 0x3b, 0xbc, 0xff, 0x80, 0x96, 0x72, 0xfe, 0x9d, 0x3d, - 0x73, 0x37, 0xf3, 0xfc, 0x3c, 0xfe, 0x36, 0x1e, 0x4b, 0x0d, 0x1b, 0xa4, 0x92, 0x73, 0x09, 0xcf, - 0xf3, 0xe7, 0xf4, 0x7f, 0x8c, 0xf2, 0x5c, 0xc2, 0xeb, 0xc6, 0x6c, 0x17, 0x41, 0x70, 0x69, 0xe6, - 0x06, 0x26, 0x4a, 0xf1, 0xb6, 0x31, 0xe9, 0x4b, 0xd6, 0xdd, 0xaa, 0x3b, 0x63, 0x9f, 0xa7, 0x7b, - 0x7b, 0x84, 0x4c, 0x95, 0x59, 0x64, 0xc0, 0xd0, 0x11, 0xeb, 0xad, 0x45, 0x31, 0x65, 0x58, 0x0d, - 0x4d, 0x4b, 0x7c, 0xe3, 0xc2, 0xb4, 0xba, 0x7e, 0x9c, 0x3f, 0xbf, 0x25, 0xfd, 0xed, 0x14, 0x0f, - 0x31, 0x04, 0x3b, 0xa9, 0xc7, 0xf4, 0xcc, 0x31, 0x46, 0x9d, 0x01, 0x9e, 0x4e, 0xa0, 0x06, 0x4a, - 0xa9, 0x78, 0x87, 0x7a, 0x6d, 0xc2, 0x86, 0xb8, 0xac, 0x34, 0x70, 0x98, 0x48, 0xd9, 0x80, 0xb9, - 0x46, 0x26, 0x8c, 0x78, 0x1b, 0x0b, 0xb3, 0xa7, 0x05, 0x4e, 0x1b, 0x41, 0xdf, 0x6c, 0xec, 0x9b, - 0x93, 0xb4, 0x63, 0xee, 0xdc, 0x29, 0x1d, 0x0c, 0xa9, 0x0f, 0x65, 0x99, 0x81, 0xfe, 0xaf, 0xbf, - 0x9c, 0x1f, 0xe4, 0x67, 0xf4, 0x2a, 0x9f, 0x57, 0x88, 0x63, 0xf0, 0xae, 0x17, 0x08, 0x91, 0x9c, - 0x3a, 0xe0, 0x73, 0xc6, 0x6a, 0xaf, 0xaf, 0x7f, 0x71, 0x80, 0x31, 0xab, 0x2d, 0x74, 0x32, 0x85, - 0x7d, 0xea, 0x3f, 0x9b, 0x31, 0x97, 0xea, 0xec, 0xa1, 0x61, 0x38, 0x20, 0x4d, 0xe1, 0x34, 0x40, - 0x81, 0x45, 0x83, 0x22, 0x08, 0x5c, 0xaa, 0x28, 0x31, 0x20, 0x0b, 0xe4, 0x49, 0x78, 0x83, 0x06, - 0x46, 0xa8, 0x67, 0x7e, 0x1f, 0x5e, 0x3f, 0x90, 0x89, 0xb1, 0xb9, 0x75, 0x5d, 0x48, 0x92, 0x0b, - 0x5b, 0x7e, 0x33, 0xbc, 0x7d, 0x5b, 0x20, 0xb9, 0xb9, 0x93, 0x4e, 0x2b, 0x32, 0x17, 0x13, 0xba, - 0xd5, 0xe2, 0x07, 0x2d, 0x0f, 0x6f, 0xce, 0x4e, 0xe9, 0x8e, 0x1b, 0x46, 0x09, 0xb0, 0x6c, 0x82, - 0x5e, 0x27, 0xc0, 0xb8, 0xb1, 0x13, 0xb0, 0x1c, 0xa8, 0x27, 0x8a, 0x47, 0xe2, 0xee, 0xc1, 0x10, - 0x72, 0x72, 0xd6, 0xbc, 0xa2, 0xab, 0x43, 0xba, 0xf7, 0xb9, 0x46, 0x2f, 0xef, 0xe8, 0xa8, 0x1e, - 0x5d, 0x17, 0x71, 0x73, 0xc4, 0x5a, 0x98, 0x4b, 0xb9, 0x0a, 0xac, 0x06, 0x09, 0x86, 0xc8, 0xf3, - 0x1b, 0x12, 0xc1, 0x07, 0xe7, 0x0c, 0x93, 0x9c, 0x05, 0x08, 0x12, 0x9b, 0x80, 0x10, 0xe2, 0xaa, - 0xda, 0x86, 0x40, 0x35, 0x79, 0xa1, 0xa7, 0xc0, 0xa6, 0xd9, 0xfd, 0x02, 0x73, 0x21, 0xf3, 0x3a, - 0x74, 0xc4, 0xa7, 0x86, 0xd4, 0x8b, 0x24, 0xef, 0x13, 0x19, 0x8f, 0x23, 0x87, 0xeb, 0xac, 0x1b, - 0x60, 0xd1, 0x4e, 0xb8, 0x88, 0x41, 0x56, 0x19, 0x8f, 0x93, 0x65, 0x43, 0x77, 0x96, 0x0e, 0x5d, - 0x8a, 0xcb, 0x72, 0x9b, 0x99, 0x4b, 0x21, 0x92, 0x00, 0x46, 0x75, 0x8d, 0x27, 0x95, 0x43, 0xe2, - 0x5a, 0x47, 0x59, 0xb7, 0x03, 0x23, 0x24, 0x4a, 0xd8, 0x67, 0xb0, 0xad, 0xa7, 0x7b, 0x9a, 0x01, - 0xcb, 0xc3, 0xc9, 0x94, 0x4b, 0x05, 0x44, 0xab, 0xce, 0xa7, 0x26, 0x9c, 0x0d, 0x9a, 0xfc, 0xa7, - 0x9d, 0xcc, 0xe4, 0x4b, 0x98, 0xad, 0xc5, 0x67, 0x6f, 0x60, 0xee, 0x9f, 0x7a, 0x32, 0x53, 0xc2, - 0x0d, 0xa9, 0x6e, 0x6f, 0xdb, 0x29, 0x51, 0x10, 0x53, 0x89, 0x2c, 0xec, 0xd9, 0x68, 0x36, 0x79, - 0x13, 0xf1, 0x1c, 0xe9, 0x0d, 0x16, 0x63, 0x4a, 0x94, 0x04, 0x11, 0xbf, 0x93, 0xe6, 0x5a, 0x7f, - 0x95, 0x54, 0x5d, 0xff, 0xeb, 0x2f, 0x7b, 0x5b, 0xf7, 0x2b, 0xe8, 0xdb, 0xe2, 0xc0, 0x18, 0x21, - 0x49, 0xe1, 0x0f, 0x54, 0x81, 0xd2, 0xd2, 0x17, 0x60, 0xe3, 0x3a, 0xa0, 0x12, 0x8a, 0x23, 0x00, - 0x40, 0xc5, 0x56, 0xb1, 0x02, 0xeb, 0xcc, 0x66, 0x69, 0x5a, 0x8a, 0xba, 0x60, 0x62, 0xfa, 0x77, - 0xec, 0x0a, 0x1a, 0x2e, 0x31, 0x9f, 0x2b, 0xef, 0xa6, 0x63, 0x8a, 0xb3, 0x51, 0x92, 0xff, 0xc4, - 0x2a, 0x36, 0x41, 0xe5, 0x4f, 0xe1, 0x0c, 0xd4, 0x3a, 0xf0, 0x0a, 0x63, 0x82, 0xeb, 0x08, 0x0d, - 0xb3, 0xa2, 0x27, 0xf0, 0xfd, 0xfa, 0xee, 0x58, 0x5b, 0xdf, 0x9d, 0xae, 0x77, 0xac, 0xfa, 0x42, - 0xde, 0x9c, 0xae, 0xb8, 0xf5, 0xc7, 0x8c, 0xcc, 0xbf, 0x67, 0x9c, 0x2e, 0x9f, 0x35, 0x56, 0x34, - 0x96, 0xe5, 0xcc, 0x41, 0x94, 0x76, 0xb3, 0x33, 0x50, 0xfd, 0x57, 0x68, 0x76, 0x4e, 0xb9, 0x13, - 0xc3, 0xcb, 0x04, 0x9b, 0x1f, 0x52, 0xcf, 0xfa, 0xbc, 0x8a, 0x1e, 0xf5, 0xd2, 0x03, 0xc0, 0xa4, - 0x03, 0xd2, 0xe1, 0xfa, 0x3a, 0x49, 0xa5, 0x3c, 0x9c, 0x91, 0xad, 0x5c, 0x11, 0x87, 0x42, 0xea, - 0xf0, 0x9b, 0x94, 0x38, 0x81, 0x93, 0xfa, 0xf1, 0xde, 0x02, 0x48, 0x8e, 0x1d, 0x02, 0xa5, 0xfe, - 0x32, 0xb1, 0xa7, 0x6a, 0xf7, 0x57, 0x92, 0x85, 0x5c, 0xaa, 0x7d, 0xa1, 0x90, 0x7f, 0x38, 0x3f, - 0xff, 0xfa, 0x4b, 0xfe, 0x82, 0xd0, 0xb1, 0x8d, 0xed, 0xa0, 0x28, 0x7e, 0x07, 0x02, 0x0a, 0x07, - 0x4b, 0xdf, 0xc1, 0x26, 0xb7, 0xe9, 0x5d, 0xba, 0x72, 0xb9, 0x26, 0x1c, 0xed, 0x0a, 0xc3, 0x91, - 0xed, 0x08, 0x6d, 0x22, 0x40, 0xba, 0x60, 0x80, 0x1a, 0x45, 0x6c, 0x3b, 0x8d, 0x13, 0x5b, 0x5d, - 0x01, 0xe5, 0x97, 0x57, 0x1f, 0x4f, 0xd3, 0x27, 0x96, 0x8a, 0x41, 0x76, 0x85, 0x3f, 0x66, 0x26, - 0x95, 0xfc, 0x9d, 0xe4, 0xfc, 0x0b, 0x87, 0x23, 0xd3, 0x3d, 0xf3, 0x70, 0x87, 0xe1, 0x7a, 0xbe, - 0x02, 0x8d, 0x10, 0x0f, 0x0d, 0x74, 0x0c, 0xeb, 0xeb, 0x6c, 0x28, 0xe4, 0x67, 0xf0, 0x94, 0xd6, - 0xa9, 0x11, 0x39, 0x78, 0x85, 0xe9, 0xe7, 0x0f, 0x21, 0x2e, 0x35, 0xe5, 0x0d, 0x7d, 0x3b, 0xb9, - 0x43, 0x08, 0xbf, 0xac, 0xe9, 0xe6, 0x71, 0xd0, 0xbc, 0xa4, 0xb4, 0x69, 0x73, 0xdd, 0x53, 0x4c, - 0xf5, 0x4e, 0xd1, 0x3c, 0xdd, 0x86, 0x16, 0x06, 0x19, 0xcf, 0xab, 0x94, 0x74, 0x4f, 0x23, 0x44, - 0xd7, 0x2a, 0xec, 0x9e, 0xcc, 0x00, 0x85, 0xa8, 0x7d, 0x3d, 0x81, 0xc7, 0xb6, 0x5e, 0x41, 0x6f, - 0x34, 0x4e, 0x1a, 0xd4, 0x83, 0x6d, 0xfa, 0xb7, 0x9a, 0xe8, 0x12, 0x0c, 0xe7, 0x01, 0x69, 0xba, - 0xe4, 0x3f, 0x9a, 0xc1, 0xe3, 0xab, 0x16, 0x35, 0x9e, 0x3a, 0xfc, 0xe2, 0x7f, 0xd5, 0x3c, 0xdc, - 0x7d, 0x88, 0xa9, 0x57, 0x6d, 0x9b, 0x7b, 0xc6, 0xa3, 0xdb, 0x80, 0x96, 0xcc, 0x9d, 0xce, 0x8b, - 0x4f, 0x99, 0x4c, 0x33, 0x47, 0xfb, 0x6e, 0x8d, 0xb8, 0x1f, 0x5c, 0x4a, 0x50, 0x23, 0x3d, 0x71, - 0x5a, 0xde, 0x27, 0x78, 0xaf, 0xe9, 0x99, 0x9b, 0x2c, 0x55, 0xe8, 0x7f, 0x28, 0x9e, 0x90, 0x29, - 0xe9, 0x34, 0x8d, 0xe1, 0x10, 0x24, 0x10, 0xdc, 0x8b, 0xcc, 0x37, 0x14, 0xbb, 0x78, 0x66, 0x6c, - 0xaa, 0xcc, 0xfd, 0x01, 0x83, 0xb0, 0xb7, 0x0d, 0xc5, 0x02, 0x2e, 0xcc, 0x0d, 0xc4, 0xa4, 0x73, - 0x4e, 0x79, 0x70, 0x40, 0x09, 0x78, 0xfa, 0x0b, 0x4b, 0xb3, 0xe6, 0x58, 0x6f, 0xb3, 0x84, 0xbd, - 0x4a, 0x3e, 0x03, 0x79, 0xd9, 0xd3, 0x20, 0xb2, 0x32, 0x25, 0x09, 0x64, 0xf0, 0xae, 0xbc, 0x9a, - 0x9c, 0xcd, 0x99, 0x3e, 0xfd, 0x8b, 0x77, 0xb8, 0xa5, 0x1f, 0xac, 0xe9, 0x88, 0x40, 0x94, 0x64, - 0xfb, 0x5b, 0x38, 0xe6, 0x44, 0xb5, 0x1c, 0xfe, 0xa4, 0xa7, 0x40, 0x3f, 0x59, 0x2b, 0x7e, 0xab, - 0x7e, 0xf3, 0x1d, 0x2b, 0xfc, 0xb3, 0xf6, 0x5a, 0xc8, 0x47, 0xb8, 0x26, 0xc6, 0x5f, 0x9d, 0xaf, - 0x7d, 0x00, 0x79, 0xbe, 0xf5, 0xab, 0xa6, 0xa7, 0x60, 0x61, 0x8a, 0xe8, 0x37, 0x33, 0x50, 0xc6, - 0x44, 0xd0, 0x0d, 0x17, 0x29, 0xb6, 0xf0, 0x46, 0x9c, 0x2f, 0xb0, 0xe0, 0xdc, 0xb0, 0xf1, 0x20, - 0xff, 0x5a, 0x44, 0x98, 0x28, 0x36, 0xba, 0xe0, 0xa8, 0xb6, 0x3d, 0x22, 0x54, 0xa2, 0xc6, 0x05, - 0xf6, 0x06, 0x6c, 0xd4, 0xab, 0x05, 0x9b, 0x1c, 0xca, 0x06, 0x00, 0x55, 0xf4, 0x3c, 0x7a, 0x44, - 0x89, 0xb5, 0x71, 0x08, 0x1c, 0x09, 0x3f, 0xff, 0xe3, 0x82, 0x52, 0x6d, 0x01, 0x85, 0x85, 0x91, - 0xe9, 0x56, 0xa5, 0xb7, 0x7e, 0x51, 0x80, 0x52, 0x30, 0x61, 0xac, 0x1a, 0x23, 0x9b, 0xf9, 0x5f, - 0x69, 0x9a, 0xc2, 0x8e, 0x55, 0xc6, 0xb0, 0x8d, 0xe2, 0xa7, 0x3c, 0xa8, 0xaf, 0x8f, 0xf0, 0x1f, - 0xba, 0x20, 0x08, 0x89, 0x16, 0xe8, 0x39, 0xd0, 0x05, 0xc5, 0x03, 0x32, 0x51, 0x35, 0x76, 0x45, - 0x42, 0x40, 0xcf, 0x6d, 0xea, 0xbd, 0x66, 0xb8, 0xbc, 0x80, 0x50, 0xd7, 0x17, 0xd6, 0x66, 0x12, - 0x06, 0x76, 0xe8, 0xf6, 0x42, 0xf1, 0xfa, 0x61, 0x30, 0xe7, 0x18, 0x3c, 0x21, 0x10, 0x5e, 0x74, - 0x63, 0x02, 0x7c, 0xd4, 0x30, 0xba, 0xe8, 0x23, 0xe4, 0x80, 0x0a, 0x8d, 0xa3, 0xf8, 0xf6, 0xdd, - 0xfb, 0xb6, 0x00, 0x73, 0x98, 0xee, 0xd0, 0xfb, 0x0c, 0x5e, 0xda, 0x56, 0xd0, 0xaf, 0x95, 0x5e, - 0x43, 0x2e, 0xe1, 0xa3, 0x23, 0xb4, 0xf9, 0x16, 0x22, 0x4e, 0xdf, 0xdf, 0xe7, 0x5b, 0x52, 0xa2, - 0x28, 0xa4, 0xde, 0x37, 0x22, 0x13, 0xa3, 0x5d, 0x07, 0x76, 0x8e, 0xdd, 0xe9, 0x92, 0x2f, 0x87, - 0xd1, 0x95, 0xc3, 0x98, 0x6f, 0xdd, 0x8e, 0x98, 0x49, 0x3c, 0x3a, 0x21, 0xd4, 0xdc, 0x42, 0xf9, - 0x09, 0x70, 0x64, 0xf4, 0xe2, 0xa8, 0x53, 0x15, 0x84, 0x3e, 0x6f, 0xc9, 0x49, 0x6f, 0x31, 0x1b, - 0xe6, 0x08, 0x03, 0x48, 0x79, 0xd5, 0xbe, 0xb8, 0xaa, 0x0a, 0x12, 0x1e, 0xfc, 0x4a, 0x54, 0x09, - 0x27, 0x40, 0x75, 0x09, 0x10, 0x63, 0x21, 0xe1, 0x4b, 0xdd, 0xcd, 0x05, 0x51, 0x24, 0xa2, 0x11, - 0xba, 0x44, 0xf1, 0x91, 0x42, 0x28, 0x16, 0xe4, 0x02, 0x35, 0x51, 0x20, 0xaa, 0x47, 0xf6, 0xf6, - 0x4c, 0xae, 0xce, 0xe6, 0xf3, 0x6a, 0x8c, 0x9e, 0xc8, 0x3c, 0x56, 0x48, 0xa8, 0x3f, 0xd1, 0xfe, - 0x86, 0x75, 0x46, 0x7e, 0x89, 0x83, 0xe4, 0x1a, 0x55, 0xfe, 0xf0, 0x98, 0x2d, 0x90, 0x8f, 0x08, - 0xb0, 0x96, 0x64, 0xd4, 0xca, 0xe4, 0x2b, 0x5f, 0x1e, 0xfe, 0x22, 0x83, 0xc4, 0x4e, 0x66, 0x3c, - 0xff, 0xa5, 0x15, 0xa3, 0x4c, 0x80, 0xfa, 0xf3, 0x02, 0xa2, 0x48, 0x44, 0x78, 0x94, 0xfc, 0x61, - 0x72, 0xe3, 0x64, 0xde, 0x37, 0x2e, 0x53, 0x07, 0xb5, 0xc5, 0x52, 0xb1, 0xfd, 0x64, 0x30, 0x56, - 0x3f, 0x48, 0x4e, 0x68, 0xb0, 0xbc, 0xa0, 0x8e, 0xac, 0x68, 0x71, 0xb0, 0x78, 0x70, 0xc6, 0x9d, - 0x79, 0x45, 0x86, 0x0a, 0x5a, 0xe4, 0xaa, 0x41, 0xba, 0x9e, 0x78, 0xff, 0xd0, 0x18, 0xc9, 0x07, - 0x63, 0x74, 0x3d, 0xf6, 0xff, 0xf1, 0x21, 0x52, 0x35, 0x78, 0xd5, 0x30, 0x99, 0x83, 0xd4, 0x3f, - 0x34, 0xca, 0x84, 0xeb, 0x6e, 0x45, 0xa8, 0xfd, 0x37, 0x6d, 0x0f, 0xd4, 0x1e, 0x16, 0x65, 0xa9, - 0xe9, 0x91, 0xce, 0x12, 0xc4, 0xda, 0x97, 0x9a, 0x18, 0x1e, 0x68, 0xe0, 0xa6, 0xf5, 0x37, 0x86, - 0x8c, 0x3b, 0x0f, 0xf6, 0xc5, 0x25, 0x6c, 0xc9, 0xbc, 0x3a, 0x05, 0x48, 0x81, 0x3b, 0x8b, 0x87, - 0xe3, 0xab, 0x53, 0x7f, 0x03, 0x86, 0x1d, 0x0f, 0x18, 0x03, 0x14, 0xf4, 0x8d, 0x62, 0x80, 0x1d, - 0x5f, 0x58, 0x34, 0x58, 0x16, 0x6c, 0x2e, 0xa0, 0x45, 0xa0, 0x2b, 0x4a, 0x7d, 0x8b, 0xfc, 0x90, - 0x7f, 0x6e, 0x39, 0x68, 0x19, 0x93, 0x08, 0xb2, 0xc6, 0xb8, 0x5b, 0x40, 0x57, 0xe8, 0x86, 0x45, - 0xf1, 0x8e, 0x37, 0x11, 0xbe, 0x61, 0x3f, 0x28, 0x1e, 0x92, 0x50, 0xe3, 0xd7, 0xd2, 0x38, 0x46, - 0x02, 0x7e, 0x3b, 0xdc, 0xbd, 0x1c, 0x04, 0x72, 0x2e, 0x34, 0x31, 0x7f, 0xd5, 0xda, 0xa2, 0x17, - 0x43, 0x0f, 0x93, 0x72, 0x3f, 0xb7, 0xf1, 0x0f, 0x0a, 0x14, 0x61, 0xc7, 0x43, 0xc6, 0x05, 0x12, - 0x6e, 0x35, 0xd8, 0x1a, 0x51, 0x52, 0xfe, 0x91, 0xfd, 0x39, 0xf7, 0x79, 0xeb, 0xaf, 0x1a, 0x63, - 0xa7, 0xaf, 0xda, 0x62, 0x30, 0x1d, 0xef, 0xd3, 0x68, 0x30, 0x17, 0x68, 0xa0, 0x14, 0x62, 0x4b, - 0xfa, 0x9a, 0x91, 0x5f, 0x98, 0x87, 0xc8, 0xa9, 0xb3, 0xf3, 0x05, 0x7c, 0xfb, 0xac, 0xd8, 0xe3, - 0xc2, 0x09, 0xc6, 0xd1, 0x38, 0xf3, 0xdf, 0x6a, 0x79, 0x23, 0xc9, 0x04, 0xbb, 0xe4, 0xcc, 0x95, - 0xd5, 0x98, 0x70, 0x25, 0xff, 0x74, 0xc5, 0x40, 0xd0, 0x64, 0xec, 0xe8, 0x92, 0x62, 0x15, 0x40, - 0xd1, 0xa6, 0x93, 0xd7, 0x19, 0x9a, 0x97, 0x49, 0x8f, 0x1e, 0x98, 0x80, 0x82, 0x84, 0xc1, 0x1d, - 0x56, 0x24, 0x5c, 0x37, 0x3f, 0x9b, 0xcd, 0x14, 0x15, 0x3f, 0x99, 0x67, 0x0f, 0x1e, 0x46, 0x24, - 0x93, 0xb8, 0x0d, 0xa9, 0x3a, 0x08, 0xf9, 0xcc, 0xe8, 0xec, 0xab, 0x7c, 0x78, 0x78, 0xc1, 0x54, - 0x7c, 0xa5, 0x8e, 0x25, 0x41, 0xde, 0xab, 0x29, 0xb0, 0xb7, 0x00, 0xd9, 0x98, 0x23, 0x7b, 0x90, - 0xf8, 0x41, 0x24, 0x45, 0xf2, 0xa4, 0x6e, 0x3c, 0xa5, 0x60, 0xc9, 0xb0, 0xe2, 0x9d, 0x54, 0x8c, - 0x90, 0x44, 0xa3, 0xf6, 0x78, 0x34, 0x40, 0xe6, 0x86, 0xb8, 0xf5, 0x2b, 0x30, 0xbb, 0x99, 0x6a, - 0x17, 0xe5, 0xad, 0x68, 0x3d, 0xd5, 0xd7, 0x99, 0x70, 0xdf, 0xfc, 0x15, 0x03, 0x19, 0xcd, 0xc1, - 0x82, 0x1f, 0xb1, 0x27, 0x9e, 0x72, 0xc8, 0x3c, 0x89, 0x60, 0x42, 0x72, 0xfc, 0xb6, 0xe8, 0x3b, - 0x37, 0x7f, 0x0b, 0xc7, 0xb0, 0xfa, 0xc6, 0x1c, 0xca, 0xf3, 0x2c, 0x68, 0x03, 0x6a, 0x28, 0x73, - 0x4f, 0xe3, 0x20, 0xc9, 0x39, 0x8a, 0x03, 0x51, 0xb7, 0x68, 0xff, 0x9b, 0x82, 0x42, 0x4f, 0xb3, - 0xb8, 0x21, 0xea, 0x98, 0x11, 0x0e, 0x0d, 0xd1, 0x22, 0x20, 0xcd, 0x43, 0x5e, 0x2a, 0x2b, 0xcb, - 0x73, 0x2f, 0x58, 0x5d, 0xc7, 0xfd, 0x24, 0x0a, 0x73, 0xcd, 0x8d, 0x6b, 0x20, 0x02, 0x1d, 0x9d, - 0x19, 0x3d, 0x20, 0x1c, 0x7c, 0x46, 0xbf, 0x51, 0xf0, 0xf9, 0x8a, 0x1b, 0x1f, 0x04, 0x01, 0x47, - 0x26, 0x05, 0x54, 0x46, 0x3e, 0x12, 0x92, 0x07, 0xdc, 0x87, 0x1d, 0xf4, 0xc9, 0x9d, 0x01, 0xea, - 0x32, 0x9a, 0x4a, 0xcd, 0x97, 0x08, 0x30, 0x0e, 0xcd, 0xdf, 0x92, 0xb7, 0x13, 0x54, 0x10, 0xa1, - 0x92, 0xc4, 0xfa, 0xba, 0xec, 0xfe, 0x26, 0x96, 0x7b, 0x78, 0xa0, 0x69, 0x14, 0x85, 0x00, 0x77, - 0x39, 0x00, 0xe5, 0x51, 0xef, 0xd5, 0xe5, 0xe5, 0x17, 0xbc, 0x41, 0xd8, 0xaa, 0x48, 0x7a, 0x56, - 0x58, 0x84, 0x55, 0x0d, 0xc9, 0x0a, 0xbe, 0xc9, 0xf6, 0xb2, 0x91, 0x08, 0x36, 0x25, 0x64, 0x98, - 0x8c, 0x35, 0x44, 0x63, 0xa0, 0xb1, 0x95, 0x8d, 0x21, 0xd0, 0x78, 0x05, 0x83, 0x2d, 0x8e, 0x9e, - 0x41, 0x8f, 0x20, 0x3d, 0xff, 0x58, 0xe2, 0xae, 0x56, 0x92, 0x46, 0x2a, 0xac, 0x2d, 0x9c, 0x7f, - 0xf1, 0x08, 0x72, 0xd2, 0x43, 0xba, 0x25, 0x64, 0x7e, 0xfc, 0xc7, 0x28, 0x2f, 0x17, 0xe4, 0x0d, - 0xfc, 0xe9, 0xf5, 0xe0, 0x6f, 0x41, 0xc6, 0x97, 0x42, 0xb7, 0x0d, 0x2f, 0x05, 0x42, 0x5f, 0x2a, - 0x3d, 0xcc, 0xe9, 0x55, 0xe8, 0x4b, 0x4f, 0xa1, 0x2f, 0xbd, 0x52, 0x09, 0x5f, 0x7a, 0x15, 0xac, - 0x93, 0xcd, 0x67, 0xe1, 0x65, 0x77, 0xb3, 0xb2, 0xfb, 0x33, 0x83, 0x67, 0x3b, 0x4b, 0x8e, 0xde, - 0xfc, 0x70, 0xa2, 0xe8, 0xf2, 0x4d, 0x3f, 0xbd, 0xce, 0x5c, 0xb2, 0xf0, 0xf4, 0x55, 0xdc, 0xa5, - 0xdd, 0x6b, 0xa3, 0x79, 0xad, 0x5e, 0xaf, 0xe3, 0x3c, 0x2d, 0x73, 0x5f, 0x5c, 0x05, 0x86, 0xa4, - 0xf1, 0x5b, 0x23, 0x54, 0x69, 0x12, 0x13, 0xf8, 0xe1, 0xa1, 0x24, 0xa8, 0xde, 0x0e, 0x3d, 0x3c, - 0xf2, 0x12, 0xdd, 0x94, 0x6e, 0x9a, 0xf1, 0x7d, 0x27, 0x70, 0x88, 0x26, 0xd4, 0x7b, 0x07, 0x58, - 0x01, 0xbc, 0x84, 0xbc, 0xb8, 0x51, 0x84, 0xb4, 0x3c, 0xf7, 0x68, 0xb7, 0x14, 0xbc, 0x01, 0x8d, - 0x52, 0xaf, 0x65, 0x92, 0xee, 0xd9, 0x69, 0x94, 0x19, 0x99, 0xcc, 0xcc, 0x7d, 0x20, 0xc8, 0x1b, - 0xb9, 0x1b, 0x14, 0xa0, 0xee, 0xbb, 0x09, 0xe9, 0xdd, 0x0e, 0xd0, 0x27, 0x0a, 0x0b, 0xae, 0xab, - 0x13, 0xfa, 0x34, 0xfb, 0x90, 0x81, 0x9c, 0xa6, 0xdb, 0xa1, 0xb7, 0xf4, 0xa4, 0x4a, 0x3d, 0x9e, - 0x57, 0x15, 0x19, 0x40, 0x91, 0x04, 0x7a, 0x48, 0x0f, 0x27, 0x78, 0xf4, 0x34, 0xc4, 0xbd, 0x76, - 0x3b, 0xc1, 0x85, 0x49, 0x93, 0x77, 0x17, 0xb7, 0x26, 0x16, 0x24, 0x8d, 0x0f, 0x06, 0x97, 0xdd, - 0x8d, 0xdd, 0x96, 0x16, 0x0b, 0xe6, 0x56, 0x15, 0x4c, 0x56, 0x57, 0xb4, 0xbc, 0x1c, 0x66, 0xf6, - 0x53, 0x5d, 0xcc, 0x2d, 0x2d, 0x95, 0x5c, 0xdc, 0x1c, 0xbd, 0x75, 0xc2, 0x6d, 0x65, 0x30, 0x61, - 0x16, 0x21, 0x03, 0xa2, 0x98, 0x19, 0xfc, 0x4c, 0x5f, 0xcd, 0xae, 0xdb, 0x69, 0xc7, 0xd8, 0x57, - 0xa7, 0xa4, 0x9b, 0xc8, 0x26, 0xdd, 0xfd, 0xcb, 0x45, 0xae, 0x39, 0xb1, 0x24, 0xad, 0x2e, 0x9e, - 0x1b, 0x8e, 0x80, 0x1f, 0x97, 0xa3, 0x20, 0xbb, 0x62, 0x4d, 0xdf, 0xca, 0x92, 0xfc, 0xb6, 0x56, - 0x4f, 0xe8, 0xf0, 0xff, 0x4c, 0x1d, 0x5e, 0x92, 0x3e, 0x08, 0xc8, 0x93, 0xb7, 0xe5, 0x6a, 0x36, - 0x99, 0x4c, 0x89, 0x42, 0x43, 0xac, 0xea, 0x38, 0x1d, 0x09, 0x5a, 0xb6, 0x28, 0xff, 0x49, 0x2d, - 0x91, 0xd4, 0x96, 0x0d, 0x15, 0x61, 0x59, 0x63, 0xa1, 0x61, 0x43, 0xf4, 0xf6, 0x38, 0x26, 0x30, - 0x91, 0xf4, 0x28, 0x89, 0xbb, 0x27, 0x32, 0x5e, 0xe7, 0x07, 0x50, 0xe3, 0x4f, 0x50, 0x23, 0xa3, - 0x42, 0x2d, 0x94, 0x49, 0xda, 0xb0, 0x25, 0x6e, 0x2b, 0xa9, 0xba, 0x67, 0x02, 0x84, 0xa2, 0xf4, - 0x10, 0x1a, 0xf7, 0xd4, 0x6a, 0x38, 0x9d, 0xb5, 0xa0, 0xd6, 0xc5, 0x93, 0xd1, 0x68, 0xa0, 0xbc, - 0x8c, 0xc4, 0x1a, 0x49, 0x83, 0x12, 0x9b, 0xa6, 0x67, 0x1b, 0xee, 0x89, 0xa8, 0x9c, 0xce, 0x16, - 0xd2, 0xd4, 0xfa, 0x0b, 0xe5, 0x0e, 0x0d, 0x10, 0x23, 0xe9, 0xa2, 0xea, 0xe8, 0x34, 0x05, 0x1f, - 0xd8, 0xee, 0x37, 0x06, 0xe6, 0x8c, 0x95, 0xe7, 0x02, 0xc8, 0x4d, 0xea, 0xdc, 0xd7, 0xca, 0xbf, - 0xd3, 0xaf, 0x62, 0x22, 0xab, 0xfe, 0x63, 0xa6, 0xcc, 0xe9, 0x0f, 0xba, 0x3b, 0xd4, 0x95, 0x6d, - 0x51, 0xac, 0x7e, 0xf3, 0xcd, 0x91, 0x86, 0x86, 0xf7, 0x40, 0xea, 0xb9, 0xad, 0xef, 0x03, 0xcb, - 0x33, 0x32, 0x78, 0x77, 0x85, 0xfc, 0x0f, 0xac, 0xbb, 0x1f, 0xc4, 0x93, 0x6b, 0xcc, 0x47, 0x1f, - 0x3f, 0x89, 0xbc, 0xf8, 0xfd, 0x56, 0x4c, 0xa5, 0xda, 0xb2, 0x6b, 0xae, 0xfc, 0xc6, 0x1a, 0xcd, - 0x15, 0x4b, 0xeb, 0x78, 0x2e, 0xe4, 0x6c, 0x7b, 0x08, 0x10, 0x77, 0x49, 0x7b, 0xd4, 0x17, 0xa5, - 0x6f, 0x2b, 0xe2, 0x5c, 0xc6, 0xde, 0x10, 0x9c, 0xfd, 0xc7, 0xb7, 0x2e, 0x56, 0xfd, 0x8f, 0x6f, - 0xd5, 0x6f, 0xa9, 0x44, 0x36, 0x57, 0x76, 0x01, 0x8b, 0x3d, 0x05, 0x18, 0x36, 0xec, 0xcc, 0xf4, - 0x14, 0x35, 0x99, 0xfa, 0x46, 0xc5, 0xc2, 0xe8, 0xa6, 0x19, 0xae, 0x02, 0xfa, 0x6a, 0x95, 0x06, - 0xbb, 0x85, 0xe2, 0xc1, 0x97, 0xe5, 0x42, 0x37, 0xc6, 0xbe, 0xa1, 0xe1, 0x98, 0x0d, 0xc2, 0xef, - 0xfa, 0xce, 0x48, 0xd5, 0xd0, 0x99, 0x22, 0x3d, 0x56, 0xbb, 0xc9, 0x48, 0x5e, 0x4b, 0xed, 0x83, - 0xd4, 0x4e, 0xef, 0xde, 0xa0, 0x7c, 0x8d, 0xa5, 0x26, 0x6a, 0x4f, 0x4d, 0xdb, 0x34, 0x3d, 0x25, - 0xfe, 0x4b, 0xa0, 0x7e, 0xc5, 0x34, 0xcd, 0xb2, 0x6d, 0x55, 0x12, 0x85, 0xee, 0xce, 0x10, 0x78, - 0x65, 0x04, 0xce, 0xad, 0x89, 0x66, 0x77, 0x51, 0x8a, 0x98, 0xe0, 0xd3, 0x23, 0x9a, 0x9e, 0x8c, - 0x16, 0xc7, 0xe8, 0x5f, 0x02, 0xae, 0x20, 0x58, 0x4f, 0x00, 0xf2, 0x65, 0xc7, 0x03, 0x48, 0xd2, - 0xa6, 0x6d, 0x29, 0xc3, 0xed, 0x70, 0xc9, 0xcb, 0xd6, 0x75, 0xe3, 0x4c, 0x94, 0x12, 0x6e, 0x2e, - 0x5d, 0x76, 0x49, 0x6e, 0xcd, 0xb9, 0x20, 0x16, 0x87, 0xbe, 0x07, 0x0c, 0x73, 0x88, 0x4b, 0x4e, - 0x70, 0x2f, 0xb8, 0x88, 0x92, 0x16, 0xed, 0x4b, 0x03, 0x08, 0x11, 0xf6, 0x66, 0x61, 0xff, 0xb2, - 0x85, 0xc3, 0xa7, 0xcb, 0xb6, 0x67, 0xda, 0xd1, 0x62, 0x67, 0x8d, 0xa6, 0x00, 0xac, 0x02, 0x2f, - 0x6a, 0x61, 0xb1, 0xa1, 0xd2, 0x59, 0x18, 0x94, 0xaa, 0x11, 0xfb, 0xcd, 0x86, 0xfd, 0x1d, 0x0b, - 0x00, 0x53, 0x1f, 0xa5, 0xf0, 0x9c, 0x9e, 0x3e, 0x3a, 0x29, 0xec, 0x22, 0x22, 0x93, 0x5b, 0xc0, - 0x20, 0x9e, 0xfc, 0xc9, 0x0a, 0x66, 0x58, 0x21, 0x58, 0xcc, 0xff, 0x5a, 0xc4, 0xed, 0x9e, 0x3e, - 0x56, 0x2d, 0x43, 0x1f, 0xd2, 0xee, 0x93, 0x34, 0x5e, 0xeb, 0xa7, 0xe7, 0x06, 0xe8, 0x8d, 0x62, - 0x11, 0x78, 0xa4, 0x53, 0xa4, 0x4d, 0x54, 0x13, 0xbd, 0xbd, 0x69, 0x6d, 0x20, 0x66, 0xba, 0x92, - 0x7e, 0x31, 0xbe, 0xf7, 0x32, 0x0e, 0x6f, 0xe0, 0x54, 0xb4, 0xa6, 0x92, 0x32, 0xda, 0x97, 0x82, - 0x22, 0x4b, 0x7c, 0xf0, 0x23, 0xb1, 0x69, 0x92, 0xcc, 0x6b, 0xc8, 0xf7, 0x93, 0x70, 0x0d, 0x63, - 0x6e, 0xcd, 0x96, 0x8a, 0xa7, 0x75, 0x7d, 0x74, 0x29, 0x08, 0xc5, 0xc6, 0xe1, 0x5d, 0x4b, 0x3c, - 0xe6, 0xea, 0x5d, 0x44, 0xe7, 0x19, 0x2c, 0x95, 0xe0, 0x6d, 0x7f, 0xaf, 0x0b, 0x9d, 0xb1, 0x26, - 0xf8, 0x8b, 0x48, 0xe1, 0xdb, 0x47, 0xee, 0xa5, 0x23, 0x14, 0xb1, 0xfa, 0xae, 0x8e, 0xe0, 0x15, - 0x4e, 0xa5, 0x28, 0x4c, 0x2d, 0xd0, 0x0a, 0xf4, 0x34, 0xac, 0x84, 0x1a, 0xf5, 0x3a, 0x08, 0x80, - 0x50, 0xd9, 0x8e, 0x83, 0xa9, 0xa5, 0x80, 0xb0, 0xb4, 0x2d, 0x04, 0x8c, 0x59, 0x08, 0x5f, 0x4b, - 0x52, 0x48, 0x0a, 0x33, 0x0c, 0x03, 0x7c, 0x31, 0xa5, 0x25, 0x25, 0xb5, 0xfe, 0xe5, 0x8b, 0x82, - 0x87, 0x2c, 0xf1, 0x27, 0x62, 0xbe, 0x42, 0xf6, 0xd7, 0x5f, 0x78, 0x5d, 0x41, 0x5b, 0x5f, 0xe7, - 0x7d, 0x89, 0x21, 0x1b, 0xbd, 0xa8, 0xc4, 0xe0, 0x4b, 0xd2, 0x62, 0xcd, 0x9e, 0xa8, 0x28, 0x5d, - 0xe9, 0x28, 0x2e, 0x26, 0x67, 0x1d, 0xf4, 0x67, 0xc9, 0x56, 0x8d, 0xd0, 0xb1, 0x65, 0xad, 0x6d, - 0x11, 0xe5, 0xa5, 0x46, 0xf3, 0x72, 0x7c, 0x5e, 0x3f, 0x9c, 0x97, 0xe7, 0xf3, 0xb4, 0xa4, 0x38, - 0xc7, 0xfe, 0x5b, 0xae, 0xfe, 0xe1, 0x4a, 0xca, 0x20, 0xe7, 0x6b, 0xf3, 0x20, 0xea, 0x55, 0xdb, - 0x5e, 0xe4, 0x43, 0x5c, 0x8c, 0x25, 0x01, 0xb6, 0x34, 0xe1, 0x8f, 0x99, 0x9e, 0x36, 0xf4, 0x6d, - 0x3c, 0x1c, 0x16, 0x99, 0xba, 0xeb, 0x4b, 0xdd, 0xda, 0x1c, 0x0a, 0x84, 0x95, 0x18, 0x40, 0xdd, - 0xe5, 0xc4, 0x4a, 0x60, 0x5e, 0x32, 0xc2, 0xb7, 0x96, 0x47, 0xca, 0xe2, 0xe3, 0x33, 0x31, 0xb8, - 0xf4, 0x53, 0x25, 0xab, 0x63, 0xfd, 0x91, 0x3e, 0xba, 0xfe, 0xb3, 0x86, 0x7e, 0x27, 0x68, 0xd9, - 0x92, 0x4f, 0xdd, 0xe1, 0x30, 0xa1, 0x55, 0x18, 0x5e, 0x66, 0xeb, 0xc3, 0x58, 0x4d, 0xfc, 0x5f, - 0xd0, 0x0a, 0xeb, 0x3a, 0xdb, 0x1a, 0xa5, 0x2e, 0x7d, 0x32, 0x4c, 0xc9, 0xf4, 0x92, 0x1e, 0xa5, - 0xbe, 0x9b, 0xf6, 0x28, 0x8d, 0xea, 0x20, 0x73, 0x01, 0x49, 0x7c, 0x1f, 0x4e, 0xfe, 0x1c, 0x0e, - 0xa4, 0x1e, 0x4c, 0x0d, 0x8b, 0xb7, 0x13, 0x8a, 0xb2, 0xe3, 0x7e, 0xe8, 0x15, 0xef, 0xdc, 0xe2, - 0x65, 0x47, 0x22, 0xa0, 0x26, 0x78, 0x86, 0xbb, 0xa2, 0xd8, 0x55, 0x2d, 0x76, 0x10, 0x21, 0xce, - 0x97, 0x84, 0x85, 0xe4, 0x50, 0x08, 0x70, 0x22, 0x28, 0x03, 0x80, 0x1e, 0xbe, 0x70, 0xb4, 0x50, - 0x60, 0x5b, 0x74, 0x23, 0xe6, 0xd0, 0x99, 0xdd, 0xfa, 0x20, 0x3a, 0x92, 0x17, 0x31, 0xe7, 0x97, - 0x34, 0xfe, 0xa0, 0xeb, 0x67, 0x2a, 0xea, 0x30, 0x1f, 0xf7, 0x71, 0x18, 0xfd, 0x74, 0xe1, 0x99, - 0xca, 0xf7, 0x70, 0xa8, 0xfe, 0xdd, 0x0e, 0x0e, 0x50, 0x7c, 0x1b, 0x22, 0x8b, 0x19, 0xa1, 0x2b, - 0xcf, 0xe7, 0x30, 0xfd, 0x09, 0x9c, 0x3e, 0x2e, 0xa2, 0xf4, 0x31, 0x84, 0xd3, 0xc7, 0xbf, 0xdb, - 0xe3, 0xe1, 0x3f, 0x85, 0xd2, 0xc7, 0x05, 0x94, 0x86, 0x7a, 0x38, 0xfc, 0xbb, 0x3d, 0x64, 0xfc, - 0xb0, 0x1d, 0xe6, 0x27, 0xb4, 0x45, 0xc5, 0xc4, 0x3b, 0xdd, 0x34, 0x20, 0x29, 0x3c, 0xe3, 0x27, - 0x10, 0x4d, 0x2e, 0x36, 0xac, 0xd6, 0xd6, 0x36, 0x6c, 0x37, 0x6a, 0xd4, 0x1e, 0x65, 0x90, 0x42, - 0x76, 0x57, 0xd8, 0x7f, 0xa0, 0x42, 0x20, 0xbf, 0xd0, 0x88, 0xb6, 0x61, 0x42, 0xb3, 0xec, 0xec, - 0x2d, 0x9c, 0x1a, 0x6a, 0x2e, 0x9b, 0x8b, 0x8e, 0x30, 0x9b, 0xf3, 0x18, 0xce, 0x77, 0x37, 0x74, - 0x59, 0xf0, 0xa5, 0xc3, 0x3f, 0x66, 0xc0, 0x89, 0x61, 0xd8, 0xd9, 0xdc, 0x36, 0x9e, 0x87, 0xb3, - 0xfb, 0xb0, 0x6c, 0xe4, 0x97, 0x20, 0x52, 0x68, 0xf6, 0xf7, 0x0c, 0xab, 0x13, 0xad, 0x9b, 0xc5, - 0xba, 0xd9, 0x65, 0x75, 0x77, 0x14, 0x6b, 0x59, 0xc5, 0x1c, 0x56, 0xcc, 0x2d, 0xab, 0xd8, 0xb0, - 0x3a, 0xcb, 0x2a, 0xe6, 0xb1, 0x62, 0x7e, 0x59, 0xc5, 0x26, 0xbd, 0x15, 0x1e, 0xd4, 0xcd, 0xb0, - 0xec, 0x08, 0x2f, 0x3a, 0x72, 0xe7, 0x87, 0xce, 0x86, 0xad, 0x23, 0xda, 0xd4, 0xd8, 0xa9, 0x68, - 0xa1, 0x58, 0x22, 0xd8, 0xea, 0xf0, 0xef, 0xce, 0x83, 0x1d, 0x5d, 0xbb, 0x2d, 0xf5, 0xc3, 0x59, - 0xb0, 0xd5, 0x45, 0x44, 0x12, 0x05, 0x6a, 0xea, 0x1f, 0xcf, 0x42, 0x4c, 0xdd, 0x7b, 0x72, 0xaf, - 0x6a, 0xda, 0xb5, 0xd1, 0x79, 0x79, 0x34, 0x46, 0x1f, 0x60, 0xa6, 0x16, 0x35, 0xc5, 0xc1, 0x30, - 0xa8, 0x31, 0x09, 0xe0, 0x6b, 0x78, 0xf6, 0x33, 0xc4, 0x3d, 0x9c, 0xf4, 0xb7, 0xc5, 0x50, 0x1b, - 0xc8, 0x7d, 0xb7, 0x83, 0x8d, 0x7d, 0x61, 0x03, 0x74, 0xe9, 0x1e, 0x6f, 0x52, 0xd3, 0x2d, 0x04, - 0x1e, 0xd0, 0x0c, 0x15, 0xb3, 0x92, 0x59, 0xa4, 0xef, 0xad, 0x8f, 0x57, 0xb0, 0x4d, 0xb4, 0x30, - 0x66, 0x51, 0x1e, 0xe1, 0x97, 0x30, 0xa4, 0xfc, 0xbd, 0x35, 0x1c, 0x19, 0xfe, 0x82, 0x09, 0x12, - 0x1b, 0xda, 0x9b, 0xfa, 0xb3, 0xb8, 0xc4, 0xaa, 0x67, 0xbd, 0x87, 0xba, 0x4b, 0xdf, 0x03, 0x9b, - 0x1e, 0x3a, 0xb9, 0x51, 0x39, 0x11, 0x7e, 0x5d, 0xdf, 0xc7, 0x44, 0xb2, 0x16, 0x44, 0x01, 0xa6, - 0xc0, 0x6b, 0x54, 0x34, 0xc0, 0xb1, 0x40, 0xed, 0x6d, 0xdb, 0x35, 0xc5, 0xb0, 0x5f, 0x00, 0x0b, - 0x92, 0x13, 0xe0, 0xbc, 0x90, 0xc5, 0x5b, 0x60, 0x18, 0xe2, 0x11, 0x7f, 0xf2, 0xb9, 0xa2, 0x38, - 0xa7, 0x82, 0xc4, 0xaf, 0x14, 0x88, 0x4b, 0xfa, 0x36, 0xfc, 0xab, 0x7a, 0xd1, 0xd9, 0x04, 0x14, - 0xce, 0x52, 0xdf, 0x42, 0xe6, 0x42, 0xc3, 0x64, 0x94, 0xfe, 0x61, 0xdf, 0x58, 0x32, 0x6e, 0xd1, - 0xe8, 0x9a, 0xa6, 0xf4, 0xe9, 0x69, 0x2f, 0x1e, 0x6a, 0x6f, 0x7d, 0x4b, 0xfd, 0x8a, 0x22, 0xa1, - 0xef, 0x86, 0xe9, 0xf2, 0xce, 0xbb, 0xa9, 0x6a, 0xf9, 0xc7, 0xcc, 0x98, 0xd7, 0x78, 0xc3, 0x29, - 0xc6, 0xa2, 0xd3, 0xc9, 0xd4, 0x09, 0xcb, 0xc9, 0x8b, 0x4e, 0x72, 0xdf, 0xb0, 0x87, 0xdf, 0x5c, - 0x74, 0xe4, 0x36, 0xcb, 0x7f, 0xcc, 0x5a, 0xd4, 0x40, 0x98, 0xc6, 0x2f, 0x94, 0x34, 0x07, 0x8a, - 0xd5, 0x44, 0x27, 0x58, 0x4a, 0x55, 0x29, 0xb1, 0x21, 0xa6, 0x3b, 0x6e, 0x52, 0x03, 0x3d, 0x3a, - 0x93, 0x1e, 0x3a, 0x7e, 0x45, 0xc6, 0xbd, 0xd1, 0xf1, 0x82, 0xf4, 0x51, 0xb2, 0x08, 0x75, 0xd5, - 0x93, 0x0f, 0x7b, 0xc9, 0x5a, 0x58, 0x70, 0x3b, 0xb0, 0x4c, 0x3a, 0x37, 0x92, 0x1c, 0x74, 0xa7, - 0xe1, 0x05, 0x65, 0x59, 0x01, 0xc8, 0x5a, 0x0a, 0x28, 0x1b, 0x00, 0xda, 0xf9, 0x04, 0xa0, 0xfe, - 0x52, 0x40, 0xb9, 0x00, 0x50, 0xf3, 0x13, 0x80, 0xb4, 0xa5, 0x80, 0xf2, 0x01, 0xa0, 0x5d, 0x1f, - 0x10, 0xc7, 0x24, 0x84, 0x5f, 0x8b, 0x13, 0x1e, 0x63, 0x2c, 0x77, 0x09, 0x7f, 0xb9, 0xb9, 0x5c, - 0x8b, 0x37, 0x95, 0xc7, 0x41, 0x8f, 0xb5, 0x94, 0x6b, 0xb1, 0x56, 0x72, 0x2d, 0x6a, 0x21, 0x87, - 0x85, 0x10, 0xbd, 0xaa, 0x68, 0x51, 0x0f, 0xfd, 0x28, 0x9f, 0x53, 0xf5, 0x50, 0xc7, 0xe1, 0x95, - 0xf5, 0x65, 0x21, 0xdc, 0x9d, 0x47, 0x43, 0xce, 0xd4, 0x09, 0xd5, 0x70, 0x62, 0x3f, 0xc3, 0x13, - 0x7c, 0x85, 0xe7, 0x8f, 0x99, 0x48, 0x6c, 0xb3, 0x9c, 0x2b, 0x95, 0xc4, 0x7a, 0xdd, 0xa6, 0x6a, - 0xeb, 0x76, 0x3e, 0x57, 0x2d, 0x15, 0xe6, 0xbc, 0x78, 0xed, 0xae, 0x59, 0xe4, 0xa0, 0xa1, 0xb8, - 0x7a, 0xf4, 0x53, 0x3f, 0x02, 0x72, 0xa3, 0x74, 0x3a, 0x2d, 0x66, 0x5c, 0xd3, 0x90, 0x8f, 0x28, - 0xd0, 0x0c, 0x69, 0x14, 0x43, 0x07, 0x08, 0x1a, 0xdd, 0xcc, 0xa0, 0xe7, 0x4e, 0x77, 0xeb, 0x8f, - 0xd9, 0x68, 0x5b, 0x6c, 0xa1, 0x88, 0x2d, 0x3c, 0xa0, 0x97, 0x08, 0x7d, 0x3a, 0xdd, 0xdb, 0x15, - 0x99, 0x47, 0x1a, 0x57, 0x8a, 0xc7, 0x11, 0xf4, 0x77, 0x5b, 0xbc, 0x47, 0x6b, 0x11, 0xad, 0x03, - 0x3c, 0x02, 0x2a, 0x2f, 0x14, 0x60, 0x11, 0x83, 0x40, 0x9d, 0xf4, 0x0a, 0xc5, 0xc2, 0x45, 0x89, - 0xfc, 0xa2, 0xd7, 0xc3, 0x1b, 0x3f, 0x9c, 0x17, 0x1c, 0xd7, 0x45, 0x17, 0xc1, 0x1c, 0xc3, 0x0d, - 0xf3, 0xf9, 0x95, 0x31, 0x16, 0xff, 0x98, 0x25, 0x46, 0xdb, 0xc3, 0x49, 0xd5, 0xb3, 0x39, 0x27, - 0x37, 0xb2, 0x73, 0x4e, 0x59, 0xe9, 0xcc, 0x17, 0x94, 0x9e, 0x53, 0xa2, 0x07, 0xea, 0x90, 0xff, - 0x29, 0x25, 0x68, 0x8c, 0x7d, 0x4a, 0xc9, 0xe3, 0xea, 0xdc, 0x28, 0x3e, 0xe8, 0x20, 0xf9, 0xa0, - 0x83, 0xa1, 0xfe, 0xf1, 0x9d, 0xeb, 0x6e, 0x24, 0xa2, 0x38, 0xed, 0x54, 0xe5, 0xe4, 0x3f, 0xd0, - 0x65, 0x01, 0x5b, 0xf5, 0xfc, 0x96, 0x90, 0x66, 0x37, 0x14, 0x4d, 0xed, 0xeb, 0x55, 0xe4, 0xe9, - 0x96, 0x83, 0xce, 0x4a, 0xb8, 0x1d, 0x62, 0xa1, 0x71, 0x8a, 0x9a, 0x1a, 0xc5, 0x54, 0x0f, 0x93, - 0x16, 0x47, 0x4a, 0x21, 0x31, 0x5b, 0xf0, 0xc2, 0xa6, 0x6e, 0xf4, 0xa2, 0x23, 0xe7, 0xa8, 0xd8, - 0xe8, 0xad, 0x1a, 0x07, 0x67, 0x60, 0x84, 0xe5, 0x09, 0x2d, 0xb8, 0x96, 0xcc, 0x2d, 0x46, 0xa0, - 0x8f, 0x9e, 0x37, 0x25, 0x74, 0x6c, 0x01, 0x47, 0xe2, 0x21, 0x35, 0x6c, 0x7a, 0x44, 0xf7, 0x88, - 0xb6, 0x3f, 0xbf, 0x7c, 0x98, 0xc2, 0x3e, 0x98, 0xbd, 0x6f, 0x29, 0x2d, 0xf5, 0xcd, 0x7e, 0x5c, - 0x39, 0x7f, 0xdf, 0x52, 0x89, 0xe1, 0x60, 0x23, 0x8b, 0xf6, 0x45, 0x6f, 0x78, 0xdf, 0x52, 0x26, - 0xbe, 0xc5, 0x0c, 0x8e, 0x02, 0x5c, 0x32, 0x4b, 0x6e, 0xde, 0x56, 0xd0, 0xd5, 0x0f, 0x3a, 0x46, - 0x3e, 0xea, 0xd8, 0x70, 0x10, 0xea, 0x54, 0xa2, 0xbf, 0x48, 0x4f, 0x66, 0x15, 0xed, 0xe1, 0xff, - 0x7e, 0x67, 0x85, 0xe5, 0xb4, 0x04, 0xdb, 0xff, 0xd0, 0x23, 0xa2, 0x01, 0x3c, 0xf8, 0x13, 0x20, - 0x52, 0x26, 0xeb, 0xcf, 0xec, 0x01, 0x46, 0x1e, 0x83, 0x4d, 0xdb, 0x1f, 0x7f, 0x0b, 0x2f, 0x19, - 0x70, 0xef, 0xe1, 0xa9, 0x13, 0x3f, 0xb5, 0xf6, 0xfa, 0x96, 0x19, 0x8b, 0xa4, 0x2c, 0x6f, 0xcf, - 0xe0, 0xa8, 0x12, 0xca, 0xff, 0x0f, 0x70, 0x04, 0xdb, 0xec, 0xac, 0x9c, 0xba, 0x68, 0xaf, 0xa0, - 0xfc, 0x3f, 0xd2, 0xab, 0x4f, 0x18, 0xe2, 0x99, 0x49, 0x68, 0x99, 0xec, 0xea, 0x7f, 0xf0, 0xc9, - 0x8f, 0xd5, 0x4b, 0x77, 0xd9, 0xf8, 0x6f, 0xbc, 0x71, 0xf3, 0xe5, 0xd9, 0x56, 0xc3, 0x5b, 0xea, - 0x40, 0x68, 0x87, 0x75, 0x21, 0xa0, 0x48, 0xd1, 0xdf, 0xe4, 0x13, 0x74, 0x6b, 0xe8, 0x25, 0xe1, - 0x61, 0x7d, 0xbd, 0xbf, 0x61, 0x6e, 0x65, 0xd7, 0xd7, 0xbb, 0x1b, 0x9d, 0xad, 0xec, 0x76, 0x9b, - 0x12, 0x4e, 0x82, 0xa4, 0x1b, 0xa3, 0xae, 0x6a, 0x5c, 0x13, 0x76, 0xdf, 0x62, 0x7d, 0x3d, 0x92, - 0x40, 0xcd, 0x6d, 0x62, 0xf5, 0x08, 0x37, 0xf2, 0x15, 0x26, 0x81, 0x50, 0x07, 0xda, 0xce, 0x50, - 0x74, 0xdb, 0xa6, 0x41, 0x7d, 0x4d, 0x83, 0x9e, 0x38, 0x30, 0xab, 0x81, 0x1b, 0xc2, 0x0c, 0xdb, - 0x06, 0xee, 0xb9, 0x5a, 0x03, 0xa1, 0x0b, 0xc4, 0x31, 0x23, 0xba, 0xdd, 0x8d, 0xe9, 0xaf, 0xaa, - 0x6f, 0x28, 0x7e, 0x3b, 0x66, 0x48, 0x03, 0x81, 0xd5, 0xb0, 0x85, 0xa7, 0x36, 0x1f, 0x43, 0x8e, - 0xb3, 0xf8, 0x84, 0x20, 0x47, 0x6c, 0x3e, 0x14, 0x32, 0xf2, 0xc1, 0xdf, 0xd7, 0x70, 0xba, 0x18, - 0x88, 0x14, 0x45, 0xf8, 0xe5, 0xd4, 0xe3, 0xf6, 0xcc, 0x62, 0x22, 0x97, 0xff, 0x75, 0x5b, 0x13, - 0x74, 0x52, 0x37, 0x0e, 0x1a, 0x5e, 0xd0, 0xe1, 0x4e, 0x7b, 0xcc, 0x4f, 0x11, 0x59, 0xe8, 0x2b, - 0x88, 0x81, 0xdf, 0xcf, 0x67, 0xba, 0xd2, 0x0d, 0x75, 0x65, 0x97, 0x3a, 0xd9, 0x70, 0x1d, 0xe8, - 0xf2, 0xca, 0xe0, 0xd6, 0x6f, 0x7e, 0xd6, 0x2c, 0xa4, 0x0f, 0x2f, 0xca, 0x8e, 0x40, 0x72, 0x16, - 0xb2, 0x35, 0xe6, 0xf3, 0x39, 0xf7, 0xec, 0xde, 0x8b, 0x4e, 0x13, 0xae, 0x89, 0x9d, 0xb7, 0xa0, - 0x6f, 0xd5, 0xd9, 0x99, 0x77, 0x2d, 0xb8, 0xbd, 0xa5, 0xb9, 0x07, 0xb1, 0xa0, 0x56, 0xe2, 0xf5, - 0xd3, 0xa4, 0xe7, 0x29, 0xea, 0xbd, 0x7b, 0xc1, 0xba, 0xd1, 0x67, 0xd9, 0xb7, 0xfc, 0x2b, 0x75, - 0xb9, 0xa6, 0x7c, 0xaf, 0xe3, 0x20, 0x6b, 0x4a, 0x2a, 0x95, 0x0c, 0x8c, 0xef, 0x0a, 0x02, 0x08, - 0x18, 0x88, 0xe2, 0xdf, 0x18, 0xa2, 0xa6, 0x5e, 0xea, 0x93, 0x4f, 0xd7, 0x82, 0x82, 0xb6, 0xe3, - 0x5f, 0x49, 0xbf, 0xf1, 0xbe, 0x85, 0x75, 0x97, 0x9c, 0x14, 0x7f, 0xe1, 0xeb, 0x41, 0xc7, 0x7e, - 0xf9, 0xbd, 0x82, 0x95, 0xfb, 0xb9, 0xce, 0x67, 0x93, 0xec, 0xca, 0xb6, 0x7b, 0x00, 0xf1, 0x3d, - 0x17, 0x14, 0xed, 0x77, 0x41, 0x2d, 0x85, 0x91, 0xac, 0x3c, 0xa7, 0x46, 0xe4, 0xcb, 0x4b, 0x0f, - 0xa9, 0xa5, 0x2f, 0xd4, 0x64, 0xfc, 0x45, 0x63, 0x97, 0x36, 0xc3, 0x5b, 0xa0, 0x77, 0xc4, 0x11, - 0x0c, 0x02, 0x5b, 0x9b, 0xdb, 0xde, 0x2d, 0x88, 0x24, 0xec, 0x91, 0xa9, 0x65, 0xa5, 0x88, 0x5f, - 0xea, 0xbb, 0x27, 0xc2, 0xf9, 0x63, 0x46, 0x9c, 0x45, 0x3b, 0x1e, 0x77, 0x12, 0xef, 0xc7, 0x28, - 0x8f, 0x7a, 0x2f, 0x78, 0xd8, 0x00, 0x9e, 0x17, 0x8e, 0xd3, 0x22, 0x85, 0x2f, 0x5a, 0xa2, 0x47, - 0x82, 0x69, 0x27, 0x51, 0xf5, 0xc7, 0x07, 0xdf, 0x99, 0xdd, 0xbb, 0x50, 0xfc, 0xed, 0x94, 0x06, - 0x0e, 0xaf, 0xb2, 0x98, 0xe2, 0x31, 0x26, 0x29, 0xbb, 0xcf, 0xb3, 0x93, 0xc8, 0x61, 0x2c, 0x8b, - 0x3a, 0xfe, 0x1f, 0xdf, 0xaa, 0x3e, 0x0e, 0xb8, 0x8f, 0x72, 0xc7, 0xd8, 0xa9, 0x02, 0xf3, 0xd2, - 0xd6, 0xad, 0x0b, 0xb3, 0xeb, 0x5b, 0x95, 0xbe, 0xd5, 0xfc, 0x53, 0x76, 0xea, 0x8e, 0x28, 0xb0, - 0x2e, 0xd3, 0xf3, 0x27, 0xea, 0x4c, 0x18, 0x86, 0xf5, 0xc7, 0xcc, 0x49, 0xab, 0xdd, 0x39, 0xfa, - 0x71, 0xc9, 0xf5, 0x3a, 0x3e, 0x6f, 0x8b, 0xae, 0xc9, 0x41, 0xac, 0x3a, 0x69, 0xbc, 0x08, 0x01, - 0xaa, 0x90, 0x1b, 0x17, 0x3d, 0x85, 0xf9, 0x29, 0x91, 0xb9, 0x29, 0xcf, 0xfd, 0x26, 0x7f, 0xd5, - 0x08, 0xf5, 0xc1, 0x0e, 0x99, 0xb3, 0x5c, 0x67, 0x6c, 0xb7, 0x66, 0xc8, 0xdd, 0x2f, 0x92, 0xb3, - 0x6c, 0xee, 0x38, 0xcf, 0xc2, 0x98, 0xb2, 0x1c, 0xf5, 0x2d, 0x1e, 0xe2, 0xf9, 0x2e, 0xb1, 0xae, - 0xcf, 0x26, 0x75, 0xa1, 0x95, 0xe8, 0x51, 0x1e, 0xf1, 0x5c, 0x4b, 0xfd, 0x03, 0x47, 0xbc, 0x26, - 0xe0, 0x7c, 0x27, 0xee, 0xa4, 0xd6, 0x1c, 0x58, 0xce, 0xe4, 0x87, 0xf3, 0xb3, 0x3e, 0x53, 0xbb, - 0x55, 0x7c, 0x40, 0xef, 0x03, 0x54, 0xfa, 0xd8, 0x4b, 0xf6, 0xe7, 0x1c, 0x61, 0xf0, 0xfe, 0x9d, - 0xd4, 0x3b, 0x89, 0xde, 0x26, 0xd7, 0x08, 0xc6, 0x8d, 0x52, 0x2c, 0x92, 0x70, 0x68, 0x62, 0x12, - 0x5d, 0x0d, 0x3c, 0xdf, 0x55, 0x84, 0x27, 0x33, 0x48, 0x62, 0x0b, 0x2f, 0xdf, 0x8a, 0xf3, 0xa0, - 0x13, 0xf4, 0x4a, 0x24, 0xf1, 0xe8, 0x09, 0xef, 0xd5, 0x4b, 0x3a, 0xfc, 0xd0, 0x5b, 0xd9, 0xa2, - 0x20, 0xa2, 0xc3, 0x86, 0xc8, 0x42, 0x2e, 0xd0, 0xc6, 0x54, 0xbd, 0x4b, 0xa6, 0x17, 0xbd, 0x84, - 0x78, 0xdd, 0xba, 0xdb, 0x15, 0x93, 0xdf, 0x65, 0xea, 0x7e, 0x18, 0x26, 0x5a, 0xe6, 0x18, 0x8b, - 0xce, 0xe6, 0xcc, 0x87, 0xd6, 0x25, 0x5a, 0x6c, 0x04, 0x03, 0x2b, 0xb0, 0x54, 0xbc, 0x6f, 0xc2, - 0x32, 0xb6, 0xc5, 0x5a, 0xed, 0x4b, 0x2d, 0x0b, 0x12, 0x81, 0x97, 0x51, 0x63, 0xd8, 0x41, 0x77, - 0x07, 0x6d, 0xfb, 0xc7, 0xcf, 0xaa, 0xe6, 0xdd, 0x27, 0xaf, 0xd1, 0xb8, 0x10, 0x8e, 0x5b, 0xf1, - 0x7b, 0xfe, 0xaf, 0xbf, 0xa8, 0x4b, 0x04, 0xf5, 0x36, 0x85, 0x72, 0xf8, 0xeb, 0x15, 0x95, 0xe8, - 0xd5, 0xc5, 0x98, 0xeb, 0xe3, 0x34, 0x7c, 0x96, 0x17, 0xc4, 0x8c, 0xde, 0x1b, 0x77, 0xaf, 0x43, - 0x04, 0xdf, 0xd5, 0xf3, 0x4e, 0x36, 0xfd, 0x86, 0x0a, 0x7e, 0x43, 0xf9, 0x9f, 0xdb, 0x20, 0x62, - 0x56, 0xf1, 0xa1, 0x26, 0xd3, 0x6b, 0x59, 0x09, 0x74, 0x34, 0x49, 0x4a, 0x0a, 0xd7, 0x56, 0x42, - 0x01, 0x3c, 0x75, 0xb4, 0x11, 0xc6, 0x86, 0x05, 0xd1, 0x2f, 0x68, 0x80, 0x7d, 0x0f, 0x0f, 0x0b, - 0x07, 0xf9, 0x59, 0x3e, 0x9f, 0x7e, 0x8e, 0x2e, 0x9c, 0x9f, 0xe3, 0xf2, 0xd9, 0xd7, 0xe0, 0xc2, - 0xf9, 0x63, 0x3e, 0x9f, 0x7e, 0x8b, 0x2d, 0x9c, 0xdf, 0x0b, 0xe7, 0x17, 0x6b, 0xe8, 0xda, 0xe3, - 0xa4, 0xea, 0x7d, 0xbc, 0x65, 0x8b, 0x9b, 0x05, 0x10, 0x35, 0xfa, 0xe1, 0x1d, 0x3a, 0x43, 0x2d, - 0x81, 0xdf, 0xe4, 0x94, 0x88, 0xa4, 0x4b, 0x28, 0x79, 0xec, 0x3f, 0x00, 0x16, 0xa9, 0x93, 0x00, - 0xdb, 0xeb, 0xbc, 0xef, 0x5d, 0xf2, 0x5b, 0x5d, 0x8c, 0x07, 0xad, 0xef, 0xf9, 0xce, 0x9c, 0xe4, - 0x7d, 0x8f, 0x6a, 0xf7, 0x2d, 0xe4, 0xa0, 0x9c, 0xfd, 0x19, 0x25, 0x5f, 0xea, 0xc1, 0xea, 0x96, - 0xf5, 0x08, 0xf8, 0x87, 0x2c, 0xf9, 0xbc, 0xe1, 0xa7, 0x17, 0x92, 0x0b, 0xc8, 0xd2, 0x5f, 0x48, - 0x48, 0xc3, 0xb4, 0x0a, 0x72, 0x9a, 0xf8, 0x81, 0xb9, 0xfe, 0xff, 0xa2, 0x84, 0x6e, 0xc7, 0x12, - 0x36, 0x43, 0xc7, 0x78, 0xe9, 0x25, 0xff, 0x8a, 0x7e, 0x4d, 0xd2, 0xa4, 0xe7, 0x83, 0xae, 0xf6, - 0xf3, 0xc7, 0x0c, 0xa0, 0x42, 0xd9, 0x4b, 0x48, 0x6c, 0xda, 0x76, 0x82, 0x7a, 0x55, 0xfb, 0xee, - 0x94, 0xbf, 0xe8, 0x0e, 0xc7, 0x5c, 0x28, 0xbd, 0xcf, 0xfe, 0x86, 0xf8, 0xce, 0x17, 0x2f, 0x5a, - 0x9f, 0x77, 0x92, 0x0f, 0x53, 0xe2, 0x3b, 0xb0, 0xe1, 0x57, 0x5b, 0xa9, 0x31, 0x25, 0xe9, 0x7b, - 0x22, 0x00, 0x63, 0x20, 0xdf, 0x17, 0x0b, 0x00, 0xbb, 0x4b, 0x79, 0xbe, 0x06, 0x0b, 0x91, 0x31, - 0xa0, 0x23, 0xbe, 0x9f, 0xb3, 0xdf, 0x09, 0x3e, 0xa0, 0x05, 0xde, 0x38, 0x4d, 0x1b, 0x23, 0xc7, - 0xed, 0xd5, 0x07, 0x68, 0x02, 0x4d, 0x65, 0x83, 0x48, 0xe2, 0x7f, 0x09, 0xee, 0x97, 0x71, 0xc4, - 0x14, 0xf2, 0x83, 0xff, 0x12, 0xff, 0x1d, 0xac, 0x51, 0x98, 0x3c, 0xda, 0x38, 0x37, 0x08, 0x8b, - 0x74, 0x2d, 0x65, 0xe2, 0x16, 0xf6, 0x03, 0x66, 0xc4, 0x5c, 0x3f, 0x17, 0xbf, 0xba, 0xc3, 0x13, - 0xd2, 0xd4, 0x03, 0x39, 0x59, 0xe3, 0x9d, 0xe0, 0x05, 0x12, 0x38, 0x64, 0x10, 0x58, 0xc0, 0xa1, - 0xea, 0x09, 0x31, 0xed, 0xf7, 0x31, 0x89, 0x01, 0xdc, 0xbc, 0xb0, 0x71, 0xf5, 0xc8, 0xec, 0xfa, - 0x01, 0xfa, 0xd4, 0x6e, 0x32, 0x1c, 0x06, 0x84, 0x2f, 0xc6, 0x7c, 0xc4, 0xf9, 0xc0, 0xb8, 0xc1, - 0x2d, 0xdb, 0x20, 0x0d, 0xf9, 0x19, 0x7a, 0x68, 0x3b, 0xde, 0x8d, 0x40, 0x57, 0x06, 0xa8, 0x0a, - 0x74, 0xc3, 0xaf, 0x65, 0xeb, 0x3e, 0x9f, 0x41, 0xbf, 0x4a, 0x20, 0xcc, 0x3a, 0x25, 0xd1, 0x30, - 0x4f, 0xa5, 0xeb, 0xc2, 0xcd, 0x47, 0x67, 0x5a, 0x40, 0x65, 0xd2, 0xbb, 0xae, 0xed, 0xba, 0x87, - 0x07, 0x94, 0xe3, 0xc1, 0x63, 0xf4, 0xc2, 0xb6, 0x64, 0xad, 0xee, 0x78, 0x9c, 0x55, 0x91, 0x54, - 0xc9, 0x90, 0x2c, 0x10, 0xcd, 0x6a, 0x0b, 0xbc, 0x5b, 0x4b, 0x26, 0xad, 0x3a, 0xe7, 0x96, 0x83, - 0x3e, 0xe3, 0x19, 0x68, 0xec, 0x4f, 0x0c, 0x40, 0x20, 0x31, 0xbf, 0x71, 0x49, 0xad, 0x63, 0xc0, - 0x1b, 0xc9, 0xa8, 0x63, 0x34, 0x1b, 0x1a, 0x28, 0x44, 0xc0, 0x48, 0x26, 0x16, 0xf2, 0xeb, 0xa4, - 0x82, 0x7d, 0x73, 0x5d, 0xf3, 0x14, 0xbd, 0x6b, 0x0c, 0x13, 0xe8, 0x15, 0xb2, 0x98, 0x66, 0x2c, - 0xa6, 0x05, 0x31, 0x47, 0x08, 0x6d, 0x68, 0x23, 0xeb, 0x3a, 0x10, 0xb2, 0x9b, 0xec, 0x36, 0x93, - 0x2b, 0x81, 0x96, 0x2d, 0xa2, 0xd7, 0x14, 0xce, 0x85, 0x05, 0x37, 0x13, 0x6f, 0xca, 0x2c, 0x6c, - 0x2e, 0x3e, 0xab, 0x8f, 0xad, 0xc6, 0x67, 0xb5, 0x93, 0xf3, 0x2f, 0x30, 0x13, 0x75, 0x0b, 0x70, - 0x1c, 0x42, 0x00, 0xc9, 0x78, 0xd8, 0xa4, 0x28, 0xc0, 0x9b, 0xec, 0xd4, 0x2b, 0xde, 0x0d, 0x45, - 0xa8, 0x60, 0x14, 0x42, 0x15, 0xff, 0x18, 0xf3, 0x24, 0xc6, 0x43, 0x9c, 0xff, 0x0b, 0xc8, 0xda, - 0xbd, 0x33, 0x1c, 0xb8, 0xd8, 0x55, 0x85, 0x68, 0x08, 0x45, 0x8c, 0x7c, 0x8d, 0xc6, 0x2c, 0x09, - 0xc3, 0xed, 0x3c, 0x1b, 0x2a, 0x8d, 0xf3, 0x50, 0xfb, 0x15, 0x26, 0xb6, 0xc5, 0x05, 0x4a, 0xef, - 0x25, 0x03, 0x7f, 0xc6, 0x6d, 0x59, 0x52, 0x42, 0x17, 0x94, 0x23, 0x2b, 0x91, 0xc9, 0x55, 0x78, - 0x24, 0x48, 0xe3, 0x9b, 0xbb, 0x46, 0x3c, 0x7a, 0x18, 0x87, 0xaa, 0x14, 0x5e, 0x4f, 0xc6, 0xd3, - 0x32, 0xce, 0xa7, 0x90, 0xe6, 0x81, 0x68, 0x85, 0x26, 0x25, 0x05, 0x4d, 0x47, 0xdf, 0xe6, 0x86, - 0xde, 0x64, 0x7a, 0xd5, 0x1f, 0x33, 0x7d, 0x4e, 0x23, 0x2f, 0x26, 0xfd, 0xc3, 0x3b, 0x57, 0x05, - 0x73, 0x53, 0x85, 0x95, 0x5f, 0xed, 0x8d, 0x3f, 0x59, 0x8a, 0x1c, 0xf6, 0xd1, 0xaa, 0x9c, 0x79, - 0x04, 0x3b, 0x88, 0x42, 0x07, 0x3e, 0x93, 0xb9, 0x18, 0x3e, 0xc4, 0xa3, 0x85, 0xc3, 0x2a, 0xee, - 0xb2, 0xcf, 0x01, 0x87, 0xea, 0x05, 0x1f, 0x03, 0x66, 0x97, 0xb3, 0x43, 0x67, 0x1c, 0xee, 0x49, - 0x3e, 0xa8, 0xdb, 0xbe, 0x96, 0xe7, 0x4f, 0x47, 0x1b, 0x3b, 0x89, 0x6b, 0xde, 0xf5, 0x48, 0x22, - 0xae, 0x37, 0x52, 0xae, 0xca, 0x9c, 0x8b, 0x72, 0x55, 0x77, 0x7d, 0xef, 0xb5, 0x2e, 0xf3, 0x39, - 0xd1, 0x73, 0x39, 0x62, 0x3f, 0xf9, 0x50, 0xe6, 0x46, 0xcb, 0xcb, 0x2f, 0xb8, 0xf9, 0x85, 0x48, - 0x7e, 0xde, 0xcd, 0x2f, 0xba, 0xf9, 0xc5, 0x70, 0x7e, 0xd3, 0xcb, 0xcf, 0xb2, 0xfc, 0x32, 0xdf, - 0x38, 0x3d, 0x65, 0x70, 0x49, 0x50, 0xdc, 0xe6, 0x47, 0xa0, 0x87, 0x2e, 0x05, 0x8b, 0x18, 0x11, - 0x88, 0xde, 0xea, 0xc3, 0xf4, 0x6d, 0x90, 0xed, 0xcc, 0x2a, 0x7b, 0x5e, 0xdc, 0xd4, 0x59, 0x9c, - 0x7b, 0x1a, 0x0a, 0x97, 0xf1, 0x1c, 0xa0, 0x3e, 0x1d, 0xff, 0x80, 0x44, 0x87, 0x4c, 0x04, 0xa4, - 0x4e, 0x2c, 0x91, 0xf4, 0xd5, 0x54, 0x74, 0x50, 0x73, 0x13, 0x7f, 0x43, 0x66, 0xf5, 0xc0, 0x24, - 0x01, 0xa4, 0xc2, 0x12, 0x5d, 0x76, 0xb0, 0xe2, 0x60, 0x08, 0xcf, 0xbf, 0x73, 0xe5, 0x75, 0x85, - 0x06, 0x7e, 0xa2, 0x87, 0x0e, 0x78, 0xf8, 0xc2, 0x9f, 0x10, 0x59, 0x43, 0xe7, 0xa6, 0xaf, 0x25, - 0xbe, 0xc1, 0x72, 0x85, 0x41, 0xce, 0xbf, 0xd1, 0x6f, 0x61, 0x25, 0x6b, 0x62, 0xd8, 0xff, 0x8a, - 0x5e, 0xb5, 0xf5, 0x1c, 0x0d, 0x7f, 0xc5, 0x5d, 0x10, 0xf5, 0xaf, 0x37, 0x51, 0x30, 0xa1, 0x8f, - 0x52, 0xbb, 0x1f, 0x91, 0x77, 0xaf, 0x77, 0x7f, 0xa3, 0x71, 0xcf, 0x33, 0x19, 0xaf, 0x41, 0xea, - 0xce, 0xca, 0x91, 0x67, 0xdb, 0xa3, 0x40, 0x36, 0x25, 0x4a, 0xd2, 0xbd, 0x10, 0x83, 0xe5, 0xc7, - 0x6a, 0xf7, 0x7b, 0x2e, 0x2f, 0x6f, 0x66, 0xf3, 0x32, 0x0e, 0x86, 0x70, 0xf7, 0xa2, 0xa4, 0x5f, - 0x50, 0x83, 0x92, 0x61, 0x36, 0xb7, 0xe9, 0x0e, 0x18, 0xaa, 0xa2, 0x7f, 0x82, 0xca, 0xf4, 0x28, - 0x5a, 0x7d, 0x5b, 0x3c, 0xcf, 0x34, 0xc4, 0x2a, 0x7d, 0x9e, 0xd3, 0x91, 0x81, 0x40, 0x95, 0x4a, - 0xcd, 0x09, 0xfa, 0xca, 0x7f, 0x97, 0xb7, 0x6d, 0x90, 0x05, 0x43, 0xdf, 0xd8, 0xc0, 0x4b, 0xb6, - 0xb0, 0x2b, 0xa1, 0x25, 0xaf, 0x9b, 0x16, 0xab, 0x32, 0x75, 0xcc, 0x4b, 0x60, 0xb1, 0x73, 0x43, - 0x30, 0xf0, 0x36, 0x70, 0xf0, 0xa1, 0x05, 0xa1, 0x87, 0xfc, 0x2c, 0x8d, 0x82, 0x38, 0x2a, 0x75, - 0xbe, 0x93, 0xb2, 0xc0, 0x39, 0x69, 0x36, 0x99, 0x7f, 0xa9, 0x5f, 0xa9, 0x8a, 0xae, 0x9a, 0x74, - 0x36, 0xe7, 0xac, 0xa4, 0xce, 0xae, 0xdd, 0x44, 0x1c, 0x33, 0xf5, 0x90, 0xd4, 0x64, 0x87, 0xaf, - 0x05, 0xba, 0x5f, 0x5a, 0x88, 0xbd, 0x0f, 0xc8, 0xbe, 0x4b, 0xf1, 0xa9, 0xeb, 0x80, 0xfe, 0xbd, - 0xf3, 0x91, 0xd6, 0xa5, 0xf1, 0xf4, 0x11, 0xb6, 0x80, 0xc0, 0x05, 0x94, 0x29, 0x58, 0x08, 0x90, - 0xd8, 0x7b, 0x82, 0x71, 0x5f, 0xd8, 0x91, 0xc2, 0xeb, 0xc3, 0x93, 0xd8, 0x24, 0xf2, 0xc1, 0x95, - 0xc8, 0x85, 0x18, 0x36, 0xd4, 0x46, 0xc3, 0xe4, 0x09, 0x16, 0x02, 0x8a, 0xb8, 0xd2, 0x42, 0x2d, - 0x88, 0xc0, 0x85, 0x28, 0xc5, 0x76, 0x3e, 0xeb, 0x99, 0x8a, 0x97, 0xce, 0x70, 0x69, 0x82, 0xee, - 0xb3, 0x34, 0xbe, 0xb0, 0x43, 0xfd, 0x5c, 0xbd, 0x88, 0x33, 0x77, 0xc8, 0x79, 0x69, 0x8c, 0xd8, - 0xbe, 0x98, 0xf4, 0x56, 0x3a, 0x49, 0x0f, 0x14, 0xbb, 0xe1, 0x38, 0x96, 0x0a, 0x64, 0x08, 0xb9, - 0x43, 0x65, 0x2a, 0x26, 0x81, 0x5b, 0x28, 0x5e, 0x12, 0xbd, 0xc0, 0xc1, 0x8c, 0x06, 0x55, 0xd8, - 0xd2, 0xbd, 0x00, 0x22, 0xbc, 0x5b, 0x2f, 0xcd, 0xcc, 0xc0, 0x92, 0xd3, 0xbf, 0xd3, 0xb8, 0x15, - 0xb0, 0xd0, 0x72, 0x4c, 0x7a, 0xd1, 0xea, 0x0b, 0xc1, 0x85, 0x2b, 0x2c, 0xb6, 0x30, 0x3b, 0xad, - 0x6e, 0xf7, 0x93, 0x94, 0x5e, 0xfe, 0xe5, 0x25, 0x74, 0x36, 0x4a, 0x6e, 0x4a, 0xf2, 0x57, 0x6d, - 0x59, 0x1c, 0x3b, 0x6d, 0xce, 0x6c, 0x65, 0x21, 0xb4, 0x2d, 0xc3, 0xa0, 0x1f, 0x78, 0x8e, 0x7d, - 0x38, 0x92, 0x21, 0x4e, 0x71, 0xb5, 0x38, 0x5f, 0x86, 0xf7, 0xac, 0x22, 0x41, 0x9c, 0x56, 0x2e, - 0x28, 0x11, 0x8d, 0xb3, 0x9a, 0x66, 0x5f, 0x56, 0xf9, 0xbb, 0x4d, 0xc6, 0x45, 0x08, 0xe2, 0xbe, - 0x6c, 0xe9, 0xc6, 0xbe, 0x89, 0x10, 0x0e, 0x5a, 0xfa, 0xb8, 0xe0, 0x7a, 0xcc, 0x7c, 0x45, 0xd0, - 0xc2, 0xe5, 0xd1, 0x4f, 0x24, 0xec, 0x4b, 0xa4, 0x94, 0x3b, 0x2a, 0x50, 0xaa, 0x63, 0x4b, 0x04, - 0x36, 0xb0, 0xc5, 0xc3, 0x38, 0xa7, 0x4a, 0x83, 0xc5, 0xd8, 0x1b, 0x9e, 0xb9, 0x33, 0x04, 0xfa, - 0xf1, 0x17, 0x4a, 0x8b, 0x21, 0x58, 0x98, 0xa4, 0xd6, 0x23, 0x1d, 0x00, 0x81, 0x2c, 0xd2, 0x20, - 0x08, 0xa6, 0x7c, 0x8a, 0xd1, 0x83, 0xa4, 0x0e, 0x93, 0x00, 0x87, 0x2f, 0xad, 0xc7, 0x43, 0x58, - 0xe7, 0xdd, 0xe0, 0x75, 0x97, 0x05, 0x84, 0x54, 0xed, 0x33, 0xdc, 0x33, 0x9c, 0xad, 0x3a, 0x75, - 0x1d, 0x4d, 0x22, 0xff, 0xd2, 0xdc, 0xdb, 0xf6, 0xb2, 0xa4, 0xa5, 0xd9, 0xa7, 0x1f, 0xe0, 0x57, - 0xd5, 0x31, 0xb4, 0x34, 0x9b, 0x5d, 0x96, 0x9d, 0x05, 0x6d, 0x19, 0xb3, 0xe9, 0x2f, 0xcb, 0x56, - 0xe9, 0x03, 0x73, 0x42, 0x55, 0x69, 0xa6, 0x67, 0x01, 0xdc, 0xc8, 0x4a, 0x46, 0x90, 0x99, 0xa2, - 0x6f, 0x5c, 0xb6, 0xd4, 0x59, 0x5f, 0xef, 0x2c, 0x31, 0x66, 0x76, 0xd7, 0xd7, 0xbb, 0x4b, 0xb2, - 0x40, 0xe8, 0xb4, 0x96, 0x5a, 0xa3, 0x98, 0x50, 0x1c, 0x01, 0x1c, 0x31, 0x36, 0x46, 0x60, 0x47, - 0x72, 0x23, 0xe0, 0xb9, 0x96, 0xe9, 0xcc, 0x71, 0xd2, 0xb2, 0xe6, 0xd1, 0x03, 0x27, 0x26, 0x2b, - 0x4b, 0x29, 0x40, 0x05, 0x0a, 0xa8, 0xe9, 0x7f, 0xd6, 0x8d, 0x0d, 0x95, 0x02, 0x32, 0x43, 0x13, - 0x87, 0x27, 0x2e, 0x4c, 0x31, 0x06, 0x12, 0xc1, 0x23, 0x1e, 0x28, 0x86, 0x86, 0x4b, 0x73, 0x7d, - 0xdd, 0x5c, 0x3e, 0x58, 0x2e, 0x0a, 0xa8, 0x6f, 0x6e, 0x08, 0xeb, 0x70, 0xbf, 0xa8, 0x0e, 0xf7, - 0x83, 0x13, 0x64, 0x83, 0x2f, 0x7a, 0xcc, 0xc5, 0x9f, 0xac, 0x49, 0x87, 0xc9, 0x0d, 0xf6, 0x12, - 0x0d, 0x90, 0x6e, 0xbf, 0xee, 0x66, 0x73, 0x43, 0xa6, 0x8e, 0xa4, 0x87, 0xba, 0x4e, 0xfd, 0x33, - 0x01, 0x90, 0x4e, 0xa3, 0x73, 0xfa, 0x26, 0xaf, 0xff, 0xef, 0x7f, 0xff, 0xdf, 0x68, 0xf1, 0xda, - 0xd6, 0x97, 0x76, 0xbf, 0xaa, 0x2f, 0xbb, 0x4b, 0xc5, 0x6c, 0x8a, 0x26, 0xde, 0x27, 0x5e, 0x61, - 0xec, 0xf6, 0x3a, 0xe0, 0x98, 0xbf, 0x42, 0x16, 0x74, 0xca, 0xce, 0x4c, 0x90, 0xb5, 0xd9, 0xa5, - 0xe2, 0x24, 0xb5, 0xc8, 0xe9, 0x5b, 0xd9, 0x6d, 0xb3, 0x8e, 0x61, 0x93, 0x40, 0x8e, 0xb3, 0xc5, - 0x2a, 0x3a, 0x01, 0x22, 0xfc, 0xba, 0x98, 0xa5, 0xfe, 0x18, 0xb0, 0x3a, 0x61, 0x2b, 0xf9, 0x12, - 0x1a, 0x59, 0xdf, 0x02, 0xc8, 0x8c, 0xb3, 0xf7, 0xe3, 0x97, 0x3c, 0x2d, 0xe1, 0x91, 0xc1, 0x68, - 0x09, 0xe3, 0x30, 0x3b, 0x7e, 0x19, 0xb4, 0x82, 0xe1, 0x9d, 0x80, 0x7e, 0xdd, 0xbd, 0xee, 0xd5, - 0x63, 0xec, 0xbf, 0x43, 0x60, 0x47, 0xd3, 0x33, 0x89, 0x7e, 0x6a, 0x04, 0x8a, 0xaa, 0xfb, 0x8d, - 0x80, 0x1e, 0x3d, 0x27, 0xd8, 0xca, 0xfe, 0xf5, 0xd7, 0x68, 0x4b, 0xc6, 0x67, 0x13, 0x64, 0x08, - 0x01, 0x34, 0x88, 0xde, 0x5c, 0x18, 0xab, 0x96, 0x33, 0x52, 0xb4, 0x24, 0xa8, 0x4f, 0xd4, 0xa4, - 0xef, 0xad, 0x65, 0x56, 0x4a, 0x14, 0x7e, 0xe0, 0xd5, 0x50, 0xf3, 0x67, 0x04, 0x53, 0x40, 0x87, - 0xa1, 0x00, 0x43, 0x66, 0x94, 0x43, 0xe2, 0xe5, 0x50, 0x26, 0x43, 0xd6, 0x88, 0x17, 0x19, 0x0e, - 0xaf, 0x91, 0x8a, 0xc9, 0xb0, 0xf9, 0x88, 0x24, 0x63, 0xc3, 0x6e, 0x79, 0xae, 0x8e, 0x49, 0xae, - 0x36, 0xde, 0x7d, 0xff, 0xdd, 0xda, 0x30, 0x5f, 0xa1, 0xcf, 0xca, 0xe0, 0xe5, 0xfd, 0x70, 0x78, - 0xa6, 0x50, 0xf6, 0xdc, 0xf8, 0x45, 0x03, 0x51, 0x3a, 0x51, 0x62, 0x09, 0x40, 0x4a, 0x89, 0x65, - 0x75, 0x5f, 0xb5, 0xf6, 0x2f, 0x1a, 0x28, 0x72, 0x79, 0xe5, 0x79, 0x14, 0x4d, 0x18, 0x96, 0x60, - 0xc6, 0x5d, 0xba, 0xbc, 0x34, 0x26, 0xc4, 0xf2, 0xec, 0xde, 0xb8, 0x57, 0xd5, 0xf1, 0x1b, 0x3e, - 0xdb, 0x5e, 0x04, 0x3c, 0x8c, 0xc8, 0xc5, 0x5f, 0xd1, 0xd4, 0x42, 0x45, 0x75, 0xad, 0xb1, 0xac, - 0x64, 0xeb, 0x4d, 0xef, 0x84, 0xca, 0x7a, 0x9f, 0xfb, 0x09, 0x55, 0x60, 0x7d, 0x6a, 0xf9, 0xeb, - 0xda, 0x8f, 0x9e, 0xd0, 0x0a, 0xbe, 0xd7, 0x83, 0x06, 0x96, 0x04, 0xf7, 0xfd, 0x9e, 0xc5, 0xf3, - 0x2e, 0x77, 0xff, 0xdc, 0xb1, 0x54, 0x3c, 0x28, 0x5a, 0x92, 0xdb, 0x32, 0x09, 0x22, 0x64, 0x69, - 0xfe, 0x91, 0xf7, 0xc9, 0xfa, 0x15, 0x65, 0x9a, 0xd9, 0x55, 0x99, 0xb9, 0x55, 0x99, 0x79, 0xcc, - 0xf4, 0x3e, 0x81, 0x90, 0x58, 0x52, 0xea, 0x7a, 0x05, 0x84, 0x83, 0x15, 0x79, 0x3b, 0x34, 0x1e, - 0x41, 0xf0, 0x5d, 0x85, 0x25, 0xc5, 0xee, 0xc5, 0x24, 0xff, 0x9d, 0x03, 0x2e, 0xbc, 0x3c, 0x33, - 0x27, 0x4e, 0xf0, 0x1e, 0xca, 0xc2, 0x11, 0x96, 0x07, 0x36, 0x7a, 0x80, 0xc5, 0xaa, 0xb4, 0x15, - 0x2d, 0xae, 0x46, 0xb3, 0x79, 0x13, 0x5b, 0x7e, 0x40, 0xa6, 0x93, 0x85, 0xf2, 0x04, 0x43, 0xf7, - 0xc7, 0x16, 0x67, 0x5f, 0x13, 0x8a, 0x6b, 0x80, 0xe2, 0x11, 0x04, 0x2f, 0x5a, 0x20, 0xbe, 0xa9, - 0x65, 0xa3, 0x61, 0x5f, 0xa1, 0x58, 0x59, 0xd7, 0xfe, 0x37, 0xea, 0x8e, 0x57, 0xd4, 0x8d, 0xad, - 0xf0, 0xb2, 0xba, 0xb1, 0x15, 0xd8, 0xb4, 0xfa, 0xed, 0x95, 0x75, 0x09, 0x7e, 0x36, 0x20, 0xb6, - 0xe6, 0x6b, 0xc7, 0xde, 0x98, 0xac, 0xa8, 0x47, 0xbf, 0xda, 0x14, 0xad, 0xc9, 0xdd, 0xc2, 0x77, - 0x1f, 0x69, 0xc8, 0x4a, 0xcb, 0x4e, 0x2c, 0xc8, 0xab, 0xd1, 0xf5, 0x1b, 0x0a, 0x52, 0x17, 0xd8, - 0xad, 0xa5, 0xc5, 0x8d, 0xfb, 0x17, 0x8b, 0x3a, 0xca, 0xec, 0x41, 0x9e, 0x95, 0xfa, 0xe7, 0x0f, - 0xdf, 0x58, 0x44, 0xd8, 0xde, 0x6f, 0xd3, 0x2d, 0x9b, 0x3f, 0x39, 0x67, 0x16, 0xc4, 0x45, 0x39, - 0x80, 0x63, 0xce, 0xf8, 0x69, 0xa0, 0x95, 0xec, 0x5b, 0x72, 0x3e, 0x14, 0x42, 0x58, 0xfb, 0xc8, - 0x74, 0x3f, 0x57, 0x72, 0x39, 0x6f, 0xe6, 0xc4, 0xe9, 0xa8, 0xcd, 0x13, 0xaf, 0x33, 0xa3, 0x28, - 0x45, 0xbe, 0x97, 0x92, 0x5a, 0x58, 0x67, 0x88, 0xc8, 0x7c, 0x64, 0x2b, 0xb7, 0xbe, 0x4e, 0x83, - 0x7c, 0x2c, 0x2d, 0x52, 0xa4, 0xc7, 0x57, 0x68, 0xc9, 0x5d, 0x2d, 0x7b, 0x0a, 0xa1, 0x0b, 0x92, - 0x5a, 0x52, 0xcc, 0x52, 0xa3, 0x91, 0x67, 0x39, 0xc5, 0x92, 0x48, 0x1a, 0x1f, 0x9c, 0x90, 0x2e, - 0xb2, 0x74, 0x3e, 0xae, 0x9c, 0x27, 0xeb, 0x49, 0xa8, 0xea, 0xae, 0x98, 0xf8, 0xde, 0x94, 0x9f, - 0xf3, 0xa8, 0xe0, 0x87, 0xa1, 0x0e, 0x9c, 0x85, 0xc9, 0xb7, 0x17, 0x40, 0x86, 0x26, 0xdf, 0xa5, - 0x98, 0x55, 0xb3, 0xef, 0x05, 0x2f, 0x65, 0x9f, 0x88, 0x64, 0x81, 0x89, 0xfc, 0xab, 0xed, 0x7f, - 0x43, 0x3a, 0xd5, 0x93, 0x33, 0x7d, 0xc5, 0xc6, 0x8e, 0x21, 0x2e, 0xe8, 0x39, 0xf2, 0xa5, 0x62, - 0xc1, 0xa8, 0x1d, 0x5c, 0x49, 0x01, 0x14, 0x4f, 0x6f, 0x26, 0x31, 0x47, 0x23, 0xfc, 0x89, 0x08, - 0x33, 0xfb, 0xbb, 0x73, 0x46, 0x35, 0xc4, 0x60, 0xce, 0x0c, 0xd3, 0x09, 0x47, 0x89, 0xe1, 0xbf, - 0x54, 0x04, 0x99, 0xdc, 0x79, 0x6b, 0x8d, 0x70, 0x87, 0x21, 0xf4, 0x70, 0x13, 0x04, 0x3e, 0xf7, - 0x6b, 0x7a, 0x7f, 0xfd, 0x95, 0xf5, 0x9f, 0x21, 0xe3, 0x0b, 0x9e, 0x8a, 0x62, 0xe0, 0xdc, 0xfc, - 0xcf, 0x40, 0x68, 0x96, 0xe9, 0x21, 0xf1, 0x5f, 0x7f, 0x31, 0x3f, 0x0d, 0xcc, 0x63, 0x7f, 0x83, - 0x12, 0xb0, 0x3f, 0x6e, 0xd5, 0xe5, 0x68, 0x6a, 0x96, 0x8a, 0xda, 0x4b, 0xc8, 0xaa, 0x4a, 0x96, - 0x47, 0x4b, 0x70, 0x55, 0x7f, 0xfd, 0x73, 0x82, 0xbf, 0x5a, 0x8f, 0xb8, 0xf1, 0x2c, 0x86, 0x3b, - 0xee, 0xaa, 0xe3, 0x1f, 0xd1, 0xbb, 0x5b, 0x5e, 0xc0, 0x63, 0x0e, 0xc9, 0x6a, 0x52, 0x59, 0x54, - 0x15, 0x96, 0xf7, 0xb3, 0xba, 0x64, 0x68, 0xb5, 0xdf, 0xe9, 0x91, 0x77, 0x7f, 0xe9, 0xc3, 0xee, - 0xfc, 0x5f, 0xff, 0x0f, 0x76, 0x67, 0x7d, 0x3d, 0x94, 0xf6, 0xff, 0xfe, 0x4d, 0x14, 0x73, 0xc2, - 0xa3, 0xbb, 0x43, 0x5c, 0x63, 0x08, 0x3f, 0x66, 0x1e, 0x66, 0x1b, 0x10, 0xfd, 0xfa, 0xe8, 0x62, - 0xb0, 0x12, 0x2f, 0xa6, 0x08, 0xf5, 0xf8, 0x00, 0x01, 0x03, 0xf9, 0x86, 0x7b, 0xa5, 0x05, 0x7a, - 0x22, 0xd2, 0x82, 0x68, 0x4e, 0x7b, 0x4c, 0xc8, 0xe6, 0x34, 0x49, 0x03, 0x02, 0xf8, 0x29, 0xf8, - 0xe5, 0xd3, 0xa4, 0xe8, 0xaf, 0x68, 0x4d, 0x35, 0xb7, 0xe9, 0x5f, 0x0c, 0x25, 0xeb, 0x1f, 0xf4, - 0xa3, 0x73, 0x91, 0x0d, 0xca, 0x02, 0x5e, 0x0f, 0x11, 0xc4, 0x94, 0xed, 0xfa, 0xe1, 0x68, 0xe1, - 0x3b, 0xdf, 0xbf, 0xd8, 0xb7, 0x63, 0xe9, 0x27, 0x38, 0x89, 0x4a, 0xe3, 0x13, 0x62, 0x2f, 0x30, - 0xe6, 0x63, 0x5a, 0x1b, 0xce, 0xe9, 0x21, 0x09, 0x9e, 0x0e, 0xb8, 0x86, 0xc9, 0xe0, 0xa3, 0x9a, - 0x8b, 0x12, 0x0a, 0x1b, 0x0f, 0x1d, 0x4c, 0x64, 0x5b, 0xe4, 0xe2, 0x68, 0x0e, 0xcd, 0x4b, 0x86, - 0x1c, 0xba, 0x0a, 0x91, 0x29, 0xeb, 0x5e, 0x2c, 0x3f, 0x3f, 0x46, 0x57, 0x8d, 0xcd, 0x1d, 0x0c, - 0x8d, 0xe6, 0x87, 0x6f, 0xb2, 0x80, 0x7e, 0xea, 0xc4, 0x24, 0xd7, 0xa6, 0x75, 0x7b, 0xab, 0xb0, - 0xb9, 0xbe, 0x6e, 0x7f, 0x2f, 0x96, 0xff, 0xfa, 0xcb, 0xde, 0x2a, 0x15, 0xf0, 0xb9, 0x92, 0xc5, - 0xe7, 0x4a, 0x09, 0x9f, 0xb3, 0xb9, 0x3c, 0xbe, 0xe4, 0x8a, 0xc5, 0x6d, 0xb1, 0x0e, 0x5d, 0xdb, - 0x12, 0xa5, 0xb7, 0xba, 0x4e, 0x2b, 0xe9, 0xb4, 0x92, 0x4e, 0x2b, 0xe9, 0xb4, 0x92, 0x4e, 0x2b, - 0xe9, 0xac, 0x92, 0xce, 0x57, 0x72, 0x63, 0x94, 0x26, 0x12, 0xb4, 0x77, 0x5e, 0x3c, 0xd4, 0x6d, - 0xf1, 0xbb, 0x58, 0x9d, 0x26, 0x53, 0xee, 0x90, 0x22, 0x56, 0x7d, 0x7a, 0x56, 0x19, 0x2e, 0xfb, - 0x96, 0x4c, 0xb1, 0x71, 0xb0, 0x18, 0x85, 0xb2, 0x34, 0xd3, 0x99, 0x23, 0x06, 0x7e, 0xae, 0x91, - 0xdb, 0x2c, 0x86, 0xca, 0x0b, 0xb9, 0x6f, 0x25, 0x28, 0xc2, 0x26, 0xf6, 0xff, 0x5f, 0xdc, 0x95, - 0x36, 0xb7, 0x6d, 0xa4, 0xe9, 0xef, 0xfb, 0x2b, 0x28, 0x24, 0xb1, 0x88, 0x08, 0x92, 0x41, 0xca, - 0xf2, 0x38, 0xa0, 0x20, 0x96, 0xe3, 0x63, 0x47, 0x35, 0x8e, 0xa3, 0x8d, 0x3c, 0xc9, 0xb8, 0x5c, - 0xaa, 0x15, 0x49, 0x35, 0x25, 0x94, 0x21, 0x80, 0x01, 0xa0, 0xc3, 0xa1, 0xf8, 0xdf, 0xf7, 0x3d, - 0xfa, 0x04, 0xc0, 0x43, 0x71, 0x66, 0xb6, 0x2a, 0xb1, 0x88, 0x46, 0x77, 0xa3, 0xef, 0xee, 0xf7, - 0xe8, 0xe7, 0x79, 0x78, 0xd0, 0xa6, 0xf0, 0xbb, 0xf2, 0x30, 0xb4, 0x35, 0xa3, 0x02, 0xd1, 0x3f, - 0x87, 0x5a, 0x1b, 0x7c, 0x87, 0x38, 0x31, 0x85, 0xa0, 0xcb, 0x13, 0x5d, 0x62, 0x03, 0xf0, 0x02, - 0xef, 0x8e, 0x10, 0x84, 0xef, 0x90, 0x1f, 0xc4, 0xdb, 0xa9, 0x31, 0x30, 0x18, 0x06, 0x02, 0x4a, - 0x3c, 0x80, 0xaf, 0x11, 0x89, 0xc7, 0x6f, 0x62, 0x7c, 0x0a, 0x7d, 0x29, 0x88, 0xcb, 0x6e, 0x6f, - 0x9c, 0x64, 0xa3, 0xe2, 0xcb, 0x07, 0x32, 0x52, 0x11, 0xa4, 0xfd, 0xf8, 0x06, 0xd6, 0xe7, 0xc2, - 0x0b, 0xee, 0xca, 0x3d, 0xc4, 0x22, 0x28, 0x4b, 0x54, 0x3a, 0xa2, 0xa6, 0x17, 0x3b, 0x58, 0xd2, - 0x9b, 0x69, 0xed, 0x37, 0x4c, 0x46, 0xb2, 0xad, 0xfe, 0x48, 0x89, 0x34, 0xfd, 0x85, 0x85, 0x28, - 0xc6, 0x09, 0x7c, 0x36, 0x13, 0x13, 0xe8, 0x82, 0x3f, 0x77, 0x20, 0xa3, 0x2d, 0xa4, 0x38, 0x3f, - 0xb0, 0x1e, 0x98, 0x9e, 0xc3, 0xa2, 0x27, 0x55, 0x04, 0x24, 0x41, 0x5d, 0x5b, 0xad, 0x90, 0xde, - 0x37, 0x45, 0x03, 0x4f, 0xf5, 0x54, 0x83, 0x75, 0x1f, 0xa1, 0x07, 0xca, 0x61, 0xd7, 0x60, 0x25, - 0xc1, 0xbc, 0x62, 0xee, 0xd6, 0x27, 0x4f, 0x1c, 0x6c, 0x98, 0xd2, 0xf7, 0x23, 0x0b, 0xae, 0x40, - 0x1d, 0xbd, 0x08, 0xa0, 0x73, 0x28, 0xff, 0x46, 0xd5, 0xc0, 0x59, 0x35, 0xca, 0x20, 0x43, 0x4c, - 0xfb, 0xd1, 0xc5, 0x29, 0x01, 0x10, 0x65, 0xb0, 0xbc, 0x2c, 0xb8, 0x61, 0x89, 0x3d, 0x9a, 0x9a, - 0xf5, 0xd1, 0x48, 0xe6, 0xcc, 0x66, 0xba, 0xb3, 0x73, 0x78, 0xe0, 0xc0, 0x47, 0xf2, 0xb8, 0x0a, - 0x7a, 0x07, 0xa8, 0xbb, 0xbf, 0x63, 0x76, 0x13, 0xf9, 0x31, 0x04, 0x72, 0xa7, 0x6f, 0x29, 0x1e, - 0xd4, 0x42, 0xfc, 0x5e, 0xbe, 0x13, 0x97, 0xa3, 0x34, 0x46, 0x2a, 0x51, 0xcb, 0x4f, 0x41, 0x95, - 0x54, 0x41, 0xad, 0xd3, 0xa4, 0x96, 0x83, 0x92, 0x4d, 0xea, 0x62, 0xaf, 0xbc, 0x99, 0x4c, 0x60, - 0x58, 0xa8, 0xd0, 0x70, 0x40, 0x0c, 0xb8, 0xe8, 0xb8, 0x1c, 0xd4, 0x25, 0x53, 0xa9, 0x86, 0x14, - 0x78, 0xb9, 0x9e, 0x08, 0x72, 0xc5, 0x5e, 0x96, 0x62, 0x44, 0x66, 0xb3, 0xa5, 0xa7, 0x8b, 0x9b, - 0x42, 0x72, 0xda, 0xd2, 0x63, 0xc5, 0x51, 0xdf, 0x8e, 0x10, 0x5c, 0x1e, 0x03, 0xa6, 0xf0, 0xcb, - 0x10, 0xe7, 0x8a, 0xbd, 0x9b, 0x8b, 0x19, 0xde, 0x89, 0xcb, 0x2e, 0x6a, 0x5c, 0xb6, 0x20, 0xa0, - 0xa4, 0xb4, 0xe4, 0xcf, 0xca, 0x08, 0x7f, 0x23, 0xf5, 0xac, 0x5c, 0x9f, 0x89, 0x0b, 0x9b, 0x0b, - 0x57, 0x55, 0xba, 0x54, 0x55, 0xf1, 0xb4, 0x17, 0x06, 0x2d, 0x10, 0x15, 0x72, 0x70, 0x84, 0xb0, - 0x32, 0x85, 0x92, 0x97, 0x50, 0x4b, 0x84, 0xb1, 0x61, 0xe4, 0xd5, 0xb4, 0xbb, 0x35, 0xa7, 0xb7, - 0xae, 0xc1, 0xa6, 0xb0, 0xdd, 0xdf, 0xa0, 0xed, 0x42, 0xd2, 0x62, 0xd1, 0xeb, 0x4f, 0xd5, 0x19, - 0xd2, 0xbc, 0x98, 0xab, 0xa7, 0xb4, 0xb8, 0xa3, 0xb2, 0xae, 0xc7, 0xc0, 0xc3, 0x14, 0x03, 0x4e, - 0x46, 0x70, 0x9c, 0x3a, 0xe4, 0x95, 0xbf, 0xc2, 0xa5, 0xb2, 0x2f, 0x4f, 0x48, 0x0e, 0x93, 0x1c, - 0x29, 0x2d, 0x27, 0x9f, 0xac, 0x8c, 0xcf, 0x64, 0xb9, 0x1f, 0xe2, 0xad, 0xad, 0x6e, 0xef, 0x49, - 0x6a, 0x24, 0x65, 0x0a, 0xe9, 0xcb, 0x10, 0xa8, 0x09, 0x3d, 0x3f, 0x7b, 0xa2, 0x11, 0x2f, 0xba, - 0xe6, 0xe3, 0x55, 0x3e, 0xdb, 0xb5, 0x9e, 0x46, 0x45, 0xe5, 0x7f, 0xef, 0xbe, 0xfe, 0x38, 0x74, - 0x1f, 0x6b, 0xd1, 0x3f, 0x46, 0x3d, 0x38, 0x83, 0xca, 0x66, 0x92, 0x7f, 0x0f, 0x47, 0xc3, 0x51, - 0x24, 0x7f, 0x6b, 0x4b, 0x06, 0x26, 0x2a, 0xc9, 0xa2, 0x83, 0x8a, 0x3e, 0xf4, 0xa5, 0x6b, 0xab, - 0xdf, 0xc8, 0xaa, 0x58, 0xa3, 0x5e, 0xb5, 0x6a, 0xa9, 0x5a, 0x2d, 0x70, 0x04, 0x8f, 0xd4, 0x8e, - 0x64, 0x59, 0xc9, 0xde, 0xe7, 0x1d, 0xd5, 0xe5, 0xd2, 0x30, 0x66, 0x94, 0x45, 0xf0, 0x48, 0x38, - 0xd0, 0x97, 0xd6, 0xd6, 0xdb, 0xe6, 0xad, 0xb3, 0x07, 0x83, 0x07, 0x86, 0x13, 0x74, 0xff, 0x9b, - 0x91, 0x34, 0x87, 0xad, 0x38, 0x59, 0x28, 0x60, 0xa5, 0x36, 0xe1, 0xc7, 0xf8, 0xb8, 0x24, 0xf2, - 0x9b, 0xbb, 0xbd, 0x81, 0x38, 0x42, 0x8f, 0x97, 0xdd, 0x5d, 0x3f, 0x71, 0x7c, 0x40, 0xe2, 0x11, - 0x6a, 0x30, 0x20, 0x88, 0xf8, 0x9a, 0x1c, 0x1f, 0x10, 0xf3, 0xaa, 0x57, 0x7b, 0x35, 0x36, 0xaf, - 0xfa, 0x67, 0x41, 0x57, 0x8f, 0x86, 0x87, 0xad, 0x06, 0x47, 0x25, 0xc1, 0x3a, 0xd9, 0x69, 0xef, - 0x4c, 0x5a, 0x24, 0x78, 0x92, 0x3c, 0xa0, 0x09, 0xe1, 0x7b, 0x93, 0xf7, 0xb3, 0x66, 0x1a, 0x41, - 0x92, 0x69, 0xa5, 0x9a, 0x85, 0x34, 0x93, 0x0a, 0x4f, 0x65, 0xf0, 0x87, 0xce, 0xc0, 0xb6, 0x5a, - 0xe6, 0xa5, 0x9e, 0x85, 0xf4, 0xde, 0x0f, 0x9a, 0x5a, 0x2b, 0xfd, 0xbe, 0xbc, 0x0f, 0xda, 0x75, - 0x56, 0x3a, 0x46, 0xe2, 0xc4, 0x40, 0x8d, 0x95, 0xc9, 0xbc, 0x37, 0xc4, 0x7f, 0xa2, 0x30, 0xa8, - 0xa9, 0xad, 0x4c, 0x8c, 0x3e, 0xc6, 0xe8, 0xd7, 0x62, 0xec, 0xdb, 0x31, 0xf6, 0x31, 0xc6, 0xbe, - 0x8a, 0x41, 0x32, 0xd8, 0xcf, 0x3d, 0xdb, 0x0f, 0x7c, 0x6b, 0xb4, 0x97, 0xf7, 0xec, 0xb7, 0xfd, - 0xfa, 0xdb, 0xbe, 0xfd, 0x76, 0xbf, 0xfe, 0x76, 0x1f, 0xa6, 0x3c, 0x51, 0x1d, 0x10, 0xfe, 0xa0, - 0xfc, 0xcd, 0x9b, 0x69, 0x8e, 0xce, 0x80, 0xca, 0x2d, 0x43, 0xbd, 0x60, 0xff, 0x88, 0x10, 0x31, - 0x5f, 0x8c, 0xb5, 0xf7, 0x1a, 0xad, 0x34, 0x9d, 0xa9, 0x06, 0x27, 0xda, 0x72, 0x00, 0x62, 0x7a, - 0x84, 0x2c, 0x83, 0xf8, 0x64, 0x22, 0xcb, 0x6f, 0x2e, 0xaf, 0x3a, 0xe5, 0x0c, 0x0e, 0x12, 0x08, - 0x00, 0x5d, 0x22, 0xf4, 0x36, 0xa3, 0x0f, 0xd6, 0x92, 0x10, 0xe0, 0x8c, 0x84, 0xa6, 0xc7, 0x2f, - 0x48, 0xf3, 0xb8, 0x13, 0x87, 0x80, 0x67, 0x7e, 0x4a, 0x98, 0xd5, 0x3e, 0x29, 0x98, 0xf8, 0xc6, - 0x8d, 0xf2, 0x03, 0x46, 0x79, 0x69, 0x95, 0xac, 0x43, 0xd5, 0xe8, 0xc0, 0x80, 0xeb, 0xe4, 0x13, - 0x58, 0xc5, 0xd1, 0x32, 0xbf, 0xb0, 0xe6, 0x26, 0xed, 0xed, 0x04, 0x7c, 0x44, 0x11, 0x77, 0xbc, - 0x08, 0x1e, 0x72, 0x32, 0x2f, 0xab, 0x89, 0x6c, 0x71, 0x9b, 0x8f, 0xe0, 0xa4, 0x91, 0xda, 0xd4, - 0xe7, 0xa3, 0xbd, 0xe9, 0x7d, 0x50, 0xf3, 0xb9, 0x73, 0x67, 0xb7, 0x43, 0x6a, 0xdb, 0x90, 0x47, - 0xa5, 0xd1, 0x71, 0x53, 0xcf, 0x5f, 0xd7, 0x1a, 0x59, 0xf7, 0x00, 0x0e, 0x4a, 0x13, 0x44, 0x6e, - 0x25, 0x48, 0x1a, 0xf1, 0xe9, 0x2c, 0x2a, 0x6d, 0xbf, 0x5f, 0xf2, 0x1d, 0xce, 0x64, 0x0a, 0xf6, - 0xc7, 0x45, 0x58, 0x49, 0x8c, 0x87, 0x7f, 0x2d, 0xbf, 0xdf, 0x60, 0xa4, 0xe3, 0x1d, 0xf6, 0x55, - 0xcc, 0x9e, 0x8c, 0xd9, 0x73, 0x62, 0x26, 0x26, 0xe6, 0xbe, 0x8a, 0xd9, 0x97, 0x31, 0x5d, 0x5f, - 0x62, 0xed, 0x2f, 0x0d, 0xeb, 0x0d, 0x1c, 0xb7, 0x07, 0x25, 0xba, 0xd6, 0xf1, 0xe0, 0xb3, 0xe6, - 0x04, 0x89, 0x1c, 0x85, 0x1d, 0x42, 0x64, 0xa0, 0x18, 0x3c, 0xd8, 0xaa, 0xf0, 0x40, 0xde, 0x15, - 0x70, 0xbc, 0x7e, 0x31, 0xec, 0x47, 0x07, 0x20, 0x14, 0xa7, 0xaa, 0x85, 0x4a, 0x76, 0x50, 0x4e, - 0x61, 0x85, 0x1f, 0x76, 0x9d, 0xd0, 0x2d, 0x15, 0x5c, 0x58, 0x02, 0x0c, 0x06, 0x44, 0x76, 0x40, - 0x48, 0x34, 0x1b, 0xdc, 0x4b, 0x30, 0x6a, 0x71, 0x71, 0x88, 0x7a, 0x76, 0x58, 0xa2, 0x97, 0x84, - 0xc8, 0x63, 0x8f, 0x4e, 0x6f, 0xa7, 0x5b, 0xee, 0xc2, 0x46, 0x9a, 0xaf, 0x00, 0x1e, 0xcc, 0x97, - 0x68, 0x75, 0xa0, 0xeb, 0x75, 0x21, 0x0f, 0xa4, 0xcc, 0x37, 0xbd, 0xcf, 0x67, 0x55, 0xab, 0x57, - 0x3d, 0x9e, 0x4e, 0xac, 0x16, 0x64, 0x1f, 0xc5, 0x7d, 0x72, 0x4e, 0x3c, 0xd8, 0x11, 0x87, 0xa9, - 0xf6, 0x7e, 0x24, 0x1f, 0xed, 0xf4, 0x13, 0x04, 0x9e, 0x49, 0xb4, 0x45, 0xcc, 0x72, 0x47, 0xac, - 0xbb, 0x66, 0x01, 0xb1, 0x64, 0x33, 0x0b, 0x5b, 0xcc, 0x83, 0xb6, 0xd3, 0xd9, 0x79, 0x3f, 0xd3, - 0x95, 0x01, 0x2f, 0xe2, 0x67, 0x38, 0xa0, 0x8d, 0xcb, 0xaa, 0xe8, 0x86, 0x41, 0xef, 0x39, 0xd4, - 0x73, 0xc9, 0xb7, 0xec, 0x2a, 0x9b, 0x3b, 0x01, 0xcd, 0x8a, 0x52, 0x3c, 0x59, 0x4b, 0x44, 0x35, - 0xc5, 0x6b, 0x7a, 0xb0, 0x30, 0x4a, 0x82, 0x27, 0x17, 0x84, 0xb7, 0xe1, 0x82, 0x61, 0x8d, 0x95, - 0x12, 0xf9, 0x0a, 0x18, 0xbc, 0xcf, 0xc7, 0xab, 0x0d, 0x07, 0x03, 0xe5, 0xeb, 0x5b, 0xd3, 0x65, - 0x7c, 0xc3, 0xfa, 0xb2, 0x8e, 0xad, 0xc7, 0x62, 0xe5, 0x97, 0xa3, 0xa8, 0x02, 0xa9, 0x06, 0xe9, - 0x7d, 0x17, 0xc1, 0xdf, 0x0e, 0xa4, 0x2e, 0x6c, 0x82, 0x3e, 0x5b, 0x33, 0xfc, 0x07, 0x01, 0xc2, - 0x6e, 0x62, 0xdc, 0x8c, 0x6a, 0x1d, 0xd3, 0xb2, 0xf5, 0x3a, 0xee, 0xa4, 0x6c, 0xe3, 0xd3, 0xb1, - 0xa0, 0xc5, 0x06, 0xe4, 0xad, 0xa5, 0xe6, 0x3a, 0x77, 0x23, 0x4e, 0x65, 0x5a, 0x22, 0xa6, 0xcb, - 0xfb, 0x6e, 0xea, 0xe8, 0x10, 0xa1, 0x3c, 0x34, 0xd8, 0x39, 0x25, 0x7e, 0xe5, 0x96, 0x7e, 0x9b, - 0xae, 0xea, 0xc3, 0x18, 0xb2, 0xba, 0xf7, 0x36, 0xb8, 0xe5, 0xd8, 0x78, 0xf5, 0x67, 0x27, 0x9e, - 0xed, 0xdc, 0xee, 0x80, 0xb4, 0xba, 0x43, 0x8b, 0xc8, 0x8c, 0x49, 0x5f, 0xb8, 0xd7, 0xa6, 0xee, - 0x44, 0x11, 0x43, 0xef, 0xed, 0x3d, 0x4d, 0x0f, 0xf8, 0xf5, 0xe3, 0x25, 0x4e, 0x08, 0x90, 0xfc, - 0xe0, 0x70, 0x79, 0xb3, 0x85, 0x20, 0xe0, 0xd6, 0x56, 0x2d, 0x60, 0x7c, 0xa1, 0xdf, 0x14, 0x66, - 0x52, 0x0d, 0x9d, 0xaa, 0xd8, 0x96, 0xdb, 0x5a, 0x3d, 0x7a, 0x81, 0xfd, 0x41, 0x0f, 0xe6, 0x99, - 0xd8, 0xe9, 0x21, 0x8a, 0xe7, 0x63, 0x9a, 0xa2, 0x2d, 0x8b, 0x60, 0x79, 0x19, 0xfd, 0x85, 0xea, - 0x90, 0x77, 0x0d, 0x88, 0xda, 0x09, 0xf5, 0xfc, 0x95, 0x56, 0xb1, 0x23, 0x8f, 0xd0, 0xb5, 0x51, - 0xb8, 0xb3, 0x71, 0x52, 0x9b, 0xa0, 0x90, 0xb8, 0x2a, 0xa9, 0xdd, 0x9b, 0x48, 0xe8, 0xda, 0x04, - 0x9b, 0x70, 0xf1, 0xb7, 0xcf, 0xa0, 0xd3, 0x57, 0x35, 0x6d, 0x88, 0x97, 0x64, 0xe8, 0xcb, 0xb3, - 0xcb, 0x6a, 0x90, 0xc0, 0xce, 0x05, 0x53, 0x19, 0xd5, 0x53, 0xec, 0xf9, 0xca, 0xfe, 0x39, 0x8e, - 0x1b, 0xaf, 0x06, 0x64, 0x3f, 0x86, 0xa3, 0x2f, 0x74, 0x39, 0xff, 0x4c, 0x32, 0x74, 0x1d, 0x0f, - 0xf4, 0x1c, 0xa2, 0x24, 0x72, 0x58, 0x8c, 0xb1, 0x6d, 0xf1, 0x8a, 0x19, 0x7a, 0x45, 0x5b, 0x2f, - 0x60, 0xab, 0x85, 0xf4, 0x63, 0x58, 0xab, 0xec, 0xca, 0x6c, 0xc9, 0xda, 0x0c, 0xaf, 0xad, 0x06, - 0xc2, 0x80, 0xc8, 0x0e, 0xd8, 0x6e, 0x40, 0xbe, 0x89, 0x54, 0xde, 0x8e, 0xb5, 0xc1, 0x2c, 0x88, - 0x83, 0x5a, 0xde, 0x65, 0x1c, 0xef, 0x33, 0x26, 0x33, 0x89, 0xa2, 0x1d, 0x69, 0x9f, 0xd8, 0xe6, - 0xa1, 0xf3, 0xef, 0xc8, 0x9a, 0xce, 0x1a, 0x78, 0xb1, 0x70, 0x3b, 0x68, 0x74, 0x03, 0xab, 0x9f, - 0xb0, 0x75, 0x2d, 0x19, 0xb6, 0x37, 0xb0, 0x44, 0x58, 0x73, 0x0b, 0xcc, 0xa2, 0x9c, 0x78, 0x9c, - 0x90, 0xfd, 0x05, 0x84, 0xec, 0x2d, 0x18, 0x8a, 0xfa, 0x13, 0xfe, 0xdc, 0x52, 0x4c, 0x3c, 0x3c, - 0xd8, 0x3a, 0x8b, 0x06, 0xc3, 0xd5, 0x1d, 0xec, 0x6c, 0x77, 0xa8, 0x74, 0x07, 0x01, 0xbf, 0xab, - 0x25, 0xf1, 0xa0, 0x8e, 0xd7, 0xbf, 0x08, 0xf6, 0xc5, 0xbe, 0xaf, 0x78, 0xd5, 0x39, 0x4a, 0x2c, - 0xd3, 0xa2, 0x1c, 0xfe, 0x85, 0x04, 0xf1, 0x38, 0x8e, 0xb5, 0xba, 0x66, 0xef, 0xe7, 0x93, 0x37, - 0xef, 0xe1, 0x08, 0x01, 0x33, 0x7b, 0x96, 0x97, 0x88, 0x14, 0x80, 0xae, 0x80, 0x24, 0x93, 0xa3, - 0x87, 0xd6, 0x2d, 0xd2, 0x46, 0x82, 0xc0, 0x0b, 0x65, 0xb1, 0x69, 0xac, 0x50, 0x63, 0xb2, 0x97, - 0xe5, 0x77, 0x5d, 0xff, 0x29, 0xa2, 0xcf, 0x4a, 0xf1, 0x51, 0xcb, 0xc2, 0x03, 0xda, 0xee, 0x60, - 0x41, 0x4f, 0x2e, 0x60, 0x03, 0xe5, 0x1f, 0x8a, 0xaa, 0xd1, 0x96, 0x9e, 0x15, 0x79, 0xac, 0x1e, - 0xa7, 0xbd, 0xf0, 0x7b, 0xe5, 0x51, 0x33, 0x18, 0x6d, 0x81, 0x30, 0x4d, 0x37, 0x0e, 0x4c, 0x82, - 0x78, 0xe4, 0x2f, 0xba, 0x52, 0x13, 0x64, 0x80, 0xaf, 0x85, 0x45, 0x5a, 0xb3, 0xff, 0x2c, 0x24, - 0xb9, 0x16, 0x39, 0xe2, 0x2a, 0xbd, 0xe3, 0x22, 0x8d, 0x95, 0x12, 0xfe, 0x60, 0x50, 0x1b, 0x64, - 0x11, 0x2d, 0x11, 0x22, 0xc0, 0x88, 0x4a, 0xb8, 0x28, 0x87, 0x77, 0x25, 0x69, 0x03, 0xba, 0xd0, - 0x2f, 0xdb, 0x73, 0xef, 0xd6, 0x8b, 0x10, 0x68, 0x75, 0xb1, 0xed, 0x47, 0x6d, 0xde, 0x94, 0x65, - 0x62, 0xb9, 0x52, 0x66, 0x01, 0xd2, 0xb1, 0xc2, 0xd6, 0x14, 0xcd, 0x91, 0x39, 0x0d, 0x1d, 0xaa, - 0x77, 0xd1, 0xed, 0x14, 0x5a, 0x16, 0x69, 0x27, 0x13, 0x56, 0xa3, 0x51, 0xc2, 0x41, 0x07, 0x95, - 0x93, 0xa8, 0x66, 0xf8, 0xe7, 0x87, 0xb7, 0xbb, 0x2f, 0xbc, 0x45, 0x30, 0xce, 0x2f, 0xbe, 0x44, - 0x95, 0xed, 0x88, 0xf9, 0x08, 0xad, 0xd6, 0x23, 0x28, 0x1c, 0xb0, 0x7f, 0x36, 0xd0, 0x81, 0xe1, - 0x60, 0x7a, 0xa4, 0x1a, 0xec, 0x12, 0x46, 0xb9, 0x50, 0xd6, 0x13, 0xa5, 0xd4, 0x21, 0x66, 0x00, - 0xd2, 0x8a, 0x19, 0xe0, 0x4f, 0xd2, 0x77, 0x19, 0x05, 0x59, 0xd5, 0xc2, 0x04, 0x52, 0x2d, 0x51, - 0x9a, 0x55, 0x78, 0x62, 0xd7, 0x4a, 0x25, 0xa9, 0x2c, 0x93, 0x7f, 0x23, 0x21, 0x01, 0xd4, 0xe9, - 0xd6, 0x1a, 0xdf, 0x21, 0x62, 0x60, 0x74, 0xdc, 0x04, 0x5a, 0x98, 0x24, 0x25, 0x7d, 0x81, 0x9c, - 0x65, 0xac, 0xc9, 0x5a, 0x3f, 0x63, 0x1e, 0x1e, 0x94, 0xc6, 0x15, 0xb9, 0x26, 0xfb, 0x07, 0x7e, - 0x4d, 0xfb, 0xc5, 0x78, 0xea, 0x96, 0xf0, 0x81, 0x05, 0x81, 0x75, 0xa4, 0x9c, 0xc1, 0x12, 0x26, - 0x3c, 0x49, 0x7a, 0xb1, 0xca, 0xe1, 0xb5, 0xee, 0x37, 0x49, 0xfe, 0x25, 0xda, 0x06, 0x38, 0xcf, - 0xb3, 0x88, 0x34, 0x64, 0xc8, 0x63, 0x90, 0x2d, 0x48, 0x5b, 0x66, 0x0f, 0x71, 0xa3, 0xe9, 0x20, - 0x75, 0xbb, 0xf3, 0x58, 0x8a, 0x4b, 0x16, 0x9d, 0x59, 0x19, 0x8f, 0x5a, 0x27, 0xd2, 0x4b, 0x20, - 0x31, 0x07, 0x6b, 0x4d, 0x42, 0xbe, 0x52, 0x59, 0x4f, 0x15, 0x4c, 0x8b, 0x3f, 0xa2, 0xad, 0x1e, - 0x31, 0x6a, 0x5a, 0x0b, 0x62, 0xc3, 0xc5, 0xf3, 0x7d, 0xea, 0x10, 0x08, 0x76, 0x51, 0x47, 0xb7, - 0x05, 0xff, 0xf8, 0xc3, 0x73, 0x6c, 0x7f, 0x98, 0xf1, 0x0c, 0x4a, 0xd0, 0xf9, 0x88, 0x34, 0x4b, - 0x4c, 0x28, 0x48, 0x2c, 0x47, 0x24, 0x85, 0x7d, 0x3b, 0x27, 0xc5, 0xdd, 0x51, 0x68, 0x41, 0x16, - 0x2f, 0x28, 0x14, 0x89, 0x22, 0x21, 0x10, 0x2d, 0x25, 0x30, 0x99, 0xa6, 0x70, 0x66, 0x94, 0x2f, - 0x5e, 0xdf, 0x14, 0x0b, 0x84, 0x8d, 0x20, 0xdf, 0xda, 0xf3, 0xc8, 0xe3, 0xaf, 0x5c, 0x30, 0xf8, - 0x01, 0x02, 0xf8, 0xa2, 0xf7, 0xb5, 0x73, 0x95, 0x37, 0x4b, 0x23, 0x6c, 0x42, 0x28, 0xd4, 0x62, - 0xd1, 0x28, 0x3f, 0xba, 0xdc, 0xb8, 0x35, 0xd0, 0x9a, 0xc2, 0x2d, 0xf5, 0xcb, 0x87, 0x03, 0x32, - 0xf9, 0x79, 0x53, 0xf1, 0x89, 0xa6, 0x15, 0x99, 0x96, 0x32, 0x51, 0xdd, 0xe5, 0xc5, 0x67, 0xae, - 0x0e, 0x2c, 0x90, 0x1d, 0x8c, 0x8f, 0xf2, 0x30, 0x71, 0x37, 0xc1, 0x36, 0x83, 0x84, 0x6f, 0x1f, - 0xf0, 0x37, 0x57, 0x9b, 0xd8, 0x9c, 0xd6, 0xe7, 0xd3, 0x49, 0xf3, 0xec, 0x12, 0x22, 0x61, 0x6e, - 0x7b, 0x9e, 0xf2, 0x3d, 0x99, 0xa3, 0xd6, 0x32, 0x9a, 0xe3, 0x42, 0x15, 0xa9, 0x72, 0x2d, 0x16, - 0x03, 0x0b, 0x3d, 0x9e, 0x3a, 0x99, 0x74, 0x9b, 0x05, 0x62, 0xc9, 0xeb, 0xc2, 0xaf, 0xe9, 0x40, - 0x04, 0xaf, 0xbf, 0x4d, 0xc4, 0x1d, 0xda, 0x13, 0xe4, 0x04, 0x64, 0x63, 0x24, 0xbd, 0xa5, 0x39, - 0x88, 0x53, 0x93, 0x7c, 0xb8, 0x9d, 0x57, 0xd2, 0xe7, 0x1c, 0xde, 0xbd, 0xbb, 0xc5, 0xa1, 0xf9, - 0xee, 0x56, 0x1a, 0x1d, 0xd6, 0xcf, 0x28, 0x45, 0xf7, 0x91, 0xca, 0x6f, 0xc3, 0x1e, 0x84, 0xf9, - 0x0a, 0x26, 0xc5, 0xf0, 0xfa, 0xaf, 0x3d, 0xca, 0x55, 0x69, 0x7c, 0x3e, 0xa7, 0xb7, 0x84, 0xc4, - 0x6e, 0xd9, 0xa8, 0x0e, 0x93, 0x29, 0x4a, 0xdb, 0x1d, 0x73, 0x59, 0x07, 0x69, 0xc2, 0xbd, 0xd1, - 0x18, 0x26, 0x7c, 0x34, 0x4e, 0x47, 0x19, 0xdd, 0x7c, 0xe1, 0x48, 0xe8, 0xe1, 0xcf, 0x2e, 0xb1, - 0x32, 0x9f, 0xba, 0xe1, 0x0d, 0xbf, 0xb5, 0x91, 0x7d, 0x8d, 0xf3, 0xa9, 0xea, 0x86, 0x2e, 0x4e, - 0xdf, 0x74, 0x18, 0xc1, 0x88, 0x50, 0x2a, 0x7a, 0xad, 0x77, 0x11, 0x6f, 0xa7, 0x82, 0x03, 0xeb, - 0xd0, 0x83, 0x6d, 0x87, 0x10, 0x2a, 0xfc, 0xc8, 0x29, 0xb5, 0xe3, 0x0e, 0x56, 0x38, 0x82, 0x94, - 0x72, 0x7c, 0x56, 0x3c, 0xab, 0xc1, 0x16, 0x37, 0x92, 0xa0, 0xe6, 0xa6, 0x2d, 0x0c, 0xf6, 0xaf, - 0x14, 0x36, 0x30, 0x42, 0x0c, 0x87, 0x1d, 0x2c, 0x28, 0x93, 0x3f, 0x44, 0xb7, 0xd1, 0xe5, 0xdc, - 0xa9, 0x73, 0xdd, 0xa9, 0xcd, 0xfe, 0x74, 0x3a, 0xda, 0x8c, 0x10, 0x84, 0xfd, 0xc7, 0xc4, 0xd8, - 0xdd, 0xc7, 0x7c, 0x51, 0xd3, 0xe1, 0xe2, 0x95, 0xdc, 0xf6, 0xf0, 0xa6, 0xb5, 0x95, 0x31, 0xc9, - 0x46, 0xed, 0x6c, 0x37, 0xc2, 0x71, 0xcd, 0xcf, 0x8e, 0x33, 0x31, 0xee, 0x70, 0x8d, 0x05, 0x49, - 0x5e, 0x85, 0x50, 0x83, 0xb9, 0x36, 0x8e, 0x57, 0xd6, 0x8d, 0xd2, 0x62, 0xe5, 0xe8, 0x87, 0xcf, - 0xd4, 0xc8, 0xaa, 0x5d, 0x98, 0x6c, 0xc2, 0xa1, 0x5b, 0xb0, 0x2b, 0x47, 0xd1, 0x1e, 0x5d, 0x3b, - 0x45, 0xdf, 0x60, 0xd7, 0x50, 0xe6, 0xd4, 0x56, 0x45, 0xdc, 0x88, 0x10, 0xc1, 0x43, 0x6d, 0x0d, - 0x61, 0x80, 0x5b, 0x58, 0xe9, 0x80, 0x69, 0x90, 0x46, 0x15, 0x25, 0x08, 0x9c, 0x8d, 0x59, 0x9b, - 0x8f, 0x6a, 0xb9, 0xdb, 0x33, 0xce, 0xeb, 0x41, 0x2f, 0x6c, 0xf1, 0x5e, 0x5e, 0x92, 0xaa, 0xb4, - 0x53, 0xa1, 0x83, 0x33, 0x62, 0x0b, 0x77, 0xb9, 0x1c, 0xd7, 0x77, 0x20, 0xc5, 0x65, 0x16, 0x1c, - 0x04, 0x1e, 0x9f, 0xd1, 0x67, 0x45, 0xbb, 0x87, 0x37, 0xbe, 0x22, 0x10, 0x86, 0x69, 0x61, 0x83, - 0x41, 0x60, 0xd3, 0x4e, 0x8a, 0x3c, 0x4d, 0xe1, 0xdb, 0xf9, 0xaf, 0xd8, 0x31, 0xf3, 0xb1, 0xb8, - 0x1a, 0xdd, 0x26, 0x79, 0x11, 0x69, 0x4e, 0x60, 0x9a, 0x69, 0xf0, 0x48, 0x5c, 0xc9, 0x0b, 0xe5, - 0x6c, 0xd2, 0x0e, 0xcf, 0xa9, 0xb1, 0x37, 0x8f, 0x9a, 0xa8, 0x76, 0x47, 0x2d, 0x18, 0x76, 0x1a, - 0x15, 0xa7, 0x5c, 0x0b, 0x5b, 0xb7, 0xdf, 0x37, 0xd0, 0x0f, 0x0e, 0x22, 0xdd, 0x7b, 0x38, 0x63, - 0x95, 0x12, 0x5a, 0x12, 0x33, 0x6a, 0x80, 0xd2, 0x19, 0x38, 0x3a, 0xc4, 0x90, 0x22, 0xfa, 0x81, - 0xd8, 0xdb, 0x7f, 0xf1, 0x1d, 0xf3, 0xf6, 0xfc, 0xb4, 0x0a, 0x99, 0xae, 0x3d, 0xc1, 0x5f, 0x0a, - 0x52, 0xb7, 0x29, 0x4c, 0x18, 0x56, 0x6d, 0x1d, 0x0a, 0x1d, 0x16, 0xee, 0xfa, 0x6e, 0xb7, 0x17, - 0x99, 0x3b, 0x02, 0x36, 0xd4, 0x9b, 0x58, 0x86, 0xef, 0x54, 0x2e, 0xc7, 0x77, 0x2a, 0x17, 0x1b, - 0xa2, 0x85, 0x61, 0xd4, 0x75, 0x20, 0x74, 0x0e, 0xf0, 0x5c, 0xf5, 0xf5, 0xa5, 0x79, 0x0c, 0xd4, - 0x54, 0xd9, 0x4a, 0xe4, 0x30, 0xae, 0xae, 0x1a, 0x58, 0x53, 0xe5, 0x06, 0x58, 0x53, 0x55, 0x41, - 0x09, 0xf8, 0x16, 0x88, 0xca, 0xd2, 0x80, 0x7f, 0x93, 0x2a, 0x05, 0xaf, 0x89, 0xb6, 0x80, 0xc9, - 0x7d, 0x3b, 0x5f, 0x8b, 0x25, 0xb7, 0x68, 0xff, 0xd2, 0xeb, 0x35, 0x5f, 0x5a, 0x37, 0x7a, 0x3e, - 0xae, 0xe9, 0x1e, 0x84, 0x98, 0x33, 0x3d, 0x14, 0xfe, 0xbb, 0x07, 0xcb, 0xfa, 0xe2, 0xd8, 0xc3, - 0x85, 0xc6, 0xf6, 0x55, 0xd4, 0xfb, 0xba, 0x51, 0x63, 0x03, 0x85, 0x39, 0x28, 0x61, 0x4e, 0xd1, - 0x08, 0x22, 0xec, 0xdb, 0xb9, 0x9e, 0x45, 0x62, 0x41, 0xf7, 0x1a, 0xe4, 0xd5, 0x5c, 0x2b, 0xd9, - 0xc4, 0x5b, 0x36, 0x08, 0x67, 0x0e, 0xef, 0x88, 0xc2, 0x59, 0x42, 0x1e, 0x4f, 0xf4, 0xc3, 0x48, - 0x5b, 0x71, 0x9e, 0x14, 0xfa, 0x71, 0x6d, 0x89, 0xb6, 0x38, 0x3c, 0x6d, 0xdb, 0xbf, 0xca, 0x53, - 0x90, 0xe5, 0x7f, 0x69, 0x9a, 0xc6, 0x42, 0xad, 0x4a, 0x58, 0x22, 0xad, 0x2c, 0x94, 0x12, 0x96, - 0x59, 0xbe, 0x8f, 0x5d, 0x63, 0x98, 0x0d, 0x07, 0x7f, 0x1e, 0x1b, 0x99, 0x80, 0x97, 0x1a, 0xb8, - 0xc8, 0x68, 0x84, 0x65, 0x9c, 0xff, 0xaf, 0x02, 0x41, 0xa6, 0x72, 0x7b, 0x16, 0xd3, 0xad, 0xde, - 0xa7, 0x91, 0xa5, 0x76, 0x35, 0xce, 0x56, 0xef, 0xc5, 0x88, 0xe6, 0xf4, 0xcb, 0x8b, 0x0b, 0xb5, - 0x69, 0x34, 0x7b, 0x75, 0x29, 0x1c, 0x71, 0x1b, 0xee, 0xf0, 0x32, 0xd0, 0xe1, 0xaf, 0x04, 0x18, - 0x7e, 0xb3, 0xff, 0xec, 0xc7, 0x06, 0x15, 0xc3, 0x9f, 0xc4, 0x0b, 0x4e, 0x11, 0x54, 0xf7, 0x2b, - 0xa1, 0x82, 0x29, 0x8f, 0xaf, 0x44, 0x09, 0xa6, 0x3c, 0xbe, 0x12, 0x20, 0x98, 0xf2, 0x58, 0x87, - 0x0d, 0x2c, 0x27, 0x92, 0x7b, 0x92, 0x3b, 0x81, 0x21, 0x98, 0x6a, 0x4f, 0x19, 0x75, 0x75, 0x7c, - 0xd0, 0xc6, 0x8d, 0x98, 0x2d, 0xa1, 0x45, 0xb4, 0x99, 0x0f, 0x3b, 0x5a, 0xc7, 0x46, 0xae, 0xcd, - 0xd9, 0x90, 0xff, 0x44, 0x86, 0x1b, 0x1c, 0xbd, 0xa2, 0xc9, 0xd2, 0x96, 0xda, 0xce, 0x67, 0xb5, - 0xc7, 0x3d, 0x84, 0xa5, 0xea, 0x96, 0x6d, 0xa0, 0x54, 0x98, 0x9e, 0x70, 0x11, 0xf0, 0x07, 0x59, - 0x08, 0x5c, 0x44, 0x75, 0x44, 0x7c, 0x30, 0xf8, 0x53, 0xc6, 0xd6, 0x6a, 0x2f, 0x12, 0x53, 0x28, - 0xcc, 0xd5, 0x49, 0xfa, 0xa6, 0xee, 0xdd, 0x9e, 0x0a, 0x65, 0x2d, 0xa9, 0x0c, 0x73, 0x67, 0x19, - 0x3b, 0xa8, 0xdc, 0xd3, 0xa4, 0x28, 0x61, 0xf9, 0xf6, 0x8e, 0x14, 0xb5, 0x61, 0x47, 0x36, 0x07, - 0x37, 0xef, 0x36, 0xf9, 0xdb, 0x64, 0x87, 0xb3, 0x54, 0x73, 0x93, 0x2b, 0xdf, 0xc7, 0x41, 0xb6, - 0xb3, 0xe3, 0x43, 0x9d, 0xb8, 0xd9, 0x61, 0x19, 0x2e, 0xbe, 0x40, 0xc3, 0x23, 0xaf, 0xe4, 0x8e, - 0xfb, 0x89, 0xab, 0xe2, 0x0f, 0x85, 0xc0, 0xb2, 0x1d, 0x54, 0xf6, 0x8d, 0x6b, 0xa9, 0xf8, 0xac, - 0x96, 0xde, 0x30, 0xa6, 0x45, 0x36, 0xdd, 0x45, 0xe0, 0x40, 0x7f, 0x90, 0x6a, 0x1b, 0x2b, 0x5e, - 0xb6, 0x24, 0xcd, 0x7b, 0x8b, 0x1e, 0x5a, 0x91, 0x71, 0x19, 0xa0, 0xba, 0x2e, 0x71, 0x11, 0xfa, - 0x2b, 0x18, 0x76, 0x28, 0x7b, 0x9b, 0xeb, 0xa6, 0x33, 0xf2, 0x33, 0x6d, 0x21, 0x81, 0xbe, 0xc2, - 0x3b, 0x61, 0x86, 0xbf, 0xc6, 0x7a, 0xe1, 0x23, 0x15, 0x9c, 0x74, 0x4a, 0x70, 0x5e, 0x44, 0x76, - 0x8b, 0x7d, 0x32, 0xaf, 0xc8, 0xf0, 0x70, 0x66, 0xb3, 0xe1, 0xb0, 0xbe, 0xd6, 0xd6, 0x58, 0xc1, - 0xda, 0x7c, 0x92, 0xb2, 0x03, 0xa7, 0xd3, 0xee, 0x68, 0x1d, 0x9e, 0x08, 0x90, 0xe7, 0x7b, 0x41, - 0x18, 0xe0, 0x65, 0x70, 0xfd, 0xf2, 0xe2, 0xa6, 0x70, 0xdf, 0x3a, 0xaf, 0x3e, 0x55, 0x67, 0x76, - 0x64, 0xa3, 0x0f, 0x5e, 0x96, 0xc6, 0xc4, 0xa0, 0xa4, 0xce, 0x08, 0xb3, 0x7c, 0x71, 0x45, 0xda, - 0x5a, 0x4c, 0x63, 0x09, 0xef, 0xb6, 0x16, 0x3f, 0xe8, 0x2d, 0x2b, 0xba, 0xfb, 0xa6, 0xa5, 0x9c, - 0x18, 0xc1, 0x29, 0x8d, 0x0d, 0x89, 0x96, 0x8a, 0x93, 0x92, 0xf1, 0x4a, 0xdc, 0x02, 0x21, 0xc4, - 0x99, 0x6e, 0xef, 0xb2, 0x71, 0xaf, 0x1a, 0xd2, 0xbd, 0xbe, 0x29, 0x54, 0xc2, 0xb2, 0xa1, 0x77, - 0xef, 0xd6, 0xdb, 0xd2, 0xd6, 0xe4, 0xf7, 0xc2, 0xef, 0x4b, 0xdd, 0x83, 0x76, 0x96, 0x1f, 0x36, - 0xcb, 0xd1, 0x69, 0xe9, 0x4d, 0x32, 0xfe, 0xc5, 0x4c, 0x72, 0x9d, 0xcb, 0x00, 0x1d, 0x90, 0xf8, - 0x6a, 0x5e, 0x8a, 0x02, 0x40, 0x51, 0x5d, 0x5a, 0xc0, 0x89, 0x81, 0xfd, 0x66, 0xe6, 0xbc, 0x1a, - 0x76, 0xd1, 0x30, 0x88, 0xe0, 0x9a, 0x20, 0x6e, 0xca, 0x35, 0x12, 0xd7, 0x43, 0x27, 0x4d, 0xde, - 0x3b, 0xf7, 0xdb, 0x67, 0x5a, 0x64, 0x92, 0xbb, 0xc2, 0xad, 0xfa, 0x98, 0xb9, 0xd8, 0x49, 0xb9, - 0xb6, 0xc6, 0x82, 0xc9, 0xf7, 0x26, 0xbb, 0x30, 0x31, 0xd7, 0x7c, 0x99, 0x55, 0x42, 0x35, 0xd7, - 0xdd, 0x13, 0x17, 0x29, 0x44, 0xae, 0x78, 0x48, 0xf8, 0x24, 0x4c, 0x6b, 0xa3, 0x56, 0x76, 0x56, - 0x46, 0xe8, 0x85, 0x05, 0xfd, 0x08, 0x7f, 0x43, 0xc4, 0xe5, 0xd2, 0xed, 0x1f, 0x7d, 0xaa, 0x8a, - 0xb3, 0x80, 0xab, 0x13, 0x85, 0x41, 0x11, 0xa1, 0x5e, 0x37, 0xbb, 0x88, 0x42, 0x2d, 0x0d, 0x9b, - 0x5e, 0xe3, 0x58, 0xc3, 0x7a, 0x00, 0x9c, 0xa6, 0x4a, 0x8b, 0x8d, 0x05, 0x46, 0x01, 0x8b, 0x63, - 0x72, 0xcf, 0x83, 0xc3, 0x0f, 0x88, 0xc8, 0xbb, 0x70, 0xbc, 0x88, 0x7a, 0xe1, 0xec, 0x7e, 0xa0, - 0xb9, 0x8b, 0x56, 0xb1, 0xcc, 0x9c, 0x5e, 0xdd, 0x4c, 0xa7, 0x20, 0xe6, 0x12, 0xa9, 0xeb, 0xd2, - 0xc3, 0x98, 0xe9, 0x77, 0xfb, 0x40, 0x86, 0xa3, 0x85, 0xc9, 0x6b, 0x61, 0x7f, 0xb1, 0x0a, 0xfb, - 0xf0, 0x90, 0xa1, 0xf7, 0xbb, 0x43, 0x58, 0x41, 0x1f, 0x58, 0x7d, 0x5e, 0x23, 0x6a, 0x33, 0x3e, - 0xb2, 0xe1, 0xcf, 0xd5, 0xfc, 0x3d, 0x84, 0xd8, 0x8a, 0x8b, 0xdd, 0x34, 0xc9, 0x92, 0x4a, 0xa4, - 0x5f, 0x36, 0xab, 0xc1, 0x6c, 0x55, 0x15, 0xb2, 0x23, 0x42, 0x28, 0xd1, 0x05, 0xff, 0x33, 0xa5, - 0x36, 0x9d, 0xc3, 0x23, 0x4c, 0xf7, 0x8e, 0x42, 0xc9, 0x92, 0x9f, 0x71, 0x5d, 0xeb, 0x3d, 0x9d, - 0xd6, 0xc8, 0x04, 0xb2, 0x8e, 0x4e, 0x9d, 0x94, 0x90, 0x63, 0xd7, 0xc8, 0x12, 0x65, 0xac, 0xda, - 0x10, 0x02, 0x40, 0xff, 0x6f, 0x24, 0x0e, 0x85, 0xf2, 0x38, 0xc0, 0x9f, 0xce, 0x40, 0xfc, 0x39, - 0xea, 0xa0, 0xc9, 0xb0, 0x34, 0xe4, 0xb9, 0x2e, 0x1d, 0x8c, 0x77, 0x04, 0x53, 0x46, 0xba, 0x87, - 0x45, 0x08, 0xc7, 0xd2, 0x8c, 0xb2, 0x8c, 0x31, 0x06, 0xce, 0x04, 0x56, 0xe9, 0x78, 0xf2, 0x2d, - 0x69, 0x70, 0xba, 0xf1, 0x01, 0x25, 0x8b, 0xed, 0xc1, 0x83, 0x37, 0x67, 0x9d, 0x27, 0x98, 0x20, - 0xf4, 0xf9, 0x3a, 0xc3, 0xcc, 0xd1, 0x7b, 0x68, 0x39, 0x7d, 0x72, 0x69, 0xc6, 0x40, 0x64, 0x6a, - 0x68, 0x43, 0x38, 0x6d, 0x17, 0xca, 0xd3, 0xcd, 0x8e, 0x0d, 0x92, 0xa1, 0x3e, 0xce, 0xad, 0xfc, - 0x3a, 0xd9, 0x7b, 0xa8, 0x93, 0x5b, 0x48, 0x66, 0x34, 0xef, 0x70, 0xb3, 0xfb, 0x36, 0x10, 0xe9, - 0x2a, 0x28, 0x1d, 0xec, 0x70, 0xd8, 0x1c, 0x41, 0x47, 0xc9, 0x34, 0x1b, 0x91, 0x3e, 0x7f, 0x80, - 0x94, 0x35, 0xe9, 0xef, 0x7c, 0xa1, 0x70, 0xcb, 0xca, 0x35, 0xc4, 0x52, 0x8d, 0x41, 0x6d, 0x20, - 0xa4, 0xf0, 0xd5, 0x31, 0x23, 0x2d, 0x76, 0xc6, 0x04, 0xe7, 0x95, 0x89, 0xb2, 0x64, 0x6c, 0x1b, - 0x35, 0xda, 0x57, 0xce, 0x32, 0xac, 0x4b, 0x32, 0xa6, 0x49, 0x26, 0x67, 0xd1, 0x5f, 0x3c, 0xf3, - 0xd7, 0x14, 0xfe, 0x14, 0xfd, 0x1a, 0x95, 0x22, 0x6f, 0x8c, 0x06, 0xd0, 0xc7, 0x96, 0xbe, 0xfc, - 0x7f, 0x2c, 0xfd, 0x2b, 0xfe, 0xa8, 0xaa, 0x00, 0x5a, 0xa4, 0xe4, 0xc2, 0xf6, 0x98, 0xf2, 0xc3, - 0xa7, 0xbc, 0x47, 0x96, 0xfb, 0xbc, 0x86, 0xce, 0xa7, 0x4d, 0x8b, 0x12, 0xad, 0xd7, 0x79, 0xb6, - 0x40, 0x7b, 0xcb, 0x1a, 0xc5, 0x12, 0xf2, 0x4d, 0x41, 0x35, 0x5d, 0x10, 0xdf, 0xc7, 0x50, 0x4d, - 0x51, 0x15, 0xd2, 0xeb, 0x59, 0x13, 0xaa, 0xb7, 0x05, 0xa1, 0xf7, 0xbc, 0x8e, 0xd0, 0xeb, 0x14, - 0x93, 0x9c, 0xf1, 0xcb, 0xe5, 0x40, 0xbd, 0xf0, 0x25, 0x74, 0xa1, 0x99, 0xa9, 0xd9, 0xce, 0xd0, - 0xb8, 0x0a, 0xba, 0xb7, 0x53, 0x17, 0x93, 0xbe, 0x02, 0xd4, 0xb7, 0x6c, 0x82, 0xfa, 0x2a, 0x34, - 0x36, 0x85, 0x75, 0xb7, 0x92, 0x99, 0x85, 0xc9, 0xb4, 0x50, 0x74, 0x43, 0xcc, 0x1c, 0x43, 0x5e, - 0x41, 0x8d, 0x45, 0xcc, 0x2d, 0x1b, 0x2a, 0xbd, 0xa9, 0xca, 0x43, 0x45, 0x15, 0xbf, 0x01, 0x31, - 0x4b, 0x73, 0x59, 0xfb, 0x1f, 0xbc, 0x30, 0xcd, 0x20, 0x53, 0x34, 0x74, 0xa2, 0xce, 0xf2, 0xb2, - 0x97, 0x54, 0x36, 0x53, 0x10, 0xab, 0x1c, 0xbf, 0xa7, 0x8a, 0xaf, 0xde, 0xaa, 0xca, 0xef, 0x69, - 0x5b, 0x4d, 0x9e, 0x1e, 0xb5, 0x2e, 0xb1, 0x57, 0xde, 0x51, 0x37, 0x15, 0x38, 0xdd, 0x05, 0x19, - 0xef, 0x61, 0x28, 0xa0, 0x25, 0xd6, 0x2a, 0x1f, 0x2f, 0x8f, 0xbe, 0x9b, 0x1a, 0x7a, 0x9f, 0xae, - 0xeb, 0x61, 0x6b, 0xd2, 0xc6, 0xbc, 0xad, 0x36, 0x66, 0xdc, 0x89, 0xb7, 0xf5, 0x61, 0xe5, 0x6b, - 0xa6, 0x31, 0x7c, 0x63, 0xe8, 0x9d, 0x42, 0x5f, 0x75, 0x66, 0x5a, 0xe8, 0x85, 0xf3, 0x79, 0x5e, - 0x78, 0x11, 0xb6, 0xbf, 0xf7, 0xf3, 0x2d, 0x52, 0x61, 0xc2, 0xa9, 0xa5, 0x73, 0x97, 0x54, 0x57, - 0x1d, 0x72, 0x8c, 0x80, 0x0f, 0xff, 0x13, 0x96, 0x6f, 0x79, 0xbd, 0x45, 0x86, 0x2d, 0x1e, 0x39, - 0xf7, 0x27, 0x65, 0xed, 0x78, 0x03, 0x8f, 0xaf, 0x4a, 0x73, 0xc0, 0xc1, 0x7a, 0x3f, 0x3c, 0x54, - 0x5f, 0x7d, 0x34, 0x6b, 0xeb, 0x8f, 0x59, 0xde, 0xb7, 0x4a, 0x02, 0x0f, 0x47, 0x2f, 0x4f, 0x8e, - 0x3b, 0xd0, 0x95, 0xd7, 0xa3, 0xec, 0x82, 0xf9, 0x9f, 0x61, 0x6c, 0x8c, 0x0a, 0x31, 0x52, 0x29, - 0x46, 0xb3, 0x44, 0xd3, 0x0e, 0x51, 0x22, 0x08, 0x20, 0x15, 0xab, 0x8c, 0x77, 0xb4, 0xe4, 0x3b, - 0x3d, 0xfb, 0x3b, 0x3d, 0x85, 0x7b, 0xd8, 0xb6, 0x0b, 0x77, 0xae, 0x9f, 0xc3, 0x09, 0x17, 0xc7, - 0x48, 0x95, 0x77, 0x8e, 0x5f, 0x77, 0x2c, 0xda, 0x51, 0xde, 0xa9, 0x2e, 0xea, 0xda, 0x63, 0x7d, - 0x94, 0xa2, 0x36, 0x80, 0x1e, 0xb9, 0xb0, 0x0f, 0x54, 0xfd, 0x83, 0x90, 0x0e, 0x54, 0x3d, 0x7d, - 0xa0, 0xc2, 0xfe, 0x14, 0x11, 0x08, 0xfe, 0xef, 0x2c, 0x73, 0xde, 0x49, 0xd7, 0x5f, 0x1c, 0x2d, - 0x3b, 0x17, 0x50, 0x6b, 0xaf, 0x3f, 0x1b, 0xa0, 0x83, 0xfe, 0x09, 0x1f, 0x0d, 0x14, 0x4a, 0xe5, - 0x4a, 0x9d, 0xa4, 0xb2, 0x33, 0x60, 0x6d, 0xf5, 0xc9, 0x80, 0x07, 0x23, 0x96, 0x71, 0x7b, 0xf9, - 0x27, 0xa9, 0x35, 0xb6, 0x77, 0xc4, 0xce, 0xf6, 0x85, 0x48, 0x5d, 0xe6, 0x81, 0x93, 0x2e, 0x85, - 0x6f, 0x4c, 0x3c, 0xc0, 0xec, 0x05, 0xdb, 0xd1, 0xf6, 0xa6, 0xfa, 0xec, 0x13, 0x57, 0xa1, 0xbd, - 0xbd, 0xb0, 0x8b, 0xde, 0xde, 0xfd, 0x77, 0xa3, 0x42, 0x55, 0xca, 0x1b, 0xcf, 0x98, 0xb2, 0x6f, - 0x62, 0x8d, 0x08, 0x7c, 0xef, 0x99, 0xd6, 0x57, 0xd5, 0x77, 0x57, 0x0e, 0x18, 0x0b, 0x58, 0x33, - 0x05, 0x8a, 0x89, 0x99, 0xd4, 0x15, 0x7d, 0x5c, 0x32, 0xe9, 0xed, 0xcc, 0xfa, 0x2e, 0x56, 0x8b, - 0x0f, 0xda, 0xae, 0xfb, 0xc0, 0x7c, 0xfd, 0x32, 0xce, 0x2b, 0x66, 0x44, 0x77, 0x9d, 0x6a, 0x19, - 0x9c, 0x27, 0x10, 0xcb, 0xd4, 0xe9, 0xf8, 0x3e, 0xc9, 0x2c, 0xab, 0xa7, 0x3c, 0x9a, 0x76, 0x43, - 0x85, 0xa2, 0x78, 0x6e, 0xa3, 0x48, 0xcd, 0x42, 0x9c, 0x34, 0x3e, 0xc8, 0xe4, 0xd3, 0x7c, 0x72, - 0x83, 0x56, 0xee, 0x4a, 0xdd, 0xb8, 0x23, 0x8c, 0x69, 0x90, 0x87, 0x2e, 0xd0, 0x67, 0x49, 0xd0, - 0x55, 0x33, 0xeb, 0x9a, 0x3d, 0x01, 0x16, 0x42, 0x64, 0x0e, 0x22, 0xcf, 0xb3, 0x8d, 0xed, 0xb6, - 0x13, 0x91, 0x91, 0x3b, 0x8f, 0x34, 0xa9, 0xcf, 0xca, 0xb7, 0xec, 0x6d, 0xd6, 0xde, 0x10, 0x15, - 0xde, 0x90, 0xaa, 0xeb, 0x4d, 0x95, 0x02, 0xaf, 0x6a, 0x05, 0x78, 0x85, 0xf5, 0x1e, 0xdf, 0xcb, - 0xe9, 0xd1, 0xae, 0xdc, 0xa3, 0x57, 0x06, 0x9f, 0x11, 0xcd, 0x9d, 0xf8, 0xb7, 0x63, 0xd9, 0x57, - 0x5f, 0x84, 0xdf, 0x79, 0x16, 0x85, 0x3c, 0xbd, 0xee, 0x6c, 0x2a, 0xb9, 0xb8, 0x62, 0x0a, 0x2a, - 0x7b, 0xf4, 0xf4, 0x0b, 0x24, 0xb3, 0xb0, 0x16, 0x59, 0xbc, 0x6f, 0xeb, 0x2a, 0x20, 0x8d, 0x45, - 0x8b, 0x0a, 0x38, 0x69, 0x9a, 0x94, 0x05, 0x68, 0x97, 0x35, 0x28, 0x15, 0x03, 0x48, 0x76, 0x3a, - 0xb5, 0xe3, 0x01, 0xd7, 0x0b, 0x8d, 0x4d, 0xba, 0x86, 0xeb, 0x25, 0x8b, 0x74, 0x17, 0xc6, 0x9b, - 0x35, 0xc3, 0x58, 0xcd, 0xb7, 0xf9, 0x12, 0xa2, 0xcc, 0x1a, 0xae, 0xa9, 0x52, 0x02, 0x5b, 0x16, - 0xcd, 0x36, 0x37, 0x25, 0x7a, 0x7d, 0x53, 0x90, 0x2d, 0x63, 0x59, 0x89, 0x3f, 0x68, 0x2d, 0xc8, - 0xb2, 0x18, 0xdf, 0x40, 0x09, 0x77, 0x7a, 0x8b, 0x4d, 0xbf, 0xa8, 0xfa, 0xfb, 0x19, 0xf4, 0x77, - 0xab, 0x89, 0xd0, 0x5d, 0xd5, 0x9d, 0x33, 0x8e, 0x2a, 0x2c, 0x2f, 0xe9, 0xcf, 0x0f, 0x0e, 0xf6, - 0xf7, 0x78, 0x55, 0x0f, 0xf7, 0xfa, 0xb0, 0xef, 0x8a, 0x19, 0xfc, 0xe8, 0xd9, 0x32, 0x35, 0xa9, - 0xef, 0x1a, 0x43, 0x41, 0x1f, 0x65, 0xea, 0xea, 0xbb, 0xa7, 0xbd, 0x10, 0x7a, 0xbe, 0x5c, 0x52, - 0xd3, 0xaf, 0x29, 0xb9, 0x69, 0x46, 0x55, 0x76, 0x5d, 0xf2, 0xb0, 0xbd, 0xe4, 0x1f, 0x36, 0x2b, - 0xb8, 0xa3, 0x25, 0x5c, 0x5d, 0xfe, 0x15, 0xa3, 0xaf, 0xb9, 0x7d, 0x3c, 0x66, 0xf4, 0x2d, 0x25, - 0xaf, 0x69, 0x8c, 0x88, 0xa7, 0x7a, 0x0d, 0x58, 0x62, 0xa2, 0x91, 0x4b, 0xf7, 0xec, 0xfd, 0xcd, - 0x35, 0xea, 0xf2, 0x2d, 0x3f, 0xcf, 0x8f, 0xf9, 0x4d, 0x27, 0x13, 0x20, 0x61, 0x8d, 0xaa, 0x0e, - 0x1c, 0x1e, 0xe1, 0x60, 0xd6, 0x97, 0xba, 0x81, 0x12, 0x8f, 0x08, 0x98, 0xbc, 0x33, 0xd2, 0xa7, - 0xb6, 0x2d, 0x89, 0x5d, 0xf3, 0x9f, 0x5d, 0xff, 0x95, 0x0d, 0xb9, 0x17, 0x86, 0xd6, 0x5e, 0x40, - 0x6a, 0x08, 0x97, 0xf9, 0xd7, 0x52, 0x54, 0x87, 0x6a, 0x61, 0xe6, 0xcd, 0x41, 0x6f, 0x0d, 0xff, - 0xa9, 0x25, 0xde, 0xde, 0xcc, 0xe7, 0xcb, 0xd2, 0x33, 0x2c, 0x8c, 0x4a, 0xbc, 0xae, 0x65, 0x75, - 0xec, 0x66, 0xb3, 0xaa, 0x82, 0xb4, 0xb4, 0xec, 0xb2, 0x93, 0x87, 0xed, 0xcd, 0x61, 0x6d, 0xef, - 0x5a, 0x3b, 0x37, 0x05, 0x89, 0xa1, 0x8a, 0x52, 0x31, 0xad, 0x06, 0x9b, 0x2e, 0x93, 0x27, 0x52, - 0xa7, 0xa4, 0x86, 0xeb, 0x86, 0x1f, 0x4e, 0x5b, 0xbf, 0x4c, 0xba, 0x96, 0xcd, 0x3f, 0x2d, 0x07, - 0xa8, 0xfe, 0xf8, 0xb6, 0xe5, 0x52, 0x47, 0x47, 0x7e, 0x51, 0x47, 0xe3, 0x93, 0xc2, 0x81, 0xd1, - 0xcd, 0x0f, 0xcc, 0x9b, 0x16, 0x3d, 0x78, 0xd5, 0xe6, 0x1c, 0x29, 0x63, 0xf7, 0xdb, 0x62, 0x53, - 0xac, 0x48, 0x26, 0x72, 0x4a, 0x43, 0x14, 0xa9, 0x42, 0x79, 0x96, 0x63, 0x3e, 0xe2, 0x10, 0xc6, - 0xf6, 0x50, 0x63, 0x43, 0x9e, 0x47, 0x94, 0xf1, 0x2e, 0x04, 0xa2, 0x34, 0x6b, 0x70, 0x8f, 0x9a, - 0xf8, 0xb1, 0x84, 0x19, 0x1b, 0xd8, 0x47, 0x1f, 0x75, 0x9a, 0x81, 0x61, 0xd0, 0x0a, 0xc9, 0x1e, - 0x2c, 0x31, 0xba, 0xdb, 0xb7, 0x41, 0x95, 0x5b, 0x81, 0x6e, 0xb4, 0x39, 0x14, 0x2d, 0xfa, 0x74, - 0xb6, 0xa8, 0x5d, 0x92, 0x64, 0x96, 0xaa, 0xd2, 0x61, 0xa9, 0x2a, 0x09, 0x22, 0x0b, 0xaf, 0x8d, - 0x13, 0x8a, 0x3e, 0xfa, 0x65, 0x97, 0x78, 0x2f, 0x15, 0xe1, 0x66, 0xb8, 0xa1, 0x17, 0xfe, 0xc0, - 0xf6, 0xb8, 0xac, 0x1a, 0x9f, 0x7e, 0x73, 0xff, 0xd7, 0x7e, 0xb9, 0x04, 0x29, 0x6f, 0x81, 0x07, - 0x44, 0x89, 0x32, 0x10, 0x8b, 0x60, 0x75, 0x01, 0x18, 0x42, 0xdd, 0x72, 0xbf, 0xc6, 0x42, 0x10, - 0x69, 0x0f, 0xe5, 0xe7, 0x20, 0x65, 0xda, 0x94, 0x59, 0x8e, 0x6f, 0xb6, 0xb4, 0xaa, 0xe3, 0xb5, - 0x94, 0x47, 0x75, 0xc4, 0xc0, 0xb2, 0x28, 0xaf, 0xc0, 0x08, 0x3a, 0x37, 0x18, 0x41, 0xcc, 0xbc, - 0xcd, 0xa8, 0x63, 0x41, 0xd9, 0x6c, 0x32, 0xbe, 0xf6, 0xc7, 0x4d, 0x26, 0x9c, 0x26, 0x13, 0x44, - 0x3c, 0xe5, 0x34, 0x19, 0x57, 0x11, 0xbd, 0xe6, 0xd9, 0xaa, 0xe3, 0x60, 0x83, 0x55, 0x86, 0x7b, - 0xc3, 0x32, 0x41, 0xe1, 0xc9, 0xda, 0xba, 0x94, 0x85, 0x17, 0x7a, 0x4a, 0x09, 0x81, 0x40, 0x7e, - 0xf9, 0x15, 0x67, 0x19, 0x2e, 0x16, 0xa5, 0x85, 0x27, 0xe0, 0xfa, 0xdd, 0x96, 0xf6, 0xe2, 0xc9, - 0x1c, 0x73, 0xee, 0x94, 0xd5, 0x93, 0x43, 0x79, 0x6f, 0x96, 0x6b, 0x31, 0x8f, 0xb3, 0x75, 0x98, - 0xc7, 0x58, 0xc3, 0x70, 0x2b, 0x96, 0x3e, 0x07, 0x2e, 0xc0, 0x31, 0xf4, 0x96, 0x65, 0xd2, 0x73, - 0x91, 0x8e, 0xaf, 0x13, 0xeb, 0x55, 0x0d, 0xf1, 0xd8, 0x1e, 0x0f, 0x35, 0xec, 0xe3, 0xd9, 0x5d, - 0xe1, 0xc0, 0xc2, 0x61, 0xd7, 0xe2, 0x88, 0x24, 0x77, 0x68, 0xf4, 0xf8, 0x8f, 0xad, 0x81, 0x96, - 0x61, 0xb3, 0xa1, 0x93, 0x1b, 0x0e, 0x62, 0x34, 0x61, 0x35, 0x3c, 0x4f, 0x4b, 0x24, 0x37, 0xcb, - 0x60, 0x28, 0xdf, 0x46, 0x69, 0x70, 0x9d, 0x44, 0xa3, 0x20, 0xcf, 0xa2, 0x3c, 0x18, 0x17, 0x49, - 0xd4, 0x5a, 0x6f, 0x62, 0x85, 0xd3, 0x78, 0xd0, 0xd0, 0x23, 0xc9, 0x62, 0xa1, 0x68, 0x6d, 0x5a, - 0xe0, 0x63, 0x27, 0x1b, 0xc0, 0xc7, 0x5e, 0xac, 0x87, 0x8f, 0x0d, 0x66, 0xed, 0x71, 0x10, 0xf6, - 0x59, 0x75, 0x43, 0x41, 0xc3, 0x02, 0x72, 0x8e, 0x27, 0x01, 0xff, 0x86, 0x1c, 0xe2, 0x0b, 0xf9, - 0x3b, 0x9f, 0xc6, 0xb3, 0x05, 0xff, 0x84, 0x91, 0x41, 0x17, 0xbc, 0x98, 0x10, 0x5a, 0xb8, 0xf7, - 0x02, 0x0a, 0xdb, 0xa4, 0x2f, 0x3d, 0x14, 0x57, 0x8f, 0xa1, 0x01, 0x2f, 0x28, 0x75, 0xc4, 0xea, - 0xac, 0x8e, 0x58, 0x2d, 0xdd, 0x26, 0x1a, 0x36, 0xed, 0x60, 0xd4, 0xf4, 0x2b, 0x68, 0xfa, 0x21, - 0xa7, 0xe4, 0x64, 0x3c, 0xed, 0xa6, 0x87, 0x25, 0xde, 0x74, 0x7c, 0x78, 0x48, 0x8f, 0x08, 0x51, - 0x5d, 0xe1, 0x71, 0x20, 0x52, 0x92, 0xca, 0x32, 0xa6, 0x28, 0x7c, 0xe1, 0xf6, 0x30, 0xe3, 0xe8, - 0xa3, 0xdd, 0xd6, 0x2c, 0x8f, 0xb2, 0x46, 0x26, 0xc6, 0x31, 0x02, 0xdf, 0x10, 0x24, 0xad, 0x9b, - 0x90, 0x34, 0x7d, 0xa3, 0x87, 0x87, 0xad, 0x46, 0x38, 0x52, 0x0e, 0xda, 0x79, 0x75, 0x2e, 0xd4, - 0x4a, 0x28, 0x01, 0x3b, 0x5a, 0x87, 0x66, 0xca, 0x43, 0x73, 0xc4, 0x03, 0x89, 0x7c, 0xd2, 0xd3, - 0x43, 0x06, 0xe8, 0xb6, 0xb6, 0x37, 0x07, 0x33, 0xbc, 0x6c, 0x60, 0x86, 0x0f, 0xf8, 0x92, 0xbd, - 0xa1, 0xa8, 0x53, 0xad, 0x5b, 0x34, 0x5b, 0xbc, 0xd9, 0xba, 0xb9, 0x6c, 0xdd, 0xfc, 0xb0, 0xe2, - 0xe6, 0xca, 0x8f, 0xaa, 0x46, 0xc3, 0x28, 0x8d, 0x40, 0xa5, 0x5b, 0xb7, 0x50, 0x9d, 0x51, 0xac, - 0xee, 0x0c, 0x6a, 0x47, 0x1e, 0x92, 0x04, 0xe6, 0x12, 0xe7, 0x81, 0x7a, 0xcc, 0x67, 0x1f, 0xe3, - 0x62, 0x81, 0xd5, 0x9c, 0x34, 0x21, 0x98, 0xa9, 0xf1, 0x1b, 0x2b, 0xe5, 0x64, 0x0d, 0x1c, 0xbb, - 0x33, 0x71, 0xb2, 0xf5, 0x13, 0x27, 0xd1, 0x13, 0xa7, 0x52, 0xc5, 0x82, 0x89, 0x53, 0xca, 0xdf, - 0x30, 0x71, 0xb2, 0x80, 0x3a, 0xa5, 0x0e, 0x3d, 0x8d, 0xe0, 0x26, 0x14, 0xa5, 0x72, 0x21, 0xbd, - 0x6d, 0x58, 0x6a, 0x74, 0x7d, 0xd2, 0x1e, 0x96, 0xce, 0x44, 0x4b, 0x5c, 0x9f, 0x14, 0x39, 0xcf, - 0x0c, 0xff, 0xe3, 0xb0, 0x4d, 0xc0, 0x00, 0x69, 0xe2, 0x0a, 0x15, 0x8f, 0xd7, 0xb0, 0xf9, 0x25, - 0x20, 0x89, 0x19, 0x9b, 0x0e, 0xbc, 0x91, 0xae, 0x10, 0x70, 0x64, 0xda, 0x42, 0x2f, 0x07, 0x95, - 0xd5, 0xee, 0x6e, 0xb0, 0x6c, 0x1b, 0xc6, 0x61, 0x07, 0x1b, 0x8a, 0xef, 0x6c, 0xb8, 0xd5, 0x2f, - 0xe2, 0x76, 0xc5, 0xde, 0x8d, 0x2b, 0xe5, 0xd2, 0x25, 0xbe, 0xb6, 0x77, 0x63, 0x56, 0x1f, 0x57, - 0xe5, 0xf5, 0xd1, 0xcd, 0xea, 0xe3, 0xf2, 0x9c, 0x7e, 0x4a, 0x56, 0xe4, 0x03, 0xeb, 0xf6, 0xb2, - 0x9d, 0xa5, 0x99, 0xcf, 0xaa, 0x02, 0x5d, 0xbb, 0x05, 0xba, 0x5e, 0x55, 0xa0, 0x5e, 0x7f, 0x55, - 0x46, 0xbd, 0xbe, 0x9b, 0x53, 0x8f, 0xce, 0xb7, 0x52, 0x6f, 0x76, 0x8c, 0xda, 0x9c, 0x7a, 0x86, - 0xa7, 0xab, 0x6a, 0x58, 0xba, 0x35, 0x2c, 0x93, 0x75, 0xb9, 0x7d, 0x98, 0xad, 0xc8, 0xad, 0x9a, - 0x45, 0xcb, 0x06, 0x6c, 0x3d, 0x1f, 0x3a, 0x7d, 0xa1, 0x7a, 0xed, 0x71, 0xe7, 0xaf, 0xa5, 0x43, - 0x4e, 0x54, 0x51, 0xd5, 0xa8, 0xb9, 0xb8, 0x3c, 0xb9, 0x2b, 0x56, 0x94, 0x17, 0xb6, 0xe4, 0xad, - 0x47, 0x9c, 0x01, 0x5a, 0xf2, 0xff, 0xb1, 0x58, 0xd5, 0xba, 0x1b, 0xed, 0xf6, 0xee, 0x9d, 0xc1, - 0xcb, 0xf4, 0x6d, 0x21, 0xc4, 0x1f, 0x42, 0x5f, 0x0d, 0xb7, 0x4e, 0xda, 0x73, 0xbc, 0x32, 0xe9, - 0x55, 0x1e, 0x2c, 0xe8, 0x0c, 0x60, 0x44, 0x0e, 0x3d, 0x7c, 0xaa, 0x06, 0x31, 0x5c, 0x04, 0xe6, - 0xca, 0xa6, 0xb0, 0x6e, 0x23, 0xcb, 0x0b, 0x97, 0x8d, 0x7b, 0x9c, 0x5d, 0xc8, 0x16, 0xfd, 0x4e, - 0xe1, 0x34, 0xe9, 0xaf, 0x38, 0x73, 0x57, 0x6f, 0xff, 0xa5, 0x0b, 0xc3, 0xb7, 0xae, 0x63, 0x31, - 0xb4, 0x20, 0x35, 0xea, 0xf0, 0x18, 0xdb, 0x0a, 0x1e, 0xa3, 0x8e, 0x1c, 0x1b, 0xc9, 0xa1, 0xb0, - 0xad, 0xf9, 0x5f, 0xeb, 0x49, 0xcf, 0x97, 0x25, 0xad, 0x03, 0x0d, 0x5b, 0x28, 0xb3, 0x2d, 0x23, - 0x62, 0x7a, 0x6f, 0x5a, 0x1d, 0x96, 0xea, 0xe9, 0xfd, 0x85, 0x98, 0x9a, 0x0b, 0x2a, 0xf4, 0x58, - 0xef, 0x4a, 0x8d, 0x88, 0xfc, 0xa8, 0x8a, 0x2a, 0x2a, 0xbc, 0x56, 0x70, 0xe4, 0x4d, 0xaa, 0xbb, - 0x32, 0x83, 0xc7, 0x55, 0x1a, 0x92, 0x45, 0xa2, 0x5e, 0x2d, 0x1c, 0x9e, 0xb5, 0xd1, 0xd9, 0x18, - 0x93, 0x4d, 0x34, 0x3c, 0xbf, 0x3e, 0xce, 0x11, 0xd1, 0xa6, 0xdb, 0x36, 0xca, 0xcb, 0xfb, 0xd6, - 0xbc, 0x1c, 0x7c, 0xac, 0xc6, 0xb4, 0xd1, 0xf8, 0x58, 0xad, 0x59, 0x26, 0xed, 0x59, 0x36, 0x40, - 0xb5, 0x1a, 0xd9, 0x32, 0xae, 0x0e, 0xf4, 0xa0, 0x04, 0x05, 0x44, 0xc1, 0xfd, 0xe1, 0x41, 0x1c, - 0xed, 0xfb, 0xee, 0x24, 0x5a, 0x2c, 0xea, 0x1b, 0xbc, 0x42, 0xd4, 0x22, 0xfc, 0x19, 0xb9, 0x79, - 0xef, 0x53, 0xef, 0xf3, 0xdc, 0x9a, 0xec, 0xc7, 0x65, 0xd4, 0xb7, 0x03, 0xfa, 0x10, 0x20, 0x7f, - 0xf6, 0x60, 0x47, 0xaf, 0x4d, 0x1e, 0xa7, 0x58, 0x8c, 0x7c, 0x83, 0xc5, 0xb2, 0x00, 0x0b, 0xeb, - 0x65, 0x2b, 0x75, 0xd9, 0xe4, 0x87, 0x59, 0x16, 0xcb, 0xf7, 0xe3, 0xad, 0xad, 0x4a, 0x7e, 0x5a, - 0x06, 0xf5, 0x29, 0x48, 0x3e, 0xf4, 0xf0, 0x21, 0xa8, 0x89, 0x6a, 0xce, 0xe7, 0xdf, 0xe5, 0xcd, - 0x05, 0x10, 0x27, 0xbd, 0xa8, 0x4f, 0x00, 0x3a, 0x4f, 0x58, 0xa2, 0x3d, 0x62, 0x14, 0x2e, 0x90, - 0x39, 0x42, 0xa9, 0x6f, 0xba, 0x28, 0x8f, 0xca, 0xdb, 0xf0, 0xca, 0x0d, 0x01, 0x11, 0x4b, 0xb4, - 0x4b, 0xc2, 0x1d, 0x9e, 0xd8, 0xec, 0x27, 0x83, 0x2b, 0x72, 0x82, 0xea, 0x4b, 0xe1, 0xf9, 0x87, - 0x31, 0xf1, 0x4e, 0x60, 0xf6, 0xb0, 0x3e, 0x2e, 0x02, 0xe9, 0x73, 0x2e, 0x79, 0xbb, 0xaa, 0x40, - 0xa5, 0xf6, 0x8d, 0xff, 0xe5, 0xef, 0xa9, 0xf9, 0x9d, 0xe1, 0x05, 0x4b, 0xa7, 0x3c, 0xb0, 0xfa, - 0xe5, 0x19, 0x62, 0x4d, 0x07, 0xd6, 0xb1, 0xe6, 0x5d, 0x3e, 0xc2, 0xeb, 0x1c, 0x52, 0x57, 0xda, - 0xf1, 0x76, 0x94, 0x0f, 0xc1, 0x8e, 0xd7, 0xe9, 0x12, 0x93, 0xa6, 0xef, 0xad, 0x58, 0xf1, 0xc8, - 0x96, 0xa9, 0x00, 0x63, 0xa1, 0xaf, 0x66, 0xc7, 0x75, 0x57, 0x4d, 0xb6, 0xc6, 0xea, 0x15, 0xdc, - 0x87, 0x6a, 0x1f, 0x1f, 0xf6, 0x88, 0x51, 0xe3, 0x38, 0x5e, 0x66, 0x64, 0x05, 0x61, 0xeb, 0xf8, - 0xa8, 0x7f, 0x10, 0xfa, 0x30, 0xbf, 0x0b, 0x28, 0xa5, 0x74, 0x9a, 0x3f, 0x7e, 0x0d, 0xa7, 0x2e, - 0x58, 0x02, 0xc6, 0xa2, 0x83, 0x06, 0xdb, 0x1c, 0x64, 0x19, 0x51, 0x96, 0x7b, 0x8a, 0x79, 0x06, - 0x41, 0xb1, 0xba, 0xb3, 0xf7, 0x96, 0x66, 0x8c, 0x94, 0x4e, 0xf2, 0xcb, 0xf8, 0xc5, 0xf7, 0x71, - 0xb7, 0x1a, 0x7a, 0xda, 0x61, 0xdd, 0x33, 0xee, 0xf8, 0xfe, 0xce, 0xec, 0x58, 0x41, 0x45, 0xce, - 0x8d, 0x34, 0xd9, 0xa6, 0x5f, 0xf3, 0xab, 0x21, 0x1c, 0xac, 0x95, 0x2a, 0xd9, 0x38, 0x77, 0x06, - 0x25, 0xb7, 0x2f, 0xfe, 0xc5, 0x66, 0x8e, 0x90, 0x91, 0x65, 0x6c, 0x95, 0x86, 0xdc, 0xa7, 0x2c, - 0xa1, 0x1a, 0x06, 0xa6, 0xfd, 0xba, 0x6c, 0xbe, 0x9e, 0x38, 0xaf, 0x27, 0x57, 0x9f, 0x1b, 0xce, - 0xb9, 0xd2, 0xab, 0x06, 0x4f, 0xc2, 0x84, 0x49, 0x55, 0x0b, 0xe5, 0xba, 0x13, 0x6e, 0xb8, 0xf4, - 0x82, 0x69, 0xe9, 0x1e, 0x2b, 0x26, 0xe2, 0xd3, 0x50, 0x5b, 0x1a, 0x36, 0xcb, 0x73, 0x65, 0xc1, - 0xd7, 0xc2, 0x66, 0x55, 0x7c, 0x99, 0x97, 0x36, 0x2a, 0x6c, 0xe6, 0x2f, 0x18, 0x51, 0x81, 0xc7, - 0x41, 0x89, 0x03, 0x1a, 0x4e, 0xec, 0x06, 0xda, 0xcc, 0x11, 0x4a, 0x4c, 0xa6, 0x68, 0xd1, 0x75, - 0x38, 0x51, 0x88, 0xf8, 0xf7, 0xc5, 0x8b, 0x41, 0x87, 0x27, 0x41, 0x87, 0x34, 0xd7, 0x9d, 0x2f, - 0x88, 0x56, 0x60, 0xf9, 0x1c, 0x74, 0xe8, 0xea, 0x01, 0xa3, 0x9d, 0x58, 0x13, 0x67, 0xee, 0xf9, - 0x47, 0xbb, 0xbd, 0x47, 0x7f, 0xea, 0xf4, 0x0b, 0x1c, 0x5c, 0xee, 0x25, 0x88, 0x5d, 0x92, 0x75, - 0x26, 0xcc, 0x22, 0x8b, 0xd5, 0xb3, 0x3f, 0xca, 0x9f, 0x23, 0x60, 0xb7, 0xc6, 0x54, 0xfd, 0xb3, - 0xd5, 0x93, 0x7a, 0x7e, 0x02, 0x1e, 0x80, 0x73, 0x9b, 0x80, 0x81, 0x3d, 0x45, 0xa7, 0xc6, 0xeb, - 0xfc, 0x22, 0x99, 0x7e, 0xc1, 0x69, 0x49, 0xe8, 0x05, 0x3c, 0x37, 0xe1, 0x4c, 0xc5, 0x03, 0x0b, - 0xfe, 0xcc, 0x70, 0xe2, 0xc5, 0xb3, 0x63, 0x18, 0x23, 0x20, 0x5c, 0xbd, 0xb7, 0x60, 0x60, 0xce, - 0xa5, 0xbf, 0x8d, 0xd1, 0x0c, 0xd8, 0x6c, 0xcf, 0x25, 0x2c, 0x11, 0x20, 0x1e, 0xdb, 0x0b, 0xc0, - 0xe9, 0x88, 0x50, 0xa5, 0x71, 0xe2, 0xf3, 0x94, 0x9f, 0x1d, 0x37, 0xe7, 0x7c, 0x89, 0xc8, 0xf2, - 0xf9, 0x90, 0x2f, 0xba, 0x7c, 0x9a, 0x1d, 0x9f, 0xc1, 0x42, 0xee, 0xdc, 0x8c, 0x81, 0x20, 0x2e, - 0x54, 0x33, 0x38, 0x6f, 0x06, 0xdd, 0x36, 0x83, 0xd0, 0x6b, 0x15, 0x66, 0x8c, 0xf9, 0xc0, 0x3c, - 0x8b, 0x66, 0xef, 0x03, 0x18, 0x48, 0x91, 0xb7, 0xac, 0xb5, 0x10, 0xed, 0x50, 0x08, 0x6e, 0xa3, - 0x4c, 0xdc, 0xa5, 0x5f, 0x68, 0x3d, 0xba, 0x50, 0x3d, 0xb6, 0xe7, 0xc1, 0xee, 0x85, 0x43, 0x11, - 0x67, 0xbe, 0xfe, 0x10, 0x0e, 0x4d, 0x0a, 0xc5, 0x2a, 0xfd, 0x9e, 0x3a, 0xef, 0xa0, 0x71, 0x30, - 0xcc, 0xb7, 0x20, 0x51, 0x24, 0x4a, 0x09, 0x36, 0x87, 0x31, 0x84, 0x04, 0x75, 0x40, 0x93, 0xd9, - 0x75, 0xf5, 0x0e, 0x5a, 0x13, 0x89, 0xbb, 0x2c, 0x68, 0x13, 0x09, 0x67, 0x66, 0x23, 0x8a, 0xb0, - 0x5f, 0xa8, 0x5a, 0x30, 0x89, 0x50, 0x57, 0xdd, 0xef, 0xc0, 0x77, 0x6a, 0x20, 0xb9, 0xa1, 0x78, - 0xa3, 0xdb, 0x1e, 0x45, 0x9b, 0x7b, 0x92, 0x7a, 0x8c, 0x5e, 0x4d, 0xa2, 0x01, 0x94, 0x7b, 0x50, - 0xcb, 0xb7, 0xf7, 0x98, 0x7c, 0xf7, 0x25, 0xf9, 0x24, 0x5e, 0x42, 0xf5, 0xcc, 0x4a, 0xb9, 0x72, - 0x25, 0x5c, 0xa6, 0x18, 0x55, 0x05, 0x72, 0xf7, 0x5a, 0x95, 0x11, 0xee, 0xed, 0xb5, 0xdb, 0x22, - 0x6d, 0x66, 0x8f, 0x0b, 0xd4, 0x50, 0x0e, 0x9c, 0x36, 0x9c, 0x64, 0xd3, 0x61, 0xd7, 0xcd, 0xf3, - 0x02, 0x35, 0xf6, 0x0b, 0xdf, 0x1d, 0x71, 0x88, 0xbb, 0xd6, 0xe8, 0x61, 0xdb, 0x60, 0xb5, 0xd4, - 0x5c, 0x45, 0x57, 0x17, 0xd8, 0x46, 0x32, 0x69, 0x62, 0x39, 0x3f, 0xa2, 0x39, 0x5d, 0xcf, 0x9a, - 0x2d, 0x4c, 0x6b, 0xd5, 0x02, 0x0e, 0x66, 0x8e, 0x02, 0xde, 0x60, 0xa8, 0xcd, 0x11, 0x08, 0x2f, - 0x16, 0xb6, 0x72, 0x7d, 0x19, 0xfa, 0x2c, 0x29, 0xba, 0xfd, 0x36, 0xfb, 0xda, 0xfd, 0x3d, 0x91, - 0xa7, 0x0c, 0x90, 0x68, 0xb9, 0x5e, 0x55, 0xf9, 0x0e, 0xc7, 0xf8, 0x09, 0x71, 0xc4, 0x74, 0x8b, - 0xcb, 0xf1, 0x69, 0x55, 0x74, 0x2b, 0x0b, 0x45, 0x16, 0xa6, 0x08, 0x2c, 0x85, 0x13, 0x24, 0x91, - 0xe1, 0x76, 0x50, 0x1b, 0x4d, 0x9d, 0x56, 0x25, 0x70, 0xd9, 0x7b, 0xa4, 0x3e, 0xca, 0xa8, 0xc8, - 0x1c, 0x64, 0xda, 0xa5, 0xf4, 0x40, 0xc8, 0xfb, 0x53, 0xc7, 0x00, 0x25, 0xd8, 0x30, 0x14, 0xd3, - 0xae, 0x10, 0xb3, 0x59, 0xdf, 0x73, 0x79, 0x25, 0x01, 0x3f, 0xbd, 0x02, 0xd6, 0x6c, 0x64, 0xa7, - 0x9c, 0xc3, 0x79, 0x72, 0x7e, 0x15, 0xc1, 0xb6, 0x0c, 0xff, 0xdf, 0x46, 0x68, 0x8b, 0x02, 0xb9, - 0xdd, 0xbe, 0x31, 0x73, 0x10, 0xba, 0xe4, 0xce, 0x3b, 0x88, 0x41, 0x78, 0x91, 0xcf, 0xc5, 0xde, - 0x95, 0x1d, 0x6d, 0xff, 0x79, 0x2d, 0x9e, 0xbf, 0xb8, 0x83, 0x36, 0x17, 0x5d, 0x0a, 0x1c, 0x8d, - 0xcb, 0x2e, 0x24, 0xd8, 0xa5, 0x12, 0xf9, 0x87, 0x98, 0x05, 0x17, 0x0e, 0x02, 0x17, 0xa6, 0x2d, - 0x05, 0x23, 0xee, 0x62, 0x93, 0xa1, 0x1b, 0x50, 0x9d, 0x02, 0x4c, 0xb7, 0x9b, 0xc4, 0x94, 0xb0, - 0x5b, 0x18, 0xba, 0x61, 0xe0, 0x52, 0x2d, 0x69, 0x40, 0xee, 0x22, 0x70, 0x79, 0x96, 0xf4, 0x8b, - 0xcb, 0xc0, 0x25, 0x59, 0x32, 0x10, 0xde, 0x3c, 0x80, 0xe0, 0x78, 0x6f, 0x7f, 0xe2, 0x4a, 0xdc, - 0x9f, 0x92, 0xed, 0xc3, 0xb2, 0x82, 0xf4, 0x1a, 0x0a, 0xbc, 0xda, 0x80, 0xfb, 0x84, 0x23, 0xd2, - 0xee, 0xc5, 0x41, 0xc6, 0x9b, 0xcd, 0x0e, 0xec, 0x95, 0x55, 0x7e, 0x2a, 0xb3, 0x79, 0xee, 0xfb, - 0x9a, 0x41, 0x69, 0xa2, 0x4b, 0x52, 0x9a, 0xb0, 0x6c, 0xba, 0x1e, 0xe5, 0x6a, 0xdf, 0xf7, 0x24, - 0xe9, 0x8c, 0x53, 0xec, 0x1b, 0x11, 0x8c, 0x9c, 0x90, 0x72, 0x54, 0x49, 0x67, 0x90, 0x20, 0x69, - 0x0e, 0x53, 0xbb, 0x19, 0xff, 0xae, 0x8b, 0x92, 0x3a, 0xb0, 0xc5, 0x06, 0x31, 0xd8, 0x0e, 0xfe, - 0x55, 0x07, 0x27, 0x20, 0xa2, 0x24, 0x45, 0xbe, 0xf7, 0x8a, 0x4b, 0x50, 0xde, 0x7e, 0xc8, 0x7f, - 0xb9, 0x1c, 0x77, 0x61, 0xa4, 0xa5, 0x30, 0xd2, 0x60, 0x94, 0xa9, 0xb1, 0x56, 0xcf, 0xb5, 0xe5, - 0xae, 0x6f, 0x3b, 0x35, 0xa8, 0xb7, 0x84, 0x6e, 0xf4, 0x9b, 0xd1, 0x68, 0xd4, 0xd9, 0xed, 0x1d, - 0x7c, 0x17, 0x74, 0x90, 0xd9, 0x1b, 0xbd, 0x93, 0x8b, 0x1d, 0x2f, 0xc0, 0xbf, 0x97, 0xf2, 0xef, - 0x18, 0xb6, 0x70, 0x5c, 0x8e, 0x56, 0x94, 0x70, 0xd4, 0x56, 0xbe, 0x5f, 0xff, 0x92, 0xf2, 0x85, - 0x61, 0xb8, 0x59, 0xf9, 0xac, 0x2f, 0xff, 0x43, 0x37, 0xac, 0xdd, 0x5b, 0x9f, 0x45, 0x0a, 0xa7, - 0x13, 0x33, 0x4b, 0x60, 0x98, 0xf0, 0xad, 0x7d, 0x7f, 0xde, 0x03, 0xe1, 0x8f, 0x15, 0x5f, 0x9f, - 0xc5, 0x17, 0xe4, 0x99, 0x78, 0xf2, 0x04, 0xa9, 0x34, 0x08, 0x8e, 0xd0, 0x5e, 0x3a, 0xe5, 0x35, - 0x7f, 0xd1, 0x9a, 0x42, 0x1b, 0x57, 0x4c, 0x0a, 0x9d, 0x89, 0x4d, 0xfa, 0x63, 0x0f, 0xd9, 0x41, - 0xc3, 0x68, 0x68, 0xe6, 0xca, 0x73, 0x1f, 0x51, 0x5a, 0xf9, 0x80, 0xac, 0xa7, 0xbc, 0xf7, 0x0d, - 0x62, 0x1f, 0xdb, 0x58, 0x8f, 0x30, 0x15, 0xe4, 0x81, 0x99, 0xd4, 0xcd, 0x26, 0xe2, 0x74, 0x3a, - 0x1a, 0x85, 0xa1, 0x67, 0x30, 0x32, 0x57, 0x4c, 0xb3, 0x98, 0x51, 0x2e, 0x2b, 0x7f, 0x18, 0x92, - 0x61, 0x52, 0x2e, 0x2a, 0xfd, 0x9a, 0xac, 0xaa, 0x96, 0x1d, 0xb9, 0x7d, 0x22, 0xe4, 0x9c, 0x1e, - 0x14, 0x68, 0x14, 0x91, 0x16, 0x05, 0x10, 0xc4, 0x9c, 0xf9, 0x03, 0xf2, 0x6d, 0xe5, 0x47, 0xb5, - 0xa0, 0x57, 0x57, 0x23, 0xd8, 0xde, 0x52, 0x68, 0x8f, 0xf2, 0x16, 0x3a, 0x12, 0xfe, 0x0f, 0x97, - 0x2e, 0xd9, 0x5f, 0xc3, 0x04, 0x57, 0xeb, 0x0d, 0xe8, 0x8b, 0xd5, 0x05, 0xb9, 0x72, 0x86, 0xd2, - 0xdf, 0x8d, 0xda, 0xc3, 0xc9, 0xe7, 0x74, 0x6d, 0x3e, 0xa5, 0xd7, 0xba, 0x04, 0xd4, 0xf2, 0xf9, - 0x75, 0x6d, 0x3e, 0xb7, 0x5e, 0xeb, 0x9a, 0x51, 0xcb, 0xe7, 0x1f, 0xcd, 0x7c, 0xba, 0x73, 0x1e, - 0xf1, 0x51, 0xdb, 0xcc, 0x58, 0xd4, 0xd2, 0xe3, 0x64, 0x76, 0x46, 0x69, 0x6d, 0x5f, 0x08, 0xaa, - 0xb8, 0x6d, 0x57, 0x90, 0x86, 0xab, 0xfa, 0x9e, 0x30, 0x30, 0x83, 0xe5, 0x1c, 0xa7, 0xad, 0xf1, - 0x2e, 0x23, 0x84, 0x8c, 0x73, 0x76, 0xeb, 0xc9, 0x5a, 0x4f, 0x1c, 0xf5, 0xb1, 0x59, 0xc4, 0x22, - 0xa8, 0x87, 0x5d, 0x22, 0x1d, 0x42, 0x2d, 0x6c, 0x1c, 0x97, 0x0a, 0x7f, 0x5e, 0xbe, 0xaa, 0x55, - 0xf1, 0x37, 0xd7, 0x4f, 0x57, 0x1f, 0x06, 0x82, 0xf6, 0x93, 0x4f, 0xd5, 0x98, 0x23, 0x42, 0xd5, - 0x99, 0xbf, 0x22, 0x23, 0xb8, 0x83, 0x4f, 0xd4, 0x74, 0x63, 0x72, 0x66, 0xcc, 0x97, 0x9f, 0xb0, - 0xc8, 0xda, 0x1a, 0x64, 0x41, 0x0a, 0xbb, 0x4e, 0xed, 0x9b, 0xb0, 0xdd, 0x84, 0x78, 0x26, 0x15, - 0x88, 0x6c, 0x05, 0x3d, 0xf4, 0x63, 0x0a, 0xab, 0x66, 0x17, 0x81, 0xc6, 0xd7, 0x0e, 0x19, 0xa2, - 0xe9, 0xee, 0x6f, 0x61, 0x52, 0x43, 0x84, 0xd8, 0x4d, 0x5a, 0xf5, 0x6f, 0xfa, 0x28, 0xe5, 0x2b, - 0xab, 0x63, 0xfd, 0xa4, 0x30, 0x82, 0x5e, 0x28, 0x15, 0x69, 0x5f, 0xbe, 0x57, 0x44, 0x49, 0x30, - 0x82, 0x4e, 0xc8, 0x4c, 0xd0, 0x25, 0x05, 0x8d, 0xe3, 0xd4, 0x04, 0x8d, 0x29, 0x08, 0x96, 0x96, - 0x7a, 0x83, 0xd1, 0x47, 0x94, 0x59, 0x1f, 0x3e, 0x12, 0x7d, 0xfa, 0x74, 0x16, 0xd0, 0x7f, 0x67, - 0x8b, 0x85, 0x34, 0x7b, 0x23, 0xa9, 0x00, 0xc5, 0x8e, 0x3f, 0x71, 0xe3, 0x24, 0x67, 0x75, 0xb3, - 0xb6, 0xa3, 0x6f, 0x1d, 0xa5, 0xe8, 0x1a, 0xde, 0x6e, 0x12, 0x98, 0x4c, 0x2a, 0x5b, 0x2f, 0xed, - 0xc8, 0x03, 0xc5, 0x75, 0xf5, 0xe1, 0x32, 0xfd, 0x53, 0x16, 0x11, 0x06, 0x11, 0x3d, 0xd7, 0x9c, - 0xf7, 0x62, 0xf1, 0x14, 0xe5, 0xc3, 0x0f, 0x71, 0xff, 0x7c, 0x29, 0x25, 0xbb, 0xd8, 0xc3, 0x6b, - 0x0b, 0x5d, 0x1b, 0xc5, 0xd3, 0x0b, 0xe1, 0x64, 0x19, 0x77, 0x71, 0x2d, 0x95, 0x2c, 0x3d, 0xaf, - 0x7f, 0xfe, 0xe9, 0x04, 0x8b, 0x5b, 0xf8, 0xac, 0x12, 0x79, 0x8b, 0xeb, 0x0d, 0x2f, 0xf7, 0x22, - 0xa0, 0xbb, 0x33, 0x4f, 0xef, 0xaf, 0x71, 0x0c, 0xb5, 0x93, 0x6b, 0x8f, 0x26, 0x4c, 0xac, 0x8d, - 0x11, 0x25, 0x76, 0xe9, 0xb0, 0xc1, 0x89, 0x8a, 0x57, 0x66, 0xfc, 0xa8, 0x8d, 0xbd, 0x95, 0xde, - 0x2c, 0xf8, 0x44, 0x7c, 0x35, 0xb1, 0x8f, 0xc3, 0xc8, 0x15, 0xf3, 0xdf, 0xb8, 0x80, 0xca, 0x72, - 0xe2, 0x33, 0xd3, 0x0d, 0x21, 0xc9, 0xd0, 0x65, 0x52, 0x5d, 0xdd, 0x8c, 0x51, 0xd5, 0xff, 0xf4, - 0x65, 0x52, 0x4c, 0xf2, 0x3c, 0xff, 0x9c, 0x88, 0xa7, 0x48, 0x39, 0x05, 0xcd, 0xf2, 0x39, 0x41, - 0x8d, 0x43, 0x1d, 0x23, 0x5c, 0x21, 0xb9, 0x75, 0xbb, 0x57, 0x93, 0x9d, 0xb8, 0xf7, 0xc2, 0x3f, - 0xda, 0x47, 0x8c, 0xd7, 0x2e, 0x7e, 0xd6, 0x0f, 0xae, 0x26, 0x47, 0x7d, 0xf5, 0xb8, 0x1f, 0xe2, - 0x6e, 0xf8, 0xec, 0x59, 0x1c, 0x5f, 0x4d, 0x28, 0x64, 0x27, 0xde, 0xc7, 0x90, 0xf0, 0x85, 0x15, - 0x02, 0x19, 0xa8, 0x03, 0x20, 0xe2, 0x87, 0xf9, 0x8e, 0x68, 0x75, 0x7e, 0x55, 0xa2, 0x9f, 0xe9, - 0xd5, 0x64, 0x11, 0x74, 0x10, 0xad, 0x2d, 0xe8, 0x1c, 0x84, 0xdf, 0x21, 0xeb, 0x6e, 0xf0, 0x43, - 0x4f, 0xa1, 0x84, 0x67, 0xd3, 0xc2, 0x41, 0x0c, 0x86, 0x80, 0x5f, 0x48, 0x3b, 0xcb, 0xca, 0x63, - 0x7c, 0xef, 0xac, 0x91, 0x24, 0xed, 0x81, 0x24, 0xe6, 0xf9, 0x03, 0xc5, 0x6b, 0xb5, 0x5c, 0x9c, - 0xb3, 0xfd, 0x0f, 0x11, 0x53, 0x76, 0x9a, 0x14, 0xd7, 0x9d, 0x5f, 0xc4, 0x38, 0xcf, 0xa5, 0x64, - 0xdd, 0xe5, 0xef, 0xc3, 0x41, 0xbe, 0xc1, 0xd6, 0x54, 0x88, 0x69, 0xac, 0x71, 0x06, 0x95, 0x02, - 0x47, 0x15, 0xf9, 0xd4, 0x45, 0x39, 0x86, 0x33, 0x48, 0xe9, 0x2e, 0xe5, 0x45, 0xc9, 0x65, 0x54, - 0x75, 0x38, 0xf5, 0xff, 0x64, 0x69, 0xf9, 0xcb, 0xa6, 0xb0, 0xa7, 0x44, 0x36, 0xa8, 0xca, 0x10, - 0x2c, 0xc9, 0x6e, 0x5a, 0xcf, 0x8e, 0xda, 0x54, 0x5b, 0xba, 0xbd, 0x81, 0xed, 0xd3, 0x36, 0x67, - 0x17, 0x8a, 0x90, 0x6d, 0xd9, 0x9a, 0x60, 0x5c, 0xba, 0x4a, 0x9d, 0x2d, 0x18, 0x4f, 0x92, 0x6d, - 0x6f, 0x8c, 0xbd, 0x91, 0xcf, 0xe2, 0xeb, 0xbb, 0xc0, 0x0a, 0x80, 0xf4, 0xff, 0x22, 0x2d, 0x87, - 0x15, 0xe5, 0x63, 0x7c, 0x7d, 0x65, 0x43, 0xf1, 0xf7, 0x1c, 0xd7, 0x2f, 0xdb, 0x3f, 0x4e, 0xda, - 0xd0, 0x97, 0x7b, 0xe3, 0x91, 0x52, 0x46, 0x82, 0xdb, 0xbe, 0x86, 0x75, 0xda, 0xc6, 0x92, 0x9e, - 0x59, 0xe1, 0x2e, 0xf7, 0x03, 0x71, 0x84, 0x9d, 0x56, 0x79, 0x01, 0x87, 0x5d, 0x9c, 0xb7, 0xc7, - 0x95, 0xb8, 0xee, 0x7a, 0x77, 0x29, 0xf1, 0x54, 0xdc, 0x7b, 0xd2, 0xad, 0x0c, 0xcf, 0x7a, 0xac, - 0x0c, 0xb1, 0x14, 0xa2, 0x15, 0x53, 0xa9, 0xa0, 0x4f, 0xda, 0x2d, 0x5d, 0xd6, 0xc0, 0x3f, 0xaa, - 0x0b, 0xed, 0x2f, 0xc2, 0x9b, 0x19, 0x77, 0x0e, 0x32, 0x53, 0x76, 0xed, 0x73, 0xe1, 0xc2, 0x89, - 0x37, 0x5f, 0x04, 0x97, 0xda, 0xf4, 0xc6, 0x95, 0x08, 0x03, 0x09, 0xa6, 0x6b, 0x15, 0xb3, 0x6c, - 0x14, 0x33, 0xa8, 0x61, 0x36, 0xcf, 0x67, 0x91, 0x9d, 0x71, 0x70, 0x6b, 0xe3, 0xcd, 0xc2, 0xc3, - 0xa2, 0x29, 0x69, 0x07, 0xc2, 0xa1, 0xa6, 0x12, 0xc1, 0x0f, 0x3f, 0x38, 0x66, 0xaf, 0x7a, 0xc1, - 0x68, 0x65, 0x6e, 0xc3, 0x6b, 0x86, 0x0f, 0xdf, 0x0f, 0x67, 0x24, 0x3b, 0xec, 0x08, 0xdf, 0x5d, - 0x71, 0xbf, 0x02, 0xbd, 0xd9, 0x86, 0x6d, 0xde, 0x10, 0x8b, 0xb9, 0x44, 0xa5, 0x9d, 0xdd, 0xbe, - 0xae, 0x75, 0x05, 0x5a, 0xdb, 0x69, 0x24, 0xe8, 0x25, 0xc8, 0x03, 0x3d, 0x6d, 0x86, 0x75, 0xd5, - 0x5f, 0xa3, 0xf2, 0x3b, 0x3d, 0xa8, 0xfe, 0x22, 0x38, 0x08, 0x61, 0xad, 0xee, 0xae, 0x03, 0x1b, - 0xb6, 0x36, 0x44, 0x04, 0xc2, 0x26, 0xfc, 0x21, 0x3d, 0x34, 0xc5, 0x72, 0x59, 0x4c, 0xa3, 0x5a, - 0xa0, 0xce, 0x5f, 0x1e, 0x72, 0xea, 0x8e, 0xbd, 0x1a, 0xd7, 0x42, 0xc2, 0x9f, 0xae, 0x26, 0xe1, - 0x4c, 0x62, 0x6f, 0x46, 0x2e, 0x9a, 0xb0, 0xb3, 0x55, 0x20, 0x52, 0xf4, 0x06, 0xc9, 0xa1, 0x06, - 0xec, 0x49, 0x14, 0x9d, 0x42, 0x16, 0x97, 0x9f, 0x60, 0x5b, 0x4f, 0x37, 0x24, 0xad, 0x04, 0xf1, - 0xff, 0x9f, 0xb3, 0x99, 0x28, 0x5e, 0x8d, 0x10, 0x3d, 0x7d, 0x90, 0xd5, 0x4a, 0x9f, 0x6a, 0x55, - 0xba, 0xac, 0x82, 0x1b, 0x1f, 0x39, 0x1f, 0x95, 0xfb, 0x31, 0xf4, 0xb2, 0x45, 0x53, 0x98, 0x8a, - 0x51, 0xc6, 0x38, 0xe9, 0x6d, 0xf0, 0x22, 0x72, 0xfe, 0x0a, 0x3a, 0x17, 0x24, 0xf9, 0x4d, 0xe9, - 0x36, 0xa1, 0x12, 0x79, 0x90, 0x5b, 0xc2, 0x76, 0x38, 0xc6, 0x4c, 0xb0, 0xab, 0xde, 0xe0, 0xe1, - 0x81, 0x36, 0x77, 0xfe, 0xe5, 0x91, 0xc5, 0x19, 0x45, 0x16, 0x6f, 0x7a, 0x4f, 0xbe, 0xef, 0xa8, - 0x72, 0x44, 0xe2, 0xc0, 0x4c, 0x75, 0xce, 0x1e, 0x82, 0xb3, 0x30, 0xe5, 0x46, 0x92, 0x56, 0x44, - 0x8f, 0xd1, 0xd2, 0xdc, 0x6c, 0xb9, 0xa6, 0x6b, 0x20, 0xea, 0x8a, 0xe7, 0x59, 0x93, 0x70, 0x4a, - 0x19, 0xae, 0x7b, 0xce, 0x79, 0x9f, 0xb2, 0x7d, 0x7b, 0xaf, 0xd8, 0x6c, 0x84, 0x4d, 0x2d, 0x58, - 0x29, 0x66, 0x5a, 0xe5, 0x98, 0xaf, 0x24, 0xc6, 0xf0, 0x4c, 0xd7, 0x55, 0x67, 0x3c, 0x34, 0x2c, - 0xa9, 0xd3, 0xb4, 0x8a, 0x1e, 0xdd, 0x06, 0x5f, 0x5b, 0xcb, 0x0a, 0x6a, 0x59, 0x69, 0x77, 0x0c, - 0x53, 0x5b, 0x67, 0x36, 0x20, 0x8c, 0xeb, 0xa8, 0x7a, 0x59, 0x98, 0x73, 0x78, 0x80, 0x4c, 0x9a, - 0x06, 0x41, 0x0a, 0xdb, 0xc0, 0xbd, 0xd8, 0x2e, 0xf0, 0x92, 0x8e, 0xaf, 0x46, 0x29, 0x3d, 0x0d, - 0x58, 0x42, 0xce, 0xd0, 0xf4, 0x97, 0xc5, 0x74, 0xbc, 0xa6, 0xf0, 0xf8, 0x53, 0x76, 0x86, 0xc4, - 0x30, 0xdd, 0x8a, 0xe3, 0xc9, 0x4c, 0xfd, 0xc3, 0xd2, 0xd7, 0x10, 0x5e, 0x70, 0x88, 0x4a, 0x0f, - 0xcb, 0xdd, 0x6a, 0x90, 0xc2, 0xd0, 0xe7, 0x58, 0xb4, 0xd9, 0x08, 0xbe, 0x0b, 0xb4, 0xdb, 0x63, - 0xb6, 0xac, 0x46, 0x21, 0x2c, 0x8c, 0x7d, 0x7f, 0x9e, 0x39, 0xa0, 0xfb, 0x6e, 0x71, 0xaa, 0x02, - 0x4b, 0x63, 0x21, 0xec, 0xdb, 0x85, 0xb2, 0x00, 0x8c, 0xdc, 0xb2, 0xd5, 0xcb, 0x65, 0x45, 0x94, - 0xc5, 0xb3, 0x6f, 0xfc, 0x60, 0x29, 0x4d, 0xa3, 0x6a, 0x67, 0x53, 0x4b, 0xb2, 0x61, 0x87, 0x7d, - 0xe9, 0x43, 0x6d, 0x79, 0xeb, 0xe7, 0x52, 0xde, 0x93, 0xb2, 0xe2, 0x4c, 0x3a, 0x6f, 0xd7, 0xe8, - 0x9d, 0xa1, 0x45, 0x1d, 0x65, 0x73, 0xd9, 0xaa, 0x6c, 0xb6, 0xf8, 0x82, 0x05, 0x74, 0x7c, 0xe5, - 0x52, 0x30, 0xab, 0x58, 0xfa, 0x96, 0x0c, 0xef, 0xab, 0x2d, 0x77, 0x04, 0x4c, 0x8c, 0x40, 0x1c, - 0x51, 0x77, 0xaa, 0xce, 0xc6, 0x22, 0xd7, 0x53, 0x19, 0x7f, 0x24, 0x93, 0x0e, 0x81, 0x88, 0xb5, - 0x49, 0x3c, 0xf3, 0x87, 0xea, 0xce, 0x5e, 0x76, 0x16, 0xcf, 0xe4, 0x0f, 0x6d, 0xcd, 0x08, 0xcc, - 0x18, 0xd4, 0xb1, 0x08, 0x7b, 0x1b, 0xba, 0x50, 0x07, 0x48, 0xf8, 0x1e, 0xdf, 0x60, 0x05, 0xe9, - 0xb0, 0xd8, 0xc0, 0x6c, 0x65, 0x84, 0x9c, 0x63, 0xc7, 0x20, 0x96, 0x84, 0x7a, 0x5e, 0x88, 0x0f, - 0xee, 0x64, 0x84, 0xc0, 0x47, 0xea, 0xfe, 0x8f, 0xf4, 0x72, 0xb7, 0xce, 0x64, 0x7c, 0x7d, 0x28, - 0x23, 0xb2, 0x3b, 0xeb, 0xc2, 0x50, 0xa6, 0x48, 0x82, 0x96, 0xa6, 0x30, 0x5e, 0xc0, 0xb3, 0xe4, - 0x57, 0x38, 0xd7, 0x43, 0x80, 0x32, 0xaa, 0x64, 0xb6, 0x9d, 0x37, 0x4e, 0x51, 0xc7, 0x9f, 0x36, - 0xcd, 0x9d, 0x12, 0x0a, 0x9c, 0x13, 0xd4, 0x8c, 0xe3, 0xcc, 0xff, 0x40, 0x37, 0x55, 0xb2, 0xa5, - 0x26, 0x95, 0xc6, 0xdd, 0x2a, 0x46, 0x38, 0xb1, 0xd8, 0xd9, 0x97, 0xd4, 0xc0, 0xf3, 0x36, 0xb3, - 0xd2, 0x2c, 0xaa, 0x3f, 0x71, 0x3d, 0xca, 0x52, 0xc6, 0x67, 0xb4, 0x22, 0x1a, 0x65, 0x7c, 0xc3, - 0xf7, 0x67, 0x9c, 0xde, 0x14, 0xdd, 0x56, 0x9e, 0xbb, 0xe6, 0x1b, 0xdb, 0x1d, 0x87, 0xdf, 0x2e, - 0x18, 0xd9, 0xe2, 0x7f, 0x5f, 0x35, 0xf9, 0x92, 0xd4, 0xb8, 0x45, 0x52, 0xe2, 0xe0, 0x7d, 0xfc, - 0x8c, 0x66, 0x61, 0x42, 0x25, 0x81, 0x03, 0xf2, 0x7d, 0x28, 0xb9, 0x45, 0xa8, 0x72, 0xa7, 0x64, - 0x6f, 0x94, 0xad, 0x3e, 0xb0, 0x4a, 0xcf, 0xdc, 0x1c, 0x73, 0x2d, 0x32, 0x48, 0x78, 0x8d, 0x0f, - 0xf9, 0x0d, 0xf4, 0x52, 0x39, 0xac, 0x07, 0x20, 0xa9, 0x8c, 0xb0, 0x94, 0xac, 0xa3, 0xf2, 0xb8, - 0xc8, 0x09, 0xe5, 0x0e, 0x73, 0x51, 0x4b, 0x22, 0xd3, 0x61, 0x0a, 0x9b, 0x04, 0x93, 0x0e, 0x29, - 0x9a, 0x1f, 0xb2, 0xfc, 0x0d, 0xc4, 0xc9, 0xae, 0x07, 0x69, 0xb5, 0x45, 0x1c, 0xce, 0xff, 0x8a, - 0x6d, 0xd4, 0x3e, 0x8d, 0x4f, 0x3e, 0xab, 0x7d, 0x6c, 0x36, 0x41, 0x6e, 0x01, 0xb5, 0x22, 0xc1, - 0xea, 0x35, 0x2a, 0x2e, 0x85, 0x35, 0x8d, 0x69, 0xd9, 0x97, 0x81, 0xee, 0x8e, 0xab, 0xa3, 0x0c, - 0xec, 0xb9, 0x9e, 0xe5, 0xd4, 0xe6, 0x9e, 0xff, 0xf0, 0x60, 0x57, 0xa3, 0xaa, 0x3d, 0x97, 0xf0, - 0xdc, 0x85, 0xc6, 0x54, 0x4d, 0x05, 0xb9, 0xa1, 0x06, 0xfb, 0x5f, 0xba, 0x61, 0x2f, 0xdf, 0xfc, - 0xf8, 0xea, 0x7d, 0xd7, 0xab, 0x46, 0xe3, 0x09, 0x1f, 0x46, 0x41, 0x3e, 0xe7, 0x5e, 0x38, 0x93, - 0x23, 0xeb, 0x43, 0x3e, 0x0b, 0xfe, 0xf7, 0x55, 0xdb, 0x55, 0x26, 0x39, 0xbc, 0xb6, 0xba, 0xaa, - 0x6f, 0x42, 0xdf, 0x01, 0xe9, 0xa3, 0xb1, 0xcf, 0xf5, 0xe7, 0x18, 0x4f, 0x9e, 0xd4, 0xda, 0xa1, - 0x59, 0xac, 0xb8, 0xda, 0xbd, 0x47, 0x06, 0x53, 0x32, 0x35, 0xd1, 0x11, 0xb5, 0x44, 0x9e, 0xb9, - 0x9d, 0x6e, 0xf6, 0x7d, 0xf9, 0xf4, 0xee, 0x37, 0x38, 0xd5, 0xe6, 0x6f, 0x93, 0x7b, 0x71, 0x81, - 0xf8, 0x99, 0xe1, 0x16, 0xae, 0xb1, 0x5d, 0x2e, 0xee, 0x51, 0x48, 0x98, 0x5d, 0xbe, 0x0e, 0x38, - 0x24, 0xc2, 0x64, 0x0c, 0x48, 0x8f, 0xf6, 0x7a, 0x7d, 0x38, 0xb6, 0x6c, 0x52, 0x55, 0x10, 0x61, - 0xb8, 0x65, 0x20, 0x1f, 0xa8, 0x35, 0x9f, 0xba, 0xc8, 0x15, 0x2a, 0x87, 0xe3, 0x5a, 0xf5, 0xa5, - 0xeb, 0xed, 0xee, 0x26, 0x5e, 0xc0, 0xe9, 0x76, 0x11, 0x6a, 0x3c, 0x8d, 0x7b, 0xbb, 0xa9, 0xd2, - 0xb3, 0x8d, 0xf0, 0xe0, 0xf5, 0xb9, 0x94, 0x45, 0x80, 0x53, 0xc4, 0xb2, 0x3c, 0xa6, 0x5e, 0x90, - 0xfa, 0x9b, 0xb6, 0x6b, 0x0f, 0x32, 0x92, 0x33, 0xc2, 0x76, 0xe4, 0x22, 0x98, 0xfd, 0xf9, 0xdd, - 0x6f, 0xb1, 0x94, 0xc9, 0x69, 0xf9, 0x20, 0x0c, 0xee, 0x81, 0x25, 0x61, 0xd3, 0x55, 0x45, 0xd9, - 0xc0, 0x0c, 0xb0, 0x3c, 0x28, 0x5f, 0xe5, 0x29, 0x16, 0x02, 0xbf, 0x22, 0x09, 0xc9, 0x02, 0x15, - 0x36, 0x56, 0x3a, 0x66, 0x5a, 0x5f, 0x9c, 0x74, 0x32, 0xa6, 0x24, 0x49, 0x80, 0xda, 0x3f, 0x33, - 0xc9, 0x90, 0xd6, 0x59, 0x65, 0x25, 0xe9, 0x44, 0xa8, 0xa7, 0x61, 0x85, 0x40, 0xa1, 0xeb, 0x2e, - 0xbe, 0xfb, 0xad, 0xc1, 0x37, 0xc2, 0x11, 0x18, 0xb7, 0x97, 0x50, 0xe8, 0x28, 0xe0, 0x65, 0x2c, - 0x07, 0xc9, 0xcb, 0xa0, 0x5d, 0xe2, 0x9b, 0x4d, 0xae, 0xbd, 0x40, 0x46, 0x41, 0x0f, 0x06, 0xfa, - 0x05, 0xf9, 0xe3, 0x56, 0xd9, 0x7f, 0xf6, 0xe4, 0x89, 0x4a, 0x4d, 0x8a, 0x42, 0xa5, 0x8e, 0xc4, - 0x1b, 0xaa, 0xd0, 0x5c, 0xfc, 0xee, 0xc9, 0x13, 0x88, 0x0d, 0x91, 0xf7, 0xf1, 0xc7, 0x61, 0xaf, - 0x7f, 0x10, 0x0e, 0xfb, 0xfb, 0x61, 0xd4, 0x7f, 0x0e, 0x3b, 0xcc, 0x16, 0x96, 0x04, 0x43, 0x29, - 0x2f, 0x2a, 0x3b, 0xfd, 0x7e, 0x78, 0x30, 0x5f, 0xa0, 0x50, 0x7e, 0xc0, 0xf9, 0x85, 0xba, 0x26, - 0xe8, 0x79, 0xbe, 0xe1, 0x5a, 0x1f, 0x09, 0x6a, 0x5f, 0xe3, 0x6b, 0x8e, 0x27, 0x50, 0x76, 0x1b, - 0x77, 0x9f, 0xcb, 0x63, 0xc3, 0xee, 0xdb, 0x8d, 0xcf, 0x23, 0x87, 0xd9, 0xe7, 0x62, 0x55, 0x74, - 0x73, 0x13, 0x04, 0x1a, 0x02, 0xe2, 0x0d, 0xbd, 0x10, 0x65, 0xc7, 0x9b, 0x2a, 0xf7, 0x1e, 0xd1, - 0x89, 0x7a, 0x5c, 0xf2, 0x65, 0x6e, 0x55, 0x0e, 0xd4, 0x3e, 0x41, 0x6e, 0xcf, 0xf0, 0x8f, 0x8d, - 0x7f, 0x20, 0x60, 0x61, 0x7a, 0x2d, 0x04, 0xba, 0x67, 0xef, 0xed, 0xed, 0x49, 0xda, 0x74, 0xc5, - 0x7e, 0xa4, 0x55, 0x36, 0x9a, 0x30, 0x1d, 0x76, 0xa5, 0xab, 0x64, 0x0a, 0x52, 0x21, 0x5f, 0x32, - 0x01, 0x99, 0x93, 0x1c, 0xf3, 0xf8, 0x57, 0xe9, 0xfb, 0x36, 0xe8, 0x51, 0x02, 0x23, 0xd9, 0x97, - 0x6f, 0x10, 0x4e, 0x60, 0x48, 0x2b, 0xed, 0xc3, 0x83, 0x2b, 0xa8, 0x8a, 0x60, 0x0e, 0xa1, 0xe4, - 0x30, 0x11, 0x58, 0xa5, 0x81, 0xb0, 0x80, 0x52, 0xf9, 0x51, 0x6b, 0x7c, 0x82, 0x35, 0xd0, 0x1a, - 0xb0, 0x46, 0x35, 0x16, 0x3c, 0x87, 0x96, 0xce, 0xd2, 0xcc, 0x0b, 0x60, 0x8c, 0xcb, 0xe9, 0x05, - 0x3b, 0x2f, 0xc9, 0x08, 0x38, 0x59, 0x45, 0x86, 0x66, 0x2c, 0x1e, 0x54, 0x1e, 0x11, 0x5e, 0x50, - 0xdf, 0x43, 0x3e, 0xcd, 0x58, 0xd7, 0x39, 0x3a, 0xfb, 0xe5, 0x77, 0x90, 0x19, 0x4e, 0xe8, 0x00, - 0x0f, 0x0e, 0xad, 0x11, 0x2b, 0xdc, 0xa5, 0x98, 0x5f, 0x60, 0x4d, 0x4c, 0xca, 0x12, 0x24, 0x73, - 0x2f, 0xc0, 0x35, 0x76, 0x4d, 0xbc, 0x9b, 0xd9, 0xba, 0x68, 0xf4, 0x61, 0x38, 0x84, 0x99, 0x78, - 0xff, 0x75, 0xf8, 0x14, 0xd6, 0xc1, 0x64, 0x56, 0x1d, 0x75, 0x0e, 0x9f, 0x22, 0x67, 0x14, 0xfe, - 0xbd, 0xaa, 0xae, 0xd3, 0xa3, 0xce, 0xff, 0x01, 0xfa, 0xdd, 0xa1, 0xd7, 0xa5, 0x8d, 0x01, 0x00 -}; diff --git a/wled00/improv.cpp b/wled00/improv.cpp index d99be68df..695d07ff7 100644 --- a/wled00/improv.cpp +++ b/wled00/improv.cpp @@ -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.0-b3/%i"), VERSION); + sprintf_P(vString, PSTR("0.15.0-a0/%i"), VERSION); const char *str[4] = {"WLED", vString, bString, useMdnsName ? cmDNS : serverDescription}; sendImprovRPCResult(ImprovRPCType::Request_Info, 4, str); diff --git a/wled00/ir.cpp b/wled00/ir.cpp index 4770b7134..3da4d68be 100644 --- a/wled00/ir.cpp +++ b/wled00/ir.cpp @@ -643,8 +643,8 @@ void decodeIRJson(uint32_t code) // this may fail for two reasons: ir.json does not exist or IR code not found // if the IR code is not found readObjectFromFile() will clean() doc JSON document // so we can differentiate between the two - readObjectFromFile("/ir.json", objKey, &doc); - fdo = doc.as(); + readObjectFromFile("/ir.json", objKey, pDoc); + fdo = pDoc->as(); lastValidCode = 0; if (fdo.isNull()) { //the received code does not exist @@ -675,7 +675,7 @@ void decodeIRJson(uint32_t code) } else { // HTTP API command String apireq = "win"; apireq += '&'; // reduce flash string usage - if (cmdStr.indexOf("~") || fdo["rpt"]) lastValidCode = code; // repeatable action + if (cmdStr.indexOf("~") > 0 || fdo["rpt"]) lastValidCode = code; // repeatable action if (!cmdStr.startsWith(apireq)) cmdStr = apireq + cmdStr; // if no "win&" prefix if (!irApplyToAllSelected && cmdStr.indexOf(F("SS="))<0) { char tmp[10]; diff --git a/wled00/json.cpp b/wled00/json.cpp index c0c729890..395ee7cbc 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -20,6 +20,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) byte id = elem["id"] | it; if (id >= strip.getMaxSegments()) return false; + bool newSeg = false; int stop = elem["stop"] | -1; // append segment @@ -27,10 +28,14 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) if (stop <= 0) return false; // ignore empty/inactive segments strip.appendSegment(Segment(0, strip.getLengthTotal())); id = strip.getSegmentsNum()-1; // segments are added at the end of list + newSeg = true; } + //DEBUG_PRINTLN("-- JSON deserialize segment."); Segment& seg = strip.getSegment(id); - Segment prev = seg; //make a backup so we can tell if something changed + //DEBUG_PRINTF("-- Original segment: %p (%p)\n", &seg, seg.data); + Segment prev = seg; //make a backup so we can tell if something changed (calling copy constructor) + //DEBUG_PRINTF("-- Duplicate segment: %p (%p)\n", &prev, prev.data); uint16_t start = elem["start"] | seg.start; if (stop < 0) { @@ -95,7 +100,7 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) if ((spc>0 && spc!=seg.spacing) || seg.map1D2D!=map1D2D) seg.fill(BLACK); // clear spacing gaps seg.map1D2D = constrain(map1D2D, 0, 7); - seg.soundSim = constrain(soundSim, 0, 1); + seg.soundSim = constrain(soundSim, 0, 3); uint8_t set = elem[F("set")] | seg.set; seg.set = constrain(set, 0, 3); @@ -112,11 +117,14 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) if (stop > start && of > len -1) of = len -1; // update segment (delete if necessary) - // do not call seg.setUp() here, as it may cause a crash due to concurrent access if the segment is currently drawing effects - // WS2812FX handles queueing of the change - strip.setSegment(id, start, stop, grp, spc, of, startY, stopY); + seg.setUp(start, stop, grp, spc, of, startY, stopY); // strip needs to be suspended for this to work without issues - if (seg.reset && seg.stop == 0) return true; // segment was deleted & is marked for reset, no need to change anything else + if (newSeg) seg.refreshLightCapabilities(); // fix for #3403 + + if (seg.reset && seg.stop == 0) { + if (id == strip.getMainSegmentId()) strip.setMainSegmentId(0); // fix for #3403 + return true; // segment was deleted & is marked for reset, no need to change anything else + } byte segbri = seg.opacity; if (getVal(elem["bri"], &segbri)) { @@ -124,12 +132,8 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) seg.setOption(SEG_OPTION_ON, segbri); // use transition } - bool on = elem["on"] | seg.on; - if (elem["on"].is() && elem["on"].as()[0] == 't') on = !on; - seg.setOption(SEG_OPTION_ON, on); // use transition - bool frz = elem["frz"] | seg.freeze; - if (elem["frz"].is() && elem["frz"].as()[0] == 't') frz = !seg.freeze; - seg.freeze = frz; + seg.setOption(SEG_OPTION_ON, getBoolVal(elem["on"], seg.on)); // use transition + seg.freeze = getBoolVal(elem["frz"], seg.freeze); seg.setCCT(elem["cct"] | seg.cct); @@ -192,20 +196,27 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) bool reverse = seg.reverse; bool mirror = seg.mirror; #endif - seg.selected = elem["sel"] | seg.selected; - seg.reverse = elem["rev"] | seg.reverse; - seg.mirror = elem["mi"] | seg.mirror; + seg.selected = getBoolVal(elem["sel"], seg.selected); + seg.reverse = getBoolVal(elem["rev"], seg.reverse); + seg.mirror = getBoolVal(elem["mi"] , seg.mirror); #ifndef WLED_DISABLE_2D bool reverse_y = seg.reverse_y; bool mirror_y = seg.mirror_y; - seg.reverse_y = elem["rY"] | seg.reverse_y; - seg.mirror_y = elem["mY"] | seg.mirror_y; - seg.transpose = elem[F("tp")] | seg.transpose; + seg.reverse_y = getBoolVal(elem["rY"] , seg.reverse_y); + seg.mirror_y = getBoolVal(elem["mY"] , seg.mirror_y); + seg.transpose = getBoolVal(elem[F("tp")], seg.transpose); if (seg.is2D() && seg.map1D2D == M12_pArc && (reverse != seg.reverse || reverse_y != seg.reverse_y || mirror != seg.mirror || mirror_y != seg.mirror_y)) seg.fill(BLACK); // clear entire segment (in case of Arc 1D to 2D expansion) #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 *tmp = elem["fx"].as(); + 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")]); } @@ -225,9 +236,9 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) getVal(elem["c3"], &cust3); // we can't pass reference to bifield seg.custom3 = constrain(cust3, 0, 31); - seg.check1 = elem["o1"] | seg.check1; - seg.check2 = elem["o2"] | seg.check2; - seg.check3 = elem["o3"] | seg.check3; + seg.check1 = getBoolVal(elem["o1"], seg.check1); + seg.check2 = getBoolVal(elem["o2"], seg.check2); + seg.check3 = getBoolVal(elem["o3"], seg.check3); JsonArray iarr = elem[F("i")]; //set individual LEDs if (!iarr.isNull()) { @@ -235,8 +246,9 @@ bool deserializeSegment(JsonObject elem, byte it, byte presetId) seg.map1D2D = M12_Pixels; // no mapping // set brightness immediately and disable transition - transitionDelayTemp = 0; jsonTransitionOnce = true; + seg.stopTransition(); + strip.setTransition(0); strip.setBrightness(scaledBri(bri), true); // freeze and init to black @@ -318,36 +330,32 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) int tr = -1; if (!presetId || currentPlaylist < 0) { //do not apply transition time from preset if playlist active, as it would override playlist transition times tr = root[F("transition")] | -1; - if (tr >= 0) - { - transitionDelay = tr; - transitionDelay *= 100; - transitionDelayTemp = transitionDelay; + if (tr >= 0) { + transitionDelay = tr * 100; + if (fadeTransition) strip.setTransition(transitionDelay); } } // temporary transition (applies only once) tr = root[F("tt")] | -1; - if (tr >= 0) - { - transitionDelayTemp = tr; - transitionDelayTemp *= 100; + if (tr >= 0) { jsonTransitionOnce = true; + if (fadeTransition) strip.setTransition(tr * 100); } - strip.setTransition(transitionDelayTemp); // required here for color transitions to have correct duration tr = root[F("tb")] | -1; if (tr >= 0) strip.timebase = ((uint32_t)tr) - millis(); JsonObject nl = root["nl"]; - nightlightActive = nl["on"] | nightlightActive; + nightlightActive = getBoolVal(nl["on"], nightlightActive); nightlightDelayMins = nl["dur"] | nightlightDelayMins; nightlightMode = nl["mode"] | nightlightMode; nightlightTargetBri = nl[F("tbri")] | nightlightTargetBri; JsonObject udpn = root["udpn"]; - notifyDirect = udpn["send"] | notifyDirect; - receiveNotifications = udpn["recv"] | receiveNotifications; + sendNotificationsRT = getBoolVal(udpn["send"], sendNotificationsRT); + syncGroups = udpn["sgrp"] | syncGroups; + receiveGroups = udpn["rgrp"] | receiveGroups; if ((bool)udpn[F("nn")]) callMode = CALL_MODE_NO_NOTIFY; //send no notification just for this request unsigned long timein = root["time"] | UINT32_MAX; //backup time source if NTP not synced @@ -369,8 +377,8 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) if (root.containsKey("live")) { if (root["live"].as()) { - transitionDelayTemp = 0; jsonTransitionOnce = true; + strip.setTransition(0); realtimeLock(65000); } else { exitRealtime(); @@ -379,6 +387,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) int it = 0; JsonVariant segVar = root["seg"]; + if (!segVar.isNull()) strip.suspend(); if (segVar.is()) { int id = segVar["id"] | -1; @@ -406,6 +415,7 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId) } if (strip.getSegmentsNum() > 3 && deleted >= strip.getSegmentsNum()/2U) strip.purgeSegments(); // batch deleting more than half segments } + strip.resume(); usermods.readFromJsonState(root); @@ -490,7 +500,8 @@ void serializeSegment(JsonObject& root, Segment& seg, byte id, bool forPreset, b root["cct"] = seg.cct; root[F("set")] = seg.set; - if (segmentBounds && seg.name != nullptr) root["n"] = reinterpret_cast(seg.name); //not good practice, but decreases required JSON buffer + if (seg.name != nullptr) root["n"] = reinterpret_cast(seg.name); //not good practice, but decreases required JSON buffer + else if (forPreset) root["n"] = ""; // to conserve RAM we will serialize the col array manually // this will reduce RAM footprint from ~300 bytes to 84 bytes per segment @@ -562,8 +573,10 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme } JsonObject udpn = root.createNestedObject("udpn"); - udpn["send"] = notifyDirect; - udpn["recv"] = receiveNotifications; + udpn["send"] = sendNotificationsRT; + udpn["recv"] = receiveGroups != 0; + udpn["sgrp"] = syncGroups; + udpn["rgrp"] = receiveGroups; root[F("lor")] = realtimeOverride; } @@ -596,13 +609,13 @@ void serializeInfo(JsonObject root) { root[F("ver")] = versionString; root[F("vid")] = VERSION; - //root[F("cn")] = WLED_CODENAME; + root[F("cn")] = F(WLED_CODENAME); JsonObject leds = root.createNestedObject("leds"); leds[F("count")] = strip.getLengthTotal(); - leds[F("pwr")] = strip.currentMilliamps; + leds[F("pwr")] = BusManager::currentMilliamps(); leds["fps"] = strip.getFps(); - leds[F("maxpwr")] = (strip.currentMilliamps)? strip.ablMilliampsMax : 0; + leds[F("maxpwr")] = BusManager::currentMilliamps()>0 ? BusManager::ablMilliampsMax() : 0; leds[F("maxseg")] = strip.getMaxSegments(); //leds[F("actseg")] = strip.getActiveSegmentsNum(); //leds[F("seglock")] = false; //might be used in the future to prevent modifications to segment config @@ -641,10 +654,11 @@ void serializeInfo(JsonObject root) spi.add(spi_miso); #endif - root[F("str")] = syncToggleReceive; + root[F("str")] = false; //syncToggleReceive; root[F("name")] = serverDescription; root[F("udpport")] = udpPort; + root[F("simplifiedui")] = simplifiedUI; root["live"] = (bool)realtimeMode; root[F("liveseg")] = useMainSegmentOnly ? strip.getMainSegmentId() : -1; // if using main segment only for live @@ -735,6 +749,10 @@ void serializeInfo(JsonObject root) #endif root[F("uptime")] = millis()/1000 + rolloverMillis*4294967; + char time[32]; + getTimeString(time); + root[F("time")] = time; + usermods.addToJsonInfo(root); uint16_t os = 0; @@ -936,11 +954,11 @@ void serializeNetworks(JsonObject root) for (int i = 0; i < status; i++) { JsonObject node = networks.createNestedObject(); - node["ssid"] = WiFi.SSID(i); - node["rssi"] = WiFi.RSSI(i); - node["bssid"] = WiFi.BSSIDstr(i); - node["channel"] = WiFi.channel(i); - node["enc"] = WiFi.encryptionType(i); + node[F("ssid")] = WiFi.SSID(i); + node[F("rssi")] = WiFi.RSSI(i); + node[F("bssid")] = WiFi.BSSIDstr(i); + node[F("channel")] = WiFi.channel(i); + node[F("enc")] = WiFi.encryptionType(i); } WiFi.scanDelete(); @@ -971,9 +989,10 @@ void serializeNodes(JsonObject root) // deserializes mode data string into JsonArray void serializeModeData(JsonArray fxdata) { - char lineBuffer[128]; + char lineBuffer[256]; for (size_t i = 0; i < strip.getModeCount(); i++) { - strncpy_P(lineBuffer, strip.getModeData(i), 127); + strncpy_P(lineBuffer, strip.getModeData(i), sizeof(lineBuffer)/sizeof(char)-1); + lineBuffer[sizeof(lineBuffer)/sizeof(char)-1] = '\0'; // terminate string if (lineBuffer[0] != 0) { char* dataPtr = strchr(lineBuffer,'@'); if (dataPtr) fxdata.add(dataPtr+1); @@ -984,10 +1003,12 @@ void serializeModeData(JsonArray fxdata) // deserializes mode names string into JsonArray // also removes effect data extensions (@...) from deserialised names -void serializeModeNames(JsonArray arr) { - char lineBuffer[128]; +void serializeModeNames(JsonArray arr) +{ + char lineBuffer[256]; for (size_t i = 0; i < strip.getModeCount(); i++) { - strncpy_P(lineBuffer, strip.getModeData(i), 127); + strncpy_P(lineBuffer, strip.getModeData(i), sizeof(lineBuffer)/sizeof(char)-1); + lineBuffer[sizeof(lineBuffer)/sizeof(char)-1] = '\0'; // terminate string if (lineBuffer[0] != 0) { char* dataPtr = strchr(lineBuffer,'@'); if (dataPtr) *dataPtr = 0; // terminate mode data after name @@ -996,6 +1017,17 @@ void serializeModeNames(JsonArray arr) { } } + +// Global buffer locking response helper class +class GlobalBufferAsyncJsonResponse: public JSONBufferGuard, public AsyncJsonResponse { + public: + inline GlobalBufferAsyncJsonResponse(bool isArray) : JSONBufferGuard(17), AsyncJsonResponse(pDoc, isArray) {}; + virtual ~GlobalBufferAsyncJsonResponse() {}; + + // Other members are inherited +}; + + void serveJson(AsyncWebServerRequest* request) { byte subJson = 0; @@ -1022,15 +1054,16 @@ void serveJson(AsyncWebServerRequest* request) return; } else if (url.length() > 6) { //not just /json - request->send(501, "application/json", F("{\"error\":\"Not implemented\"}")); + serveJsonError(request, 501, ERR_NOT_IMPL); return; } - if (!requestJSONBufferLock(17)) { - request->send(503, "application/json", F("{\"error\":3}")); + GlobalBufferAsyncJsonResponse *response = new GlobalBufferAsyncJsonResponse(subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary + if (!response->owns_lock()) { + serveJsonError(request, 503, ERR_NOBUF); + delete response; return; } - AsyncJsonResponse *response = new AsyncJsonResponse(&doc, subJson==JSON_PATH_FXDATA || subJson==JSON_PATH_EFFECTS); // will clear and convert JsonDocument into JsonArray if necessary JsonVariant lDoc = response->getRoot(); @@ -1073,11 +1106,10 @@ void serveJson(AsyncWebServerRequest* request) DEBUG_PRINT(F("JSON content length: ")); DEBUG_PRINTLN(len); request->send(response); - releaseJSONBufferLock(); } #ifdef WLED_ENABLE_JSONLIVE -#define MAX_LIVE_LEDS 180 +#define MAX_LIVE_LEDS 256 bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient) { @@ -1091,13 +1123,26 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient) uint16_t used = strip.getLengthTotal(); uint16_t n = (used -1) /MAX_LIVE_LEDS +1; //only serve every n'th LED if count over MAX_LIVE_LEDS - char buffer[2000]; +#ifndef WLED_DISABLE_2D + if (strip.isMatrix) { + // ignore anything behid matrix (i.e. extra strip) + used = Segment::maxWidth*Segment::maxHeight; // always the size of matrix (more or less than strip.getLengthTotal()) + n = 1; + if (used > MAX_LIVE_LEDS) n = 2; + if (used > MAX_LIVE_LEDS*4) n = 4; + } +#endif + + char buffer[2048]; // shoud be enough for 256 LEDs [RRGGBB] + all other text (9+25) strcpy_P(buffer, PSTR("{\"leds\":[")); - obuf = buffer; + obuf = buffer; // assign buffer for oappnd() functions olen = 9; - for (size_t i= 0; i < used; i += n) + for (size_t i = 0; i < used; i += n) { +#ifndef WLED_DISABLE_2D + if (strip.isMatrix && n>1 && (i/Segment::maxWidth)%n) i += Segment::maxWidth * (n-1); +#endif uint32_t c = strip.getPixelColor(i); uint8_t r = R(c); uint8_t g = G(c); @@ -1106,11 +1151,19 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient) r = scale8(qadd8(w, r), strip.getBrightness()); //R, add white channel to RGB channels as a simple RGBW -> RGB map g = scale8(qadd8(w, g), strip.getBrightness()); //G b = scale8(qadd8(w, b), strip.getBrightness()); //B - olen += sprintf(obuf + olen, "\"%06X\",", RGBW32(r,g,b,0)); + olen += sprintf_P(obuf + olen, PSTR("\"%06X\","), RGBW32(r,g,b,0)); } olen -= 1; oappend((const char*)F("],\"n\":")); oappendi(n); +#ifndef WLED_DISABLE_2D + if (strip.isMatrix) { + oappend((const char*)F(",\"w\":")); + oappendi(Segment::maxWidth/n); + oappend((const char*)F(",\"h\":")); + oappendi(Segment::maxHeight/n); + } +#endif oappend("}"); if (request) { request->send(200, "application/json", buffer); @@ -1120,6 +1173,7 @@ bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient) wsc->text(obuf, olen); } #endif + obuf = nullptr; return true; } #endif diff --git a/wled00/led.cpp b/wled00/led.cpp index 97499e76d..b8b51873c 100644 --- a/wled00/led.cpp +++ b/wled00/led.cpp @@ -37,12 +37,12 @@ void applyValuesToSelectedSegs() if (effectSpeed != selsegPrev.speed) {seg.speed = effectSpeed; stateChanged = true;} if (effectIntensity != selsegPrev.intensity) {seg.intensity = effectIntensity; stateChanged = true;} - if (effectPalette != selsegPrev.palette) {seg.setPalette(effectPalette); stateChanged = true;} - if (effectCurrent != selsegPrev.mode) {seg.setMode(effectCurrent); stateChanged = true;} + if (effectPalette != selsegPrev.palette) {seg.setPalette(effectPalette);} + if (effectCurrent != selsegPrev.mode) {seg.setMode(effectCurrent);} uint32_t col0 = RGBW32( col[0], col[1], col[2], col[3]); uint32_t col1 = RGBW32(colSec[0], colSec[1], colSec[2], colSec[3]); - if (col0 != selsegPrev.colors[0]) {seg.setColor(0, col0); stateChanged = true;} - if (col1 != selsegPrev.colors[1]) {seg.setColor(1, col1); stateChanged = true;} + if (col0 != selsegPrev.colors[0]) {seg.setColor(0, col0);} + if (col1 != selsegPrev.colors[1]) {seg.setColor(1, col1);} } } @@ -134,11 +134,9 @@ void stateUpdated(byte callMode) { usermods.onStateChange(callMode); if (fadeTransition) { - //set correct delay if not using notification delay - if (callMode != CALL_MODE_NOTIFICATION && !jsonTransitionOnce) transitionDelayTemp = transitionDelay; // load actual transition duration - jsonTransitionOnce = false; - strip.setTransition(transitionDelayTemp); - if (transitionDelayTemp == 0) { + if (strip.getTransition() == 0) { + jsonTransitionOnce = false; + transitionActive = false; applyFinalBri(); strip.trigger(); return; @@ -152,7 +150,6 @@ void stateUpdated(byte callMode) { transitionActive = true; transitionStartTime = millis(); } else { - strip.setTransition(0); applyFinalBri(); strip.trigger(); } @@ -161,8 +158,12 @@ void stateUpdated(byte callMode) { void updateInterfaces(uint8_t callMode) { + if (!interfaceUpdateCallMode || millis() - lastInterfaceUpdate < INTERFACE_UPDATE_COOLDOWN) return; + sendDataWs(); lastInterfaceUpdate = millis(); + interfaceUpdateCallMode = 0; //disable further updates + if (callMode == CALL_MODE_WS_SEND) return; #ifndef WLED_DISABLE_ALEXA @@ -172,25 +173,25 @@ void updateInterfaces(uint8_t callMode) } #endif doPublishMqtt = true; - interfaceUpdateCallMode = 0; //disable } void handleTransitions() { //handle still pending interface update - if (interfaceUpdateCallMode && millis() - lastInterfaceUpdate > INTERFACE_UPDATE_COOLDOWN) updateInterfaces(interfaceUpdateCallMode); + updateInterfaces(interfaceUpdateCallMode); #ifndef WLED_DISABLE_MQTT if (doPublishMqtt) publishMqtt(); #endif - if (transitionActive && transitionDelayTemp > 0) - { - float tper = (millis() - transitionStartTime)/(float)transitionDelayTemp; - if (tper >= 1.0) - { - strip.setTransitionMode(false); + if (transitionActive && strip.getTransition() > 0) { + float tper = (millis() - transitionStartTime)/(float)strip.getTransition(); + if (tper >= 1.0f) { + strip.setTransitionMode(false); // stop all transitions + // restore (global) transition time if not called from UDP notifier or single/temporary transition from JSON (also playlist) + if (jsonTransitionOnce) strip.setTransition(transitionDelay); transitionActive = false; + jsonTransitionOnce = false; tperLast = 0; applyFinalBri(); return; @@ -224,7 +225,7 @@ void handleNightlight() if (!nightlightActiveOld) //init { nightlightStartTime = millis(); - nightlightDelayMs = (int)(nightlightDelayMins*60000); + nightlightDelayMs = (unsigned)(nightlightDelayMins*60000); nightlightActiveOld = true; briNlT = bri; for (byte i=0; i<4; i++) colNlT[i] = col[i]; // remember starting color diff --git a/wled00/lx_parser.cpp b/wled00/lx_parser.cpp index 8dd47bdef..7fd91ea02 100644 --- a/wled00/lx_parser.cpp +++ b/wled00/lx_parser.cpp @@ -25,7 +25,7 @@ bool parseLx(int lxValue, byte* rgbw) float tmpBri = floor((lxValue - 200000000) / 10000); ; uint16_t ct = (lxValue - 200000000) - (((uint8_t)tmpBri) * 10000); - tmpBri *= 2.55; + tmpBri *= 2.55f; tmpBri = constrain(tmpBri, 0, 255); colorKtoRGB(ct, rgbw); diff --git a/wled00/mqtt.cpp b/wled00/mqtt.cpp index a5caaf472..3c753a9a9 100644 --- a/wled00/mqtt.cpp +++ b/wled00/mqtt.cpp @@ -109,8 +109,8 @@ void onMqttMessage(char* topic, char* payload, AsyncMqttClientMessageProperties return; } if (payloadStr[0] == '{') { //JSON API - deserializeJson(doc, payloadStr); - deserializeState(doc.as()); + deserializeJson(*pDoc, payloadStr); + deserializeState(pDoc->as()); } else { //HTTP API String apireq = "win"; apireq += '&'; // reduce flash string usage apireq += payloadStr; diff --git a/wled00/ntp.cpp b/wled00/ntp.cpp index 1d867846c..c9c4874b9 100644 --- a/wled00/ntp.cpp +++ b/wled00/ntp.cpp @@ -2,6 +2,21 @@ #include "wled.h" #include "fcn_declare.h" +// on esp8266, building with `-D WLED_USE_UNREAL_MATH` saves around 7Kb flash and 1KB RAM +// warning: causes errors in sunset calculations, see #3400 +#if defined(WLED_USE_UNREAL_MATH) +#define sinf sin_t +#define asinf asin_t +#define cosf cos_t +#define acosf acos_t +#define tanf tan_t +#define atanf atan_t +#define fmodf fmod_t +#define floorf floor_t +#else +#include +#endif + /* * Acquires time from NTP server */ @@ -412,8 +427,8 @@ int getSunriseUTC(int year, int month, int day, float lat, float lon, bool sunse //1. first calculate the day of the year float N1 = 275 * month / 9; float N2 = (month + 9) / 12; - float N3 = (1 + floor_t((year - 4 * floor_t(year / 4) + 2) / 3)); - float N = N1 - (N2 * N3) + day - 30; + float N3 = (1.0f + floorf((year - 4 * floorf(year / 4) + 2.0f) / 3.0f)); + float N = N1 - (N2 * N3) + day - 30.0f; //2. convert the longitude to hour value and calculate an approximate time float lngHour = lon / 15.0f; @@ -423,37 +438,37 @@ int getSunriseUTC(int year, int month, int day, float lat, float lon, bool sunse float M = (0.9856f * t) - 3.289f; //4. calculate the Sun's true longitude - float L = fmod_t(M + (1.916f * sin_t(DEG_TO_RAD*M)) + (0.02f * sin_t(2*DEG_TO_RAD*M)) + 282.634f, 360.0f); + float L = fmodf(M + (1.916f * sinf(DEG_TO_RAD*M)) + (0.02f * sinf(2*DEG_TO_RAD*M)) + 282.634f, 360.0f); //5a. calculate the Sun's right ascension - float RA = fmod_t(RAD_TO_DEG*atan_t(0.91764f * tan_t(DEG_TO_RAD*L)), 360.0f); + float RA = fmodf(RAD_TO_DEG*atanf(0.91764f * tanf(DEG_TO_RAD*L)), 360.0f); //5b. right ascension value needs to be in the same quadrant as L - float Lquadrant = floor_t( L/90) * 90; - float RAquadrant = floor_t(RA/90) * 90; + float Lquadrant = floorf( L/90) * 90; + float RAquadrant = floorf(RA/90) * 90; RA = RA + (Lquadrant - RAquadrant); //5c. right ascension value needs to be converted into hours RA /= 15.0f; //6. calculate the Sun's declination - float sinDec = 0.39782f * sin_t(DEG_TO_RAD*L); - float cosDec = cos_t(asin_t(sinDec)); + float sinDec = 0.39782f * sinf(DEG_TO_RAD*L); + float cosDec = cosf(asinf(sinDec)); //7a. calculate the Sun's local hour angle - float cosH = (sin_t(DEG_TO_RAD*ZENITH) - (sinDec * sin_t(DEG_TO_RAD*lat))) / (cosDec * cos_t(DEG_TO_RAD*lat)); - if (cosH > 1 && !sunset) return 0; // the sun never rises on this location (on the specified date) - if (cosH < -1 && sunset) return 0; // the sun never sets on this location (on the specified date) + float cosH = (sinf(DEG_TO_RAD*ZENITH) - (sinDec * sinf(DEG_TO_RAD*lat))) / (cosDec * cosf(DEG_TO_RAD*lat)); + if ((cosH > 1.0f) && !sunset) return 0; // the sun never rises on this location (on the specified date) + if ((cosH < -1.0f) && sunset) return 0; // the sun never sets on this location (on the specified date) //7b. finish calculating H and convert into hours - float H = sunset ? RAD_TO_DEG*acos_t(cosH) : 360 - RAD_TO_DEG*acos_t(cosH); + float H = sunset ? RAD_TO_DEG*acosf(cosH) : 360 - RAD_TO_DEG*acosf(cosH); H /= 15.0f; //8. calculate local mean time of rising/setting float T = H + RA - (0.06571f * t) - 6.622f; //9. adjust back to UTC - float UT = fmod_t(T - lngHour, 24.0f); + float UT = fmodf(T - lngHour, 24.0f); // return in minutes from midnight return UT*60; diff --git a/wled00/overlay.cpp b/wled00/overlay.cpp index cfee7e817..f065cd36a 100644 --- a/wled00/overlay.cpp +++ b/wled00/overlay.cpp @@ -15,11 +15,11 @@ void _overlayAnalogClock() float minuteP = ((float)minute(localTime))/60.0f; hourP = hourP + minuteP/12.0f; float secondP = ((float)second(localTime))/60.0f; - int hourPixel = floorf(analogClock12pixel + overlaySize*hourP); + unsigned hourPixel = floorf(analogClock12pixel + overlaySize*hourP); if (hourPixel > overlayMax) hourPixel = overlayMin -1 + hourPixel - overlayMax; - int minutePixel = floorf(analogClock12pixel + overlaySize*minuteP); + unsigned minutePixel = floorf(analogClock12pixel + overlaySize*minuteP); if (minutePixel > overlayMax) minutePixel = overlayMin -1 + minutePixel - overlayMax; - int secondPixel = floorf(analogClock12pixel + overlaySize*secondP); + unsigned secondPixel = floorf(analogClock12pixel + overlaySize*secondP); if (secondPixel > overlayMax) secondPixel = overlayMin -1 + secondPixel - overlayMax; if (analogClockSecondsTrail) { @@ -36,7 +36,7 @@ void _overlayAnalogClock() { for (byte i = 0; i <= 12; i++) { - int pix = analogClock12pixel + roundf((overlaySize / 12.0f) *i); + unsigned pix = analogClock12pixel + roundf((overlaySize / 12.0f) *i); if (pix > overlayMax) pix -= overlaySize; strip.setPixelColor(pix, 0x00FFAA); } diff --git a/wled00/pin_manager.cpp b/wled00/pin_manager.cpp index a1ac59ce7..102acd0ea 100644 --- a/wled00/pin_manager.cpp +++ b/wled00/pin_manager.cpp @@ -238,7 +238,7 @@ bool PinManagerClass::isPinAllocated(byte gpio, PinOwner tag) // Check if supplied GPIO is ok to use bool PinManagerClass::isPinOk(byte gpio, bool output) { -#ifdef ESP32 +#ifdef ARDUINO_ARCH_ESP32 if (digitalPinIsValid(gpio)) { #if defined(CONFIG_IDF_TARGET_ESP32C3) // strapping pins: 2, 8, & 9 @@ -257,6 +257,9 @@ bool PinManagerClass::isPinOk(byte gpio, bool output) // GPIO46 is input only and pulled down #else if (gpio > 5 && gpio < 12) return false; //SPI flash pins + #ifdef BOARD_HAS_PSRAM + if (gpio == 16 || gpio == 17) return false; //PSRAM pins + #endif #endif if (output) return digitalPinCanOutput(gpio); else return true; diff --git a/wled00/pin_manager.h b/wled00/pin_manager.h index 6248a6066..1402de2bd 100644 --- a/wled00/pin_manager.h +++ b/wled00/pin_manager.h @@ -41,7 +41,7 @@ enum struct PinOwner : uint8_t { UM_Temperature = USERMOD_ID_TEMPERATURE, // 0x03 // Usermod "usermod_temperature.h" // #define USERMOD_ID_FIXNETSERVICES // 0x04 // Usermod "usermod_Fix_unreachable_netservices.h" -- Does not allocate pins UM_PIR = USERMOD_ID_PIRSWITCH, // 0x05 // Usermod "usermod_PIR_sensor_switch.h" - // #define USERMOD_ID_IMU // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Uses "standard" HW_I2C pins + UM_IMU = USERMOD_ID_IMU, // 0x06 // Usermod "usermod_mpu6050_imu.h" -- Interrupt pin UM_FourLineDisplay = USERMOD_ID_FOUR_LINE_DISP, // 0x07 // Usermod "usermod_v2_four_line_display.h -- May use "standard" HW_I2C pins UM_RotaryEncoderUI = USERMOD_ID_ROTARY_ENC_UI, // 0x08 // Usermod "usermod_v2_rotary_encoder_ui.h" // #define USERMOD_ID_AUTO_SAVE // 0x09 // Usermod "usermod_v2_auto_save.h" -- Does not allocate pins diff --git a/wled00/playlist.cpp b/wled00/playlist.cpp index d74ac5a3a..bcbcb4516 100644 --- a/wled00/playlist.cpp +++ b/wled00/playlist.cpp @@ -112,7 +112,7 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) { if (playlistEndPreset == 255 && currentPreset > 0) playlistEndPreset = currentPreset; if (playlistEndPreset > 250) playlistEndPreset = 0; shuffle = shuffle || playlistObj["r"]; - if (shuffle) playlistOptions += PL_OPTION_SHUFFLE; + if (shuffle) playlistOptions |= PL_OPTION_SHUFFLE; currentPlaylist = presetId; DEBUG_PRINTLN(F("Playlist loaded.")); @@ -144,7 +144,7 @@ void handlePlaylist() { } jsonTransitionOnce = true; - transitionDelayTemp = playlistEntries[playlistIndex].tr * 100; + strip.setTransition(fadeTransition ? playlistEntries[playlistIndex].tr * 100 : 0); playlistEntryDur = playlistEntries[playlistIndex].dur; applyPreset(playlistEntries[playlistIndex].preset); } @@ -156,7 +156,7 @@ void serializePlaylist(JsonObject sObj) { JsonArray ps = playlist.createNestedArray("ps"); JsonArray dur = playlist.createNestedArray("dur"); JsonArray transition = playlist.createNestedArray(F("transition")); - playlist[F("repeat")] = (playlistIndex < 0) ? playlistRepeat - 1 : playlistRepeat; // remove added repetition count (if not yet running) + playlist[F("repeat")] = (playlistIndex < 0 && playlistRepeat > 0) ? playlistRepeat - 1 : playlistRepeat; // remove added repetition count (if not yet running) playlist["end"] = playlistEndPreset; playlist["r"] = playlistOptions & PL_OPTION_SHUFFLE; for (int i=0; i(); + JsonObject sObj = pDoc->to(); DEBUG_PRINTLN(F("Serialize current state")); if (playlistSave) { @@ -42,7 +44,7 @@ static void doSaveState() { /* #ifdef WLED_DEBUG DEBUG_PRINTLN(F("Serialized preset")); - serializeJson(doc,Serial); + serializeJson(*pDoc,Serial); DEBUG_PRINTLN(); #endif */ @@ -83,9 +85,9 @@ bool getPresetName(byte index, String& name) { if (!requestJSONBufferLock(9)) return false; bool presetExists = false; - if (readObjectFromFileUsingId(getFileName(), index, &doc)) + if (readObjectFromFileUsingId(getFileName(), index, pDoc)) { - JsonObject fdo = doc.as(); + JsonObject fdo = pDoc->as(); if (fdo["n"]) { name = (const char*)(fdo["n"]); presetExists = true; @@ -132,7 +134,9 @@ void applyPresetWithFallback(uint8_t index, uint8_t callMode, uint8_t effectID, void handlePresets() { if (presetToSave) { + strip.suspend(); doSaveState(); + strip.resume(); return; } @@ -212,9 +216,9 @@ void savePreset(byte index, const char* pname, JsonObject sObj) playlistSave = false; if (sObj[F("ql")].is()) strlcpy(quickLoad, sObj[F("ql")].as(), 9); // client limits QL to 2 chars, buffer for 8 bytes to allow unicode - if (sObj["o"].isNull()) { // no "o" means not a playlist or custom API call, saving of state is async (not immediately) - includeBri = sObj["ib"].as() || index==255; // temporary preset needs brightness - segBounds = sObj["sb"].as() || index==255; // temporary preset needs bounds + if (sObj.size()==0 || sObj["o"].isNull()) { // no "o" means not a playlist or custom API call, saving of state is async (not immediately) + includeBri = sObj["ib"].as() || sObj.size()==0 || index==255; // temporary preset needs brightness + segBounds = sObj["sb"].as() || sObj.size()==0 || index==255; // temporary preset needs bounds selectedOnly = sObj[F("sc")].as(); saveLedmap = sObj[F("ledmap")] | -1; } else { diff --git a/wled00/remote.cpp b/wled00/remote.cpp index 0a833d6e9..c41d88421 100644 --- a/wled00/remote.cpp +++ b/wled00/remote.cpp @@ -1,8 +1,5 @@ #include "wled.h" - -#define ESP_NOW_STATE_UNINIT 0 -#define ESP_NOW_STATE_ON 1 -#define ESP_NOW_STATE_ERROR 2 +#ifndef WLED_DISABLE_ESPNOW #define NIGHT_MODE_DEACTIVATED -1 #define NIGHT_MODE_BRIGHTNESS 5 @@ -17,59 +14,59 @@ #define WIZMOTE_BUTTON_BRIGHT_UP 9 #define WIZMOTE_BUTTON_BRIGHT_DOWN 8 -#ifdef WLED_DISABLE_ESPNOW -void handleRemote(){} -#else +#define WIZ_SMART_BUTTON_ON 100 +#define WIZ_SMART_BUTTON_OFF 101 +#define WIZ_SMART_BUTTON_BRIGHT_UP 102 +#define WIZ_SMART_BUTTON_BRIGHT_DOWN 103 // This is kind of an esoteric strucure because it's pulled from the "Wizmote" // product spec. That remote is used as the baseline for behavior and availability // since it's broadly commercially available and works out of the box as a drop-in -typedef struct message_structure { - uint8_t program; // 0x91 for ON button, 0x81 for all others - uint8_t seq[4]; // Incremetal sequence number 32 bit unsigned integer LSB first - uint8_t byte5 = 32; // Unknown - uint8_t button; // Identifies which button is being pressed - uint8_t byte8 = 1; // Unknown, but always 0x01 - uint8_t byte9 = 100; // Unnkown, but always 0x64 +typedef struct WizMoteMessageStructure { + uint8_t program; // 0x91 for ON button, 0x81 for all others + uint8_t seq[4]; // Incremetal sequence number 32 bit unsigned integer LSB first + uint8_t byte5; // Unknown (seen 0x20) + uint8_t button; // Identifies which button is being pressed + uint8_t byte8; // Unknown, but always 0x01 + uint8_t byte9; // Unnkown, but always 0x64 - uint8_t byte10; // Unknown, maybe checksum - uint8_t byte11; // Unknown, maybe checksum - uint8_t byte12; // Unknown, maybe checksum - uint8_t byte13; // Unknown, maybe checksum -} message_structure; + uint8_t byte10; // Unknown, maybe checksum + uint8_t byte11; // Unknown, maybe checksum + uint8_t byte12; // Unknown, maybe checksum + uint8_t byte13; // Unknown, maybe checksum +} message_structure_t; -static int esp_now_state = ESP_NOW_STATE_UNINIT; -static uint32_t last_seq = -1; +static uint32_t last_seq = UINT32_MAX; static int brightnessBeforeNightMode = NIGHT_MODE_DEACTIVATED; -static message_structure incoming; // Pulled from the IR Remote logic but reduced to 10 steps with a constant of 3 static const byte brightnessSteps[] = { 6, 9, 14, 22, 33, 50, 75, 113, 170, 255 }; -static const size_t numBrightnessSteps = sizeof(brightnessSteps) / sizeof(uint8_t); +static const size_t numBrightnessSteps = sizeof(brightnessSteps) / sizeof(byte); -static bool nightModeActive() { +inline bool nightModeActive() { return brightnessBeforeNightMode != NIGHT_MODE_DEACTIVATED; } static void activateNightMode() { + if (nightModeActive()) return; brightnessBeforeNightMode = bri; bri = NIGHT_MODE_BRIGHTNESS; + stateUpdated(CALL_MODE_BUTTON); } static bool resetNightMode() { - if (!nightModeActive()) { - return false; - } + if (!nightModeActive()) return false; bri = brightnessBeforeNightMode; brightnessBeforeNightMode = NIGHT_MODE_DEACTIVATED; + stateUpdated(CALL_MODE_BUTTON); return true; } // increment `bri` to the next `brightnessSteps` value static void brightnessUp() { - if (nightModeActive()) { return; } + if (nightModeActive()) return; // dumb incremental search is efficient enough for so few items for (uint8_t index = 0; index < numBrightnessSteps; ++index) { if (brightnessSteps[index] > bri) { @@ -77,11 +74,12 @@ static void brightnessUp() { break; } } + stateUpdated(CALL_MODE_BUTTON); } // decrement `bri` to the next `brightnessSteps` value static void brightnessDown() { - if (nightModeActive()) { return; } + if (nightModeActive()) return; // dumb incremental search is efficient enough for so few items for (int index = numBrightnessSteps - 1; index >= 0; --index) { if (brightnessSteps[index] < bri) { @@ -89,39 +87,98 @@ static void brightnessDown() { break; } } + stateUpdated(CALL_MODE_BUTTON); } static void setOn() { - if (resetNightMode()) { - stateUpdated(CALL_MODE_BUTTON); - } + resetNightMode(); if (!bri) { - toggleOnOff(); + toggleOnOff(); + stateUpdated(CALL_MODE_BUTTON); } } static void setOff() { - if (resetNightMode()) { + resetNightMode(); + if (bri) { + toggleOnOff(); stateUpdated(CALL_MODE_BUTTON); } - if (bri) { - toggleOnOff(); - } } -static void presetWithFallback(uint8_t presetID, uint8_t effectID, uint8_t paletteID) { +void presetWithFallback(uint8_t presetID, uint8_t effectID, uint8_t paletteID) { + resetNightMode(); + unloadPlaylist(); applyPresetWithFallback(presetID, CALL_MODE_BUTTON_PRESET, effectID, paletteID); } - -// Callback function that will be executed when data is received -#ifdef ESP8266 -void OnDataRecv(uint8_t * mac, uint8_t *incomingData, uint8_t len) { -#else -void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { -#endif - sprintf (last_signal_src, "%02x%02x%02x%02x%02x%02x", - mac [0], mac [1], mac [2], mac [3], mac [4], mac [5]); +// this function follows the same principle as decodeIRJson() +static bool remoteJson(int button) +{ + char objKey[10]; + bool parsed = false; + + if (!requestJSONBufferLock(22)) return false; + + sprintf_P(objKey, PSTR("\"%d\":"), button); + + // attempt to read command from remote.json + readObjectFromFile("/remote.json", objKey, pDoc); + JsonObject fdo = pDoc->as(); + if (fdo.isNull()) { + // the received button does not exist + if (!WLED_FS.exists("/remote.json")) errorFlag = ERR_FS_RMLOAD; //warn if file itself doesn't exist + releaseJSONBufferLock(); + return parsed; + } + + String cmdStr = fdo["cmd"].as(); + JsonObject jsonCmdObj = fdo["cmd"]; //object + + if (jsonCmdObj.isNull()) // we could also use: fdo["cmd"].is() + { + if (cmdStr.startsWith("!")) { + // call limited set of C functions + if (cmdStr.startsWith(F("!incBri"))) { + brightnessUp(); + parsed = true; + } else if (cmdStr.startsWith(F("!decBri"))) { + brightnessDown(); + parsed = true; + } else if (cmdStr.startsWith(F("!presetF"))) { //!presetFallback + uint8_t p1 = fdo["PL"] | 1; + uint8_t p2 = fdo["FX"] | random8(strip.getModeCount() -1); + uint8_t p3 = fdo["FP"] | 0; + presetWithFallback(p1, p2, p3); + parsed = true; + } + } else { + // HTTP API command + String apireq = "win"; apireq += '&'; // reduce flash string usage + //if (cmdStr.indexOf("~") || fdo["rpt"]) lastValidCode = code; // repeatable action + if (!cmdStr.startsWith(apireq)) cmdStr = apireq + cmdStr; // if no "win&" prefix + if (!irApplyToAllSelected && cmdStr.indexOf(F("SS="))<0) { + char tmp[10]; + sprintf_P(tmp, PSTR("&SS=%d"), strip.getMainSegmentId()); + cmdStr += tmp; + } + fdo.clear(); // clear JSON buffer (it is no longer needed) + handleSet(nullptr, cmdStr, false); // no stateUpdated() call here + stateUpdated(CALL_MODE_BUTTON); + parsed = true; + } + } else { + // command is JSON object (TODO: currently will not handle irApplyToAllSelected correctly) + deserializeState(jsonCmdObj, CALL_MODE_BUTTON); + parsed = true; + } + releaseJSONBufferLock(); + return parsed; +} + +// Callback function that will be executed when data is received +void handleRemote(uint8_t *incomingData, size_t len) { + message_structure_t *incoming = reinterpret_cast(incomingData); if (strcmp(last_signal_src, linked_remote) != 0) { DEBUG_PRINT(F("ESP Now Message Received from Unlinked Sender: ")); @@ -129,72 +186,44 @@ void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { return; } - if (len != sizeof(incoming)) { + if (len != sizeof(message_structure_t)) { DEBUG_PRINT(F("Unknown incoming ESP Now message received of length ")); DEBUG_PRINTLN(len); return; } - memcpy(&(incoming.program), incomingData, sizeof(incoming)); - uint32_t cur_seq = incoming.seq[0] | (incoming.seq[1] << 8) | (incoming.seq[2] << 16) | (incoming.seq[3] << 24); - + uint32_t cur_seq = incoming->seq[0] | (incoming->seq[1] << 8) | (incoming->seq[2] << 16) | (incoming->seq[3] << 24); if (cur_seq == last_seq) { return; } - - DEBUG_PRINT(F("Incoming ESP Now Packet[")); + DEBUG_PRINT(F("Incoming ESP Now Packet [")); DEBUG_PRINT(cur_seq); - DEBUG_PRINT(F("] from sender[")); + DEBUG_PRINT(F("] from sender [")); DEBUG_PRINT(last_signal_src); DEBUG_PRINT(F("] button: ")); - DEBUG_PRINTLN(incoming.button); - switch (incoming.button) { - case WIZMOTE_BUTTON_ON : setOn(); stateUpdated(CALL_MODE_BUTTON); break; - case WIZMOTE_BUTTON_OFF : setOff(); stateUpdated(CALL_MODE_BUTTON); break; - case WIZMOTE_BUTTON_ONE : presetWithFallback(1, FX_MODE_STATIC, 0); resetNightMode(); break; - case WIZMOTE_BUTTON_TWO : presetWithFallback(2, FX_MODE_BREATH, 0); resetNightMode(); break; - case WIZMOTE_BUTTON_THREE : presetWithFallback(3, FX_MODE_FIRE_FLICKER, 0); resetNightMode(); break; - case WIZMOTE_BUTTON_FOUR : presetWithFallback(4, FX_MODE_RAINBOW, 0); resetNightMode(); break; - case WIZMOTE_BUTTON_NIGHT : activateNightMode(); stateUpdated(CALL_MODE_BUTTON); break; - case WIZMOTE_BUTTON_BRIGHT_UP : brightnessUp(); stateUpdated(CALL_MODE_BUTTON); break; - case WIZMOTE_BUTTON_BRIGHT_DOWN : brightnessDown(); stateUpdated(CALL_MODE_BUTTON); break; - default: break; - - } + DEBUG_PRINTLN(incoming->button); + if (!remoteJson(incoming->button)) + switch (incoming->button) { + case WIZMOTE_BUTTON_ON : setOn(); break; + case WIZMOTE_BUTTON_OFF : setOff(); break; + case WIZMOTE_BUTTON_ONE : presetWithFallback(1, FX_MODE_STATIC, 0); break; + case WIZMOTE_BUTTON_TWO : presetWithFallback(2, FX_MODE_BREATH, 0); break; + case WIZMOTE_BUTTON_THREE : presetWithFallback(3, FX_MODE_FIRE_FLICKER, 0); break; + case WIZMOTE_BUTTON_FOUR : presetWithFallback(4, FX_MODE_RAINBOW, 0); break; + case WIZMOTE_BUTTON_NIGHT : activateNightMode(); break; + case WIZMOTE_BUTTON_BRIGHT_UP : brightnessUp(); break; + case WIZMOTE_BUTTON_BRIGHT_DOWN : brightnessDown(); break; + case WIZ_SMART_BUTTON_ON : setOn(); break; + case WIZ_SMART_BUTTON_OFF : setOff(); break; + case WIZ_SMART_BUTTON_BRIGHT_UP : brightnessUp(); break; + case WIZ_SMART_BUTTON_BRIGHT_DOWN : brightnessDown(); break; + default: break; + } last_seq = cur_seq; } -void handleRemote() { - if (enable_espnow_remote) { - if (esp_now_state == ESP_NOW_STATE_UNINIT) { - DEBUG_PRINTLN(F("Initializing ESP_NOW listener")); - // Init ESP-NOW - if (esp_now_init() != 0) { - DEBUG_PRINTLN(F("Error initializing ESP-NOW")); - esp_now_state = ESP_NOW_STATE_ERROR; - } - - #ifdef ESP8266 - esp_now_set_self_role(ESP_NOW_ROLE_SLAVE); - #endif - - esp_now_register_recv_cb(OnDataRecv); - esp_now_state = ESP_NOW_STATE_ON; - } - } else { - if (esp_now_state == ESP_NOW_STATE_ON) { - DEBUG_PRINTLN(F("Disabling ESP-NOW Remote Listener")); - if (esp_now_deinit() != 0) { - DEBUG_PRINTLN(F("Error de-initializing ESP-NOW")); - } - esp_now_state = ESP_NOW_STATE_UNINIT; - } else if (esp_now_state == ESP_NOW_STATE_ERROR) { - //Clear any error states (allows retrying by cycling) - esp_now_state = ESP_NOW_STATE_UNINIT; - } - } -} - +#else +void handleRemote(uint8_t *incomingData, size_t len) {} #endif \ No newline at end of file diff --git a/wled00/set.cpp b/wled00/set.cpp old mode 100644 new mode 100755 index 71db6c067..e83911783 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -19,27 +19,42 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) //WIFI SETTINGS if (subPage == SUBPAGE_WIFI) { - strlcpy(clientSSID,request->arg(F("CS")).c_str(), 33); + char oldSSID[sizeof(clientSSID)]; - if (!isAsterisksOnly(request->arg(F("CP")).c_str(), 65)) strlcpy(clientPass, request->arg(F("CP")).c_str(), 65); + strcpy(oldSSID, clientSSID); + strlcpy(clientSSID,request->arg(F("CS")).c_str(), 33); + if (!strcmp(oldSSID, clientSSID)) forceReconnect = true; + + if (!isAsterisksOnly(request->arg(F("CP")).c_str(), 65)) { + strlcpy(clientPass, request->arg(F("CP")).c_str(), 65); + forceReconnect = true; + } strlcpy(cmDNS, request->arg(F("CM")).c_str(), 33); apBehavior = request->arg(F("AB")).toInt(); + strcpy(oldSSID, apSSID); strlcpy(apSSID, request->arg(F("AS")).c_str(), 33); + if (!strcmp(oldSSID, apSSID) && apActive) forceReconnect = true; apHide = request->hasArg(F("AH")); int passlen = request->arg(F("AP")).length(); - if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg(F("AP")).c_str(), 65))) strlcpy(apPass, request->arg(F("AP")).c_str(), 65); - int t = request->arg(F("AC")).toInt(); if (t > 0 && t < 14) apChannel = t; + if (passlen == 0 || (passlen > 7 && !isAsterisksOnly(request->arg(F("AP")).c_str(), 65))) { + strlcpy(apPass, request->arg(F("AP")).c_str(), 65); + forceReconnect = true; + } + int t = request->arg(F("AC")).toInt(); + if (t != apChannel) forceReconnect = true; + if (t > 0 && t < 14) apChannel = t; + force802_3g = request->hasArg(F("FG")); noWifiSleep = request->hasArg(F("WS")); #ifndef WLED_DISABLE_ESPNOW - enable_espnow_remote = request->hasArg(F("RE")); - strlcpy(linked_remote,request->arg(F("RMAC")).c_str(), 13); - - //Normalize MAC format to lowercase - strlcpy(linked_remote,strlwr(linked_remote), 13); + bool oldESPNow = enableESPNow; + enableESPNow = request->hasArg(F("RE")); + if (oldESPNow != enableESPNow) forceReconnect = true; + strlcpy(linked_remote, request->arg(F("RMAC")).c_str(), 13); + strlwr(linked_remote); //Normalize MAC format to lowercase #endif #ifdef WLED_USE_ETHERNET @@ -80,10 +95,13 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } } - uint8_t colorOrder, type, skip, awmode, channelSwap; - uint16_t length, start; + uint8_t colorOrder, type, skip, awmode, channelSwap, maPerLed; + uint16_t length, start, maMax; uint8_t pins[5] = {255, 255, 255, 255, 255}; + uint16_t ablMilliampsMax = request->arg(F("MA")).toInt(); + BusManager::setMilliampsMax(ablMilliampsMax); + autoSegments = request->hasArg(F("MS")); correctWB = request->hasArg(F("CCT")); cctFromRgb = request->hasArg(F("CR")); @@ -106,6 +124,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) char aw[4] = "AW"; aw[2] = 48+s; aw[3] = 0; //auto white mode char wo[4] = "WO"; wo[2] = 48+s; wo[3] = 0; //channel swap char sp[4] = "SP"; sp[2] = 48+s; sp[3] = 0; //bus clock speed (DotStar & PWM) + char la[4] = "LA"; la[2] = 48+s; la[3] = 0; //LED mA + char ma[4] = "MA"; ma[2] = 48+s; ma[3] = 0; //max mA if (!request->hasArg(lp)) { DEBUG_PRINT(F("No data for ")); DEBUG_PRINTLN(s); @@ -117,7 +137,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) pins[i] = (request->arg(lp).length() > 0) ? request->arg(lp).toInt() : 255; } type = request->arg(lt).toInt(); - type |= request->hasArg(rf) << 7; // off refresh override skip = request->arg(sl).toInt(); colorOrder = request->arg(co).toInt(); start = (request->hasArg(ls)) ? request->arg(ls).toInt() : t; @@ -127,33 +146,41 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) break; // no parameter } awmode = request->arg(aw).toInt(); - uint16_t freqHz = request->arg(sp).toInt(); - if (type > TYPE_ONOFF && type < 49) { - switch (freqHz) { - case 0 : freqHz = WLED_PWM_FREQ/3; break; - case 1 : freqHz = WLED_PWM_FREQ/2; break; + uint16_t freq = request->arg(sp).toInt(); + if (IS_PWM(type)) { + switch (freq) { + case 0 : freq = WLED_PWM_FREQ/3; break; + case 1 : freq = WLED_PWM_FREQ/2; break; default: - case 2 : freqHz = WLED_PWM_FREQ; break; - case 3 : freqHz = WLED_PWM_FREQ*2; break; - case 4 : freqHz = WLED_PWM_FREQ*3; break; + case 2 : freq = WLED_PWM_FREQ; break; + case 3 : freq = WLED_PWM_FREQ*4/3; break; + case 4 : freq = WLED_PWM_FREQ*2; break; } - } else if (type > 48 && type < 64) { - switch (freqHz) { + } else if (IS_DIGITAL(type) && IS_2PIN(type)) { + switch (freq) { default: - case 0 : freqHz = 1000; break; - case 1 : freqHz = 2000; break; - case 2 : freqHz = 5000; break; - case 3 : freqHz = 10000; break; - case 4 : freqHz = 20000; break; + case 0 : freq = 1000; break; + case 1 : freq = 2000; break; + case 2 : freq = 5000; break; + case 3 : freq = 10000; break; + case 4 : freq = 20000; break; } } else { - freqHz = 0; + freq = 0; } - channelSwap = (type == TYPE_SK6812_RGBW || type == TYPE_TM1814) ? request->arg(wo).toInt() : 0; + channelSwap = Bus::hasWhite(type) ? request->arg(wo).toInt() : 0; + if (type == TYPE_ONOFF || IS_PWM(type) || IS_VIRTUAL(type)) { // analog and virtual + maPerLed = 0; + maMax = 0; + } else { + maPerLed = request->arg(la).toInt(); + maMax = request->arg(ma).toInt(); // if ABL is disabled this will be 0 + } + type |= request->hasArg(rf) << 7; // off refresh override // actual finalization is done in WLED::loop() (removing old busses and adding new) // this may happen even before this loop is finished so we do "doInitBusses" after the loop if (busConfigs[s] != nullptr) delete busConfigs[s]; - busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freqHz, useGlobalLedBuffer); + busConfigs[s] = new BusConfig(type, pins, start, length, colorOrder | (channelSwap<<4), request->hasArg(cv), skip, awmode, freq, useGlobalLedBuffer, maPerLed, maMax); busesChanged = true; } //doInitBusses = busesChanged; // we will do that below to ensure all input data is processed @@ -163,14 +190,16 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) char xs[4] = "XS"; xs[2] = 48+s; xs[3] = 0; //start LED char xc[4] = "XC"; xc[2] = 48+s; xc[3] = 0; //strip length char xo[4] = "XO"; xo[2] = 48+s; xo[3] = 0; //color order + char xw[4] = "XW"; xw[2] = 48+s; xw[3] = 0; //W swap if (request->hasArg(xs)) { start = request->arg(xs).toInt(); length = request->arg(xc).toInt(); - colorOrder = request->arg(xo).toInt(); + colorOrder = request->arg(xo).toInt() & 0x0F; + colorOrder |= (request->arg(xw).toInt() & 0x0F) << 4; // add W swap information com.add(start, length, colorOrder); } } - busses.updateColorOrderMap(com); + BusManager::updateColorOrderMap(com); // upate other pins int hw_ir_pin = request->arg(F("IR")).toInt(); @@ -195,15 +224,22 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) char bt[4] = "BT"; bt[2] = (i<10?48:55)+i; bt[3] = 0; // button pin (use A,B,C,... if WLED_MAX_BUTTONS>10) char be[4] = "BE"; be[2] = (i<10?48:55)+i; be[3] = 0; // button type (use A,B,C,... if WLED_MAX_BUTTONS>10) int hw_btn_pin = request->arg(bt).toInt(); - if (pinManager.allocatePin(hw_btn_pin,false,PinOwner::Button)) { + if (hw_btn_pin >= 0 && pinManager.allocatePin(hw_btn_pin,false,PinOwner::Button)) { btnPin[i] = hw_btn_pin; buttonType[i] = request->arg(be).toInt(); #ifdef ARDUINO_ARCH_ESP32 - // ESP32 only: check that analog button pin is a valid ADC gpio + // ESP32 only: check that button pin is a valid gpio if (((buttonType[i] == BTN_TYPE_ANALOG) || (buttonType[i] == BTN_TYPE_ANALOG_INVERTED)) && (digitalPinToAnalogChannel(btnPin[i]) < 0)) { // not an ADC analog pin - if (btnPin[i] >= 0) DEBUG_PRINTF("PIN ALLOC error: GPIO%d for analog button #%d is not an analog pin!\n", btnPin[i], i); + DEBUG_PRINTF("PIN ALLOC error: GPIO%d for analog button #%d is not an analog pin!\n", btnPin[i], i); + btnPin[i] = -1; + pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); + } + else if ((buttonType[i] == BTN_TYPE_TOUCH || buttonType[i] == BTN_TYPE_TOUCH_SWITCH) && digitalPinToTouchChannel(btnPin[i]) < 0) + { + // not a touch pin + DEBUG_PRINTF("PIN ALLOC error: GPIO%d for touch button #%d is not an touch pin!\n", btnPin[i], i); btnPin[i] = -1; pinManager.deallocatePin(hw_btn_pin,PinOwner::Button); } @@ -227,9 +263,6 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } touchThreshold = request->arg(F("TT")).toInt(); - strip.ablMilliampsMax = request->arg(F("MA")).toInt(); - strip.milliampsPerLed = request->arg(F("LA")).toInt(); - briS = request->arg(F("CA")).toInt(); turnOnAtBoot = request->hasArg(F("BO")); @@ -247,6 +280,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } fadeTransition = request->hasArg(F("TF")); + modeBlending = request->hasArg(F("EB")); t = request->arg(F("TD")).toInt(); if (t >= 0) transitionDelayDefault = t; strip.paletteFade = request->hasArg(F("PF")); @@ -271,14 +305,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (subPage == SUBPAGE_UI) { strlcpy(serverDescription, request->arg(F("DS")).c_str(), 33); - syncToggleReceive = request->hasArg(F("ST")); - #ifdef WLED_ENABLE_SIMPLE_UI - if (simplifiedUI ^ request->hasArg(F("SU"))) { - // UI selection changed, invalidate browser cache - cacheInvalidate++; - } + //syncToggleReceive = request->hasArg(F("ST")); simplifiedUI = request->hasArg(F("SU")); - #endif DEBUG_PRINTLN(F("Enumerating ledmaps")); enumerateLedmaps(); DEBUG_PRINTLN(F("Loading custom palettes")); @@ -293,6 +321,10 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) t = request->arg(F("U2")).toInt(); if (t > 0) udpPort2 = t; + #ifndef WLED_DISABLE_ESPNOW + useESPNowSync = request->hasArg(F("EN")); + #endif + syncGroups = request->arg(F("GS")).toInt(); receiveGroups = request->arg(F("GR")).toInt(); @@ -301,13 +333,11 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) receiveNotificationEffects = request->hasArg(F("RX")); receiveSegmentOptions = request->hasArg(F("SO")); receiveSegmentBounds = request->hasArg(F("SG")); - receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects || receiveSegmentOptions); - notifyDirectDefault = request->hasArg(F("SD")); - notifyDirect = notifyDirectDefault; + sendNotifications = request->hasArg(F("SS")); + notifyDirect = request->hasArg(F("SD")); notifyButton = request->hasArg(F("SB")); notifyAlexa = request->hasArg(F("SA")); notifyHue = request->hasArg(F("SH")); - notifyMacro = request->hasArg(F("SM")); t = request->arg(F("UR")).toInt(); if ((t>=0) && (t<30)) udpNumRetries = t; @@ -317,8 +347,9 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) if (!nodeListEnabled) Nodes.clear(); nodeBroadcastEnabled = request->hasArg(F("NB")); - receiveDirect = request->hasArg(F("RD")); + receiveDirect = request->hasArg(F("RD")); // UDP realtime useMainSegmentOnly = request->hasArg(F("MO")); + realtimeRespectLedMaps = request->hasArg(F("RLM")); e131SkipOutOfSequence = request->hasArg(F("ES")); e131Multicast = request->hasArg(F("EM")); t = request->arg(F("EP")).toInt(); @@ -347,14 +378,14 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) #ifdef WLED_ENABLE_MQTT mqttEnabled = request->hasArg(F("MQ")); - strlcpy(mqttServer, request->arg(F("MS")).c_str(), 33); + strlcpy(mqttServer, request->arg(F("MS")).c_str(), MQTT_MAX_SERVER_LEN+1); t = request->arg(F("MQPORT")).toInt(); if (t > 0) mqttPort = t; strlcpy(mqttUser, request->arg(F("MQUSER")).c_str(), 41); if (!isAsterisksOnly(request->arg(F("MQPASS")).c_str(), 41)) strlcpy(mqttPass, request->arg(F("MQPASS")).c_str(), 65); strlcpy(mqttClientID, request->arg(F("MQCID")).c_str(), 41); - strlcpy(mqttDeviceTopic, request->arg(F("MD")).c_str(), 33); - strlcpy(mqttGroupTopic, request->arg(F("MG")).c_str(), 33); + strlcpy(mqttDeviceTopic, request->arg(F("MD")).c_str(), MQTT_MAX_TOPIC_LEN+1); + strlcpy(mqttGroupTopic, request->arg(F("MG")).c_str(), MQTT_MAX_TOPIC_LEN+1); buttonPublishMqtt = request->hasArg(F("BM")); retainMqttMsg = request->hasArg(F("RT")); #endif @@ -597,7 +628,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage) } } - JsonObject um = doc.createNestedObject("um"); + JsonObject um = pDoc->createNestedObject("um"); size_t args = request->args(); uint16_t j=0; @@ -1003,7 +1034,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) //toggle receive UDP direct notifications pos = req.indexOf(F("RN=")); - if (pos > 0) receiveNotifications = (req.charAt(pos+3) != '0'); + if (pos > 0) receiveGroups = (req.charAt(pos+3) != '0') ? receiveGroups | 1 : receiveGroups & 0xFE; //receive live data via UDP/Hyperion pos = req.indexOf(F("RD=")); @@ -1062,6 +1093,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply) pos = req.indexOf(F("TT=")); if (pos > 0) transitionDelay = getNumVal(&req, pos); + if (fadeTransition) strip.setTransition(transitionDelay); //set time (unix timestamp) pos = req.indexOf(F("ST=")); diff --git a/wled00/udp.cpp b/wled00/udp.cpp index acd2bd06b..65c35882b 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -5,15 +5,26 @@ */ #define UDP_SEG_SIZE 36 -#define SEG_OFFSET (41+(MAX_NUM_SEGMENTS*UDP_SEG_SIZE)) +#define SEG_OFFSET (41) #define WLEDPACKETSIZE (41+(MAX_NUM_SEGMENTS*UDP_SEG_SIZE)+0) #define UDP_IN_MAXSIZE 1472 #define PRESUMED_NETWORK_DELAY 3 //how many ms could it take on avg to reach the receiver? This will be added to transmitted times +typedef struct PartialEspNowPacket { + uint8_t magic; + uint8_t packet; + uint8_t segs; + uint8_t data[247]; +} partial_packet_t; + void notify(byte callMode, bool followUp) { +#ifndef WLED_DISABLE_ESPNOW + if (!udpConnected && !useESPNowSync) return; +#else if (!udpConnected) return; - if (!syncGroups) return; +#endif + if (!syncGroups || !sendNotificationsRT) return; switch (callMode) { case CALL_MODE_INIT: return; @@ -26,7 +37,7 @@ void notify(byte callMode, bool followUp) case CALL_MODE_ALEXA: if (!notifyAlexa) return; break; default: return; } - byte udpOut[WLEDPACKETSIZE]; + byte udpOut[WLEDPACKETSIZE]; //TODO: optimize size to use only active segments Segment& mainseg = strip.getMainSegment(); udpOut[0] = 0; //0: wled notifier protocol 1: WARLS protocol udpOut[1] = callMode; @@ -128,9 +139,9 @@ void notify(byte callMode, bool followUp) udpOut[29+ofs] = selseg.custom1; udpOut[30+ofs] = selseg.custom2; udpOut[31+ofs] = selseg.custom3 | (selseg.check1<<5) | (selseg.check2<<6) | (selseg.check3<<7); - udpOut[32+ofs] = selseg.startY >> 8; + udpOut[32+ofs] = selseg.startY >> 8; // ATM always 0 as Segment::startY is 8-bit udpOut[33+ofs] = selseg.startY & 0xFF; - udpOut[34+ofs] = selseg.stopY >> 8; + udpOut[34+ofs] = selseg.stopY >> 8; // ATM always 0 as Segment::stopY is 8-bit udpOut[35+ofs] = selseg.stopY & 0xFF; ++s; } @@ -138,17 +149,247 @@ void notify(byte callMode, bool followUp) //uint16_t offs = SEG_OFFSET; //next value to be added has index: udpOut[offs + 0] - IPAddress broadcastIp; - broadcastIp = ~uint32_t(Network.subnetMask()) | uint32_t(Network.gatewayIP()); - - notifierUdp.beginPacket(broadcastIp, udpPort); - notifierUdp.write(udpOut, WLEDPACKETSIZE); - notifierUdp.endPacket(); +#ifndef WLED_DISABLE_ESPNOW + if (enableESPNow && useESPNowSync && statusESPNow == ESP_NOW_STATE_ON) { + partial_packet_t buffer = {'W', 0, (uint8_t)s, {0}}; + // send global data + DEBUG_PRINTLN(F("ESP-NOW sending first packet.")); + memcpy(buffer.data, udpOut, 41); + auto err = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, reinterpret_cast(&buffer), 41+3); + if (!err) { + // send segment data + buffer.packet++; + size_t packetSize = 0; + int32_t err = 0; + for (size_t i = 0; i < s; i++) { + memcpy(buffer.data + packetSize, &udpOut[41+i*UDP_SEG_SIZE], UDP_SEG_SIZE); + packetSize += UDP_SEG_SIZE; + if (packetSize + UDP_SEG_SIZE < sizeof(buffer.data)/sizeof(uint8_t)) continue; + DEBUG_PRINTF("ESP-NOW sending packet: %d (%d)\n", (int)buffer.packet, packetSize+3); + err = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, reinterpret_cast(&buffer), packetSize+3); + buffer.packet++; + packetSize = 0; + if (err) break; + } + if (!err && packetSize > 0) { + DEBUG_PRINTF("ESP-NOW sending last packet: %d (%d)\n", (int)buffer.packet, packetSize+3); + err = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, reinterpret_cast(&buffer), packetSize+3); + } + if (err) { + DEBUG_PRINTLN(F("ESP-NOW sending packet failed.")); + } + } + } + if (udpConnected) +#endif + { + DEBUG_PRINTLN(F("UDP sending packet.")); + IPAddress broadcastIp = ~uint32_t(Network.subnetMask()) | uint32_t(Network.gatewayIP()); + notifierUdp.beginPacket(broadcastIp, udpPort); + notifierUdp.write(udpOut, WLEDPACKETSIZE); // TODO: add actual used buffer size + notifierUdp.endPacket(); + } notificationSentCallMode = callMode; notificationSentTime = millis(); notificationCount = followUp ? notificationCount + 1 : 0; } +void parseNotifyPacket(uint8_t *udpIn) { + //ignore notification if received within a second after sending a notification ourselves + if (millis() - notificationSentTime < 1000) return; + if (udpIn[1] > 199) return; //do not receive custom versions + + //compatibilityVersionByte: + byte version = udpIn[11]; + DEBUG_PRINT(F("UDP packet version: ")); DEBUG_PRINTLN(version); + + // if we are not part of any sync group ignore message + if (version < 9) { + // legacy senders are treated as if sending in sync group 1 only + if (!(receiveGroups & 0x01)) return; + } else if (!(receiveGroups & udpIn[36])) return; + + bool someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects); + + // set transition time before making any segment changes + if (version > 3) { + if (fadeTransition) { + jsonTransitionOnce = true; + strip.setTransition(((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00)); + } + } + + //apply colors from notification to main segment, only if not syncing full segments + if ((receiveNotificationColor || !someSel) && (version < 11 || !receiveSegmentOptions)) { + // primary color, only apply white if intented (version > 0) + strip.setColor(0, RGBW32(udpIn[3], udpIn[4], udpIn[5], (version > 0) ? udpIn[10] : 0)); + if (version > 1) { + strip.setColor(1, RGBW32(udpIn[12], udpIn[13], udpIn[14], udpIn[15])); // secondary color + } + if (version > 6) { + strip.setColor(2, RGBW32(udpIn[20], udpIn[21], udpIn[22], udpIn[23])); // tertiary color + if (version > 9 && udpIn[37] < 255) { // valid CCT/Kelvin value + uint16_t cct = udpIn[38]; + if (udpIn[37] > 0) { //Kelvin + cct |= (udpIn[37] << 8); + } + strip.setCCT(cct); + } + } + } + + bool timebaseUpdated = false; + //apply effects from notification + bool applyEffects = (receiveNotificationEffects || !someSel); + if (applyEffects && currentPlaylist >= 0) unloadPlaylist(); + if (version > 10 && (receiveSegmentOptions || receiveSegmentBounds)) { + uint8_t numSrcSegs = udpIn[39]; + DEBUG_PRINT(F("UDP segments: ")); DEBUG_PRINTLN(numSrcSegs); + // are we syncing bounds and slave has more active segments than master? + if (receiveSegmentBounds && numSrcSegs < strip.getActiveSegmentsNum()) { + DEBUG_PRINTLN(F("Removing excessive segments.")); + for (size_t i=strip.getSegmentsNum(); i>numSrcSegs; i--) { + if (strip.getSegment(i).isActive()) { + strip.setSegment(i-1,0,0); // delete segment + } + } + } + size_t inactiveSegs = 0; + for (size_t i = 0; i < numSrcSegs && i < strip.getMaxSegments(); i++) { + uint16_t ofs = 41 + i*udpIn[40]; //start of segment offset byte + uint8_t id = udpIn[0 +ofs]; + DEBUG_PRINT(F("UDP segment received: ")); DEBUG_PRINTLN(id); + if (id > strip.getSegmentsNum()) break; + else if (id == strip.getSegmentsNum()) { + if (receiveSegmentBounds && id < strip.getMaxSegments()) strip.appendSegment(); + else break; + } + DEBUG_PRINT(F("UDP segment check: ")); DEBUG_PRINTLN(id); + Segment& selseg = strip.getSegment(id); + // if we are not syncing bounds skip unselected segments + if (selseg.isActive() && !(selseg.isSelected() || receiveSegmentBounds)) continue; + // ignore segment if it is inactive and we are not syncing bounds + if (!receiveSegmentBounds) { + if (!selseg.isActive()) { + inactiveSegs++; + DEBUG_PRINTLN(F("Inactive segment.")); + continue; + } else { + id += inactiveSegs; // adjust id + } + } + DEBUG_PRINT(F("UDP segment processing: ")); DEBUG_PRINTLN(id); + + uint16_t start = (udpIn[1+ofs] << 8 | udpIn[2+ofs]); + uint16_t stop = (udpIn[3+ofs] << 8 | udpIn[4+ofs]); + uint16_t startY = version > 11 ? (udpIn[32+ofs] << 8 | udpIn[33+ofs]) : 0; + uint16_t stopY = version > 11 ? (udpIn[34+ofs] << 8 | udpIn[35+ofs]) : 1; + uint16_t offset = (udpIn[7+ofs] << 8 | udpIn[8+ofs]); + if (!receiveSegmentOptions) { + DEBUG_PRINTF("Set segment w/o options: %d [%d,%d;%d,%d]\n", id, (int)start, (int)stop, (int)startY, (int)stopY); + strip.suspend(); //should not be needed as UDP handling is not done in ISR callbacks but still added "just in case" + selseg.setUp(start, stop, selseg.grouping, selseg.spacing, offset, startY, stopY); + strip.resume(); + continue; // we do receive bounds, but not options + } + selseg.options = (selseg.options & 0x0071U) | (udpIn[9 +ofs] & 0x0E); // ignore selected, freeze, reset & transitional + selseg.setOpacity(udpIn[10+ofs]); + if (applyEffects) { + DEBUG_PRINT(F("Apply effect: ")); DEBUG_PRINTLN(id); + selseg.setMode(udpIn[11+ofs]); + selseg.speed = udpIn[12+ofs]; + selseg.intensity = udpIn[13+ofs]; + selseg.palette = udpIn[14+ofs]; + } + if (receiveNotificationColor || !someSel) { + DEBUG_PRINT(F("Apply color: ")); DEBUG_PRINTLN(id); + selseg.setColor(0, RGBW32(udpIn[15+ofs],udpIn[16+ofs],udpIn[17+ofs],udpIn[18+ofs])); + selseg.setColor(1, RGBW32(udpIn[19+ofs],udpIn[20+ofs],udpIn[21+ofs],udpIn[22+ofs])); + selseg.setColor(2, RGBW32(udpIn[23+ofs],udpIn[24+ofs],udpIn[25+ofs],udpIn[26+ofs])); + selseg.setCCT(udpIn[27+ofs]); + } + if (version > 11) { + // when applying synced options ignore selected as it may be used as indicator of which segments to sync + // freeze, reset should never be synced + // LSB to MSB: select, reverse, on, mirror, freeze, reset, reverse_y, mirror_y, transpose, map1d2d (3), ssim (2), set (2) + DEBUG_PRINT(F("Apply options: ")); DEBUG_PRINTLN(id); + selseg.options = (selseg.options & 0b0000000000110001U) | (udpIn[28+ofs]<<8) | (udpIn[9 +ofs] & 0b11001110U); // ignore selected, freeze, reset + if (applyEffects) { + DEBUG_PRINT(F("Apply sliders: ")); DEBUG_PRINTLN(id); + selseg.custom1 = udpIn[29+ofs]; + selseg.custom2 = udpIn[30+ofs]; + selseg.custom3 = udpIn[31+ofs] & 0x1F; + selseg.check1 = (udpIn[31+ofs]>>5) & 0x1; + selseg.check1 = (udpIn[31+ofs]>>6) & 0x1; + selseg.check1 = (udpIn[31+ofs]>>7) & 0x1; + } + } + if (receiveSegmentBounds) { + DEBUG_PRINTF("Set segment w/ options: %d [%d,%d;%d,%d]\n", id, (int)start, (int)stop, (int)startY, (int)stopY); + strip.suspend(); //should not be needed as UDP handling is not done in ISR callbacks but still added "just in case" + selseg.setUp(start, stop, udpIn[5+ofs], udpIn[6+ofs], offset, startY, stopY); + strip.resume(); + } else { + DEBUG_PRINTF("Set segment grouping: %d [%d,%d]\n", id, (int)udpIn[5+ofs], (int)udpIn[6+ofs]); + strip.suspend(); //should not be needed as UDP handling is not done in ISR callbacks but still added "just in case" + selseg.setUp(selseg.start, selseg.stop, udpIn[5+ofs], udpIn[6+ofs], selseg.offset, selseg.startY, selseg.stopY); + strip.resume(); + } + } + stateChanged = true; + } + + // simple effect sync, applies to all selected segments + if (applyEffects && (version < 11 || !receiveSegmentOptions)) { + for (size_t i = 0; i < strip.getSegmentsNum(); i++) { + Segment& seg = strip.getSegment(i); + if (!seg.isActive() || !seg.isSelected()) continue; + seg.setMode(udpIn[8]); + seg.speed = udpIn[9]; + if (version > 2) seg.intensity = udpIn[16]; + if (version > 4) seg.setPalette(udpIn[19]); + } + stateChanged = true; + } + + if (applyEffects && version > 5) { + uint32_t t = (udpIn[25] << 24) | (udpIn[26] << 16) | (udpIn[27] << 8) | (udpIn[28]); + t += PRESUMED_NETWORK_DELAY; //adjust trivially for network delay + t -= millis(); + strip.timebase = t; + timebaseUpdated = true; + } + + //adjust system time, but only if sender is more accurate than self + if (version > 7) { + Toki::Time tm; + tm.sec = (udpIn[30] << 24) | (udpIn[31] << 16) | (udpIn[32] << 8) | (udpIn[33]); + tm.ms = (udpIn[34] << 8) | (udpIn[35]); + if (udpIn[29] > toki.getTimeSource()) { //if sender's time source is more accurate + toki.adjust(tm, PRESUMED_NETWORK_DELAY); //adjust trivially for network delay + uint8_t ts = TOKI_TS_UDP; + if (udpIn[29] > 99) ts = TOKI_TS_UDP_NTP; + else if (udpIn[29] >= TOKI_TS_SEC) ts = TOKI_TS_UDP_SEC; + toki.setTime(tm, ts); + } else if (timebaseUpdated && toki.getTimeSource() > 99) { //if we both have good times, get a more accurate timebase + Toki::Time myTime = toki.getTime(); + uint32_t diff = toki.msDifference(tm, myTime); + strip.timebase -= PRESUMED_NETWORK_DELAY; //no need to presume, use difference between NTP times at send and receive points + if (toki.isLater(tm, myTime)) { + strip.timebase += diff; + } else { + strip.timebase -= diff; + } + } + } + + nightlightActive = udpIn[6]; + if (nightlightActive) nightlightDelayMins = udpIn[7]; + + if (receiveNotificationBrightness || !someSel) bri = udpIn[2]; + stateUpdated(CALL_MODE_NOTIFICATION); +} + void realtimeLock(uint32_t timeoutMs, byte md) { if (!realtimeMode && !realtimeOverride) { @@ -195,6 +436,8 @@ void exitRealtime() { realtimeIP[0] = 0; if (useMainSegmentOnly) { // unfreeze live segment again strip.getMainSegment().freeze = false; + } else { + strip.show(); // possible fix for #3589 } updateInterfaces(CALL_MODE_WS_SEND); } @@ -262,8 +505,6 @@ void handleNotifications() } } - if (!(receiveNotifications || receiveDirect)) return; - localIP = Network.localIP(); //notifier and UDP realtime if (!packetSize || packetSize > UDP_IN_MAXSIZE) return; @@ -306,160 +547,10 @@ void handleNotifications() } //wled notifier, ignore if realtime packets active - if (udpIn[0] == 0 && !realtimeMode && receiveNotifications) + if (udpIn[0] == 0 && !realtimeMode && receiveGroups) { - //ignore notification if received within a second after sending a notification ourselves - if (millis() - notificationSentTime < 1000) return; - if (udpIn[1] > 199) return; //do not receive custom versions - - //compatibilityVersionByte: - byte version = udpIn[11]; - - // if we are not part of any sync group ignore message - if (version < 9 || version > 199) { - // legacy senders are treated as if sending in sync group 1 only - if (!(receiveGroups & 0x01)) return; - } else if (!(receiveGroups & udpIn[36])) return; - - bool someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects); - - //apply colors from notification to main segment, only if not syncing full segments - if ((receiveNotificationColor || !someSel) && (version < 11 || !receiveSegmentOptions)) { - // primary color, only apply white if intented (version > 0) - strip.setColor(0, RGBW32(udpIn[3], udpIn[4], udpIn[5], (version > 0) ? udpIn[10] : 0)); - if (version > 1) { - strip.setColor(1, RGBW32(udpIn[12], udpIn[13], udpIn[14], udpIn[15])); // secondary color - } - if (version > 6) { - strip.setColor(2, RGBW32(udpIn[20], udpIn[21], udpIn[22], udpIn[23])); // tertiary color - if (version > 9 && version < 200 && udpIn[37] < 255) { // valid CCT/Kelvin value - uint16_t cct = udpIn[38]; - if (udpIn[37] > 0) { //Kelvin - cct |= (udpIn[37] << 8); - } - strip.setCCT(cct); - } - } - } - - bool timebaseUpdated = false; - //apply effects from notification - bool applyEffects = (receiveNotificationEffects || !someSel); - if (version < 200) - { - if (applyEffects && currentPlaylist >= 0) unloadPlaylist(); - if (version > 10 && (receiveSegmentOptions || receiveSegmentBounds)) { - uint8_t numSrcSegs = udpIn[39]; - for (size_t i = 0; i < numSrcSegs; i++) { - uint16_t ofs = 41 + i*udpIn[40]; //start of segment offset byte - uint8_t id = udpIn[0 +ofs]; - if (id > strip.getSegmentsNum()) break; - - Segment& selseg = strip.getSegment(id); - if (!selseg.isActive() || !selseg.isSelected()) continue; //do not apply to non selected segments - - uint16_t startY = 0, start = (udpIn[1+ofs] << 8 | udpIn[2+ofs]); - uint16_t stopY = 1, stop = (udpIn[3+ofs] << 8 | udpIn[4+ofs]); - uint16_t offset = (udpIn[7+ofs] << 8 | udpIn[8+ofs]); - if (!receiveSegmentOptions) { - selseg.setUp(start, stop, selseg.grouping, selseg.spacing, offset, startY, stopY); - continue; - } - //for (size_t j = 1; j<4; j++) selseg.setOption(j, (udpIn[9 +ofs] >> j) & 0x01); //only take into account mirrored, on, reversed; ignore selected - selseg.options = (selseg.options & 0x0071U) | (udpIn[9 +ofs] & 0x0E); // ignore selected, freeze, reset & transitional - selseg.setOpacity(udpIn[10+ofs]); - if (applyEffects) { - strip.setMode(id, udpIn[11+ofs]); - selseg.speed = udpIn[12+ofs]; - selseg.intensity = udpIn[13+ofs]; - selseg.palette = udpIn[14+ofs]; - } - if (receiveNotificationColor || !someSel) { - selseg.setColor(0, RGBW32(udpIn[15+ofs],udpIn[16+ofs],udpIn[17+ofs],udpIn[18+ofs])); - selseg.setColor(1, RGBW32(udpIn[19+ofs],udpIn[20+ofs],udpIn[21+ofs],udpIn[22+ofs])); - selseg.setColor(2, RGBW32(udpIn[23+ofs],udpIn[24+ofs],udpIn[25+ofs],udpIn[26+ofs])); - selseg.setCCT(udpIn[27+ofs]); - } - if (version > 11) { - // when applying synced options ignore selected as it may be used as indicator of which segments to sync - // freeze, reset & transitional should never be synced - selseg.options = (selseg.options & 0x0071U) | (udpIn[28+ofs]<<8) | (udpIn[9 +ofs] & 0x8E); // ignore selected, freeze, reset & transitional - if (applyEffects) { - selseg.custom1 = udpIn[29+ofs]; - selseg.custom2 = udpIn[30+ofs]; - selseg.custom3 = udpIn[31+ofs] & 0x1F; - selseg.check1 = (udpIn[31+ofs]>>5) & 0x1; - selseg.check1 = (udpIn[31+ofs]>>6) & 0x1; - selseg.check1 = (udpIn[31+ofs]>>7) & 0x1; - } - startY = (udpIn[32+ofs] << 8 | udpIn[33+ofs]); - stopY = (udpIn[34+ofs] << 8 | udpIn[35+ofs]); - } - if (receiveSegmentBounds) { - selseg.setUp(start, stop, udpIn[5+ofs], udpIn[6+ofs], offset, startY, stopY); - } else { - selseg.setUp(selseg.start, selseg.stop, udpIn[5+ofs], udpIn[6+ofs], selseg.offset, selseg.startY, selseg.stopY); - } - } - stateChanged = true; - } - - // simple effect sync, applies to all selected segments - if (applyEffects && (version < 11 || !receiveSegmentOptions)) { - for (size_t i = 0; i < strip.getSegmentsNum(); i++) { - Segment& seg = strip.getSegment(i); - if (!seg.isActive() || !seg.isSelected()) continue; - seg.setMode(udpIn[8]); - seg.speed = udpIn[9]; - if (version > 2) seg.intensity = udpIn[16]; - if (version > 4) seg.setPalette(udpIn[19]); - } - stateChanged = true; - } - - if (applyEffects && version > 5) { - uint32_t t = (udpIn[25] << 24) | (udpIn[26] << 16) | (udpIn[27] << 8) | (udpIn[28]); - t += PRESUMED_NETWORK_DELAY; //adjust trivially for network delay - t -= millis(); - strip.timebase = t; - timebaseUpdated = true; - } - } - - //adjust system time, but only if sender is more accurate than self - if (version > 7 && version < 200) - { - Toki::Time tm; - tm.sec = (udpIn[30] << 24) | (udpIn[31] << 16) | (udpIn[32] << 8) | (udpIn[33]); - tm.ms = (udpIn[34] << 8) | (udpIn[35]); - if (udpIn[29] > toki.getTimeSource()) { //if sender's time source is more accurate - toki.adjust(tm, PRESUMED_NETWORK_DELAY); //adjust trivially for network delay - uint8_t ts = TOKI_TS_UDP; - if (udpIn[29] > 99) ts = TOKI_TS_UDP_NTP; - else if (udpIn[29] >= TOKI_TS_SEC) ts = TOKI_TS_UDP_SEC; - toki.setTime(tm, ts); - } else if (timebaseUpdated && toki.getTimeSource() > 99) { //if we both have good times, get a more accurate timebase - Toki::Time myTime = toki.getTime(); - uint32_t diff = toki.msDifference(tm, myTime); - strip.timebase -= PRESUMED_NETWORK_DELAY; //no need to presume, use difference between NTP times at send and receive points - if (toki.isLater(tm, myTime)) { - strip.timebase += diff; - } else { - strip.timebase -= diff; - } - } - } - - if (version > 3) - { - transitionDelayTemp = ((udpIn[17] << 0) & 0xFF) + ((udpIn[18] << 8) & 0xFF00); - } - - nightlightActive = udpIn[6]; - if (nightlightActive) nightlightDelayMins = udpIn[7]; - - if (receiveNotificationBrightness || !someSel) bri = udpIn[2]; - stateUpdated(CALL_MODE_NOTIFICATION); + DEBUG_PRINT(F("UDP notification from: ")); DEBUG_PRINTLN(notifierUdp.remoteIP()); + parseNotifyPacket(udpIn); return; } @@ -521,13 +612,13 @@ void handleNotifications() if (realtimeOverride && !(realtimeMode && useMainSegmentOnly)) return; uint16_t totalLen = strip.getLengthTotal(); - if (udpIn[0] == 1) //warls + if (udpIn[0] == 1 && packetSize > 5) //warls { for (size_t i = 2; i < packetSize -3; i += 4) { setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0); } - } else if (udpIn[0] == 2) //drgb + } else if (udpIn[0] == 2 && packetSize > 4) //drgb { uint16_t id = 0; for (size_t i = 2; i < packetSize -2; i += 3) @@ -536,7 +627,7 @@ void handleNotifications() id++; if (id >= totalLen) break; } - } else if (udpIn[0] == 3) //drgbw + } else if (udpIn[0] == 3 && packetSize > 6) //drgbw { uint16_t id = 0; for (size_t i = 2; i < packetSize -3; i += 4) @@ -545,7 +636,7 @@ void handleNotifications() id++; if (id >= totalLen) break; } - } else if (udpIn[0] == 4) //dnrgb + } else if (udpIn[0] == 4 && packetSize > 7) //dnrgb { uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00); for (size_t i = 4; i < packetSize -2; i += 3) @@ -554,7 +645,7 @@ void handleNotifications() setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0); id++; } - } else if (udpIn[0] == 5) //dnrgbw + } else if (udpIn[0] == 5 && packetSize > 8) //dnrgbw { uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00); for (size_t i = 4; i < packetSize -2; i += 4) @@ -577,8 +668,8 @@ void handleNotifications() apireq += (char*)udpIn; handleSet(nullptr, apireq); } else if (udpIn[0] == '{') { //JSON API - DeserializationError error = deserializeJson(doc, udpIn); - JsonObject root = doc.as(); + DeserializationError error = deserializeJson(*pDoc, udpIn); + JsonObject root = pDoc->as(); if (!error && !root.isNull()) deserializeState(root); } releaseJSONBufferLock(); @@ -739,7 +830,7 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8 if (sequenceNumber > 15) sequenceNumber = 0; if (!ddpUdp.beginPacket(client, DDP_DEFAULT_PORT)) { // port defined in ESPAsyncE131.h - DEBUG_PRINTLN(F("WiFiUDP.beginPacket returned an error")); + //DEBUG_PRINTLN(F("WiFiUDP.beginPacket returned an error")); return 1; // problem } @@ -780,7 +871,7 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8 } if (!ddpUdp.endPacket()) { - DEBUG_PRINTLN(F("WiFiUDP.endPacket returned an error")); + //DEBUG_PRINTLN(F("WiFiUDP.endPacket returned an error")); return 1; // problem } @@ -849,3 +940,78 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, uint8 } return 0; } + +#ifndef WLED_DISABLE_ESPNOW +// ESP-NOW message receive callback function +void espNowReceiveCB(uint8_t* address, uint8_t* data, uint8_t len, signed int rssi, bool broadcast) { + sprintf_P(last_signal_src, PSTR("%02x%02x%02x%02x%02x%02x"), address[0], address[1], address[2], address[3], address[4], address[5]); + + #ifdef WLED_DEBUG + DEBUG_PRINT(F("ESP-NOW: ")); DEBUG_PRINT(last_signal_src); DEBUG_PRINT(F(" -> ")); DEBUG_PRINTLN(len); + for (int i=0; i(data); + if (len < 3 || !broadcast || buffer->magic != 'W' || !useESPNowSync || WLED_CONNECTED) { + DEBUG_PRINTLN(F("ESP-NOW unexpected packet, not syncing or connected to WiFi.")); + return; + } + + static uint8_t *udpIn = nullptr; + static uint8_t packetsReceived = 0; // bitfield (max 5 packets ATM) + static uint8_t segsReceived = 0; + static unsigned long lastProcessed = 0; + + if (buffer->packet == 0) { + if (udpIn == nullptr) udpIn = (uint8_t *)malloc(WLEDPACKETSIZE); // we cannot use stack as we are in callback + DEBUG_PRINTLN(F("ESP-NOW inited UDP buffer.")); + memcpy(udpIn, buffer->data, len-3); // global data (41 bytes) + packetsReceived |= 0x01 << buffer->packet; + segsReceived = 0; + return; + } else if (((len-3)/UDP_SEG_SIZE)*UDP_SEG_SIZE != (len-3)) { + DEBUG_PRINTF("ESP-NOW incorrect packet size: %d (%d) [%d]\n", (int)buffer->packet, (int)len-3, (int)UDP_SEG_SIZE); + if (udpIn) free(udpIn); + udpIn = nullptr; + packetsReceived = 0; + segsReceived = 0; + return; + } + if (!udpIn) return; + + // TODO add verification if segsReceived > MAX_NUM_SEGMENTS or WLEDPACKETSIZE + + memcpy(udpIn+41+segsReceived, buffer->data, len-3); + packetsReceived |= 0x01 << buffer->packet; + segsReceived += (len-3)/UDP_SEG_SIZE; + + DEBUG_PRINTF("ESP-NOW packet received: %d (%d) [%d]\n", (int)buffer->packet, (int)len-3, (int)segsReceived); + + if (segsReceived == buffer->segs) { + // last packet received + if (millis() - lastProcessed > 250) { + DEBUG_PRINTLN(F("ESP-NOW processing complete message.")); + parseNotifyPacket(udpIn); + lastProcessed = millis(); + } else { + DEBUG_PRINTLN(F("ESP-NOW ignoring complete message.")); + } + free(udpIn); + udpIn = nullptr; + packetsReceived = 0; + segsReceived = 0; + } +} +#endif diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index c099658a5..6268aa983 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -177,6 +177,14 @@ #include "../usermods/boblight/boblight.h" #endif +#ifdef USERMOD_ANIMARTRIX +#include "../usermods/usermod_v2_animartrix/usermod_v2_animartrix.h" +#endif + +#ifdef USERMOD_INTERNAL_TEMPERATURE + #include "../usermods/Internal_Temperature_v2/usermod_internal_temperature.h" +#endif + #if defined(WLED_USE_SD_MMC) || defined(WLED_USE_SD_SPI) // This include of SD.h and SD_MMC.h must happen here, else they won't be // resolved correctly (when included in mod's header only) @@ -193,6 +201,13 @@ #include "../usermods/pwm_outputs/usermod_pwm_outputs.h" #endif +#ifdef USERMOD_MPU6050_IMU +#include "../usermods/mpu6050_imu/usermod_mpu6050_imu.h" +#endif + +#ifdef USERMOD_MPU6050_IMU +#include "../usermods/mpu6050_imu/usermod_gyro_surge.h" +#endif void registerUsermods() { @@ -202,6 +217,7 @@ void registerUsermods() * \/ \/ \/ */ //usermods.add(new MyExampleUsermod()); + #ifdef USERMOD_BATTERY usermods.add(new UsermodBattery()); #endif @@ -365,4 +381,20 @@ void registerUsermods() #ifdef USERMOD_SHT usermods.add(new ShtUsermod()); #endif + + #ifdef USERMOD_ANIMARTRIX + usermods.add(new AnimartrixUsermod("Animartrix", false)); + #endif + + #ifdef USERMOD_INTERNAL_TEMPERATURE + usermods.add(new InternalTemperatureUsermod()); + #endif + + #ifdef USERMOD_MPU6050_IMU + static MPU6050Driver mpu6050; usermods.add(&mpu6050); + #endif + + #ifdef USERMOD_GYRO_SURGE + static GyroSurge gyro_surge; usermods.add(&gyro_surge); + #endif } diff --git a/wled00/util.cpp b/wled00/util.cpp index b8dea2555..d6fa9fb18 100644 --- a/wled00/util.cpp +++ b/wled00/util.cpp @@ -69,6 +69,15 @@ bool getVal(JsonVariant elem, byte* val, byte vmin, byte vmax) { } +bool getBoolVal(JsonVariant elem, bool dflt) { + if (elem.is() && elem.as()[0] == 't') { + return !dflt; + } else { + return elem | dflt; + } +} + + bool updateVal(const char* req, const char* key, byte* val, byte minv, byte maxv) { const char *v = strstr(req, key); @@ -148,8 +157,14 @@ bool oappendi(int i) bool oappend(const char* txt) { uint16_t len = strlen(txt); - if (olen + len >= SETTINGS_STACK_BUF_SIZE) + if (olen + len >= SETTINGS_STACK_BUF_SIZE) { +#ifdef WLED_DEBUG + DEBUG_PRINT(F("oappend() buffer overflow. Cannnot append ")); + DEBUG_PRINT(len); DEBUG_PRINT(F(" bytes \t\"")); + DEBUG_PRINT(txt); DEBUG_PRINTLN(F("\"")); +#endif return false; // buffer full + } strcpy(obuf + olen, txt); olen += len; return true; @@ -194,6 +209,10 @@ bool isAsterisksOnly(const char* str, byte maxLen) //threading/network callback details: https://github.com/Aircoookie/WLED/pull/2336#discussion_r762276994 bool requestJSONBufferLock(uint8_t module) { + if (pDoc == nullptr) { + DEBUG_PRINTLN(F("ERROR: JSON buffer not allocated!")); + return false; + } unsigned long now = millis(); while (jsonBufferLock && millis()-now < 1000) delay(1); // wait for a second for buffer lock @@ -209,8 +228,8 @@ bool requestJSONBufferLock(uint8_t module) DEBUG_PRINT(F("JSON buffer locked. (")); DEBUG_PRINT(jsonBufferLock); DEBUG_PRINTLN(")"); - fileDoc = &doc; // used for applying presets (presets.cpp) - doc.clear(); + fileDoc = pDoc; // used for applying presets (presets.cpp) + pDoc->clear(); return true; } @@ -233,7 +252,8 @@ uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLe if (mode < strip.getModeCount()) { char lineBuffer[256]; //strcpy_P(lineBuffer, (const char*)pgm_read_dword(&(WS2812FX::_modeData[mode]))); - strcpy_P(lineBuffer, strip.getModeData(mode)); + strncpy_P(lineBuffer, strip.getModeData(mode), sizeof(lineBuffer)/sizeof(char)-1); + lineBuffer[sizeof(lineBuffer)/sizeof(char)-1] = '\0'; // terminate string size_t len = strlen(lineBuffer); size_t j = 0; for (; j < maxLen && j < len; j++) { @@ -245,6 +265,12 @@ uint8_t extractModeName(uint8_t mode, const char *src, char *dest, uint8_t maxLe } else return 0; } + if (src == JSON_palette_names && mode > GRADIENT_PALETTE_COUNT) { + snprintf_P(dest, maxLen, PSTR("~ Custom %d~"), 255-mode); + dest[maxLen-1] = '\0'; + return strlen(dest); + } + uint8_t qComma = 0; bool insideQuotes = false; uint8_t printedChars = 0; @@ -351,13 +377,13 @@ uint8_t extractModeSlider(uint8_t mode, uint8_t slider, char *dest, uint8_t maxL } -// extracts mode parameter defaults from last section of mode data (e.g. "Juggle@!,Trail;!,!,;!;sx=16,ix=240,1d") +// extracts mode parameter defaults from last section of mode data (e.g. "Juggle@!,Trail;!,!,;!;012;sx=16,ix=240") int16_t extractModeDefaults(uint8_t mode, const char *segVar) { if (mode < strip.getModeCount()) { - char lineBuffer[128] = ""; - strncpy_P(lineBuffer, strip.getModeData(mode), 127); - lineBuffer[127] = '\0'; // terminate string + char lineBuffer[256]; + strncpy_P(lineBuffer, strip.getModeData(mode), sizeof(lineBuffer)/sizeof(char)-1); + lineBuffer[sizeof(lineBuffer)/sizeof(char)-1] = '\0'; // terminate string if (lineBuffer[0] != 0) { char* startPtr = strrchr(lineBuffer, ';'); // last ";" in FX data if (!startPtr) return -1; @@ -403,9 +429,9 @@ uint16_t crc16(const unsigned char* data_p, size_t length) { // (only 2 used as stored in 1 bit in segment options, consider switching to a single global simulation type) typedef enum UM_SoundSimulations { UMS_BeatSin = 0, - UMS_WeWillRockYou - //UMS_10_13, - //UMS_14_3 + UMS_WeWillRockYou, + UMS_10_13, + UMS_14_3 } um_soundSimulations_t; um_data_t* simulateSound(uint8_t simulationId) @@ -490,7 +516,7 @@ um_data_t* simulateSound(uint8_t simulationId) fftResult[i] = 0; } break; - /*case UMS_10_3: + case UMS_10_13: for (int i = 0; i<16; i++) fftResult[i] = inoise8(beatsin8(90 / (i+1), 0, 200)*15 + (ms>>10), ms>>3); volumeSmth = fftResult[8]; @@ -499,7 +525,7 @@ um_data_t* simulateSound(uint8_t simulationId) for (int i = 0; i<16; i++) fftResult[i] = inoise8(beatsin8(120 / (i+1), 10, 30)*10 + (ms>>14), ms>>3); volumeSmth = fftResult[8]; - break;*/ + break; } samplePeak = random8() > 250; @@ -507,7 +533,7 @@ um_data_t* simulateSound(uint8_t simulationId) maxVol = 31; // this gets feedback fro UI binNum = 8; // this gets feedback fro UI volumeRaw = volumeSmth; - my_magnitude = 10000.0 / 8.0f; //no idea if 10000 is a good value for FFT_Magnitude ??? + my_magnitude = 10000.0f / 8.0f; //no idea if 10000 is a good value for FFT_Magnitude ??? if (volumeSmth < 1 ) my_magnitude = 0.001f; // noise gate closed - mute return um_data; @@ -534,11 +560,12 @@ void enumerateLedmaps() { #ifndef ESP8266 if (requestJSONBufferLock(21)) { - if (readObjectFromFile(fileName, nullptr, &doc)) { + if (readObjectFromFile(fileName, nullptr, pDoc)) { size_t len = 0; - if (!doc["n"].isNull()) { + JsonObject root = pDoc->as(); + if (!root["n"].isNull()) { // name field exists - const char *name = doc["n"].as(); + const char *name = root["n"].as(); if (name != nullptr) len = strlen(name); if (len > 0 && len < 33) { ledmapNames[i-1] = new char[len+1]; @@ -559,4 +586,18 @@ void enumerateLedmaps() { } } -} \ No newline at end of file +} + +/* + * Returns a new, random color wheel index with a minimum distance of 42 from pos. + */ +uint8_t get_random_wheel_index(uint8_t pos) { + uint8_t r = 0, x = 0, y = 0, d = 0; + while (d < 42) { + r = random8(); + x = abs(pos - r); + y = 255 - x; + d = MIN(x, y); + } + return r; +} diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 1c1ee9767..967192efe 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -54,9 +54,6 @@ void WLED::loop() handleIR(); // 2nd call to function needed for ESP32 to return valid results -- should be good for ESP8266, too #endif handleConnection(); - #ifndef WLED_DISABLE_ESPNOW - handleRemote(); - #endif handleSerial(); handleImprovWifiScan(); handleNotifications(); @@ -64,11 +61,11 @@ void WLED::loop() #ifdef WLED_ENABLE_DMX handleDMX(); #endif - userLoop(); #ifdef WLED_DEBUG unsigned long usermodMillis = millis(); #endif + userLoop(); usermods.loop(); #ifdef WLED_DEBUG usermodMillis = millis() - usermodMillis; @@ -111,7 +108,7 @@ void WLED::loop() handlePresets(); yield(); - if (!offMode || strip.isOffRefreshRequired()) + if (!offMode || strip.isOffRefreshRequired() || strip.needsUpdate()) strip.service(); #ifdef ESP8266 else if (!noWifiSleep) @@ -160,7 +157,7 @@ void WLED::loop() doInitBusses = false; DEBUG_PRINTLN(F("Re-init busses.")); bool aligned = strip.checkSegmentAlignment(); //see if old segments match old bus(ses) - busses.removeAll(); + BusManager::removeAll(); uint32_t mem = 0, globalBufMem = 0; uint16_t maxlen = 0; for (uint8_t i = 0; i < WLED_MAX_BUSSES+WLED_MIN_VIRTUAL_BUSSES; i++) { @@ -171,7 +168,7 @@ void WLED::loop() globalBufMem = maxlen * 4; } if (mem + globalBufMem <= MAX_LED_MEMORY) { - busses.add(*busConfigs[i]); + BusManager::add(*busConfigs[i]); } delete busConfigs[i]; busConfigs[i] = nullptr; } @@ -181,7 +178,7 @@ void WLED::loop() doSerializeConfig = true; } if (loadLedmap >= 0) { - if (!strip.deserializeMap(loadLedmap) && strip.isMatrix && loadLedmap == 0) strip.setUpMatrix(); + strip.deserializeMap(loadLedmap); loadLedmap = -1; } yield(); @@ -189,18 +186,23 @@ void WLED::loop() yield(); handleWs(); +#if defined(STATUSLED) handleStatusLED(); +#endif toki.resetTick(); #if WLED_WATCHDOG_TIMEOUT > 0 // we finished our mainloop, reset the watchdog timer - if (!strip.isUpdating()) + static unsigned long lastWDTFeed = 0; + if (!strip.isUpdating() || millis() - lastWDTFeed > (WLED_WATCHDOG_TIMEOUT*500)) { #ifdef ARDUINO_ARCH_ESP32 esp_task_wdt_reset(); #else ESP.wdtFeed(); #endif + lastWDTFeed = millis(); + } #endif if (doReboot && (!doInitBusses || !doSerializeConfig)) // if busses have to be inited & saved, wait until next iteration @@ -256,9 +258,9 @@ void WLED::loop() #endif // WLED_DEBUG } -void WLED::enableWatchdog() { #if WLED_WATCHDOG_TIMEOUT > 0 -#ifdef ARDUINO_ARCH_ESP32 +void WLED::enableWatchdog() { + #ifdef ARDUINO_ARCH_ESP32 esp_err_t watchdog = esp_task_wdt_init(WLED_WATCHDOG_TIMEOUT, true); DEBUG_PRINT(F("Watchdog enabled: ")); if (watchdog == ESP_OK) { @@ -268,22 +270,20 @@ void WLED::enableWatchdog() { return; } esp_task_wdt_add(NULL); -#else + #else ESP.wdtEnable(WLED_WATCHDOG_TIMEOUT * 1000); -#endif -#endif + #endif } void WLED::disableWatchdog() { -#if WLED_WATCHDOG_TIMEOUT > 0 -DEBUG_PRINTLN(F("Watchdog: disabled")); -#ifdef ARDUINO_ARCH_ESP32 + DEBUG_PRINTLN(F("Watchdog: disabled")); + #ifdef ARDUINO_ARCH_ESP32 esp_task_wdt_delete(NULL); -#else + #else ESP.wdtDisable(); -#endif -#endif + #endif } +#endif void WLED::setup() { @@ -346,6 +346,11 @@ void WLED::setup() DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap()); #if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) +/* + * The following code is obsolete as PinManager::isPinOK() will return false for reserved GPIO. + * Additionally xml.cpp will inform UI about reserved GPIO. + * + #if defined(CONFIG_IDF_TARGET_ESP32S3) // S3: reserve GPIO 33-37 for "octal" PSRAM managed_pin_type pins[] = { {33, true}, {34, true}, {35, true}, {36, true}, {37, true} }; @@ -363,12 +368,17 @@ void WLED::setup() managed_pin_type pins[] = { {16, true}, {17, true} }; pinManager.allocateMultiplePins(pins, sizeof(pins)/sizeof(managed_pin_type), PinOwner::SPI_RAM); #endif +*/ #if defined(WLED_USE_PSRAM) + pDoc = new PSRAMDynamicJsonDocument(2*JSON_BUFFER_SIZE); + if (!pDoc) pDoc = new PSRAMDynamicJsonDocument(JSON_BUFFER_SIZE); // falback if double sized buffer could not be allocated + // if the above still fails requestJsonBufferLock() will always return false preventing crashes if (psramFound()) { DEBUG_PRINT(F("Total PSRAM: ")); DEBUG_PRINT(ESP.getPsramSize()/1024); DEBUG_PRINTLN("kB"); DEBUG_PRINT(F("Free PSRAM : ")); DEBUG_PRINT(ESP.getFreePsram()/1024); DEBUG_PRINTLN("kB"); } #else + if (!pDoc) pDoc = &gDoc; // just in case ... (it should be globally assigned) DEBUG_PRINTLN(F("PSRAM not used.")); #endif #endif @@ -464,15 +474,19 @@ void WLED::setup() #ifndef WLED_DISABLE_OTA if (aOtaEnabled) { ArduinoOTA.onStart([]() { -#ifdef ESP8266 + #ifdef ESP8266 wifi_set_sleep_type(NONE_SLEEP_T); -#endif + #endif + #if WLED_WATCHDOG_TIMEOUT > 0 WLED::instance().disableWatchdog(); + #endif DEBUG_PRINTLN(F("Start ArduinoOTA")); }); ArduinoOTA.onError([](ota_error_t error) { + #if WLED_WATCHDOG_TIMEOUT > 0 // reenable watchdog on failed update WLED::instance().enableWatchdog(); + #endif }); if (strlen(cmDNS) > 0) ArduinoOTA.setHostname(cmDNS); @@ -491,7 +505,19 @@ void WLED::setup() initServer(); DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap()); + // Seed FastLED random functions with an esp random value, which already works properly at this point. +#if defined(ARDUINO_ARCH_ESP32) + const uint32_t seed32 = esp_random(); +#elif defined(ARDUINO_ARCH_ESP8266) + const uint32_t seed32 = RANDOM_REG32; +#else + const uint32_t seed32 = random(std::numeric_limits::max()); +#endif + random16_set_seed((uint16_t)((seed32 & 0xFFFF) ^ (seed32 >> 16))); + + #if WLED_WATCHDOG_TIMEOUT > 0 enableWatchdog(); + #endif #if defined(ARDUINO_ARCH_ESP32) && defined(WLED_DISABLE_BROWNOUT_DET) WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 1); //enable brownout detector @@ -511,6 +537,13 @@ void WLED::beginStrip() else if (bri == 0) bri = 128; } else { // fix for #3196 + if (bootPreset > 0) { + bool oldTransition = fadeTransition; // workaround if transitions are enabled + fadeTransition = false; // ignore transitions temporarily + strip.setColor(0, BLACK); // set all segments black + fadeTransition = oldTransition; // restore transitions + col[0] = col[1] = col[2] = col[3] = 0; // needed for colorUpdated() + } briLast = briS; bri = 0; strip.fill(BLACK); strip.show(); @@ -673,9 +706,17 @@ void WLED::initConnection() ws.onEvent(wsEvent); #endif +#ifndef WLED_DISABLE_ESPNOW + if (statusESPNow == ESP_NOW_STATE_ON) { + DEBUG_PRINTLN(F("ESP-NOW stopping.")); + quickEspNow.stop(); + statusESPNow = ESP_NOW_STATE_UNINIT; + } +#endif + WiFi.disconnect(true); // close old connections #ifdef ESP8266 - WiFi.setPhyMode(WIFI_PHY_MODE_11N); + WiFi.setPhyMode(force802_3g ? WIFI_PHY_MODE_11G : WIFI_PHY_MODE_11N); #endif if (staticIP[0] != 0 && staticGateway[0] != 0) { @@ -689,7 +730,6 @@ void WLED::initConnection() if (!WLED_WIFI_CONFIGURED) { DEBUG_PRINTLN(F("No connection configured.")); if (!apActive) initAP(); // instantly go to ap mode - return; } else if (!apActive) { if (apBehavior == AP_BEHAVIOR_ALWAYS) { DEBUG_PRINTLN(F("Access point ALWAYS enabled.")); @@ -700,29 +740,46 @@ void WLED::initConnection() WiFi.mode(WIFI_STA); } } - showWelcomePage = false; - DEBUG_PRINT(F("Connecting to ")); - DEBUG_PRINT(clientSSID); - DEBUG_PRINTLN("..."); + if (WLED_WIFI_CONFIGURED) { + showWelcomePage = false; + + DEBUG_PRINT(F("Connecting to ")); + DEBUG_PRINT(clientSSID); + DEBUG_PRINTLN("..."); - // convert the "serverDescription" into a valid DNS hostname (alphanumeric) - char hostname[25]; - prepareHostname(hostname); - -#ifdef ESP8266 - WiFi.hostname(hostname); -#endif - - WiFi.begin(clientSSID, clientPass); + // convert the "serverDescription" into a valid DNS hostname (alphanumeric) + char hostname[25]; + prepareHostname(hostname); + WiFi.begin(clientSSID, clientPass); #ifdef ARDUINO_ARCH_ESP32 #if defined(LOLIN_WIFI_FIX) && (defined(ARDUINO_ARCH_ESP32C3) || defined(ARDUINO_ARCH_ESP32S2) || defined(ARDUINO_ARCH_ESP32S3)) - WiFi.setTxPower(WIFI_POWER_8_5dBm); + WiFi.setTxPower(WIFI_POWER_8_5dBm); #endif - WiFi.setSleep(!noWifiSleep); - WiFi.setHostname(hostname); + WiFi.setSleep(!noWifiSleep); + WiFi.setHostname(hostname); #else - wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); + wifi_set_sleep_type((noWifiSleep) ? NONE_SLEEP_T : MODEM_SLEEP_T); + WiFi.hostname(hostname); +#endif + } + +#ifndef WLED_DISABLE_ESPNOW + if (enableESPNow) { + quickEspNow.onDataRcvd(espNowReceiveCB); + bool espNowOK; + if (apActive) { + DEBUG_PRINTLN(F("ESP-NOW initing in AP mode.")); + #ifdef ESP32 + quickEspNow.setWiFiBandwidth(WIFI_IF_AP, WIFI_BW_HT20); // Only needed for ESP32 in case you need coexistence with ESP8266 in the same network + #endif //ESP32 + espNowOK = quickEspNow.begin(apChannel, WIFI_IF_AP); // Same channel must be used for both AP and ESP-NOW + } else { + DEBUG_PRINTLN(F("ESP-NOW initing in STA mode.")); + espNowOK = quickEspNow.begin(); // Use no parameters to start ESP-NOW on same channel as WiFi, in STA mode + } + statusESPNow = espNowOK ? ESP_NOW_STATE_ON : ESP_NOW_STATE_ERROR; + } #endif } @@ -807,7 +864,7 @@ void WLED::handleConnection() DEBUG_PRINT(F("Heap too low! ")); DEBUG_PRINTLN(heap); forceReconnect = true; - strip.purgeSegments(true); // remove all but one segments from memory + strip.resetSegments(); } else if (heap < MIN_HEAP_SIZE) { strip.purgeSegments(); } @@ -847,8 +904,8 @@ void WLED::handleConnection() if (!Network.isConnected()) { if (interfacesInited) { DEBUG_PRINTLN(F("Disconnected!")); - interfacesInited = false; initConnection(); + interfacesInited = false; } //send improv failed 6 seconds after second init attempt (24 sec. after provisioning) if (improvActive > 2 && now - lastReconnectAttempt > 6000) { @@ -892,9 +949,9 @@ void WLED::handleConnection() // else blink at 1Hz when WLED_CONNECTED is false (no WiFi, ?? no Ethernet ??) // else blink at 2Hz when MQTT is enabled but not connected // else turn the status LED off +#if defined(STATUSLED) void WLED::handleStatusLED() { - #if defined(STATUSLED) uint32_t c = 0; #if STATUSLED>=0 @@ -920,7 +977,7 @@ void WLED::handleStatusLED() #if STATUSLED>=0 digitalWrite(STATUSLED, ledStatusState); #else - busses.setStatusPixel(ledStatusState ? c : 0); + BusManager::setStatusPixel(ledStatusState ? c : 0); #endif } } else { @@ -931,8 +988,8 @@ void WLED::handleStatusLED() digitalWrite(STATUSLED, LOW); #endif #else - busses.setStatusPixel(0); + BusManager::setStatusPixel(0); #endif } - #endif } +#endif diff --git a/wled00/wled.h b/wled00/wled.h old mode 100644 new mode 100755 index 37a13aa2e..ed92c58ae --- a/wled00/wled.h +++ b/wled00/wled.h @@ -3,12 +3,12 @@ /* Main sketch, global variable declarations @title WLED project sketch - @version 0.14.0-b3 + @version 0.15.0-a0 @author Christian Schwinne */ // version code in format yymmddb (b = daily build) -#define VERSION 2307180 +#define VERSION 2401140 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG @@ -30,8 +30,8 @@ #ifndef WLED_DISABLE_MQTT #define WLED_ENABLE_MQTT // saves 12kb #endif -#ifndef WLED_DISABLE_ADALIGHT // can be used to disable reading commands from serial RX pin (see issue #3128). - #define WLED_ENABLE_ADALIGHT // disable saves 5Kb (uses GPIO3 (RX) for serial). Related serial protocols: Adalight/TPM2, Improv, Serial JSON, Continuous Serial Streaming +#ifndef WLED_DISABLE_ADALIGHT // can be used to disable reading commands from serial RX pin (see issue #3128). + #define WLED_ENABLE_ADALIGHT // disable saves 5Kb (uses GPIO3 (RX) for serial). Related serial protocols: Adalight/TPM2, Improv, Serial JSON, Continuous Serial Streaming #else #undef WLED_ENABLE_ADALIGHT // disable has priority over enable #endif @@ -44,7 +44,7 @@ #define WLED_ENABLE_WEBSOCKETS #endif -//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now +//#define WLED_DISABLE_ESPNOW // Removes dependence on esp now #define WLED_ENABLE_FS_EDITOR // enable /edit page for editing FS content. Will also be disabled with OTA lock @@ -77,6 +77,9 @@ } #ifndef WLED_DISABLE_ESPNOW #include + #define WIFI_MODE_STA WIFI_STA + #define WIFI_MODE_AP WIFI_AP + #include #endif #undef WLED_DISABLE_GIF #define WLED_DISABLE_GIF @@ -99,6 +102,7 @@ #ifndef WLED_DISABLE_ESPNOW #include + #include #endif #endif #include @@ -258,7 +262,7 @@ using PSRAMDynamicJsonDocument = BasicJsonDocument; // Global Variable definitions WLED_GLOBAL char versionString[] _INIT(TOSTRING(WLED_VERSION)); -#define WLED_CODENAME "Hoshi" +#define WLED_CODENAME "Kōsen" // AP and OTA default passwords (for maximum security change them!) WLED_GLOBAL char apPass[65] _INIT(WLED_AP_PASS); @@ -317,6 +321,7 @@ WLED_GLOBAL bool noWifiSleep _INIT(true); // disabling #else WLED_GLOBAL bool noWifiSleep _INIT(false); #endif +WLED_GLOBAL bool force802_3g _INIT(false); #ifdef WLED_USE_ETHERNET #ifdef WLED_ETH_DEFAULT // default ethernet board type if specified @@ -352,8 +357,6 @@ WLED_GLOBAL byte briS _INIT(128); // default brightness WLED_GLOBAL byte nightlightTargetBri _INIT(0); // brightness after nightlight is over WLED_GLOBAL byte nightlightDelayMins _INIT(60); WLED_GLOBAL byte nightlightMode _INIT(NL_MODE_FADE); // See const.h for available modes. Was nightlightFade -WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading color transition -WLED_GLOBAL uint16_t transitionDelay _INIT(750); // default crossfade duration in ms WLED_GLOBAL byte briMultiplier _INIT(100); // % of brightness to set (to limit power, if you set it to 50 and set bri to 255, actual brightness will be 127) @@ -363,9 +366,8 @@ WLED_GLOBAL char serverDescription[33] _INIT("WLED"); // Name of module - use d #else WLED_GLOBAL char serverDescription[33] _INIT(SERVERNAME); // use predefined name #endif -WLED_GLOBAL bool syncToggleReceive _INIT(false); // UIs which only have a single button for sync should toggle send+receive if this is true, only send otherwise WLED_GLOBAL bool simplifiedUI _INIT(false); // enable simplified UI -WLED_GLOBAL byte cacheInvalidate _INIT(0); // used to invalidate browser cache when switching from regular to simplified UI +WLED_GLOBAL byte cacheInvalidate _INIT(0); // used to invalidate browser cache // Sync CONFIG WLED_GLOBAL NodesMap Nodes; @@ -394,7 +396,6 @@ WLED_GLOBAL bool receiveSegmentBounds _INIT(false); // apply segme WLED_GLOBAL bool notifyDirect _INIT(false); // send notification if change via UI or HTTP API WLED_GLOBAL bool notifyButton _INIT(false); // send if updated by button or infrared remote WLED_GLOBAL bool notifyAlexa _INIT(false); // send notification if updated via Alexa -WLED_GLOBAL bool notifyMacro _INIT(false); // send notification for macro WLED_GLOBAL bool notifyHue _INIT(true); // send notification if Hue light changes WLED_GLOBAL uint8_t udpNumRetries _INIT(0); // Number of times a UDP sync message is retransmitted. Increase to increase reliability @@ -404,7 +405,7 @@ WLED_GLOBAL byte alexaNumPresets _INIT(0); // number of p WLED_GLOBAL uint16_t realtimeTimeoutMs _INIT(2500); // ms timeout of realtime mode before returning to normal mode WLED_GLOBAL int arlsOffset _INIT(0); // realtime LED offset -WLED_GLOBAL bool receiveDirect _INIT(true); // receive UDP realtime +WLED_GLOBAL bool receiveDirect _INIT(true); // receive UDP/Hyperion realtime WLED_GLOBAL bool arlsDisableGammaCorrection _INIT(true); // activate if gamma correction is handled by the source WLED_GLOBAL bool arlsForceMaxBri _INIT(false); // enable to force max brightness if source has very dark colors that would be black @@ -431,12 +432,18 @@ WLED_GLOBAL uint16_t pollReplyCount _INIT(0); // count numbe // mqtt WLED_GLOBAL unsigned long lastMqttReconnectAttempt _INIT(0); // used for other periodic tasks too #ifndef WLED_DISABLE_MQTT + #ifndef MQTT_MAX_TOPIC_LEN + #define MQTT_MAX_TOPIC_LEN 32 + #endif + #ifndef MQTT_MAX_SERVER_LEN + #define MQTT_MAX_SERVER_LEN 32 + #endif WLED_GLOBAL AsyncMqttClient *mqtt _INIT(NULL); WLED_GLOBAL bool mqttEnabled _INIT(false); WLED_GLOBAL char mqttStatusTopic[40] _INIT(""); // this must be global because of async handlers -WLED_GLOBAL char mqttDeviceTopic[33] _INIT(""); // main MQTT topic (individual per device, default is wled/mac) -WLED_GLOBAL char mqttGroupTopic[33] _INIT("wled/all"); // second MQTT topic (for example to group devices) -WLED_GLOBAL char mqttServer[33] _INIT(""); // both domains and IPs should work (no SSL) +WLED_GLOBAL char mqttDeviceTopic[MQTT_MAX_TOPIC_LEN+1] _INIT(""); // main MQTT topic (individual per device, default is wled/mac) +WLED_GLOBAL char mqttGroupTopic[MQTT_MAX_TOPIC_LEN+1] _INIT("wled/all"); // second MQTT topic (for example to group devices) +WLED_GLOBAL char mqttServer[MQTT_MAX_SERVER_LEN+1] _INIT(""); // both domains and IPs should work (no SSL) WLED_GLOBAL char mqttUser[41] _INIT(""); // optional: username for MQTT auth WLED_GLOBAL char mqttPass[65] _INIT(""); // optional: password for MQTT auth WLED_GLOBAL char mqttClientID[41] _INIT(""); // override the client ID @@ -461,16 +468,27 @@ WLED_GLOBAL bool hueApplyColor _INIT(true); WLED_GLOBAL uint16_t serialBaud _INIT(1152); // serial baud rate, multiply by 100 #ifndef WLED_DISABLE_ESPNOW -WLED_GLOBAL bool enable_espnow_remote _INIT(false); -WLED_GLOBAL char linked_remote[13] _INIT(""); -WLED_GLOBAL char last_signal_src[13] _INIT(""); +WLED_GLOBAL bool enableESPNow _INIT(false); // global on/off for ESP-NOW +WLED_GLOBAL byte statusESPNow _INIT(ESP_NOW_STATE_UNINIT); // state of ESP-NOW stack (0 uninitialised, 1 initialised, 2 error) +WLED_GLOBAL bool useESPNowSync _INIT(false); // use ESP-NOW wireless technology for sync +WLED_GLOBAL char linked_remote[13] _INIT(""); // MAC of ESP-NOW remote (Wiz Mote) +WLED_GLOBAL char last_signal_src[13] _INIT(""); // last seen ESP-NOW sender #endif // Time CONFIG -WLED_GLOBAL bool ntpEnabled _INIT(false); // get internet time. Only required if you use clock overlays or time-activated macros -WLED_GLOBAL bool useAMPM _INIT(false); // 12h/24h clock format -WLED_GLOBAL byte currentTimezone _INIT(0); // Timezone ID. Refer to timezones array in wled10_ntp.ino -WLED_GLOBAL int utcOffsetSecs _INIT(0); // Seconds to offset from UTC before timzone calculation +#ifndef WLED_NTP_ENABLED + #define WLED_NTP_ENABLED false +#endif +#ifndef WLED_TIMEZONE + #define WLED_TIMEZONE 0 +#endif +#ifndef WLED_UTC_OFFSET + #define WLED_UTC_OFFSET 0 +#endif +WLED_GLOBAL bool ntpEnabled _INIT(WLED_NTP_ENABLED); // get internet time. Only required if you use clock overlays or time-activated macros +WLED_GLOBAL bool useAMPM _INIT(false); // 12h/24h clock format +WLED_GLOBAL byte currentTimezone _INIT(WLED_TIMEZONE); // Timezone ID. Refer to timezones array in wled10_ntp.ino +WLED_GLOBAL int utcOffsetSecs _INIT(WLED_UTC_OFFSET); // Seconds to offset from UTC before timzone calculation WLED_GLOBAL byte overlayCurrent _INIT(0); // 0: no overlay 1: analog clock 2: was single-digit clock 3: was cronixie WLED_GLOBAL byte overlayMin _INIT(0), overlayMax _INIT(DEFAULT_LED_COUNT - 1); // boundaries of overlay mode @@ -523,13 +541,15 @@ WLED_GLOBAL bool wasConnected _INIT(false); WLED_GLOBAL byte lastRandomIndex _INIT(0); // used to save last random color so the new one is not the same // transitions +WLED_GLOBAL bool fadeTransition _INIT(true); // enable crossfading brightness/color +WLED_GLOBAL bool modeBlending _INIT(true); // enable effect blending WLED_GLOBAL bool transitionActive _INIT(false); -WLED_GLOBAL uint16_t transitionDelayDefault _INIT(transitionDelay); // default transition time (storec in cfg.json) -WLED_GLOBAL uint16_t transitionDelayTemp _INIT(transitionDelay); // actual transition duration (overrides transitionDelay in certain cases) +WLED_GLOBAL uint16_t transitionDelay _INIT(750); // global transition duration +WLED_GLOBAL uint16_t transitionDelayDefault _INIT(750); // default transition time (stored in cfg.json) WLED_GLOBAL unsigned long transitionStartTime; -WLED_GLOBAL float tperLast _INIT(0.0f); // crossfade transition progress, 0.0f - 1.0f -WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt") -WLED_GLOBAL uint8_t randomPaletteChangeTime _INIT(5); // amount of time [s] between random palette changes (min: 1s, max: 255s) +WLED_GLOBAL float tperLast _INIT(0.0f); // crossfade transition progress, 0.0f - 1.0f +WLED_GLOBAL bool jsonTransitionOnce _INIT(false); // flag to override transitionDelay (playlist, JSON API: "live" & "seg":{"i"} & "tt") +WLED_GLOBAL uint8_t randomPaletteChangeTime _INIT(5); // amount of time [s] between random palette changes (min: 1s, max: 255s) // nightlight WLED_GLOBAL bool nightlightActive _INIT(false); @@ -559,8 +579,8 @@ WLED_GLOBAL bool disablePullUp _INIT(false); WLED_GLOBAL byte touchThreshold _INIT(TOUCH_THRESHOLD); // notifications -WLED_GLOBAL bool notifyDirectDefault _INIT(notifyDirect); -WLED_GLOBAL bool receiveNotifications _INIT(true); +WLED_GLOBAL bool sendNotifications _INIT(false); // master notification switch +WLED_GLOBAL bool sendNotificationsRT _INIT(false); // master notification switch (runtime) WLED_GLOBAL unsigned long notificationSentTime _INIT(0); WLED_GLOBAL byte notificationSentCallMode _INIT(CALL_MODE_INIT); WLED_GLOBAL uint8_t notificationCount _INIT(0); @@ -624,6 +644,7 @@ WLED_GLOBAL unsigned long realtimeTimeout _INIT(0); WLED_GLOBAL uint8_t tpmPacketCount _INIT(0); WLED_GLOBAL uint16_t tpmPayloadFrameSize _INIT(0); WLED_GLOBAL bool useMainSegmentOnly _INIT(false); +WLED_GLOBAL bool realtimeRespectLedMaps _INIT(true); // Respect LED maps when receiving realtime data WLED_GLOBAL unsigned long lastInterfaceUpdate _INIT(0); WLED_GLOBAL byte interfaceUpdateCallMode _INIT(CALL_MODE_INIT); @@ -639,6 +660,12 @@ WLED_GLOBAL String escapedMac; WLED_GLOBAL DNSServer dnsServer; // network time +#ifndef WLED_LAT + #define WLED_LAT 0.0f +#endif +#ifndef WLED_LON + #define WLED_LON 0.0f +#endif WLED_GLOBAL bool ntpConnected _INIT(false); WLED_GLOBAL time_t localTime _INIT(0); WLED_GLOBAL unsigned long ntpLastSyncTime _INIT(999000000L); @@ -646,8 +673,8 @@ WLED_GLOBAL unsigned long ntpPacketSentTime _INIT(999000000L); WLED_GLOBAL IPAddress ntpServerIP; WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390); WLED_GLOBAL uint16_t rolloverMillis _INIT(0); -WLED_GLOBAL float longitude _INIT(0.0); -WLED_GLOBAL float latitude _INIT(0.0); +WLED_GLOBAL float longitude _INIT(WLED_LON); +WLED_GLOBAL float latitude _INIT(WLED_LAT); WLED_GLOBAL time_t sunrise _INIT(0); WLED_GLOBAL time_t sunset _INIT(0); WLED_GLOBAL Toki toki _INIT(Toki()); @@ -748,7 +775,12 @@ WLED_GLOBAL int8_t spi_sclk _INIT(SPISCLKPIN); #endif // global ArduinoJson buffer -WLED_GLOBAL StaticJsonDocument doc; +#if defined(ARDUINO_ARCH_ESP32) && defined(BOARD_HAS_PSRAM) && defined(WLED_USE_PSRAM) +WLED_GLOBAL JsonDocument *pDoc _INIT(nullptr); +#else +WLED_GLOBAL StaticJsonDocument gDoc; +WLED_GLOBAL JsonDocument *pDoc _INIT(&gDoc); +#endif WLED_GLOBAL volatile uint8_t jsonBufferLock _INIT(0); // enable additional debug output @@ -853,8 +885,12 @@ public: void initAP(bool resetAP = false); void initConnection(); void initInterfaces(); + #if defined(STATUSLED) void handleStatusLED(); + #endif + #if WLED_WATCHDOG_TIMEOUT > 0 void enableWatchdog(); void disableWatchdog(); + #endif }; #endif // WLED_H diff --git a/wled00/wled_eeprom.cpp b/wled00/wled_eeprom.cpp old mode 100644 new mode 100755 index 7c5fd7836..9ea838797 --- a/wled00/wled_eeprom.cpp +++ b/wled00/wled_eeprom.cpp @@ -83,8 +83,8 @@ void loadSettingsFromEEPROM() nightlightDelayMinsDefault = EEPROM.read(224); nightlightDelayMins = nightlightDelayMinsDefault; nightlightMode = EEPROM.read(225); - notifyDirectDefault = EEPROM.read(226); - notifyDirect = notifyDirectDefault; + notifyDirect = EEPROM.read(226); + sendNotificationsRT = notifyDirect; apChannel = EEPROM.read(227); if (apChannel > 13 || apChannel < 1) apChannel = 1; @@ -99,7 +99,7 @@ void loadSettingsFromEEPROM() bool skipFirst = EEPROM.read(2204); bool reversed = EEPROM.read(252); BusConfig bc = BusConfig(EEPROM.read(372) ? TYPE_SK6812_RGBW : TYPE_WS2812_RGB, pins, 0, length, colorOrder, reversed, skipFirst); - busses.add(bc); + BusManager::add(bc); notifyButton = EEPROM.read(230); if (EEPROM.read(231)) udpNumRetries = 1; @@ -163,7 +163,6 @@ void loadSettingsFromEEPROM() receiveNotificationColor = EEPROM.read(391); receiveNotificationEffects = EEPROM.read(392); } - receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects); if (lastEEPROMversion > 4) { #ifndef WLED_DISABLE_HUESYNC @@ -278,10 +277,10 @@ void loadSettingsFromEEPROM() if (lastEEPROMversion > 13) { mqttEnabled = EEPROM.read(2299); - syncToggleReceive = EEPROM.read(397); + //syncToggleReceive = EEPROM.read(397); } else { mqttEnabled = true; - syncToggleReceive = false; + //syncToggleReceive = false; } if (lastEEPROMversion > 14) @@ -322,7 +321,7 @@ void loadSettingsFromEEPROM() } receiveDirect = !EEPROM.read(2200); - notifyMacro = EEPROM.read(2201); + //notifyMacro = EEPROM.read(2201); //strip.rgbwMode = EEPROM.read(2203); //skipFirstLed = EEPROM.read(2204); @@ -372,7 +371,7 @@ void deEEP() { DEBUGFS_PRINTLN(F("Allocating saving buffer for dEEP")); if (!requestJSONBufferLock(8)) return; - JsonObject sObj = doc.to(); + JsonObject sObj = pDoc->to(); sObj.createNestedObject("0"); EEPROM.begin(EEPSIZE); @@ -449,7 +448,7 @@ void deEEP() { releaseJSONBufferLock(); return; } - serializeJson(doc, f); + serializeJson(*pDoc, f); f.close(); releaseJSONBufferLock(); diff --git a/wled00/wled_math.cpp b/wled00/wled_math.cpp index ed698a5cd..a4c9fc123 100644 --- a/wled00/wled_math.cpp +++ b/wled00/wled_math.cpp @@ -41,7 +41,7 @@ float sin_t(float x) { float tan_t(float x) { float c = cos_t(x); - if (c==0.0) return 0; + if (c==0.0f) return 0; float res = sin_t(x) / c; #ifdef WLED_DEBUG_MATH Serial.printf("tan: %f,%f,%f,(%f)\n",x,res,tan(x),res-tan(x)); @@ -54,14 +54,14 @@ float tan_t(float x) { float acos_t(float x) { float negate = float(x < 0); float xabs = std::abs(x); - float ret = -0.0187293; + float ret = -0.0187293f; ret = ret * xabs; - ret = ret + 0.0742610; + ret = ret + 0.0742610f; ret = ret * xabs; - ret = ret - 0.2121144; + ret = ret - 0.2121144f; ret = ret * xabs; ret = ret + HALF_PI; - ret = ret * sqrt(1.0-xabs); + ret = ret * sqrt(1.0f-xabs); ret = ret - 2 * negate * ret; float res = negate * PI + ret; #ifdef WLED_DEBUG_MATH diff --git a/wled00/wled_serial.cpp b/wled00/wled_serial.cpp index 4d920e340..c6e984035 100644 --- a/wled00/wled_serial.cpp +++ b/wled00/wled_serial.cpp @@ -115,21 +115,21 @@ void handleSerial() bool verboseResponse = false; if (!requestJSONBufferLock(16)) return; Serial.setTimeout(100); - DeserializationError error = deserializeJson(doc, Serial); + DeserializationError error = deserializeJson(*pDoc, Serial); if (error) { releaseJSONBufferLock(); return; } - verboseResponse = deserializeState(doc.as()); + verboseResponse = deserializeState(pDoc->as()); //only send response if TX pin is unused for other purposes if (verboseResponse && (!pinManager.isPinAllocated(hardwareTX) || pinManager.getPinOwner(hardwareTX) == PinOwner::DebugOut)) { - doc.clear(); - JsonObject state = doc.createNestedObject("state"); + pDoc->clear(); + JsonObject state = pDoc->createNestedObject("state"); serializeState(state); - JsonObject info = doc.createNestedObject("info"); + JsonObject info = pDoc->createNestedObject("info"); serializeInfo(info); - serializeJson(doc, Serial); + serializeJson(*pDoc, Serial); Serial.println(); } releaseJSONBufferLock(); diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index 740a0ddeb..82cc55014 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -1,9 +1,6 @@ #include "wled.h" #include "html_ui.h" -#ifdef WLED_ENABLE_SIMPLE_UI - #include "html_simple.h" -#endif #include "html_settings.h" #include "html_other.h" #ifdef WLED_ENABLE_PIXART @@ -18,8 +15,9 @@ * Integrated HTTP web server page declarations */ -bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request); -void setStaticContentCacheHeaders(AsyncWebServerResponse *response); +bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request, int code, uint16_t eTagSuffix = 0); +void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix = 0); +void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip = true, uint16_t eTagSuffix = 0); // define flash strings once (saves flash memory) static const char s_redirecting[] PROGMEM = "Redirecting..."; @@ -40,7 +38,7 @@ bool isIp(String str) { void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) { if (!correctPIN) { - if (final) request->send(500, "text/plain", FPSTR(s_unlock_cfg)); + if (final) request->send(401, "text/plain", FPSTR(s_unlock_cfg)); return; } if (!index) { @@ -86,7 +84,7 @@ void createEditHandler(bool enable) { #endif } else { editHandler = &server.on("/edit", HTTP_ANY, [](AsyncWebServerRequest *request){ - serveMessage(request, 500, "Access Denied", FPSTR(s_unlock_cfg), 254); + serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_cfg), 254); }); } } @@ -116,22 +114,14 @@ void initServer() DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), "*"); #ifdef WLED_ENABLE_WEBSOCKETS - #ifndef WLED_DISABLE_2D - server.on("/liveview2D", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveviewws2D, PAGE_liveviewws2D_length); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); + #ifndef WLED_DISABLE_2D + server.on("/liveview2D", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "", 200, "text/html", PAGE_liveviewws2D, PAGE_liveviewws2D_length); }); #endif #endif - server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_liveview, PAGE_liveview_length); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); + server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "", 200, "text/html", PAGE_liveview, PAGE_liveview_length); }); //settings page @@ -141,19 +131,18 @@ void initServer() // "/settings/settings.js&p=x" request also handled by serveSettings() - server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); + server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "/style.css", 200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length); }); - server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){ - if(!handleFileRead(request, "/favicon.ico")) - { - request->send_P(200, "image/x-icon", favicon, 156); - } + server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "/favicon.ico", 200, "image/x-icon", favicon, favicon_length, false); + }); + + server.on("/skin.css", HTTP_GET, [](AsyncWebServerRequest *request) { + if (handleFileRead(request, "/skin.css")) return; + AsyncWebServerResponse *response = request->beginResponse(200, "text/css"); + request->send(response); }); server.on("/welcome", HTTP_GET, [](AsyncWebServerRequest *request){ @@ -179,11 +168,11 @@ void initServer() if (!requestJSONBufferLock(14)) return; - DeserializationError error = deserializeJson(doc, (uint8_t*)(request->_tempObject)); - JsonObject root = doc.as(); + DeserializationError error = deserializeJson(*pDoc, (uint8_t*)(request->_tempObject)); + JsonObject root = pDoc->as(); if (error || root.isNull()) { releaseJSONBufferLock(); - request->send(400, "application/json", F("{\"error\":9}")); // ERR_JSON + serveJsonError(request, 400, ERR_JSON); return; } if (root.containsKey("pin")) checkSettingsPIN(root["pin"].as()); @@ -201,8 +190,8 @@ void initServer() verboseResponse = deserializeState(root); } else { if (!correctPIN && strlen(settingsPIN)>0) { - request->send(403, "application/json", F("{\"error\":1}")); // ERR_DENIED releaseJSONBufferLock(); + serveJsonError(request, 401, ERR_DENIED); return; } verboseResponse = deserializeConfig(root); //use verboseResponse to determine whether cfg change should be saved immediately @@ -211,6 +200,8 @@ void initServer() if (verboseResponse) { if (!isConfig) { + lastInterfaceUpdate = millis(); // prevent WS update until cooldown + interfaceUpdateCallMode = CALL_MODE_WS_SEND; // schedule WS update serveJson(request); return; //if JSON contains "v" } else { doSerializeConfig = true; //serializeConfig(); //Save new settings to FS @@ -233,12 +224,8 @@ void initServer() }); #ifdef WLED_ENABLE_USERMOD_PAGE - server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_usermod, PAGE_usermod_length); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); + server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "", 200, "text/html", PAGE_usermod, PAGE_usermod_length); }); #endif @@ -251,38 +238,13 @@ void initServer() size_t len, bool final) {handleUpload(request, filename, index, data, len, final);} ); -#ifdef WLED_ENABLE_SIMPLE_UI - server.on("/simple.htm", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleFileRead(request, "/simple.htm")) return; - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_simple, PAGE_simple_L); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); - }); -#endif - - server.on("/iro.js", HTTP_GET, [](AsyncWebServerRequest *request){ - AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", iroJs, iroJs_length); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); - }); - - server.on("/rangetouch.js", HTTP_GET, [](AsyncWebServerRequest *request){ - AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", rangetouchJs, rangetouchJs_length); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); - }); - createEditHandler(correctPIN); #ifndef WLED_DISABLE_OTA //init ota page server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){ if (otaLock) { - serveMessage(request, 500, "Access Denied", FPSTR(s_unlock_ota), 254); + serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254); } else serveSettings(request); // checks for "upd" in URL and handles PIN }); @@ -292,7 +254,11 @@ void initServer() serveSettings(request, true); // handle PIN page POST request return; } - if (Update.hasError() || otaLock) { + if (otaLock) { + serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254); + return; + } + if (Update.hasError()) { serveMessage(request, 500, F("Update failed!"), F("Please check your file and retry!"), 254); } else { serveMessage(request, 200, F("Update successful!"), F("Rebooting..."), 131); @@ -302,10 +268,14 @@ void initServer() if (!correctPIN || otaLock) return; if(!index){ DEBUG_PRINTLN(F("OTA Update Start")); + #if WLED_WATCHDOG_TIMEOUT > 0 WLED::instance().disableWatchdog(); + #endif usermods.onUpdateBegin(true); // notify usermods that update is about to begin (some may require task de-init) lastEditTime = millis(); // make sure PIN does not lock during update + strip.suspend(); #ifdef ESP8266 + strip.resetSegments(); // free as much memory as you can Update.runAsync(true); #endif Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000); @@ -316,8 +286,11 @@ void initServer() DEBUG_PRINTLN(F("Update Success")); } else { DEBUG_PRINTLN(F("Update Failed")); + strip.resume(); usermods.onUpdateBegin(false); // notify usermods that update has failed (some may require task init) + #if WLED_WATCHDOG_TIMEOUT > 0 WLED::instance().enableWatchdog(); + #endif } } }); @@ -338,44 +311,29 @@ void initServer() }); #endif - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){ + server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { if (captivePortal(request)) return; - if (!showWelcomePage || request->hasArg(F("sliders"))){ - serveIndex(request); + if (!showWelcomePage || request->hasArg(F("sliders"))) { + handleStaticContent(request, "/index.htm", 200, "text/html", PAGE_index, PAGE_index_L); } else { serveSettings(request); } }); - #ifdef WLED_ENABLE_PIXART - server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleFileRead(request, "/pixart.htm")) return; - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pixart, PAGE_pixart_L); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); +#ifdef WLED_ENABLE_PIXART + server.on("/pixart.htm", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "/pixart.htm", 200, "text/html", PAGE_pixart, PAGE_pixart_L); }); #endif - #ifndef WLED_DISABLE_PXMAGIC - server.on("/pxmagic.htm", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleFileRead(request, "/pxmagic.htm")) return; - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_pxmagic, PAGE_pxmagic_L); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); +#ifndef WLED_DISABLE_PXMAGIC + server.on("/pxmagic.htm", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "/pxmagic.htm", 200, "text/html", PAGE_pxmagic, PAGE_pxmagic_L); }); - #endif +#endif - server.on("/cpal.htm", HTTP_GET, [](AsyncWebServerRequest *request){ - if (handleFileRead(request, "/cpal.htm")) return; - if (handleIfNoneMatchCacheHeader(request)) return; - AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_cpal, PAGE_cpal_L); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); + server.on("/cpal.htm", HTTP_GET, [](AsyncWebServerRequest *request) { + handleStaticContent(request, "/cpal.htm", 200, "text/html", PAGE_cpal, PAGE_cpal_L); }); #ifdef WLED_ENABLE_WEBSOCKETS @@ -401,59 +359,73 @@ void initServer() #ifndef WLED_DISABLE_ALEXA if(espalexa.handleAlexaApiCall(request)) return; #endif - if(handleFileRead(request, request->url())) return; - AsyncWebServerResponse *response = request->beginResponse_P(404, "text/html", PAGE_404, PAGE_404_length); - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); + handleStaticContent(request, request->url(), 404, "text/html", PAGE_404, PAGE_404_length); }); } -bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request) -{ - AsyncWebHeader* header = request->getHeader("If-None-Match"); - if (header && header->value() == String(VERSION)) { - request->send(304); +void generateEtag(char *etag, uint16_t eTagSuffix) { + sprintf_P(etag, PSTR("%7d-%02x-%04x"), VERSION, cacheInvalidate, eTagSuffix); +} + +bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest *request, int code, uint16_t eTagSuffix) { + // Only send 304 (Not Modified) if response code is 200 (OK) + if (code != 200) return false; + + AsyncWebHeader *header = request->getHeader("If-None-Match"); + char etag[14]; + generateEtag(etag, eTagSuffix); + if (header && header->value() == etag) { + AsyncWebServerResponse *response = request->beginResponse(304); + setStaticContentCacheHeaders(response, code, eTagSuffix); + request->send(response); return true; } return false; } -void setStaticContentCacheHeaders(AsyncWebServerResponse *response) -{ - char tmp[12]; +void setStaticContentCacheHeaders(AsyncWebServerResponse *response, int code, uint16_t eTagSuffix) { + // Only send ETag for 200 (OK) responses + if (code != 200) return; + // https://medium.com/@codebyamir/a-web-developers-guide-to-browser-caching-cc41f3b73e7c #ifndef WLED_DEBUG - //this header name is misleading, "no-cache" will not disable cache, - //it just revalidates on every load using the "If-None-Match" header with the last ETag value - response->addHeader(F("Cache-Control"),"no-cache"); + // this header name is misleading, "no-cache" will not disable cache, + // it just revalidates on every load using the "If-None-Match" header with the last ETag value + response->addHeader(F("Cache-Control"), "no-cache"); #else - response->addHeader(F("Cache-Control"),"no-store,max-age=0"); // prevent caching if debug build + response->addHeader(F("Cache-Control"), "no-store,max-age=0"); // prevent caching if debug build #endif - sprintf_P(tmp, PSTR("%8d-%02x"), VERSION, cacheInvalidate); - response->addHeader(F("ETag"), tmp); + char etag[14]; + generateEtag(etag, eTagSuffix); + response->addHeader(F("ETag"), etag); } -void serveIndex(AsyncWebServerRequest* request) -{ - if (handleFileRead(request, "/index.htm")) return; - - if (handleIfNoneMatchCacheHeader(request)) return; - - AsyncWebServerResponse *response; -#ifdef WLED_ENABLE_SIMPLE_UI - if (simplifiedUI) - response = request->beginResponse_P(200, "text/html", PAGE_simple, PAGE_simple_L); - else -#endif - response = request->beginResponse_P(200, "text/html", PAGE_index, PAGE_index_L); - - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); +/** + * Handels the request for a static file. + * If the file was found in the filesystem, it will be sent to the client. + * Otherwise it will be checked if the browser cached the file and if so, a 304 response will be sent. + * If the file was not found in the filesystem and not in the browser cache, the request will be handled as a 200 response with the content of the page. + * + * @param request The request object + * @param path If a file with this path exists in the filesystem, it will be sent to the client. Set to "" to skip this check. + * @param code The HTTP status code + * @param contentType The content type of the web page + * @param content Content of the web page + * @param len Length of the content + * @param gzip Optional. Defaults to true. If false, the gzip header will not be added. + * @param eTagSuffix Optional. Defaults to 0. A suffix that will be added to the ETag header. This can be used to invalidate the cache for a specific page. + */ +void handleStaticContent(AsyncWebServerRequest *request, const String &path, int code, const String &contentType, const uint8_t *content, size_t len, bool gzip, uint16_t eTagSuffix) { + if (path != "" && handleFileRead(request, path)) return; + if (handleIfNoneMatchCacheHeader(request, code, eTagSuffix)) return; + AsyncWebServerResponse *response = request->beginResponse_P(code, contentType, content, len); + if (gzip) response->addHeader(FPSTR(s_content_enc), "gzip"); + setStaticContentCacheHeaders(response, code, eTagSuffix); request->send(response); } + String msgProcessor(const String& var) { if (var == "MSG") { @@ -498,6 +470,18 @@ void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& h } +void serveJsonError(AsyncWebServerRequest* request, uint16_t code, uint16_t error) +{ + AsyncJsonResponse *response = new AsyncJsonResponse(64); + if (error < ERR_NOT_IMPL) response->addHeader("Retry-After", "1"); + response->setContentType("application/json"); + response->setCode(code); + JsonObject obj = response->getRoot(); + obj[F("error")] = error; + response->setLength(); + request->send(response); +} + #ifdef WLED_ENABLE_DMX String dmxProcessor(const String& var) { @@ -533,7 +517,7 @@ void serveSettingsJS(AsyncWebServerRequest* request) } if (subPage > 0 && !correctPIN && strlen(settingsPIN)>0) { strcpy_P(buf, PSTR("alert('PIN incorrect.');")); - request->send(403, "application/javascript", buf); + request->send(401, "application/javascript", buf); return; } strcat_P(buf,PSTR("function GetV(){var d=document;")); @@ -543,13 +527,11 @@ void serveSettingsJS(AsyncWebServerRequest* request) } -void serveSettings(AsyncWebServerRequest* request, bool post) -{ +void serveSettings(AsyncWebServerRequest* request, bool post) { byte subPage = 0, originalSubPage = 0; const String& url = request->url(); - if (url.indexOf("sett") >= 0) - { + if (url.indexOf("sett") >= 0) { if (url.indexOf(".js") > 0) subPage = SUBPAGE_JS; else if (url.indexOf(".css") > 0) subPage = SUBPAGE_CSS; else if (url.indexOf("wifi") > 0) subPage = SUBPAGE_WIFI; @@ -575,7 +557,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, 500, "Access Denied", FPSTR(s_unlock_ota), 254); return; + serveMessage(request, 401, "Access Denied", FPSTR(s_unlock_ota), 254); return; } if (post) { //settings/set POST request, saving @@ -585,7 +567,7 @@ void serveSettings(AsyncWebServerRequest* request, bool post) char s2[45] = ""; switch (subPage) { - case SUBPAGE_WIFI : strcpy_P(s, PSTR("WiFi")); strcpy_P(s2, PSTR("Please connect to the new IP (if changed)")); forceReconnect = true; break; + case SUBPAGE_WIFI : strcpy_P(s, PSTR("WiFi")); strcpy_P(s2, PSTR("Please connect to the new IP (if changed)")); break; case SUBPAGE_LEDS : strcpy_P(s, PSTR("LED")); break; case SUBPAGE_UI : strcpy_P(s, PSTR("UI")); break; case SUBPAGE_SYNC : strcpy_P(s, PSTR("Sync")); break; @@ -605,27 +587,30 @@ void serveSettings(AsyncWebServerRequest* request, bool post) if (!s2[0]) strcpy_P(s2, s_redirecting); bool redirectAfter9s = (subPage == SUBPAGE_WIFI || ((subPage == SUBPAGE_SEC || subPage == SUBPAGE_UM) && doReboot)); - serveMessage(request, 200, s, s2, redirectAfter9s ? 129 : (correctPIN ? 1 : 3)); + serveMessage(request, (correctPIN ? 200 : 401), s, s2, redirectAfter9s ? 129 : (correctPIN ? 1 : 3)); return; } } - AsyncWebServerResponse *response; - switch (subPage) - { - case SUBPAGE_WIFI : response = request->beginResponse_P(200, "text/html", PAGE_settings_wifi, PAGE_settings_wifi_length); break; - case SUBPAGE_LEDS : response = request->beginResponse_P(200, "text/html", PAGE_settings_leds, PAGE_settings_leds_length); break; - case SUBPAGE_UI : response = request->beginResponse_P(200, "text/html", PAGE_settings_ui, PAGE_settings_ui_length); break; - case SUBPAGE_SYNC : response = request->beginResponse_P(200, "text/html", PAGE_settings_sync, PAGE_settings_sync_length); break; - case SUBPAGE_TIME : response = request->beginResponse_P(200, "text/html", PAGE_settings_time, PAGE_settings_time_length); break; - case SUBPAGE_SEC : response = request->beginResponse_P(200, "text/html", PAGE_settings_sec, PAGE_settings_sec_length); break; + int code = 200; + String contentType = "text/html"; + const uint8_t* content; + size_t len; + + switch (subPage) { + case SUBPAGE_WIFI : content = PAGE_settings_wifi; len = PAGE_settings_wifi_length; break; + case SUBPAGE_LEDS : content = PAGE_settings_leds; len = PAGE_settings_leds_length; break; + case SUBPAGE_UI : content = PAGE_settings_ui; len = PAGE_settings_ui_length; break; + case SUBPAGE_SYNC : content = PAGE_settings_sync; len = PAGE_settings_sync_length; break; + case SUBPAGE_TIME : content = PAGE_settings_time; len = PAGE_settings_time_length; break; + case SUBPAGE_SEC : content = PAGE_settings_sec; len = PAGE_settings_sec_length; break; #ifdef WLED_ENABLE_DMX - case SUBPAGE_DMX : response = request->beginResponse_P(200, "text/html", PAGE_settings_dmx, PAGE_settings_dmx_length); break; + case SUBPAGE_DMX : content = PAGE_settings_dmx; len = PAGE_settings_dmx_length; break; #endif - case SUBPAGE_UM : response = request->beginResponse_P(200, "text/html", PAGE_settings_um, PAGE_settings_um_length); break; - case SUBPAGE_UPDATE : response = request->beginResponse_P(200, "text/html", PAGE_update, PAGE_update_length); break; + case SUBPAGE_UM : content = PAGE_settings_um; len = PAGE_settings_um_length; break; + case SUBPAGE_UPDATE : content = PAGE_update; len = PAGE_update_length; break; #ifndef WLED_DISABLE_2D - case SUBPAGE_2D : response = request->beginResponse_P(200, "text/html", PAGE_settings_2D, PAGE_settings_2D_length); break; + case SUBPAGE_2D : content = PAGE_settings_2D; len = PAGE_settings_2D_length; break; #endif case SUBPAGE_LOCK : { correctPIN = !strlen(settingsPIN); // lock if a pin is set @@ -633,13 +618,11 @@ void serveSettings(AsyncWebServerRequest* request, bool post) serveMessage(request, 200, strlen(settingsPIN) > 0 ? PSTR("Settings locked") : PSTR("No PIN set"), FPSTR(s_redirecting), 1); return; } - case SUBPAGE_PINREQ : response = request->beginResponse_P(200, "text/html", PAGE_settings_pin, PAGE_settings_pin_length); break; - case SUBPAGE_CSS : response = request->beginResponse_P(200, "text/css", PAGE_settingsCss, PAGE_settingsCss_length); break; - case SUBPAGE_JS : serveSettingsJS(request); return; - case SUBPAGE_WELCOME : response = request->beginResponse_P(200, "text/html", PAGE_welcome, PAGE_welcome_length); break; - default: response = request->beginResponse_P(200, "text/html", PAGE_settings, PAGE_settings_length); break; + case SUBPAGE_PINREQ : content = PAGE_settings_pin; len = PAGE_settings_pin_length; code = 401; break; + case SUBPAGE_CSS : content = PAGE_settingsCss; len = PAGE_settingsCss_length; contentType = "text/css"; break; + case SUBPAGE_JS : serveSettingsJS(request); return; + case SUBPAGE_WELCOME : content = PAGE_welcome; len = PAGE_welcome_length; break; + default: content = PAGE_settings; len = PAGE_settings_length; break; } - response->addHeader(FPSTR(s_content_enc),"gzip"); - setStaticContentCacheHeaders(response); - request->send(response); + handleStaticContent(request, "", code, contentType, content, len); } diff --git a/wled00/ws.cpp b/wled00/ws.cpp index 49780d026..7082a848d 100644 --- a/wled00/ws.cpp +++ b/wled00/ws.cpp @@ -38,8 +38,8 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp bool verboseResponse = false; if (!requestJSONBufferLock(11)) return; - DeserializationError error = deserializeJson(doc, data, len); - JsonObject root = doc.as(); + DeserializationError error = deserializeJson(*pDoc, data, len); + JsonObject root = pDoc->as(); if (error || root.isNull()) { releaseJSONBufferLock(); return; @@ -103,13 +103,13 @@ void sendDataWs(AsyncWebSocketClient * client) if (!requestJSONBufferLock(12)) return; - JsonObject state = doc.createNestedObject("state"); + JsonObject state = pDoc->createNestedObject("state"); serializeState(state); - JsonObject info = doc.createNestedObject("info"); + JsonObject info = pDoc->createNestedObject("info"); serializeInfo(info); - size_t len = measureJson(doc); - DEBUG_PRINTF("JSON buffer size: %u for WS request (%u).\n", doc.memoryUsage(), len); + size_t len = measureJson(*pDoc); + DEBUG_PRINTF("JSON buffer size: %u for WS request (%u).\n", pDoc->memoryUsage(), len); size_t heap1 = ESP.getFreeHeap(); DEBUG_PRINT(F("heap ")); DEBUG_PRINTLN(ESP.getFreeHeap()); @@ -136,7 +136,7 @@ void sendDataWs(AsyncWebSocketClient * client) } buffer->lock(); - serializeJson(doc, (char *)buffer->get(), len); + serializeJson(*pDoc, (char *)buffer->get(), len); DEBUG_PRINT(F("Sending WS data ")); if (client) { @@ -164,39 +164,39 @@ bool sendLiveLedsWs(uint32_t wsClient) const size_t MAX_LIVE_LEDS_WS = 1024U; #endif size_t n = ((used -1)/MAX_LIVE_LEDS_WS) +1; //only serve every n'th LED if count over MAX_LIVE_LEDS_WS - size_t pos = (strip.isMatrix ? 4 : 2); // start of data + size_t pos = 2; // start of data +#ifndef WLED_DISABLE_2D + if (strip.isMatrix) { + // ignore anything behid matrix (i.e. extra strip) + used = Segment::maxWidth*Segment::maxHeight; // always the size of matrix (more or less than strip.getLengthTotal()) + n = 1; + if (used > MAX_LIVE_LEDS_WS) n = 2; + if (used > MAX_LIVE_LEDS_WS*4) n = 4; + pos = 4; + } +#endif size_t bufSize = pos + (used/n)*3; AsyncWebSocketMessageBuffer * wsBuf = ws.makeBuffer(bufSize); if (!wsBuf) return false; //out of memory uint8_t* buffer = wsBuf->get(); + if (!buffer) return false; //out of memory + wsBuf->lock(); // protect buffer from being cleaned by another WS instance buffer[0] = 'L'; buffer[1] = 1; //version #ifndef WLED_DISABLE_2D - size_t skipLines = 0; if (strip.isMatrix) { buffer[1] = 2; //version - buffer[2] = Segment::maxWidth; - buffer[3] = Segment::maxHeight; - if (used > MAX_LIVE_LEDS_WS*4) { - buffer[2] = Segment::maxWidth/4; - buffer[3] = Segment::maxHeight/4; - skipLines = 3; - } else if (used > MAX_LIVE_LEDS_WS) { - buffer[2] = Segment::maxWidth/2; - buffer[3] = Segment::maxHeight/2; - skipLines = 1; - } + buffer[2] = Segment::maxWidth/n; + buffer[3] = Segment::maxHeight/n; } #endif for (size_t i = 0; pos < bufSize -2; i += n) { #ifndef WLED_DISABLE_2D - if (strip.isMatrix && skipLines) { - if ((i/Segment::maxWidth)%(skipLines+1)) i += Segment::maxWidth * skipLines; - } + if (strip.isMatrix && n>1 && (i/Segment::maxWidth)%n) i += Segment::maxWidth * (n-1); #endif uint32_t c = strip.getPixelColor(i); uint8_t r = R(c); @@ -209,6 +209,8 @@ bool sendLiveLedsWs(uint32_t wsClient) } wsc->binary(wsBuf); + wsBuf->unlock(); // un-protect buffer + ws._cleanBuffers(); return true; } diff --git a/wled00/xml.cpp b/wled00/xml.cpp old mode 100644 new mode 100755 index c2504cf92..de183c5a6 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -31,7 +31,7 @@ void XML_response(AsyncWebServerRequest *request, char* dest) oappend(SET_F("")); oappendi(notifyDirect); oappend(SET_F("")); - oappendi(receiveNotifications); + oappendi(receiveGroups!=0); oappend(SET_F("")); oappendi(nightlightActive); oappend(SET_F("")); @@ -133,7 +133,7 @@ void appendGPIOinfo() { // usermod pin reservations will become unnecessary when settings pages will read cfg.json directly if (requestJSONBufferLock(6)) { // if we can't allocate JSON buffer ignore usermod pins - JsonObject mods = doc.createNestedObject(F("um")); + JsonObject mods = pDoc->createNestedObject(F("um")); usermods.addToConfig(mods); if (!mods.isNull()) fillUMPins(mods); releaseJSONBufferLock(); @@ -277,14 +277,15 @@ void getSettingsJS(byte subPage, char* dest) sappends('s',SET_F("AP"),fapass); sappend('v',SET_F("AC"),apChannel); + sappend('c',SET_F("FG"),force802_3g); sappend('c',SET_F("WS"),noWifiSleep); #ifndef WLED_DISABLE_ESPNOW - sappend('c',SET_F("RE"),enable_espnow_remote); + sappend('c',SET_F("RE"),enableESPNow); sappends('s',SET_F("RMAC"),linked_remote); #else //hide remote settings if not compiled - oappend(SET_F("document.getElementById('remd').style.display='none';")); + oappend(SET_F("toggle('ESPNOW');")); // hide ESP-NOW setting #endif #ifdef WLED_USE_ETHERNET @@ -321,14 +322,11 @@ void getSettingsJS(byte subPage, char* dest) } #ifndef WLED_DISABLE_ESPNOW - if (last_signal_src[0] != 0) //Have seen an ESP-NOW Remote - { + if (strlen(last_signal_src) > 0) { //Have seen an ESP-NOW Remote sappends('m',SET_F("(\"rlid\")[0]"),last_signal_src); - } else if (!enable_espnow_remote) - { - sappends('m',SET_F("(\"rlid\")[0]"),(char*)F("(Enable remote to listen)")); - } else - { + } else if (!enableESPNow) { + sappends('m',SET_F("(\"rlid\")[0]"),(char*)F("(Enable ESP-NOW to listen)")); + } else { sappends('m',SET_F("(\"rlid\")[0]"),(char*)F("None")); } #endif @@ -357,8 +355,9 @@ void getSettingsJS(byte subPage, char* dest) sappend('v',SET_F("AW"),Bus::getGlobalAWMode()); sappend('c',SET_F("LD"),useGlobalLedBuffer); - for (uint8_t s=0; s < busses.getNumBusses(); s++) { - Bus* bus = busses.getBus(s); + uint16_t sumMa = 0; + for (uint8_t s=0; s < BusManager::getNumBusses(); s++) { + Bus* bus = BusManager::getBus(s); if (bus == nullptr) continue; char lp[4] = "L0"; lp[2] = 48+s; lp[3] = 0; //ascii 0-9 //strip data pin char lc[4] = "LC"; lc[2] = 48+s; lc[3] = 0; //strip length @@ -371,12 +370,14 @@ void getSettingsJS(byte subPage, char* dest) char aw[4] = "AW"; aw[2] = 48+s; aw[3] = 0; //auto white mode char wo[4] = "WO"; wo[2] = 48+s; wo[3] = 0; //swap channels char sp[4] = "SP"; sp[2] = 48+s; sp[3] = 0; //bus clock speed + char la[4] = "LA"; la[2] = 48+s; la[3] = 0; //LED current + char ma[4] = "MA"; ma[2] = 48+s; ma[3] = 0; //max per-port PSU current oappend(SET_F("addLEDs(1);")); uint8_t pins[5]; uint8_t nPins = bus->getPins(pins); for (uint8_t i = 0; i < nPins; i++) { lp[1] = 48+i; - if (pinManager.isPinOk(pins[i]) || bus->getType()>=TYPE_NET_DDP_RGB) sappend('v',lp,pins[i]); + if (pinManager.isPinOk(pins[i]) || IS_VIRTUAL(bus->getType())) sappend('v',lp,pins[i]); } sappend('v',lc,bus->getLength()); sappend('v',lt,bus->getType()); @@ -388,16 +389,16 @@ void getSettingsJS(byte subPage, char* dest) sappend('v',aw,bus->getAutoWhiteMode()); sappend('v',wo,bus->getColorOrder() >> 4); uint16_t speed = bus->getFrequency(); - if (bus->getType() > TYPE_ONOFF && bus->getType() < 48) { + if (IS_PWM(bus->getType())) { switch (speed) { - case WLED_PWM_FREQ/3 : speed = 0; break; - case WLED_PWM_FREQ/2 : speed = 1; break; + case WLED_PWM_FREQ/3 : speed = 0; break; + case WLED_PWM_FREQ/2 : speed = 1; break; default: - case WLED_PWM_FREQ : speed = 2; break; - case WLED_PWM_FREQ*2 : speed = 3; break; - case WLED_PWM_FREQ*3 : speed = 4; break; + case WLED_PWM_FREQ : speed = 2; break; + case WLED_PWM_FREQ*4/3 : speed = 3; break; + case WLED_PWM_FREQ*2 : speed = 4; break; } - } else { + } else if (IS_DIGITAL(bus->getType()) && IS_2PIN(bus->getType())) { switch (speed) { case 1000 : speed = 0; break; case 2000 : speed = 1; break; @@ -408,28 +409,24 @@ void getSettingsJS(byte subPage, char* dest) } } sappend('v',sp,speed); + sappend('v',la,bus->getLEDCurrent()); + sappend('v',ma,bus->getMaxCurrent()); + sumMa += bus->getMaxCurrent(); } - sappend('v',SET_F("MA"),strip.ablMilliampsMax); - sappend('v',SET_F("LA"),strip.milliampsPerLed); - if (strip.currentMilliamps) - { - sappends('m',SET_F("(\"pow\")[0]"),(char*)""); - olen -= 2; //delete "; - oappendi(strip.currentMilliamps); - oappend(SET_F("mA\";")); - } + sappend('v',SET_F("MA"),BusManager::ablMilliampsMax() ? BusManager::ablMilliampsMax() : sumMa); + sappend('c',SET_F("PPL"),!BusManager::ablMilliampsMax() && sumMa > 0); oappend(SET_F("resetCOM(")); oappend(itoa(WLED_MAX_COLOR_ORDER_MAPPINGS,nS,10)); oappend(SET_F(");")); - const ColorOrderMap& com = busses.getColorOrderMap(); + const ColorOrderMap& com = BusManager::getColorOrderMap(); for (uint8_t s=0; s < com.count(); s++) { const ColorOrderMapEntry* entry = com.get(s); if (entry == nullptr) break; oappend(SET_F("addCOM(")); - oappend(itoa(entry->start,nS,10)); oappend(","); - oappend(itoa(entry->len,nS,10)); oappend(","); - oappend(itoa(entry->colorOrder,nS,10)); oappend(");"); + oappend(itoa(entry->start,nS,10)); oappend(","); + oappend(itoa(entry->len,nS,10)); oappend(","); + oappend(itoa(entry->colorOrder,nS,10)); oappend(");"); } sappend('v',SET_F("CA"),briS); @@ -441,6 +438,7 @@ void getSettingsJS(byte subPage, char* dest) sappend('c',SET_F("GC"),gammaCorrectCol); dtostrf(gammaCorrectVal,3,1,nS); sappends('s',SET_F("GV"),nS); sappend('c',SET_F("TF"),fadeTransition); + sappend('c',SET_F("EB"),modeBlending); sappend('v',SET_F("TD"),transitionDelayDefault); sappend('c',SET_F("PF"),strip.paletteFade); sappend('v',SET_F("TP"),randomPaletteChangeTime); @@ -453,7 +451,7 @@ void getSettingsJS(byte subPage, char* dest) sappend('c',SET_F("RM"),rlyMde); for (uint8_t i=0; i